1
0

Add minimal 'echo' facebook bot

This commit is contained in:
2018-04-21 15:58:08 +02:00
parent bde5e3be09
commit d36b4589e4
6 changed files with 3450 additions and 5435 deletions

View File

@@ -5,4 +5,47 @@
## Development
$ npm i
### 1. Install dependencies
$ npx yarn
### 2. Set environment variables
#### 2.1. Generate Facebook Verify Token
$ export FB_VERIFY_TOKEN=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 32 | head -n 1)
$ echo Facebook Access Token: $FB_VERIFY_TOKEN
#### 2.2 Set [App Secret][1]
$ export FB_APP_SECRET=''
#### 2.3. Set [Facebook Access Token][2]
$ export FB_ACCESS_TOKEN=''
#### 2.4 Set local dev server port
$ export PORT=3000
### 3. Run the local dev server
$ npx yarn run dev
### 4. Point ngrok to that local dev server
$ npx ngrok http $PORT -region eu
### 5. Point the [Facebook webhook][3] to the ngrok tunnel
https://SOME_RANDOM_ID.ngrok.io/api/v1/facebook/
### 6. Start chatting with your bot
#### 6.1 [Monitor your requests][4]
[1]: https://developers.facebook.com/apps/YOUR_APP_ID/settings/basic/
[2]: https://developers.facebook.com/apps/YOUR_APP_ID/messenger/settings/
[3]: https://developers.facebook.com/apps/YOUR_APP_ID/webhooks/
[4]: http://localhost:4040/inspect/http

51
bot/facebook/index.js Normal file
View File

@@ -0,0 +1,51 @@
const {text, json, createError} = require('micro')
const {get, post, withNamespace} = require('microrouter')
const fbParser = require('claudia-bot-builder/lib/facebook/parse')
const fbReply = require('claudia-bot-builder/lib/facebook/reply')
const fbValidate = require('claudia-bot-builder/lib/facebook/validate-integrity')
const fbTemplate = require('claudia-bot-builder/lib/facebook/format-message')
const verifyToken = req => {
if (req.query['hub.verify_token'] === process.env.FB_VERIFY_TOKEN) {
return req.query['hub.challenge']
}
console.info(
`Your Facebook Access Token (that Facebook will echo back to you as part of callback URL verification): ${
process.env.FB_VERIFY_TOKEN
}`
)
return 'INVALID TOKEN'
}
const fbMessage = async req => {
req.env = {facebookAppSecret: process.env.FB_APP_SECRET}
req.rawBody = await text(req)
const data = await json(req)
const message = data.entry.map(
entry => entry.messaging.map(message => fbParser(message))[0]
)[0]
const isValid = fbValidate(req) && message.type === 'facebook'
return isValid ? message : false
}
const respond = async (req, res) => {
const message = await fbMessage(req)
if (message) {
const recipient = message.sender
const replyMessage = new fbTemplate.Text(
`You've said: "${message.text}"`
).get()
await fbReply(recipient, replyMessage, process.env.FB_ACCESS_TOKEN)
res.end()
} else {
throw createError(400, 'Invalid message signature.')
}
}
const fbApi = withNamespace('/api/v1/facebook')
module.exports = fbApi(get('/', verifyToken), post('/', respond))

View File

@@ -1 +1,14 @@
console.log('The journey of a thousand miles begins with one step. — Lao Tzu')
const micro = require('micro')
const {router} = require('microrouter')
const fbBot = require('./bot/facebook')
const bots = [fbBot, (req, res) => micro.send(res, 404, 'Not found.')]
const server = micro(router(...bots))
const port = process.env.PORT || 3000
server.listen(port)
console.info(`Listening on port ${port}`)
module.exports = server

5432
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,9 +2,19 @@
"private": true,
"name": "vodopija-bot",
"version": "0.0.1",
"dependencies": {},
"scripts": {
"dev": "npx nodemon --inspect .",
"predev": "npx check-env PORT FB_APP_SECRET FB_ACCESS_TOKEN FB_VERIFY_TOKEN"
},
"dependencies": {
"claudia-bot-builder": "4.0.0",
"micro": "9.1.4",
"microrouter": "3.1.2"
},
"devDependencies": {
"check-env": "1.3.0",
"eslint-plugin-prettier": "2.6.0",
"ngrok": "3.0.1",
"nodemon": "1.17.3",
"prettier": "1.12.1",
"xo": "0.20.3"

3330
yarn.lock Normal file

File diff suppressed because it is too large Load Diff