ปัจจัยสำคัญของเวลาในการส่งข้อความของตัวแทนคือ ผู้ใช้ที่คุณพยายามติดต่อมีการเชื่อมต่อข้อมูลในขณะที่ตัวแทนส่งข้อความหรือไม่ หากผู้ใช้ออฟไลน์อยู่ แพลตฟอร์ม RBM จะจัดเก็บข้อความดังกล่าวและพยายามส่งเป็นเวลาถึง 30 วัน ถ้าไม่สามารถส่งข้อความได้ ข้อความจะถูกนำออกจากระบบ
มีหลายสาเหตุและสถานการณ์ที่ผู้ใช้อาจไม่มีการเชื่อมต่อเมื่อตัวแทนพยายามติดต่อพวกเขา พวกเขาอาจปิดใช้อินเทอร์เน็ตมือถือ เพื่อประหยัดค่าใช้จ่ายสำหรับแพ็กเกจมือถือ, ไม่ได้นั่งเครื่องบิน โดยไม่ได้เชื่อมต่อ Wi-Fi หรือนั่งรถไฟใต้ดินในอุโมงค์ ตัวแทนของคุณจะต้องจัดการกับผู้ใช้แบบออฟไลน์อย่างค่อยเป็นค่อยไป โดยการเพิกถอนข้อความ RBM ที่ไม่ได้ส่ง และกำหนดเส้นทางข้อความเหล่านั้นใหม่ผ่านช่องทางอื่น ทั้งนี้ขึ้นอยู่กับความเร่งด่วนของข้อความที่คุณต้องการส่ง
ในบทความนี้ เราจะแสดงวิธีใช้ Google Cloud Datastore เพื่อติดตามข้อความที่คุณส่งและส่ง วิธีใช้ cron เพื่อrevokeข้อความที่ยังไม่ได้ส่ง และวิธีเปลี่ยนเส้นทางข้อความเหล่านั้นผ่าน SMS
การติดตามข้อความที่ส่งแล้ว
ทุกข้อความที่ส่งโดยตัวแทน RBM ของคุณต้องมีรหัสข้อความที่ไม่ซ้ำกัน หากต้องการติดตามข้อความที่ตัวแทนส่ง คุณต้องบันทึกรหัสข้อความ หมายเลขโทรศัพท์ และการประทับเวลาของแต่ละข้อความ
คุณสามารถใช้เทคโนโลยีที่หลากหลายในการจัดเก็บข้อมูลนี้ แต่ในบทความนี้ผมใช้ Google Cloud Datastore Cloud Datastore เป็นฐานข้อมูล NoSQL ที่รองรับการปรับขนาดได้สูง ซึ่งจะจัดการชาร์ดดิ้งและการจำลองโดยอัตโนมัติ ซึ่งเป็นวิธีแก้ปัญหาที่ดีเยี่ยมสำหรับการจัดเก็บข้อมูลที่ไม่สัมพันธ์กัน เช่น ข้อความที่ส่งโดยตัวแทน Cloud Datastore ต้องอาศัยอินสแตนซ์ Google App Engine ที่ใช้งานอยู่ ฉันจึงใช้ App Engine เพื่อโฮสต์ Agent RBM และกำหนดค่างาน Cron
มีไลบรารีของไคลเอ็นต์สำหรับ Cloud Datastore ในหลายภาษา สำหรับตัวอย่างนี้ ผมใช้ Node.js และอิงโค้ดตัวแทน RBM ในตัวอย่าง Node.js ของตัวแทนแรกที่มีอยู่บนเว็บไซต์นักพัฒนาซอฟต์แวร์ RBM สิ่งแรกที่ฉันทำคือติดตั้ง Cloud Datastore สำหรับโปรเจ็กต์ Node.js ของฉันโดยเรียกใช้คำสั่งต่อไปนี้
npm install --save @google-cloud/datastore
ในซอร์สโค้ดของ Agent ฉันเพิ่มการอ้างอิงส่วนกลางลงในไลบรารีไคลเอ็นต์ 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 ส่งข้อความ RBM ไลบรารีจะจัดเตรียมออบเจ็กต์การตอบกลับในเมธอดโค้ดเรียกกลับที่มี messageId
สำหรับข้อความที่ส่งไปยังผู้ใช้
ด้านล่างเป็นตัวอย่างการส่งข้อความแบบธรรมดาถึงผู้ใช้และการบันทึกข้อมูลข้อความหลังจากสื่อสารกับ RBM API ได้สำเร็จ
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 ภายในมุมมองเอนทิตีพื้นที่เก็บข้อมูล
กำลังอัปเดตสถานะการส่งข้อความ
เมื่อตัวแทนจัดเก็บคำขอข้อความที่ส่งแล้วใน Datastore เราจำเป็นต้องอัปเดตสถานะการนำส่งเมื่อส่งข้อความไปยังอุปกรณ์ของผู้ใช้เรียบร้อยแล้ว
อุปกรณ์ของผู้ใช้จะส่งเหตุการณ์ DELIVERED
, READ
และ IS_TYPING
ไปยัง Agent ของ RBM ผ่าน Cloud Pub/Sub ในเครื่องจัดการสำหรับ 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
}
}
Agent จะบันทึกข้อความขาออกลงใน Datastore และอัปเดตข้อมูลเมื่อได้รับการแจ้งเตือนการนำส่ง ในส่วนถัดไป เราตั้งค่างาน cron บน App Engine ของ Google ให้เรียกใช้ทุก 10 นาทีเพื่อตรวจสอบข้อความที่ยังไม่ได้ส่ง
Cron ใน App Engine ของ Google
คุณสามารถใช้งาน Cron เพื่อกำหนดเวลางานในช่วงเวลาต่างๆ ได้ ใน App Engine ของ Google งาน Cron จะได้รับการกำหนดค่าด้วยคำอธิบาย URL และช่วงเวลา
ในแอป Node.js คุณสามารถกำหนดค่าเหล่านี้ในไฟล์ cron.yaml
ซึ่งสามารถทำให้ App Engine ใช้งานได้โดยใช้ Google Cloud SDK อ่านเกี่ยวกับการตั้งค่าการกำหนดค่าภาษาอื่นๆ ได้ในการกำหนดเวลางานด้วย cron.yaml
เนื่องจากงาน Cron จำเป็นต้องใช้ URL คุณจึงต้องเพิ่มปลายทางของ URL ลงในเราเตอร์แอป Express เพื่อให้ cron เรียกใช้ เว็บฮุคนี้มีหน้าที่สืบค้นข้อความเก่าจากพื้นที่เก็บข้อมูล ลบข้อความออกจากแพลตฟอร์ม RBM และส่งไปยังผู้ใช้ผ่าน SMS
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();
});
ด้านล่างนี้คือการกำหนดค่าไฟล์ cron.yaml เพื่อเรียกใช้ปลายทางนี้ทุกๆ 10 นาที
cron:
- description: "Processing expired RBM messages"
url: /expireMessages
schedule: every 10 mins
หากต้องการทำให้งาน Cron ใช้งานได้กับ App Engine ให้เรียกใช้คำสั่งต่อไปนี้
gcloud app deploy cron.yaml
หลังจากทำให้ใช้งานได้ App Engine จะกำหนดค่างาน Cron โดยอัตโนมัติ และดูงานได้ใน App Engine > งาน Cron
การค้นหา Datastore สำหรับข้อความที่ยังไม่ได้ส่ง
ในเว็บฮุคสำหรับงาน Cron ที่ตั้งค่าไว้ในส่วนก่อนหน้า คุณต้องเพิ่มตรรกะในการค้นหาข้อความที่ส่งแล้วทั้งหมดที่มีสถานะ delivered
เท่ากับ "เท็จ" และมีระยะเวลา lastUpdated
นานกว่าระยะหมดเวลาที่กำหนดไว้ล่วงหน้าซึ่งเหมาะสมกับกรณีการใช้งานของเรา ในตัวอย่างนี้ ข้อความที่หมดอายุนานกว่า 1 ชั่วโมง
Datastore ต้องมีดัชนีผสมที่มีทั้งพร็อพเพอร์ตี้ delivered
และ lastUpdated
จึงจะรองรับการค้นหาแบบผสมนี้ได้ วิธีการคือสร้างไฟล์ในโปรเจ็กต์ชื่อ index.yaml ที่มีข้อมูลต่อไปนี้
indexes:
- kind: Message
properties:
- name: delivered
direction: asc
- name: lastUpdated
direction: desc
ใช้ Google Cloud SDK เพื่อทำให้ดัชนีผสมที่คุณกำหนดด้วยคำสั่งต่อไปนี้ใช้งานได้ คล้ายกับการทำให้งาน Cron ใช้งานได้ที่คุณกำหนดไว้ก่อนหน้านี้
gcloud datastore create-indexes index.yaml
หลังจากทำให้ใช้งานได้ App Engine จะกำหนดค่าดัชนีโดยอัตโนมัติ และคุณดูดัชนีได้ในส่วน Datastore > ดัชนี
เมื่อกำหนดดัชนีแล้ว เราสามารถกลับไปที่เว็บฮุคที่คุณสร้างขึ้นสำหรับงาน cron และทำตามตรรกะการหมดอายุของข้อความให้เสร็จสมบูรณ์ได้ ดังนี้
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();
});
RBM ไม่รองรับ SMS สำรองโดยค่าเริ่มต้น คุณจึงต้องใช้ตรรกะในการส่งข้อความที่ยังไม่ได้ส่งผ่าน SMS
สรุปและสรุปขั้นสุดท้าย
ในการจัดการผู้ใช้แบบออฟไลน์ คุณสามารถสร้างตรรกะการเพิกถอนข้อความ RBM ที่ไม่ได้ส่งได้ ระยะเวลาที่คุณใช้ก่อนที่ข้อความจะหมดอายุนั้นขึ้นอยู่กับเวลาของข้อมูลที่คุณส่ง สำหรับข้อมูลที่อิงตามเวลา เราขอแนะนำให้เผื่อเวลาไว้ไม่เกิน 2 ชั่วโมง
ตัวอย่างนี้ใช้ Cloud Datastore และ Google App Engine เพื่อจัดการพื้นที่เก็บข้อมูล การค้นหา และกระบวนการเพิกถอน แต่กลไกพื้นที่เก็บข้อมูลสำหรับการติดตามข้อความที่ส่งและนำส่งควรทำงานได้
ขอให้โชคดีและขอให้สนุกกับการเขียนโค้ด