From d19aaf55c8787db8b87a1174475d5bd97ec881ec Mon Sep 17 00:00:00 2001 From: rocketsummer Date: Thu, 19 May 2016 22:20:15 -0500 Subject: [PATCH 1/2] Add CLI options to facebook bot: --lt to get a web URL and --ltsubdomain to set the subdomain. Update instructions in facebook readme with new CLI options. Fix syntax error in storage_test.js, caught by npm run test. --- facebook_bot.js | 39 ++++++++++++++++++++++++++++++------- lib/Facebook.js | 6 +++++- lib/storage/storage_test.js | 2 +- package.json | 2 ++ readme-facebook.md | 12 +++++------- 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/facebook_bot.js b/facebook_bot.js index ea7df335c..70d09c821 100755 --- a/facebook_bot.js +++ b/facebook_bot.js @@ -25,11 +25,9 @@ This bot demonstrates many of the core features of Botkit: Run your bot from the command line: - page_token= verify_token= node facebook_bot.js + page_token= verify_token= node facebook_bot.js [--lt [--ltsubdomain LOCALTUNNEL_SUBDOMAIN]] - Use localtunnel.me to make your bot available on the web: - - lt --port 3000 + Use the --lt option to make your bot available on the web through localtunnel.me. # USE THE BOT: @@ -78,9 +76,24 @@ if (!process.env.verify_token) { process.exit(1); } - var Botkit = require('./lib/Botkit.js'); var os = require('os'); +var commandLineArgs = require('command-line-args'); +var localtunnel = require('localtunnel'); + +const cli = commandLineArgs([ + {name: 'lt', alias: 'l', args: 1, description: 'Use localtunnel.me to make your bot available on the web.', + type: Boolean, defaultValue: false}, + {name: 'ltsubdomain', alias: 's', args: 1, + description: 'Custom subdomain for the localtunnel.me URL. This option can only be used together with --lt.', + type: String, defaultValue: null}, + ]); + +const ops = cli.parse(); +if(ops.lt === false && ops.ltsubdomain !== null) { + console.log("error: --ltsubdomain can only be used together with --lt."); + process.exit(); +} var controller = Botkit.facebookbot({ debug: true, @@ -94,13 +107,25 @@ var bot = controller.spawn({ controller.setupWebserver(process.env.port || 3000, function(err, webserver) { controller.createWebhookEndpoints(webserver, bot, function() { console.log('ONLINE!'); + if(ops.lt) { + var tunnel = localtunnel(process.env.port || 3000, {subdomain: ops.ltsubdomain}, function(err, tunnel) { + if (err) { + console.log(err); + process.exit(); + } + console.log("Your bot is available on the web at the following URL: " + tunnel.url + '/facebook/receive'); + }); + + tunnel.on('close', function() { + console.log("Your bot is no longer available on the web at the localtunnnel.me URL."); + process.exit(); + }); + } }); }); controller.hears(['hello', 'hi'], 'message_received', function(bot, message) { - - controller.storage.users.get(message.user, function(err, user) { if (user && user.name) { bot.reply(message, 'Hello ' + user.name + '!!'); diff --git a/lib/Facebook.js b/lib/Facebook.js index d940264d7..292fd44ac 100644 --- a/lib/Facebook.js +++ b/lib/Facebook.js @@ -109,7 +109,7 @@ function Facebookbot(configuration) { // set up a web route for receiving outgoing webhooks and/or slash commands - facebook_botkit.createWebhookEndpoints = function(webserver, bot) { + facebook_botkit.createWebhookEndpoints = function(webserver, bot, cb) { facebook_botkit.log( '** Serving webhook endpoints for Slash commands and outgoing ' + @@ -185,6 +185,10 @@ function Facebookbot(configuration) { } }); + if (cb) { + cb(); + } + return facebook_botkit; }; diff --git a/lib/storage/storage_test.js b/lib/storage/storage_test.js index 0c97984b5..5a868b2ec 100644 --- a/lib/storage/storage_test.js +++ b/lib/storage/storage_test.js @@ -30,7 +30,7 @@ var testStorageMethod = function(storageMethod) { console.log(data); test.assert(data.foo === testObj0.foo); }); - storageMethod.get('shouldnt-be-here', function (err, data) { + storageMethod.get('shouldnt-be-here', function(err, data) { test.assert(err.displayName === 'NotFound'); test.assert(!data); }); diff --git a/package.json b/package.json index 8c991ff25..f0f8779e2 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,11 @@ "dependencies": { "back": "^1.0.1", "body-parser": "^1.14.2", + "command-line-args": "^2.1.6", "express": "^4.13.3", "https-proxy-agent": "^1.0.0", "jfs": "^0.2.6", + "localtunnel": "^1.8.1", "mustache": "^2.2.1", "request": "^2.67.0", "ware": "^1.3.0", diff --git a/readme-facebook.md b/readme-facebook.md index 01febfa29..1bc941ef6 100644 --- a/readme-facebook.md +++ b/readme-facebook.md @@ -27,17 +27,15 @@ Copy this token, you'll need it! 4) Define your own "verify token" - this a string that you control that Facebook will use to verify your web hook endpoint. -5) Run the example bot app, using the two tokens you just created: +5) Run the example bot app, using the two tokens you just created. If you are _not_ running your bot at a public, SSL-enabled internet address, specify the --lt option. Note the URL it gives you. ``` -page_token= verify_token= node facebook_bot.js +page_token= verify_token= node facebook_bot.js [--lt [--ltsubdomain CUSTOM_SUBDOMAIN]] ``` -6) If you are _not_ running your bot at a public, SSL-enabled internet address, use [localtunnel.me](http://localtunnel.me) to make it available to Facebook. Note the URL it gives you. +6) [Set up a webhook endpoint for your app](https://developers.facebook.com/docs/messenger-platform/implementation#setting_webhooks) that uses your public URL, or the URL that localtunnel gave you. Use the verify token you defined in step 4! -7) [Set up a webhook endpoint for your app](https://developers.facebook.com/docs/messenger-platform/implementation#setting_webhooks) that uses your public URL, or the URL that localtunnel gave you. Use the verify token you defined in step 4! - -8) Your bot should be online! Within Facebook, find your page, and click the "Message" button in the header. +7) Your bot should be online! Within Facebook, find your page, and click the "Message" button in the header. Try: * who are you? @@ -46,7 +44,7 @@ Try: ​ ### Things to note -Since Facebook delivers messages via web hook, your application must be available at a public internet address. Additionally, Facebook requires this address to use SSL. Luckily, you can use [LocalTunnel](https://localtunnel.me/) to make a process running locally or in your dev environment available in a Facebook-friendly way. +Since Facebook delivers messages via web hook, your application must be available at a public internet address. Additionally, Facebook requires this address to use SSL. Luckily, you can use the --lt option to make a process running locally or in your dev environment available in a Facebook-friendly way. When you are ready to go live, consider [LetsEncrypt.org](http://letsencrypt.org), a _free_ SSL Certificate Signing Authority which can be used to secure your website very quickly. It is fabulous and we love it. From df1281489762c451ef194746325002632aaed024 Mon Sep 17 00:00:00 2001 From: rocketsummer Date: Thu, 19 May 2016 22:35:13 -0500 Subject: [PATCH 2/2] Edit readme --- readme-facebook.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme-facebook.md b/readme-facebook.md index bee8ae1a6..3068e2210 100644 --- a/readme-facebook.md +++ b/readme-facebook.md @@ -27,7 +27,7 @@ Copy this token, you'll need it! 4) Define your own "verify token" - this a string that you control that Facebook will use to verify your web hook endpoint. -5) Run the example bot app, using the two tokens you just created. If you are _not_ running your bot at a public, SSL-enabled internet address, specify the --lt option. Note the URL it gives you. +5) Run the example bot app, using the two tokens you just created. If you are _not_ running your bot at a public, SSL-enabled internet address, use the --lt option and note the URL it gives you. ``` page_token= verify_token= node facebook_bot.js [--lt [--ltsubdomain CUSTOM_SUBDOMAIN]]