/** * 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; }