-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
151 lines (138 loc) · 4.33 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// IMPORTS
const express = require('express')
const bodyParser = require('body-parser')
const request = require('request')
var fs = require('fs')
const sleep = require('sleep')
const Tesseract = require('tesseract.js')
var app = express()
// Setting up the app
const PORT = process.env.PORT || 8445;
app.set('port', (process.env.PORT || 8000));
// Process application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({extended: false}))
// Process application/json
app.use(bodyParser.json())
// Index route
app.get('/', function (req, res) {
res.send('Hello world, I am a chat bot')
})
// for Facebook verification
app.get('/webhook/', function (req, res) {
if (req.query['hub.verify_token'] === 'test') {
res.send(req.query['hub.challenge'])
}
res.send('Error, wrong token')
})
// Spin up the server
app.listen(app.get('port'), function() {
console.log('running on port', app.get('port'))
})
/**
* This is the webhook that the messenger bot posts the messages
* to...here we first check that the message is an image file and
* then recognize the image and return the text
*/
app.post('/webhook/', function (req, res) {
messaging_events = req.body.entry[0].messaging
for (i = 0; i < messaging_events.length; i++) {
console.log("we have a messaging event!")
event = req.body.entry[0].messaging[i]
console.log(event)
sender = event.sender.id
if (event.message) {
const {text, attachments} = event.message;
if (attachments) {
const file = attachments[0]
// recognise stuff with tesseract
if (file.type == 'image') {
recognizeImage(file, sender)
} else {
sendTextMessage(sender, 'We only accept image files')
}
} else {
sendTextMessage(sender, 'Please only send image attachments')
}
}
}
res.sendStatus(200)
})
/**
* Download and recognize the uploaded image file
* and then dislay the result
* @param {String} file - The messenger file object
* @param {String} path - the path to write the image to
* @param {String} sender - the id of the sender
*/
function recognizeImage(file, sender) {
sendTextMessage(sender, 'Queing the recognition job...')
const path = __dirname = '/tmp/image'
downloadImage(file.payload.url, path, () => {
Tesseract.recognize(path)
.progress(message => console.log(message))
.catch(err => console.error(err))
.then(result => {
sendMultipleMessages(sender, result.text)
})
.finally(resultOrError => console.log(resultOrError))
})
}
// get the messenger token
var token = process.env.token
/**
* Break up message into multiple messages if it
* is longer than 320 characters
* @param {String} sender - The id of the sender
* @param {String} text - The text to send
*/
function sendMultipleMessages(sender, text) {
let messages = []
while (text.length > 320) {
messages.push(text.substring(0, 320))
text = text.substring(320)
}
messages.push(text)
messages.forEach(message => {
sendTextMessage(sender, message)
// we want to sleep the node process so that
// the requests don't get sent in the wrong order
// TODO: Make this less hacky...not sure how to
// chain async requests in order
sleep.sleep(1)
})
}
/**
* Send a text message to a messager user
* @param {String} sender - The id of the sender
* @param {String} text - The text to send
*/
function sendTextMessage(sender, text) {
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token:token},
method: 'POST',
json: {
recipient: {id:sender},
message: { text },
}
}, function(error, response, body) {
if (error) {
console.log('Error sending messages: ', error)
} else if (response.body.error) {
console.log('Error: ', response.body.error)
}
})
}
/**
* Function to download an image
* @param {String} uri - The uri of the image to download
* @param {String} filename - The name of the file to be written
* @param {Function} callback - Function to be run on completion
*/
function downloadImage(uri, path, callback){
request.head(uri, function(err, res, body){
console.log('content-type:', res.headers['content-type'])
console.log('content-length:', res.headers['content-length'])
request(uri).pipe(fs.createWriteStream(path)).on('close', callback)
});
};