आपके एजेंट के मैसेज की डिलीवरी में लगने वाले समय का एक बड़ा फ़ैक्टर यह है कि आप जिस उपयोगकर्ता तक पहुंचने की कोशिश कर रहे हैं उसके पास डेटा कनेक्शन होना चाहिए या नहीं. अगर उपयोगकर्ता ऑफ़लाइन है, तो आरबीएम प्लैटफ़ॉर्म इस मैसेज को सेव करता है और 30 दिनों तक डिलीवरी की कोशिश करता है. अगर तब तक मैसेज डिलीवर नहीं होता, तो उसे सिस्टम से हटा दिया जाता है.
जब आपका एजेंट उपयोगकर्ता से संपर्क करने की कोशिश करता है, तब उपयोगकर्ता के पास कनेक्टिविटी न होने की कई वजहें हो सकती हैं. वे अपने मोबाइल प्लान में पैसे बचाने के लिए डेटा बंद कर सकते थे, वाई-फ़ाई कनेक्शन के बिना हवाई जहाज़ में सफ़र कर सकते थे या शायद वे सुरंग में सबवे में थे. आपके मैसेज को डिलीवर होने की अहमियत के हिसाब से, आपके एजेंट को ऑफ़लाइन उपयोगकर्ताओं को मैनेज करने के लिए, डिलीवर नहीं किए गए आरबीएम मैसेज को रद्द करना होगा और उन मैसेज को किसी दूसरे चैनल पर रूट करना होगा.
इस लेख में, मैं आपको बताऊँगी कि भेजे और डिलीवर किए गए मैसेज को ट्रैक करने के लिए, Google Cloud Datastore का इस्तेमाल कैसे करें. डिलीवर नहीं किए गए मैसेज को revoke करने के लिए, क्रॉन का इस्तेमाल कैसे करें. साथ ही, उन मैसेज को एसएमएस की मदद से फिर से रूट करने का तरीका भी बताएंगे.
भेजे गए मैसेज पर नज़र रखना
आरबीएम एजेंट के भेजे गए हर मैसेज में एक यूनीक मैसेज आईडी होना चाहिए. आपके एजेंट जो मैसेज भेजते हैं उन्हें ट्रैक करने के लिए, आपको हर मैसेज का मैसेज आईडी, फ़ोन नंबर, और टाइमस्टैंप सेव करना होगा.
इस जानकारी को सेव करने के लिए कई तरह की टेक्नोलॉजी का इस्तेमाल किया जा सकता है, लेकिन इस लेख में Google Cloud Datastore का इस्तेमाल किया गया है. Cloud Datastore एक तरह का NoSQL डेटाबेस है. यह शार्डिंग और नकल को अपने-आप मैनेज करता है. यह गैर-रिलेशनल डेटा, जैसे कि एजेंट के भेजे गए मैसेज को सेव करने का बढ़िया तरीका है. Cloud Datastore, एक चालू Google App इंजन इंस्टेंस पर निर्भर करता है. इसलिए, मैं अपने आरबीएम एजेंट को होस्ट करने और क्रॉन जॉब को कॉन्फ़िगर करने के लिए App Engine का इस्तेमाल करता/करती हूं.
Cloud Datastore के लिए क्लाइंट लाइब्रेरी कई भाषाओं में उपलब्ध हैं. इस उदाहरण के लिए, मैं Node.js का इस्तेमाल करता/करती हूं और आरबीएम एजेंट कोड को आरबीएम डेवलपर वेबसाइट पर मौजूद पहले एजेंट Node.js सैंपल के आधार पर बनाता है. सबसे पहले मैं अपने Node.js प्रोजेक्ट के लिए Cloud Datastore को इस निर्देश से इंस्टॉल करूं:
npm install --save @google-cloud/datastore
अपने एजेंट सोर्स कोड में, मैं Cloud Datastore क्लाइंट लाइब्रेरी में ग्लोबल रेफ़रंस जोड़ता हूं.
// Imports the Google Cloud client library
const Datastore = require('@google-cloud/datastore');
// Creates a client
const datastore = new Datastore({
projectId: PROJECT_ID,
});
डेटास्टोर ऑब्जेक्ट बनाने के बाद, मैंने हर मैसेज की msisdn
, message id
, sent time
, और delivery
स्थिति को सेव करने के लिए एक फ़ंक्शन लॉन्च किया.
/**
* Records an entry in the Cloud Datastore to keep track of the
* messageIds sent to users and the delivery state.
*
* @property {string} msisdn The user's phone number in E.164 format.
* @property {string} messageId The unique message identifier.
* @property {boolean} delivered True if message has been delivered.
*/
function saveMessage(msisdn, messageId, delivered) {
const messageKey = datastore.key(['Message', messageId]);
const dataForMessage = {
key: messageKey,
data: {
id: messageId,
msisdn: msisdn,
lastUpdated: new Date().getTime(),
delivered: delivered
},
};
// Record that the message was sent.
datastore
.save(dataForMessage)
.then(function() {
console.log('saved message successfully');
})
.catch((err) => {
console.error('ERROR:', err);
});
}
इस फ़ंक्शन के साथ, जब भी आपका एजेंट किसी उपयोगकर्ता को मैसेज भेजे, आपको इस तरीके को कॉल करना होगा. जब RBM Node.js क्लाइंट
लाइब्रेरी
आरबीएम मैसेज भेजती है, तो लाइब्रेरी कॉलबैक वाले तरीके में एक रिस्पॉन्स ऑब्जेक्ट भेजती है. इसमें उपयोगकर्ता को भेजे गए मैसेज के लिए, messageId
होता है.
नीचे एक उदाहरण दिया गया है, जिसमें किसी उपयोगकर्ता को सादा टेक्स्ट मैसेज भेजने और आरबीएम एपीआई से संपर्क करने के बाद, मैसेज की जानकारी को रिकॉर्ड करने का तरीका बताया गया है.
let params = {
messageText: 'Hello, World!',
msisdn:'+12223334444',
};
// Send "Hello, World!" to the user.
rbmApiHelper.sendMessage(params,
function(response) {
// Extract the message id from the response
let messageId = response.config.params.messageId;
// Store the sent state in the Datastore
saveMessage(phoneNumber, messageId, false);
});
ऊपर दिए गए कोड को चलाने के बाद, Datastore एंटिटी व्यू में, Google Cloud Console से Datastore की जांच की जा सकती है.
मैसेज की डिलीवरी की स्थिति अपडेट की जा रही है
अब आपके एजेंट स्टोर ने Datastore में मैसेज के अनुरोध भेजे हैं, इसलिए उपयोगकर्ता के डिवाइस पर मैसेज डिलीवर होते ही हमें डिलीवरी की स्थिति की जानकारी अपडेट करनी होगी.
उपयोगकर्ता के डिवाइस, Cloud Pub/Sub पर आरबीएम एजेंट को DELIVERED
, READ
, और IS_TYPING
इवेंट भेजते हैं. Pub/Sub के हैंडलर में, डिलीवर किए गए इवेंट देखें. साथ ही, डिलीवर किए गए फ़्लैग के लिए Datastore सेटिंग को 'सही' पर अपडेट करें.
/**
* Uses the event received by the Pub/Sub subscription to send a
* response to the client's device.
* @param {object} userEvent The JSON object of a message
* received by the subscription.
*/
function handleMessage(userEvent) {
if (userEvent.senderPhoneNumber != undefined) {
let msisdn = userEvent.senderPhoneNumber;
let messageId = userEvent.messageId;
let eventType = userEvent.eventType;
if(eventType === 'DELIVERED') {
saveMessage(msisdn, messageId, true);
}
// TODO: Process message and create RBM response
}
}
एजेंट, आउटगोइंग मैसेज को Datastore में सेव करता है और डिलीवरी की सूचना मिलने पर डेटा को अपडेट करता है. अगले सेक्शन में, हमने Google के App Engine पर एक क्रॉन जॉब सेट अप किया, ताकि डिलीवर नहीं हुए मैसेज को मॉनिटर करने के लिए हर 10 मिनट में इसे चलाया जा सके.
Google के App Engine पर क्रॉन
अलग-अलग इंटरवल पर टास्क शेड्यूल करने के लिए, क्रॉन जॉब का इस्तेमाल किया जा सकता है. Google के App Engine में, एक क्रॉन जॉब को ब्यौरे, यूआरएल, और इंटरवल के साथ कॉन्फ़िगर किया जाता है.
Node.js ऐप्लिकेशन में, इन्हें cron.yaml
फ़ाइल में कॉन्फ़िगर किया जाता है. इसे Google Cloud SDK का इस्तेमाल करके, App Engine में डिप्लॉय किया जा सकता है. cron.yaml के साथ जॉब शेड्यूल
करने में दूसरे भाषा कॉन्फ़िगरेशन सेटअप के बारे में पढ़ें.
क्रॉन टास्क के लिए यूआरएल की ज़रूरत होती है. इसलिए, आपको एक्सप्रेस ऐप्लिकेशन राऊटर में उस यूआरएल का एंडपॉइंट जोड़ना होगा, जिसे क्रॉन के ज़रिए कॉल किया जा सके. यह वेबहुक पुराने मैसेज के लिए Datastore से क्वेरी करने, उन्हें आरबीएम प्लैटफ़ॉर्म से मिटाने, और उपयोगकर्ता को एसएमएस पर भेजने के लिए ज़िम्मेदार है.
router.get('/expireMessages', function(req, res, next) {
// TOOD: Query the Datastore for undelivered messages,
// remove them from the RBM platform, and send them over SMS
res.status(200).send();
});
इस एंडपॉइंट को हर 10 मिनट में एक्ज़ीक्यूट करने के लिए, cron.yaml फ़ाइल का कॉन्फ़िगरेशन नीचे दिया गया है.
cron:
- description: "Processing expired RBM messages"
url: /expireMessages
schedule: every 10 mins
App Engine पर क्रॉन टास्क डिप्लॉय करने के लिए, नीचे दिया गया कमांड चलाएं:
gcloud app deploy cron.yaml
डिप्लॉयमेंट के बाद, App Engine, क्रॉन टास्क को अपने-आप कॉन्फ़िगर करता है. इस टास्क को App Engine > Cron जॉब में देखा जा सकता है.
डिलीवर नहीं किए गए मैसेज के लिए Datastore में क्वेरी करना
पिछले सेक्शन में सेट किए गए क्रॉन जॉब के वेबहुक में, आपको भेजे गए ऐसे सभी मैसेज खोजने के लिए तर्क जोड़ना होगा जिनकी delivered
स्थिति 'गलत' के बराबर हो और जिनका टाइम आउट पहले से तय किए गए समय से lastUpdated
समय पुराना हो. इससे हमारे इस्तेमाल के उदाहरण को समझने में मदद मिलती है. इस उदाहरण में, एक घंटे से पुराने मैसेज मिटा दें.
इस तरह की कंपोज़िट क्वेरी के साथ काम करने के लिए, Datastore में delivered
और lastUpdated
, दोनों प्रॉपर्टी को शामिल करने वाला कंपोज़िट इंडेक्स होना चाहिए. ऐसा करने के लिए, अपने प्रोजेक्ट में index.yaml नाम की एक फ़ाइल बनाई जा सकती है. इस फ़ाइल में, नीचे दी गई जानकारी शामिल होगी:
indexes:
- kind: Message
properties:
- name: delivered
direction: asc
- name: lastUpdated
direction: desc
पहले तय किए गए क्रॉन जॉब को डिप्लॉय करने की तरह ही, इस कमांड से तय किए गए कंपोज़िट इंडेक्स को डिप्लॉय करने के लिए Google Cloud SDK टूल का इस्तेमाल करें:
gcloud datastore create-indexes index.yaml
डिप्लॉयमेंट के बाद, ऐप्लिकेशन इंजन, इंडेक्स को अपने-आप कॉन्फ़िगर करता है. साथ ही, इंडेक्स को डेटास्टोर > इंडेक्स में देखा जा सकता है.
इंडेक्स तय होने के बाद, हम क्रॉन जॉब के लिए बनाए गए वेबहुक पर वापस जा सकते हैं और मैसेज की समयसीमा खत्म होने के लॉजिक को पूरा कर सकते हैं:
router.get('/expireMessages', function(req, res, next) {
// Milliseconds in an hour
const TIMEOUT = 3600000;
// Threshold is current time minus one hour
const OLD_MESSAGE_THRESHOLD = new Date().getTime() - TIMEOUT;
// Create a query to find old undelivered messages
const query = datastore
.createQuery('Message')
.filter('delivered', '=', false)
.filter('lastUpdated', '<', OLD_MESSAGE_THRESHOLD);
// Execute the query
datastore.runQuery(query).then((results) => {
for(var i = 0; i < results[0].length; i++) {
let msisdn = results[0][i].msisdn;
let messageId = results[0][i].id;
// Stop the message from being sent
rbmApiHelper.revokeMessage(msisdn, messageId);
// Remove the message from the Datastore
datastore.delete(results[0][i][datastore.KEY]);
// TODO: Send the user the message as SMS
}
});
res.status(200).send();
});
आरबीएम मूल रूप से एसएमएस फ़ॉलबैक के साथ काम नहीं करता है. इसलिए, आपको डिलीवर नहीं किए गए मैसेज को एसएमएस पर भेजने के लिए, लॉजिक लागू करना होगा.
रैप-अप और कम शब्दों में, ज़्यादा जानकारी
ऑफ़लाइन उपयोगकर्ताओं को मैनेज करने के लिए, डिलीवर नहीं किए गए आरबीएम मैसेज के लिए सहमति रद्द करने का लॉजिक बनाया जा सकता है. मैसेज की समयसीमा खत्म होने से पहले, आपका कितनी देर तक इस्तेमाल किया जाएगा, यह इस बात पर निर्भर करता है कि आपकी दी गई जानकारी को शेयर करना कितना समय संवेदनशील है. समय के हिसाब से संवेदनशील जानकारी के मामले में, हम दो घंटे से कम का समय चुनने का सुझाव देते हैं.
इस उदाहरण में स्टोरेज, क्वेरी, और सहमति रद्द करने की प्रोसेस को मैनेज करने के लिए Cloud Datastore और Google App Engine का इस्तेमाल किया गया है. हालांकि, आपके भेजे और डिलीवर किए गए मैसेज को ट्रैक करने वाला कोई भी स्टोरेज तरीका काम करेगा.
शुभकामनाएं, कोडिंग करते रहें!