Я создаю чат-бота в мессенджере Facebook. Я хочу, чтобы чатбот мог поддерживать нескольких пользователей. Когда пользователь впервые получает доступ к чат-боту, он должен создать учетную запись пользователя. Процесс создания учетной записи пользователя выглядит следующим образом:
- Когда незарегистрированный пользователь взаимодействует с чат-ботом, он получает имя пользователя из API Graph Facebook, а затем говорит «Привет (имя)». Это объясняет, что пользователю необходимо создать профиль пользователя.
- Чатбот спрашивает пользователя, как он хочет, чтобы его вызывали. Возможны варианты (имя) или «Что-то еще»
- Если пользователь выбирает (имя), чат-бэт сразу переходит на номер (5).
- Если пользователь выбирает «Что-то еще», чатбот спрашивает, как он хочет позвонить, и вводит его.
- Чатбот просит пользователя выбрать пол (мужской, женский, другой, предпочитают не говорить)
- Чатбот просит пользователя выбрать его возраст (из диапазона значений, например, 18-25, 26-30 и т. Д.)
- Как только профиль создан, чатбот сообщает пользователю, что в будущем, если он захочет поговорить с чатботом, он может просто сказать «привет» или «привет».
- Затем чатбот спрашивает пользователя, что он хочет сделать сейчас, и представляет основные функции.
Вот что обычно происходит, когда любой пользователь взаимодействует с чатботом:
- Пользователь взаимодействует с чатботом.
- Чатбот проверяет, загружен ли пользователь в память
- Если пользователь загружен в память, чатбот взаимодействует с ним как обычно
- Если пользователь не загружен, чатбот пытается получить пользователя из базы данных
- Если пользователь существует в базе данных, профиль пользователя загружается в память и чат-бот взаимодействует с пользователем в обычном режиме
- Если пользователь не существует в базе данных, он никогда ранее не использовал чат-бота, поэтому ему необходимо создать профиль пользователя.
Проблема в том, что этого не происходит. Когда несколько пользователей пытаются настроить свой профиль одновременно, происходит следующее (предположим, что два пользователя - «пользователь A» и «пользователь B»):
Для лица А:
Чат-робот получает имя пользователя, говорит «Привет (человек А)» и объясняет, что ему необходимо создать профиль пользователя.
Затем чатбот спрашивает пользователя, как он хочет быть вызванным. Возможные варианты: (человек B) или «Нечто другое».
Независимо от того, что выберет пользователь, он не сможет двигаться дальше, потому что чат-робот продолжает повторять этап 2.
Итак, мой код:
Пользовательские данные хранятся в объекте «data» в файле с именем user.js
:
data: {
fbID: undefined, // senderID (user's Facebook PSID)
firstName: undefined, // User's first name (only used during user profile creation)
userID: undefined, // User ID (i.e. first name or nickname)
gender: undefined, // Gender
age: undefined, // Age
}
User.js также содержит функцию «перезагрузки», которая используется для перезагрузки пользователя. Вы увидите, как это работает позже:
reload: function(data) {
self.data.fbID = data.fbid; /** @namespace data.fbid */
self.data.userID = data.userid; /** @namespace data.userid */
self.data.gender = data.gender; /** @namespace data.gender */
self.data.age = data.age; /** @namespace data.age */
console.log("Profile reloaded for user '%s'.", self.data.fbID);
},
Когда пользователь отправляет сообщение в чат-бота, это вызывает событие webhook, в пределах app.js
:
// Accept POST requests to webhook
app.post('/webhook/', function (req, res) {
// Parse the request body from the POST
let body = req.body;
// Check the webhook event is from a Page subscription
if (body.object === 'page') {
body.entry.forEach(function(entry) { /** @namespace body.entry */
// Gets the body of the webhook event
let webhookEvent = entry.messaging[0]; /** @param entry.messaging[] */
// Get sender ID
let senderID = webhookEvent.sender.id;
// Set session ID
session.set(senderID);
// Handle webhook event
handler.handleWebhookEvent(senderID, webhookEvent);
});
// Return a '200 OK' response to all events
res.status(200).send('EVENT_RECEIVED');
} else {
// Return a '404 Not Found' if event is not from a page subscription
res.sendStatus(404);
}
});
Событие webhook передается в handler.js
, где оно обрабатывается функцией handleWebhookEvent
:
handleWebhookEvent: function(senderID, webhookEvent) {
let greetingText, delay;
let handleEvent = function() {
/**
* @param webhookEvent
* @param webhookEvent.message
* @param webhookEvent.optin
* @param webhookEvent.delivery
* @param webhookEvent.postback
* @param webhookEvent.read
* @param webhookEvent.account_linking
* */
if (webhookEvent.optin) {
handleOptIn(webhookEvent);
} else if (webhookEvent.message) {
handleMessage(senderID, webhookEvent.message);
} else if (webhookEvent.delivery) {
handleDelivery(webhookEvent);
} else if (webhookEvent.postback) {
handlePostback(senderID, webhookEvent.postback);
} else if (webhookEvent.read) {
handleRead(webhookEvent);
} else if (webhookEvent.account_linking) {
handleAccountLink(senderID, webhookEvent.account_linking);
} else {
console.log("Webhook received unknown event: ", webhookEvent);
}
};
if (common.isDefined(user.data.fbID) && user.data.fbID === senderID) {
// User is loaded - handle events as normal
console.log("User '%s' is loaded.", senderID);
//logging.logEvent(senderID, webhookEvent, function() {
handleEvent();
//});
} else { // User is not loaded
getUser(senderID, function(result) { // First try and load user
if (common.isDefined(result)) { // Result returned
user.reload(result);
//logging.logEvent(senderID, webhookEvent, function() {
handleEvent();
//});
} else {
// User was not found in database. We need to
create a new profile for the user
common.getFBUser(senderID, function(name) {
console.log("User '%s' was not found in database.", senderID);
user.data.fbID = senderID;
user.data.firstName = name; // Stores user's first name
in the user object
greetingText = strings.initialGreeting.replace("%USER",
user.data.firstName);
delay = common.setDelay(greetingText);
messaging.sendTextMessage(senderID, greetingText);
setTimeout(function() {
// Pause before kicking off the 'uprofile' intent
dialogflow.sendRequest(session.getIDs(), senderID,
strings.createUser);
}, delay);
});
}
});
}
}
Я думаю, что проблема здесь в том, что я думал, что используя объект в user.js
, чат-бот просто создаст несколько экземпляров этого объекта, по одному для каждого пользователя. Ясно, что я ошибаюсь. Каков наилучший способ создания нескольких экземпляров и, таким образом, предотвращения ситуации, когда объект пользовательских данных совместно используется несколькими пользователями? Или мне просто нужно полностью отказаться от объектов и просто читать из базы данных каждый раз? Я хочу избежать этого, так как для этого потребуется много операций чтения / записи.