You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
378 lines
12 KiB
378 lines
12 KiB
/**
|
|
* Copyright 2017-present, Facebook, Inc. All rights reserved.
|
|
*
|
|
* This source code is licensed under the license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* Messenger Platform Quick Start Tutorial
|
|
*
|
|
* This is the completed code for the Messenger Platform quick start tutorial
|
|
*
|
|
* https://developers.facebook.com/docs/messenger-platform/getting-started/quick-start/
|
|
*
|
|
* To run this code, you must do the following:
|
|
*
|
|
* 1. Deploy this code to a server running Node.js
|
|
* 2. Run `npm install`
|
|
* 3. Update the VERIFY_TOKEN
|
|
* 4. Add your PAGE_ACCESS_TOKEN to your environment vars
|
|
*
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
// Customize Verify token
|
|
const VERIFY_TOKEN = "LG8YBDVaU0Wg47n7VUns66666g";
|
|
|
|
// User Token
|
|
const User_ACCESS_TOKEN = 'EAAJRQcUfZCWIBAOhi8TQZBpFmLWXK5xWFDoR1toWPiGAXdtrWaCR8JDoLtNesjSZAtGkWxseUsoy6nrlqZAgh45jzvZAOYBnJnaj4vizOPWpKd9OrxcZBdXzvJXlPaBXuTc2FYdimRfalAMUmWxMKAwiCGr119Mv7Ic8FA2LDFpmcZAZBhBZBtSZBu';
|
|
|
|
// Messenger TOKEN: 正式
|
|
const PAGE_ACCESS_TOKEN = 'EAAJRQcUfZCWIBAEsL2HcuOaB5mmqw8yOiZCmnvleDGNGS8p3d6EZAcZAaDjIZCZC7zLaZBl6taZAJAfDYw4qzKeELZA5xalFZCSaq4VUZAWDHmHfWVLn64blwZAjwjHZBGvxahZCp4OZB7z8ZBJbHgTvUV0uHW1IrXZBdslZA361srODwVMOC94dQpFbyIGfj6SNYx988slmgZD';
|
|
const APIURL = 'https://graph.facebook.com/v3.2/';
|
|
// 社團ID
|
|
const GROUPID = "202061134174478";
|
|
|
|
// Imports dependencies and set up http server
|
|
const request = require('request');
|
|
const express = require('express');
|
|
const body_parser = require('body-parser');
|
|
const cors = require('cors');
|
|
const app = express().use(body_parser.json()); // creates express http server
|
|
const corsOptions = {
|
|
origin: [
|
|
'https://www.origtek.com',
|
|
'http://localhost:3000',
|
|
'https://www.origtek.com:3001',
|
|
],
|
|
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
|
|
allowedHeaders: ['Content-Type', 'Authorization'],
|
|
};
|
|
|
|
app.use(cors(corsOptions));
|
|
|
|
|
|
// 讀取記錄檔案
|
|
var recordIDs = {};
|
|
saveAndLoadPSID();
|
|
|
|
// Sets server port and logs message on success
|
|
app.listen(process.env.PORT || 3000, () => console.log('webhook is listening'));
|
|
|
|
// Accepts POST requests at /webhook endpoint
|
|
app.post('/webhook', (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) {
|
|
|
|
// Gets the body of the webhook event
|
|
let webhook_event = entry.messaging[0];
|
|
console.log(webhook_event);
|
|
|
|
recordIDs
|
|
// Get the sender PSID
|
|
let sender_psid = webhook_event.sender.id;
|
|
// let fullnamekeys = Object.keys(recordIDs)
|
|
lookupUser(sender_psid);
|
|
console.log('Sender ID: ' + sender_psid);
|
|
|
|
// Check if the event is a message or postback and
|
|
// pass the event to the appropriate handler function
|
|
// if (webhook_event.message) {
|
|
// handleMessage(sender_psid, webhook_event.message);
|
|
// } else if (webhook_event.postback) {
|
|
// handlePostback(sender_psid, webhook_event.postback);
|
|
// }
|
|
|
|
});
|
|
// 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);
|
|
}
|
|
|
|
});
|
|
|
|
// Accepts GET requests at the /webhook endpoint
|
|
app.get('/webhook', (req, res) => {
|
|
// Parse params from the webhook verification request
|
|
let mode = req.query['hub.mode'];
|
|
let token = req.query['hub.verify_token'];
|
|
let challenge = req.query['hub.challenge'];
|
|
let getRecords = req.query['getRecords'];
|
|
// Check if a token and mode were sent
|
|
if (mode && token) {
|
|
// Check the mode and token sent are correct
|
|
if (mode === 'subscribe' && token === VERIFY_TOKEN) {
|
|
let recipientID = req.query['recipient'];
|
|
let msgText = req.query['reply'];
|
|
let fullname = req.query['fullname'];
|
|
|
|
if (getRecords) {
|
|
challenge = JSON.stringify(recordIDs)
|
|
res.status(200).send(challenge);
|
|
}
|
|
else if (recipientID && msgText) {
|
|
callSendAPI(recipientID, { "text": msgText });
|
|
}
|
|
else if (fullname && msgText) {
|
|
let userInfo = getUserInfoByName(fullname);
|
|
if (userInfo) {
|
|
callSendAPI(userInfo.id, { "text": msgText });
|
|
res.status(200).send("send");
|
|
}
|
|
else {
|
|
res.status(200).send("No Matched Data");
|
|
}
|
|
}
|
|
else {
|
|
|
|
// Respond with 200 OK and challenge token from the request
|
|
console.log('WEBHOOK_VERIFIED');
|
|
res.status(200).send(challenge);
|
|
}
|
|
|
|
|
|
} else {
|
|
// Responds with '403 Forbidden' if verify tokens do not match
|
|
res.sendStatus(403);
|
|
}
|
|
}
|
|
});
|
|
|
|
// 社團操作類型
|
|
app.get('/Groups', (req, res) => {
|
|
let mode = req.query['hub.mode'];
|
|
let token = req.query['hub.verify_token'];
|
|
let message = req.query['message'];
|
|
let postID = req.query['postID'];
|
|
if (mode && token) {
|
|
if (mode === 'subscribe' && token === VERIFY_TOKEN) {
|
|
if (message) {
|
|
newPost(message, x => {
|
|
res.status(x.statusCode).send(x.body);
|
|
});
|
|
}
|
|
else if (postID) {
|
|
getPostComments(postID, x => {
|
|
res.status(x.statusCode).send(x.body);
|
|
});
|
|
}
|
|
|
|
} else {
|
|
res.sendStatus(403);
|
|
}
|
|
}
|
|
else {
|
|
res.sendStatus(400);
|
|
}
|
|
|
|
// 取得貼文內容
|
|
function getPostComments(postID, callbackFn) {
|
|
request({
|
|
uri: APIURL + postID, // EX: "https://graph.facebook.com/v3.2/202061134174478_205484600498798?fields=comments",
|
|
qs: {
|
|
fields: 'comments',
|
|
access_token: User_ACCESS_TOKEN
|
|
},
|
|
method: "GET",
|
|
}, (err, res, body) => {
|
|
console.log(res.statusMessage);
|
|
console.log(res.statusCode);
|
|
callbackFn(res);
|
|
});
|
|
}
|
|
|
|
// 新增貼文 **一定要有使用者授權才會看到名字 ID
|
|
function newPost(messages, callbackFn) {
|
|
request({
|
|
uri: APIURL + GROUPID + "/feed", //"202061134174478_205484600498798?fields=comments",
|
|
qs: {
|
|
access_token: User_ACCESS_TOKEN
|
|
},
|
|
method: "POST",
|
|
json: {
|
|
message: messages
|
|
}
|
|
}, (err, res, body) => {
|
|
console.log(res.statusMessage);
|
|
console.log(res.statusCode);
|
|
callbackFn(res);
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
function handleMessage(sender_psid, received_message) {
|
|
let response;
|
|
|
|
// Checks if the message contains text
|
|
if (received_message.text) {
|
|
// Create the payload for a basic text message, which
|
|
// will be added to the body of our request to the Send API
|
|
response = {
|
|
"text": `You sent the message: "${received_message.text}". Now send me an attachment!`
|
|
}
|
|
} else if (received_message.attachments) {
|
|
// Get the URL of the message attachment
|
|
let attachment_url = received_message.attachments[0].payload.url;
|
|
response = {
|
|
"attachment": {
|
|
"type": "template",
|
|
"payload": {
|
|
"template_type": "generic",
|
|
"elements": [{
|
|
"title": "Is this the right picture?",
|
|
"subtitle": "Tap a button to answer.",
|
|
"image_url": attachment_url,
|
|
"buttons": [
|
|
{
|
|
"type": "postback",
|
|
"title": "Yes!",
|
|
"payload": "yes",
|
|
},
|
|
{
|
|
"type": "postback",
|
|
"title": "No!",
|
|
"payload": "no",
|
|
}
|
|
],
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Send the response message
|
|
callSendAPI(sender_psid, response);
|
|
}
|
|
|
|
function getUserInfoByName(name) {
|
|
if (recordIDs[name]) {
|
|
return recordIDs[name];
|
|
}
|
|
}
|
|
|
|
function handlePostback(sender_psid, received_postback) {
|
|
console.log('ok')
|
|
let response;
|
|
// Get the payload for the postback
|
|
let payload = received_postback.payload;
|
|
|
|
// Set the response based on the postback payload
|
|
if (payload === 'yes') {
|
|
response = { "text": "Thanks!" }
|
|
} else if (payload === 'no') {
|
|
response = { "text": "Oops, try sending another image." }
|
|
}
|
|
// Send the message to acknowledge the postback
|
|
callSendAPI(sender_psid, response);
|
|
}
|
|
|
|
// 查詢user資料,需要messenger 權限
|
|
function lookupUser(id) {
|
|
request({
|
|
uri: APIURL + id,
|
|
qs: {
|
|
access_token: PAGE_ACCESS_TOKEN
|
|
},
|
|
method: "GET",
|
|
}, (err, res, body) => {
|
|
//debugger;
|
|
let data = JSON.parse(res.body);
|
|
if (!data.error) {
|
|
let fullname = data.first_name + " " + data.last_name;
|
|
if (!recordIDs.hasOwnProperty(fullname)) {
|
|
recordIDs[fullname] = data;
|
|
saveAndLoadPSID();
|
|
}
|
|
}
|
|
if (!err) {
|
|
console.log('message sent!')
|
|
} else {
|
|
console.error("Unable to send message:" + err);
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
|
|
function callSendAPI(sender_psid, response) {
|
|
// Construct the message body
|
|
let request_body = {
|
|
"recipient": {
|
|
"id": sender_psid
|
|
},
|
|
"message": {
|
|
"text": response.text
|
|
}
|
|
};
|
|
// Send the HTTP request to the Messenger Platform
|
|
request({
|
|
uri: APIURL + "me/messages",
|
|
qs: {
|
|
access_token: PAGE_ACCESS_TOKEN
|
|
},
|
|
method: "POST",
|
|
json: request_body
|
|
}, (err, res, body) => {
|
|
console.log(res.statusMessage);
|
|
console.log(res.statusCode);
|
|
if (!err) {
|
|
console.log('message sent!')
|
|
} else {
|
|
console.error("Unable to send message:" + err);
|
|
}
|
|
});
|
|
}
|
|
|
|
function saveAndLoadPSID() {
|
|
var fs = require('fs');
|
|
if (isEmpty(recordIDs)) {
|
|
fs.readFile('record.json', 'utf8', function readFileCallback(err, data) {
|
|
if (err) {
|
|
console.log(err);
|
|
} else {
|
|
recordIDs = JSON.parse(data);
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
let data = JSON.stringify(recordIDs);
|
|
fs.writeFile('record.json', data, 'utf8', function (err) {
|
|
console.log(err);
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
function isEmpty(obj) {
|
|
|
|
// null and undefined are "empty"
|
|
if (obj == null) return true;
|
|
|
|
// Assume if it has a length property with a non-zero value
|
|
// that that property is correct.
|
|
if (obj.length > 0) return false;
|
|
if (obj.length === 0) return true;
|
|
|
|
// If it isn't an object at this point
|
|
// it is empty, but it can't be anything *but* empty
|
|
// Is it empty? Depends on your application.
|
|
if (typeof obj !== "object") return true;
|
|
|
|
// Otherwise, does it have any properties of its own?
|
|
// Note that this doesn't handle
|
|
// toString and valueOf enumeration bugs in IE < 9
|
|
for (var key in obj) {
|
|
if (hasOwnProperty.call(obj, key)) return false;
|
|
}
|
|
|
|
return true;
|
|
}
|