Skip to content

Instantly share code, notes, and snippets.

@cAstraea
Last active August 15, 2017 20:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cAstraea/fbf1f8012bc0712c1d1078451ca1a7c0 to your computer and use it in GitHub Desktop.
Save cAstraea/fbf1f8012bc0712c1d1078451ca1a7c0 to your computer and use it in GitHub Desktop.
for messenger account linking
'use strict';
require('dotenv').config();
const express = require('express');
const router = express.Router();
const bodyParser = require('body-parser');
const LINKED = {};
const question = {};
const http = require('http');
const port = process.env.PORT || 3000;
const passport = require('passport');
const FacebookStrategy = require('passport-facebook').Strategy;
const fbConfig = require('./oauth');
const cookieParser = require('cookie-parser');
const session = require('express-session');
// used to serialize the user for the session
// Not using these yet
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (obj, done) {
done(null, obj);
});
const Botly = require('botly');
const botly = new Botly({
accessToken: process.env.ACCESS_TOKEN,
verifyToken: '123123321' // the verification token you provided when defining the webhook in facebook
});
// facebook templates
const mainMenu = require('./menus/main-menu');
const categoriesMenu = require('./menus/categories-menu');
const queryES = require('./helpers/queryES');
// set get started button
botly.setGetStarted({ pageId: process.env.page_id, payload: 'GET_STARTED_CLICKED' }, (err, body) => {
// log it
if (err !== null) {
console.log('error setting get started: ', err);
}
// console.log(body); success or fail to set get started
});
const app = express();
botly.on('postback', (sender, message, postback, ref) => {
/**
* where postback is the postback payload
* and ref will arrive if m.me params were passed on a get started button (if defined)
* message -> recipient , timestamp, sender , postback
*/
console.log(`got message from ${sender} @ ${postback}`);
question.senderId = message.sender.id; // the chat user
question.recipientId = message.recipient.id; // the bot
if (postback === 'GET_STARTED_CLICKED') {
// show the main menu dialogue
return mainMenu(botly, Botly, sender);
} else if (postback === 'CATEG_SELECT') {
return categoriesMenu(botly, sender);
} else if (postback === 'TRAVEL_CATEG' || postback === 'MOVETOJ_CATEG' || postback === 'SHOPSERV_CATEG' ||
postback === 'WORK_CATEG' || postback === 'EDUCATION_CATEG' ||
postback === 'HEALTH_CATEG' || postback === 'ENTERTAINMENT_CATEG' ||
postback === 'CULTURE_CATEG' || postback === 'FOOD_CATEG' || postback === 'OTHER_CATEG') {
question.category = postback; // Will search for the question in this category
} else if (postback === 'postQuestion') {
console.log('SHULD SEE THIS IF I POST QUESTION');
botly.sendText({
id: sender,
text: `Thank you we received your question. We'll get back to you here and on mail at ${LINKED.user.emails[0].value}`
});
}
});
// Listen on the account link event
botly.on('account_link', (sender, message, link) => {
// Continue conversation
console.log('CONFIRMED AUITH', link);
if (LINKED.user) {
console.log('got user: ', LINKED.user.emails[0].value);
// connect to mysql check if the user exists already in the database by email if not create a new wp_user , create user meta to store the messenger id so we can message back
// after create a new question with the question.body
const buttons = [];
buttons.push(botly.createPostbackButton('Send question', 'postQuestion'));
botly.sendButtons({ id: sender, text: `Post this question 「${question.body}」 to our site?`, buttons: buttons }
, (err, data) => {
// log it
console.log(err);
});
botly.sendText({
id: sender,
text: (link.status === 'unlinked') ? 'Sorry to see you go' : `Hello ${LINKED.user.displayName}`
});
}
});
botly.on('message', (senderId, message, data) => {
question.senderId = message.sender.id; // the chat user
question.recipientId = message.recipient.id; // the bot
if (data && data.text && data.text.toUpperCase().indexOf('HELLO') !== -1) {
// show the main menu dialogue
return mainMenu(botly, Botly, senderId);
} else {
// it is a question send it to elasticSearch
// const text = `echo: ${data.text}`;
// botly.sendText({
// id: senderId,
// text: text
// });
question.body = data.text;
return queryES(question, botly);
}
// botly.sendText({
// id: senderId,
// text: text
// });
});
app.use(bodyParser.json());
app.use('/', router);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({ secret: 'its_my_secret', resave: true, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use('/webhook', botly.router());
app.set('port', port);
// Passport setup
passport.use('facebook', new FacebookStrategy({
clientID: fbConfig.facebook.clientID,
clientSecret: fbConfig.facebook.clientSecret,
callbackURL: fbConfig.facebook.callbackURL,
profileFields: [ 'id', 'displayName', 'email' ]
},
// facebook will send back the tokens and profile
function (request, access_token, refresh_token, profile, done) {
// asynchronous
process.nextTick(function () {
return done(null, profile);
});
}));
/*
* This path is used for account linking. The account linking call-to-action
* (sendAccountLinking) is pointed to this URL.
*
*/
app.get('/authorize', function (req, res, next) {
req.session.senderId = req.query.senderId;
console.log('%%%%%%%% AccountLinking Testing');
const accountLinkingToken = req.query.account_linking_token;
const redirectURI = req.query.redirect_uri;
console.log('%%%%% /authorize called with accountLinkingToken %s, redirectURI %s', accountLinkingToken, redirectURI);
// Authorization Code should be generated per user by the developer. This will
// be passed to the Account Linking callback.
const authCode = '1234567890';
// Redirect users to this URI on successful login
const redirectURISuccess = `${redirectURI}&authorization_code=${authCode}`;
LINKED.redirect = redirectURISuccess;
console.log('redirect to this ', redirectURISuccess);
passport.authenticate('facebook', { scope: [ 'email' ] },
{
state: {
senderId: req.query.senderId // senderId will be used after auth to reply to the user
}
})(req, res, next);
});
// Redirection after login
app.get('/auth/fb/callback', (req, res, next) => {
passport.authenticate('facebook', (err, user, info) => {
if (err) { return next(err); }
if (!user) {
console.log('bad', info);
res.redirect(LINKED.redirect);
}
console.log('good');
LINKED.user = user;
res.redirect(LINKED.redirect);
})(req, res, next);
// res.redirect(LINKED.redirect);
});
const server = http.createServer(app);
server.listen(port);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment