Skip to content

Setup Facebook Messenger API ver 4.0 #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions lib/facebook/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ module.exports = function fbSetup(api, bot, logError, optionalParser, optionalRe
stageName: lambdaDetails.alias
}).then(data => {
if (options['configure-fb-bot']) {
let token, pageAccessToken;
let token, pageAccessToken, pageId, subscribedFields;

return Promise.resolve().then(() => {
if (data.variables && data.variables.facebookVerifyToken)
Expand All @@ -71,11 +71,18 @@ module.exports = function fbSetup(api, bot, logError, optionalParser, optionalRe
console.log(`\nYour webhook URL is: ${color.cyan}${lambdaDetails.apiUrl}/facebook${color.reset}\n`);
console.log(`Your verify token is: ${color.cyan}${token}${color.reset}\n`);

return prompt(['Facebook page access token', 'Facebook App Secret']);
return prompt([
'Facebook page access token',
'Facebook App Secret',
'Facebook page ID',
'Subscribed fields (comma separated)'
]);
})
.then(results => {
console.log('\n');
pageAccessToken = results['Facebook page access token'];
pageId = results['Facebook page ID'];
subscribedFields = results['Subscribed fields (comma separated)'].split(',').map(field => `'${field.trim()}'`).join(',');
const deployment = {
restApiId: lambdaDetails.apiId,
stageName: lambdaDetails.alias,
Expand All @@ -90,7 +97,7 @@ module.exports = function fbSetup(api, bot, logError, optionalParser, optionalRe

return utils.apiGatewayPromise.createDeploymentPromise(deployment);
})
.then(() => rp.post(`https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=${pageAccessToken}`));
.then(() => rp.post(`https://graph.facebook.com/v4.0/${pageId}/subscribed_apps?access_token=${pageAccessToken}&subscribed_fields=[${subscribedFields}]`));
}
});
})
Expand Down
90 changes: 88 additions & 2 deletions spec/facebook/facebook-setup-spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*global require, describe, it, expect, beforeEach, jasmine*/
/*global require, describe, it, expect, beforeEach, jasmine, spyOn*/
'use strict';
var underTest = require('../../lib/facebook/setup');
var https = require('https');
describe('Facebook setup', () => {
var api, bot, logError, parser, responder, botPromise, botResolve, botReject;
beforeEach(() => {
Expand Down Expand Up @@ -283,6 +284,91 @@ describe('Facebook setup', () => {
});
});
});

});
describe('post deploy step processor', () => {
it('is called once', () => {
expect(api.addPostDeployStep.calls.count()).toEqual(1);
expect(api.addPostDeployStep).toHaveBeenCalledWith('facebook', jasmine.any(Function));
});
describe('processing user input', () => {
const singleInput = (data) => {
return new Promise((resolve) => {
setTimeout(() => {
process.stdin.emit('data', data);
resolve();
}, 500);
});
};
const emulateUserInputPromise = (accessToken, appSecret, pageId, subscribedField) => {
return new Promise((resolve) => {
singleInput(accessToken)
.then(() => singleInput(appSecret))
.then(() => singleInput(pageId))
.then(() => singleInput(subscribedField))
.then(() => setTimeout(() => resolve()), 500);
});
};
let options = {'configure-fb-bot': true};
let lambdaDetails = {apiUrl: 'https://testlambdafunction.com/latest'};
let getStagePromise = () => Promise.resolve({variables: {}});
let createDeploymentPromise = () => Promise.resolve();
let utils = {apiGatewayPromise: {getStagePromise: getStagePromise, createDeploymentPromise: createDeploymentPromise}};
var handler;
beforeEach(() => {
handler = api.addPostDeployStep.calls.argsFor(0)[1];
});
it('returns webhook URL if all parameters are valid', (done) => {
handler(options, lambdaDetails, utils).then(url => {
expect(url).toEqual(`${lambdaDetails.apiUrl}/facebook`);
done();
});
emulateUserInputPromise('accessToken\n', 'appSecret\n', 'pageId\n', 'messages, messaging_postbacks\n').then(() => {
https.request.calls[0].respond(200, 'OK');
});
});
it('returns webhook URL if apiGateway already has facebookVerifyToken', (done) => {
getStagePromise = () => Promise.resolve({variables: {facebookVerifyToken: 'facebookVerityToken'}});
utils = {apiGatewayPromise: {getStagePromise: getStagePromise, createDeploymentPromise: createDeploymentPromise}};
handler(options, lambdaDetails, utils).then(url => {
expect(url).toEqual(`${lambdaDetails.apiUrl}/facebook`);
done();
});
emulateUserInputPromise('accessToken\n', 'appSecret\n', 'pageId\n', 'messages, messaging_postbacks\n').then(() => {
https.request.calls[0].respond(200, 'OK');
});
});
it('shows deprecation warning and returns webhook URL if apiGateway does not return \'variables\' key', (done) => {
spyOn(console, 'log');
getStagePromise = () => Promise.resolve({});
utils = {apiGatewayPromise: {getStagePromise: getStagePromise, createDeploymentPromise: createDeploymentPromise}};
handler(options, lambdaDetails, utils).then(url => {
expect(console.log.calls.mostRecent().args[0]).toMatch(/Deprecation warning/);
expect(url).toEqual(`${lambdaDetails.apiUrl}/facebook`);
done();
});
emulateUserInputPromise('accessToken\n', 'appSecret\n', 'pageId\n', 'messages, messaging_postbacks\n').then(() => {
https.request.calls[0].respond(200, 'OK');
});
});
it('returns webhook URL even if \'configure-fb-bot\' option is not specified', (done) => {
options = { 'configure-fb-bot': false };
handler(options, lambdaDetails, utils).then(url => {
expect(url).toEqual(`${lambdaDetails.apiUrl}/facebook`);
done();
});
emulateUserInputPromise('accessToken\n', 'appSecret\n', 'pageId\n', 'messages, messaging_postbacks\n').then(() => {
https.request.calls[0].respond(200, 'OK');
});
});
it('returns webhook URL even if subscribed fields ended with comma and space', (done) => {
handler(options, lambdaDetails, utils).then(url => {
expect(url).toEqual(`${lambdaDetails.apiUrl}/facebook`);
done();
});
emulateUserInputPromise('accessToken\n', 'appSecret\n', 'pageId\n', 'messages, \n').then(() => {
https.request.calls[0].respond(200, 'OK');
});
});
});
});
});