Messenger ChatBot をHerokuで作るメモ
package.json
{ "name": "chatbotfblaojp", "version": "1.0.0", "description": "chatbot app for facebook messenger", "main": "index.js", "dependencies": { "body-parser": "^1.17.1", "crypt": "0.0.2", "ejs": "^2.5.6", "express": "^4.15.2", "request": "^2.81.0" }, "devDependencies": {}, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
index.js
const bodyParser = require('body-parser'), express = require('express'), crypto = require('crypto'), req = require('request'); var app = express(); app.set('port', process.env.NODE_PORT || 5000); app.set('view engine', 'ejs'); app.use(express.static('public')); app.use(bodyParser.json({ verify: verifyRequestSignature })); app.get('/webhook', function(req, res){ if (req.query['hub.mode'] === 'subscribe' && req.query['hub.verify_token'] === '') { console.log("Validating webhook"); res.status(200).send(req.query['hub.challenge']); } else { console.error("Failed validation. Make sure the validation tokens match."); res.send(403); } }); app.post('/webhook', function (req, res) { var data = req.body; // Make sure this is a page subscription console.log(data); if (data.object === 'page') { // Iterate over each entry - there may be multiple if batched data.entry.forEach(function(entry) { var pageID = entry.id; var timeOfEvent = entry.time; // Iterate over each messaging event entry.messaging.forEach(function(event) { if (event.message) { receivedMessage(event); } else { console.log("Webhook received unknown event: ", event); } }); }); // Assume all went well. // // You must send back a 200, within 20 seconds, to let us know // you've successfully received the callback. Otherwise, the request // will time out and we will keep trying to resend. res.sendStatus(200); } }); function verifyRequestSignature(req, res, buf) { var signature = req.headers["x-hub-signature"]; if (!signature) { console.error("Couldn't validate the signature."); } else { var elements = signature.split('='); var method = elements[0]; var signatureHash = elements[1]; var expectedHash = crypto.createHmac('sha1', '') .update(buf) .digest('hex'); if (signatureHash != expectedHash) { throw new Error("Couldn't validate the 4 signature."); } } } function receivedMessage(event) { // Putting a stub for now, we'll expand it in the following steps console.log("Message data: ", event.message); } function receivedMessage(event) { var senderID = event.sender.id; var recipientID = event.recipient.id; var timeOfMessage = event.timestamp; var message = event.message; console.log("Received message for user %d and page %d at %d with message:", senderID, recipientID, timeOfMessage); console.log(JSON.stringify(message)); var messageId = message.mid; var messageText = message.text; var messageAttachments = message.attachments; if (messageText) { // If we receive a text message, check to see if it matches a keyword // and send back the example. Otherwise, just echo the text we received. switch (messageText) { case 'generic': sendGenericMessage(senderID); break; default: sendTextMessage(senderID, messageText); } } else if (messageAttachments) { sendTextMessage(senderID, "Message with attachment received"); } } function sendGenericMessage(recipientId, messageText) { // To be expanded in later sections } function sendTextMessage(recipientId, messageText) { var messageData = { recipient: { id: recipientId }, message: { text: messageText } }; callSendAPI(messageData); } function callSendAPI(messageData) { req({ uri: 'https://graph.facebook.com/v2.6/me/messages', qs: { access_token: '' }, method: 'POST', json: messageData }, function (error, response, body) { if (!error && response.statusCode == 200) { var recipientId = body.recipient_id; var messageId = body.message_id; console.log("Successfully sent generic message with id %s to recipient %s", messageId, recipientId); } else { console.error("Unable to send message."); console.error(response); console.error(error); } }); } var port = process.env.PORT || 5000; app.listen(port, function() { console.log("Listening on " + port); }); module.exports = app;