लाइव एजेंट ट्रांसफ़र की सुविधा

1. परिचय

53003251caaf2be5.png 6717b85f57d859d3.png

पिछले अपडेट की तारीख: 23-08-2021

Business Messages के ज़रिए लाइव एजेंट को ट्रांसफ़र करने की सुविधा

Business Messages में लाइव एजेंट को ट्रांसफ़र करने की सुविधा उपलब्ध है. इसकी मदद से, आपका एजेंट बॉट के तौर पर बातचीत शुरू कर सकता है. साथ ही, बातचीत के बीच में लाइव एजेंट (मानव प्रतिनिधि) पर स्विच कर सकता है. आपका बॉट, सामान्य सवालों के जवाब दे सकता है. जैसे, खुलने का समय. वहीं, लाइव एजेंट, उपयोगकर्ता के संदर्भ के बारे में ज़्यादा जानकारी पाकर, उसे बेहतर अनुभव दे सकता है. जब इन दोनों अनुभवों के बीच ट्रांज़िशन आसानी से होता है, तो उपयोगकर्ताओं को उनके सवालों के जवाब जल्दी और सटीक तरीके से मिलते हैं. इससे, उपयोगकर्ताओं की दिलचस्पी बढ़ती है और खरीदार संतुष्ट होते हैं.

इस कोडलैब में, लाइव एजेंट ट्रांसफ़र की सुविधा का पूरा फ़ायदा पाने का तरीका बताया गया है.

आपको क्या बनाने को मिलेगा

इस कोडलैब में, आपको अपने एजेंट के लिए एक वेबहुक बनाना है. यह वेबहुक, लाइव एजेंट ट्रांसफ़र इवेंट भेज और पा सकता है. आपने जो बनाया है उसे टेस्ट करने के लिए, स्टार्टर कोड से मिले बेसिक यूज़र इंटरफ़ेस (यूआई) का इस्तेमाल करें.

49aca3df6b196c50.png

आपको क्या सीखने को मिलेगा

  • बातचीत की स्थिति को सेव और मैनेज करने का तरीका.
  • लाइव एजेंट ट्रांसफ़र इवेंट भेजने के लिए, Business Messages का इस्तेमाल करने का तरीका.
  • एजेंट के तौर पर बातचीत में शामिल होने के लिए, वेबहुक और बुनियादी यूज़र इंटरफ़ेस (यूआई) सेट अप करने का तरीका.
  • Business Messages API इस्तेमाल करने के सबसे सही तरीके.

इस कोडलैब में, लाइव एजेंट ट्रांसफ़र की सुविधा लागू करने के लिए Business Messages API का इस्तेमाल करने के बारे में बताया गया है. हर चरण के लिए, स्टार्टर कोड पढ़ा जा सकता है. हालांकि, आपको सिर्फ़ Business Messages से जुड़ा कोड लागू करना होगा.

आपको इन चीज़ों की ज़रूरत होगी

  • Business Messages एजेंट, जिसमें आपके सेवा खाते की कुंजी भी शामिल है. एजेंट बनाने के लिए गाइड को पढ़कर, एजेंट बनाया जा सकता है.
  • आपके एजेंट के GCP प्रोजेक्ट से लिंक किया गया Cloud Datastore का चालू कॉन्फ़िगरेशन. इसे सेट अप करने के लिए, Cloud Datastore क्विकस्टार्ट का इस्तेमाल किया जा सकता है. इसके लिए, आपको Cloud Datastore का इस्तेमाल करने का तरीका जानने की ज़रूरत नहीं है.
  • कंप्यूटर पर Google Cloud SDK और Node.js (वर्शन 10 या इसके बाद का वर्शन) इंस्टॉल होना चाहिए.
  • उपयोगकर्ता अनुभव की जांच करने के लिए, Android डिवाइस (Android 5 या इसके बाद के वर्शन वाला) या iOS डिवाइस.
  • वेब ऐप्लिकेशन प्रोग्रामिंग का अनुभव हो. आपको JavaScript कोड का एक छोटा सा हिस्सा लिखना होगा. साथ ही, आपको लिखे गए कोड को डीबग करने की ज़रूरत पड़ सकती है.

2. इको बॉट बनाना

इस चरण में, आपको "इको बॉट" नाम का एक बुनियादी बॉट प्रतिनिधि डिप्लॉय करना होगा. यह बॉट, उपयोगकर्ता के मैसेज लेता है और उन्हें Cloud Datastore में बातचीत की थ्रेड में लॉग करता है. इसके बाद, यह उपयोगकर्ता के मैसेज का जवाब उसी कॉन्टेंट के साथ देता है. जब आपके पास बुनियादी बॉट और लॉगिंग इंफ़्रास्ट्रक्चर हो, तो बाद के चरणों में इसका इस्तेमाल करके, लाइव एजेंट को ट्रांसफ़र करने की सुविधा को पूरी तरह से लागू किया जा सकता है.

स्टार्टर कोड पाना

टर्मिनल में, लाइव एजेंट ट्रांसफ़र के स्टार्टर कोड को अपने प्रोजेक्ट की वर्किंग डायरेक्ट्री में क्लोन करें. इसके लिए, यह कमांड इस्तेमाल करें:

git clone https://github.com/google-business-communications/bm-nodejs-live-agent-transfer

स्टार्टर कोड को समझना

आइए, स्टार्टर कोड के स्ट्रक्चर पर एक नज़र डालें. इस कोडलैब में आपको इसी स्ट्रक्चर के साथ काम करना होगा.

step-1 डायरेक्ट्री पर जाएं और उसका कॉन्टेंट देखें. इसमें ये एलिमेंट शामिल होते हैं:

  • bin: इस डायरेक्ट्री में www स्टार्टर स्क्रिप्ट होती है. यह स्क्रिप्ट, सर्वर को सेट अप और कॉन्फ़िगर करती है.
  • libs: इस डायरेक्ट्री में datastore_util.js होता है. इसमें Cloud Datastore से डेटा पढ़ने और उसमें डेटा लिखने के लिए, आसान तरीके शामिल होते हैं. आपको यह समझने की ज़रूरत नहीं है कि यह फ़ाइल कैसे काम करती है. बस उपलब्ध तरीकों और उनके काम करने के तरीके के बारे में जान लें.
  • resources: इसमें आपकी सेवा खाते की कुंजी होती है. इसे credentials.json नाम की फ़ाइल के तौर पर सेव किया जाता है.
  • routes: index.js फ़ाइल में वेबुक और उसके सभी हेल्पर तरीके शामिल होते हैं. यह मुख्य फ़ाइल है, जिसमें आपको काम करना है और जानकारी जोड़नी है.
  • views: इस डायरेक्ट्री में, यूज़र इंटरफ़ेस (यूआई) एलिमेंट के लिए EJS टेंप्लेट फ़ाइलें होती हैं. इसमें बाद के चरणों में और फ़ाइलें शामिल होंगी.
  • app.js, app.yaml, package.json: ये फ़ाइलें, ऐप्लिकेशन और उसकी डिपेंडेंसी को कॉन्फ़िगर करती हैं.

डिप्लॉय करने से पहले, अपने GCP सेवा खाते की कुंजी डाउनलोड करें. साथ ही, JSON क्रेडेंशियल फ़ाइल को सैंपल कोड में मौजूद हर संसाधन डायरेक्ट्री में कॉपी करें. कोडलैब के हर चरण के लिए ऐसा करें.

cp credentials.json bm-nodejs-live-agent-transfer/step-<step number>/resources/credentials.json

स्टार्टर कोड डिप्लॉय करना

टर्मिनल में, सैंपल की step-1 डायरेक्ट्री पर जाएं. इसके बाद, gcloud टूल को अपने Google Cloud प्रोजेक्ट का इस्तेमाल करने के लिए सेट करें. इसके लिए, उस प्रोजेक्ट आईडी को सेट करें जिसका इस्तेमाल आपने एपीआई के साथ रजिस्टर करने के लिए किया था.

gcloud config set project <PROJECT_ID>

ऐप्लिकेशन को डिप्लॉय करने के लिए, यह कमांड चलाएं:

gcloud app deploy

आखिरी कमांड के आउटपुट में, डिप्लॉय किए गए ऐप्लिकेशन का यूआरएल नोट करें:

Deployed service [default] to [https://PROJECT_ID.appspot.com]

अभी-अभी डिप्लॉय किए गए स्टार्टर कोड में, एक वेब ऐप्लिकेशन होता है. इसमें Business Messages से मैसेज पाने के लिए, एक वेबहुक होता है. यह ऐप्लिकेशन, उपयोगकर्ता को मैसेज वापस भेजता है और मैसेज थ्रेड को Cloud Datastore में लॉग करता है.

अपने एजेंट को कॉन्फ़िगर करना

Business Communications डेवलपर कंसोल में, खाता सेटिंग वाले पेज पर जाएं. इसके बाद, अपने डिप्लॉय किए गए ऐप्लिकेशन के यूआरएल पर वेबहुक सेट करें. उदाहरण के लिए, https://PROJECT_ID.appspot.com/callback/.

इसके बाद, एजेंट की जानकारी वाले पेज पर जाकर, इंटरैक्शन के मुख्य और दूसरे टाइप को क्रमशः बॉट और व्यक्ति के तौर पर कॉन्फ़िगर करें.

db0cca5b74f999ad.png

इको बॉट से बातचीत करना

Developer Console में अपना एजेंट खोलें. आपको खास जानकारी पेज दिखेगा. इस पेज पर, अपने एजेंट की जानकारी देखी जा सकती है. अपने मोबाइल टेस्ट डिवाइस से मेल खाने वाले एजेंट टेस्ट यूआरएल को कॉपी करें. अपने एजेंट के साथ बातचीत करने के लिए, अपने फ़ोन या टैबलेट पर इस यूआरएल का इस्तेमाल करें.

536313929e5c0b3e.png

कुछ मैसेज भेजकर, एजेंट के साथ इंटरैक्ट करें. बातचीत वाली सुविधा सिर्फ़ आपके कहे गए शब्दों को कॉपी करती है. इससे उपयोगकर्ता को ज़्यादा फ़ायदा नहीं मिलता. अगर किसी असली व्यक्ति से बात करने का कोई तरीका होता, तो कितना अच्छा होता!

3. बातचीत में शामिल होना

अब लाइव एजेंट के नज़रिए से बातचीत को देखते हैं. लाइव एजेंट के तौर पर, आपको बातचीत में शामिल होने से पहले उसके बारे में कुछ चीज़ें पता होनी चाहिए. जैसे, बातचीत का आईडी. यह जानना भी मददगार होता है कि क्या उपयोगकर्ता ने लाइव एजेंट से बात करने का अनुरोध किया है. इस चरण में, आपको इस जानकारी को देखने के लिए, बुनियादी सीआरएम (कस्टमर रिलेशनशिप मैनेजमेंट) पेज का इस्तेमाल करना होगा. साथ ही, लाइव एजेंट के तौर पर बातचीत में शामिल होना होगा.

इस चरण के लिए दिए गए स्टार्टर कोड में एक बुनियादी सीआरएम जोड़ा गया है. इसमें एजेंट के साथ चल रही सभी बातचीत की थ्रेड की सूची होती है. आइए, उस सीआरएम को देखें. इससे पता चलेगा कि किन बातचीत के लिए लाइव एजेंट की ज़रूरत पड़ सकती है.

step-2 डायरेक्ट्री पर जाएं और ऐप्लिकेशन को फिर से डिप्लॉय करें. इसके लिए, वही तरीका अपनाएं जो आपने पिछले चरण में अपनाया था.

ऐप्लिकेशन को डिप्लॉय करने पर, आपको टारगेट यूआरएल दिखता है. पिछले चरण में शुरू की गई बातचीत की थ्रेड वाली सूची देखने के लिए, ब्राउज़र में इस यूआरएल पर जाएं. फ़िलहाल, बातचीत की स्थिति "बॉट मैनेज कर रहा है" है. ऐसा इसलिए है, क्योंकि इस बातचीत में Echo बॉट, हमारे एजेंट के प्रतिनिधि के तौर पर काम कर रहा है.

8f624e9befb8e827.png

चैट में शामिल हों बटन दिखता है, लेकिन अभी काम नहीं करता. इस इंटरफ़ेस से यह भी पता नहीं चलता कि उपयोगकर्ता को लाइव एजेंट से बात करनी है या नहीं.

Business Messages, लाइव एजेंट से बातचीत करने का अनुरोध करने वाला इवेंट उपलब्ध कराता है. इससे पता चलता है कि उपयोगकर्ता को लाइव एजेंट से कब बातचीत करनी है. आपको उस स्थिति को ट्रैक करना होगा, ताकि उसे यूज़र इंटरफ़ेस (यूआई) में दिखाया जा सके.

index.js में कॉलबैक फ़ंक्शन देखें. TODO टिप्पणी से पता चलता है कि आपको लाइव एजेंट के लिए उपयोगकर्ता के अनुरोध को कहां पकड़ना है और थ्रेड की स्थिति को अपडेट करना है.

step-2/routes/index.js

/**
 * The webhook callback method.
 */
router.post('/callback', async function(req, res, next) {
  ...
    } else if (requestBody.userStatus !== undefined) {
      if (requestBody.userStatus.requestedLiveAgent !== undefined) {
  ...
        // TODO: Update the thread state to QUEUED_THREAD_STATE.
      }
    }
  });
...
});

मौजूदा बातचीत के थ्रेड को लोड करने और उसकी स्थिति को QUEUED_THREAD_STATE पर अपडेट करने के लिए, आपको libs/datastore_utils.js में दिए गए तरीकों का इस्तेमाल करना होगा.

अगर आपको यह तय करने में परेशानी हो रही है कि क्या करना चाहिए, तो समाधान देखें. स्टार्टर कोड में, हर चरण के नीचे एक solutions डायरेक्ट्री शामिल होती है. इसमें आपको कुछ कोड पूरा करना होता है. इन डायरेक्ट्री में, पूरे ऐप्लिकेशन की कॉपी होती है. साथ ही, दिए गए चरण को लागू करने के बारे में पूरी जानकारी होती है.

लागू करने की प्रोसेस पूरी करने और ऐप्लिकेशन को फिर से डिप्लॉय करने के बाद, लाइव एजेंट से बात करने का अनुरोध करने के लिए, अपने फ़ोन या टैबलेट पर बातचीत के दौरान मौजूद ओवरफ़्लो मेन्यू का इस्तेमाल करें.

e58d2b77e9c64492.png

अब अगर आप वापस सीआरएम पर जाते हैं, तो आपको बातचीत के थ्रेड पर एक नोट दिखेगा. इसमें लिखा होगा कि "लाइव एजेंट से मदद मांगी गई है." इस उपयोगकर्ता को किसी व्यक्ति से मदद चाहिए! बटन को काम करने के लिए, आपको joinConversation एंडपॉइंट लागू करना होगा.

TODO के लिए, स्टब किए गए तरीके में मौजूद दूसरी TODO टिप्पणी ढूंढें./joinConversation

step-2/routes/index.js

/**
 * Updates the thread state and sends a representative join signal to the user.
 */
router.post('/joinConversation', async function(req, res, next) {
  let conversationId = req.body.conversationId;

  // TODO: Update the thread state to LIVE_AGENT_THREAD_STATE and post a REPRESENTATIVE_JOINED event.

  res.json({
    'result': 'ok',
  });
});

आपको थ्रेड की स्थिति को फिर से अपडेट करना होगा. इस बार, इसे LIVE_AGENT_THREAD_STATE पर सेट करें. इसके अलावा, आपको REPRESENTATIVE_JOINED इवेंट पोस्ट करने के लिए, Business Messages API के conversations.events.create तरीके का इस्तेमाल करना होगा.

अनुरोध पेलोड बनाने के लिए, आपको यहां दी गई टेबल में बताए गए फ़ील्ड सेट करने होंगे:

फ़ील्ड का नाम

अहम जानकारी

parent

इसे 'conversations/{conversationId}' पर सेट करें.

eventId

इवेंट के लिए, अपना रैंडम आईडी जनरेट करें.

auth

दिए गए initCredentials तरीके का इस्तेमाल करें.

resource

यह इवेंट का मुख्य हिस्सा है. आपको eventType और representative सेट करना चाहिए.

मदद पाने के लिए, create तरीके के लिए रेफ़रंस पेज या इवेंट के लिए रेफ़रंस पेज देखें.

लागू करने के बाद, ऐप्लिकेशन को फिर से डिप्लॉय करें. इसके बाद, चैट में शामिल हों बटन पर क्लिक करें. आपको बातचीत में शामिल हुए डायलॉग दिखेगा. साथ ही, चैट का स्टेटस बदलकर "लाइव चैट" हो जाएगा. अगर आपने अपने फ़ोन या टैबलेट पर बातचीत देखी, तो आपको चैट में एक सूचना दिखेगी. इसमें बताया जाएगा कि लाइव एजेंट शामिल हो गया है.

बधाई हो! अगले चरण में, हम देखेंगे कि लाइव एजेंट को उपयोगकर्ता से बातचीत करने के लिए कैसे सेट अप किया जाता है.

4. लाइव एजेंट के तौर पर मैसेज भेजना

अब जब आपने बातचीत में हिस्सा ले लिया है, तो लाइव एजेंट के तौर पर कुछ मैसेज भेजें.

step-3 डायरेक्ट्री पर जाएं और ऐप्लिकेशन को फिर से डिप्लॉय करें. सीआरएम में, पिछले चरण में की गई बातचीत के थ्रेड पर क्लिक करें. अब आपको चैट का सामान्य इंटरफ़ेस दिखेगा. यहां से, उपयोगकर्ता के मैसेज रीयल टाइम में देखे जा सकते हैं.

46dd083f08f43961.png

हालांकि, एजेंट के तौर पर मैसेज भेजने की सुविधा अब भी लागू नहीं की गई है. आपको इस चरण में वह जानकारी देनी होगी.

routes/index.js फ़ाइल खोलें और तीन नए एंडपॉइंट देखें:

  • /messages: यह messages.ejs व्यू फ़ाइल को ऐक्सेस करता है और उसे ब्राउज़र में रेंडर करता है. इंडेक्स में मौजूद किसी बातचीत की थ्रेड पर क्लिक करने पर, आपको इनमें से किसी एक पेज पर ले जाया जाता है.
  • /retrieveMessages: इससे किसी थ्रेड के मैसेज का कॉन्टेंट मिलता है. साथ ही, बातचीत में शामिल सभी मैसेज की फ़ॉर्मैट की गई सूची मिलती है. मैसेज पेज, समय-समय पर इस एंडपॉइंट को कॉल करता है, ताकि नए मैसेज दिखाए जा सकें.
  • /sendMessage: लाइव एजेंट प्रतिनिधि, उपयोगकर्ता को मैसेज भेजता है. जब 'भेजें' पर क्लिक किया जाता है, तब मैसेज पेज इस फ़ंक्शन को कॉल करता है. फ़िलहाल, यह सुविधा उपलब्ध नहीं है.

अब, storeAndSendResponse के मौजूदा तरीके पर एक नज़र डालें:

step-3/routes/index.js

/**
 * Updates the thread, adds a new message and sends a response to the user.
 *
 * @param {string} message The message content that was received.
 * @param {string} conversationId The unique id for this user and agent.
 * @param {string} threadState Represents who is managing the conversation for the CRM.
 * @param {string} representativeType The representative sending the message, BOT or HUMAN.
 */
async function storeAndSendResponse(message, conversationId, threadState, representativeType) {
...
}

वेबहुक पहले से ही इस तरीके का इस्तेमाल, इको बॉट से जवाब भेजने के लिए करता है. यह तरीका, बातचीत के लिए Cloud Datastore ऑब्जेक्ट में आने वाले मैसेज का डेटा सेव करता है. इसके बाद, यह जवाब का मैसेज भेजता है. उस मैसेज ऑब्जेक्ट को ध्यान से देखें जिसे यह बनाता है. खास तौर पर, प्रतिनिधि के टाइप को देखें.

अब /sendMessage एंडपॉइंट को खुद लागू करें. ज़्यादातर काम करने के लिए, यहां मौजूदा storeAndSendResponse तरीके का इस्तेमाल किया जा सकता है. यह ज़रूरी है कि आप सही प्रतिनिधि को सेट करें.

इसके बाद, ऐप्लिकेशन को फिर से डिप्लॉय करें और सीआरएम में अपनी बातचीत पर वापस जाएं. अब आपको चैट के इतिहास में अपने मैसेज दिखेंगे. आपको अपने एजेंट के मैसेज, टेस्टिंग के लिए इस्तेमाल किए जा रहे फ़ोन या टैबलेट पर भी दिख सकते हैं.

49aca3df6b196c50.png

आगे बढ़ने से पहले, पक्का करें कि आपको नए एंडपॉइंट के काम करने का तरीका पता हो. अगले चरण में, बातचीत छोड़ने के लिए अपना एंडपॉइंट जोड़ा जाएगा.

5. बातचीत छोड़ना

उपयोगकर्ता के सवालों के जवाब देने के बाद, आपको बातचीत बंद करनी पड़ सकती है. ऐसा इसलिए, ताकि उपयोगकर्ता बॉट से फिर से बात कर सके. Business Messages में, इस बदलाव के बारे में REPRESENTATIVE_LEFT इवेंट से पता चलता है.

step-4 डायरेक्ट्री पर जाएं, ऐप्लिकेशन को फिर से डिप्लॉय करें, और बातचीत के थ्रेड पर वापस जाएं. अब थ्रेड के सबसे नीचे, बातचीत बंद करें और छोड़ें लिंक मौजूद है. यह लिंक अभी काम नहीं कर रहा है, क्योंकि leaveConversation एंडपॉइंट लागू नहीं किया गया है.

ef4ad8107c3fff2.png

index.js फ़ाइल देखें. इसमें एक TODO टिप्पणी है, जिसमें आपको नया leaveConversation एंडपॉइंट बनाने का निर्देश दिया गया है.

step-4/routes/index.js

/* 
 * TODO: Create a '/leaveConversation' endpoint that does the following:
 * - Updates the thread to BOT_THREAD_STATE.
 * - Sends a REPRESENTATIVE_LEFT event.
 * - Sends a message to the thread informing the user that they are speaking to the echo bot again.
 * 
 * Hint: You can use the same methods that '/joinConversation' uses.
 */

इसे लागू करने के लिए, आपको अब तक कोडलैब से सीखी गई सभी चीज़ों को एक साथ रखना होगा. इस एंडपॉइंट को ये काम करने चाहिए:

  • थ्रेड को BOT_THREAD_STATE पर अपडेट करें.
  • REPRESENTATIVE_LEFT इवेंट भेजें.
  • बातचीत में एक मैसेज भेजकर, उपयोगकर्ता को बताएं कि वह इको बॉट से बात कर रहा है. storeAndSendResponse तरीके का इस्तेमाल करें. ध्यान रखें कि प्रतिनिधि को वापस BOT पर सेट कर दिया गया है.

आखिरी चरण में, उपयोगकर्ता को बातचीत की स्थिति के बारे में बताया जाता है. जब कोई प्रतिनिधि चैट छोड़ देता है, तो उपयोगकर्ता को एक इवेंट दिखता है. हालांकि, यह ज़रूरी नहीं है कि उसे पता हो कि वह फिर से इको बॉट से बात कर रहा है. बॉट से सीधे मैसेज भेजने पर, उपयोगकर्ता को कम भ्रम होता है और उसे बेहतर अनुभव मिलता है.

अब बॉट, बातचीत को मैनेज कर रहा है. इसलिए, लाइव एजेंट किसी दूसरी बातचीत में शामिल हो सकता है. सैंपल कोड और सीआरएम को अपनी पसंद के मुताबिक इस्तेमाल करके देखें. कारोबार के लिए, लाइव एजेंट को कॉल ट्रांसफ़र करने से जुड़े कुछ अलग-अलग आइडिया आज़माएं और देखें कि आपको क्या मिलता है.

6. रैप अप

लाइव एजेंट को कॉल ट्रांसफ़र करने से जुड़ा कोडलैब पूरा करने के लिए बधाई!

आपने एक ऐसा एजेंट बनाया है जो लाइव एजेंट को ट्रांसफ़र करने की प्रोसेस को शुरू से लेकर आखिर तक मैनेज कर सकता है. आपने Cloud Datastore की मदद से, बातचीत की स्थिति को ट्रैक करने का एक तरीका भी सीखा.

लाइव एजेंट को कॉल ट्रांसफ़र करने की सुविधा की मदद से, सामान्य अनुरोधों को बॉट के पास छोड़ा जा सकता है. वहीं, लाइव एजेंट ज़्यादा मुश्किल सवालों को हैंडल कर सकते हैं. उपयोगकर्ताओं को उनकी पसंद के मुताबिक और काम का नया अनुभव मिलेगा. इससे वे आपके कारोबार पर वापस आएंगे और अपने दोस्तों को भी इसके बारे में बताएंगे.

आगे क्या करना है?

इन कोडलैब को आज़माएं:

इस बारे में और पढ़ें

रेफ़रंस दस्तावेज़