forked from microsoft/BotBuilder-Samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
141 lines (120 loc) · 5.13 KB
/
app.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
/*-----------------------------------------------------------------------------
An image caption bot for the Microsoft Bot Framework.
-----------------------------------------------------------------------------*/
// This loads the environment variables from the .env file
require('dotenv-extended').load();
var builder = require('botbuilder'),
needle = require('needle'),
restify = require('restify'),
url = require('url'),
validUrl = require('valid-url'),
captionService = require('./caption-service');
//=========================================================
// Bot Setup
//=========================================================
// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});
// Create chat bot
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
server.post('/api/messages', connector.listen());
// Gets the caption by checking the type of the image (stream vs URL) and calling the appropriate caption service method.
var bot = new builder.UniversalBot(connector, function (session) {
if (hasImageAttachment(session)) {
var stream = getImageStreamFromMessage(session.message);
captionService
.getCaptionFromStream(stream)
.then(function (caption) { handleSuccessResponse(session, caption); })
.catch(function (error) { handleErrorResponse(session, error); });
} else {
var imageUrl = parseAnchorTag(session.message.text) || (validUrl.isUri(session.message.text) ? session.message.text : null);
if (imageUrl) {
captionService
.getCaptionFromUrl(imageUrl)
.then(function (caption) { handleSuccessResponse(session, caption); })
.catch(function (error) { handleErrorResponse(session, error); });
} else {
session.send('Did you upload an image? I\'m more of a visual person. Try sending me an image or an image URL');
}
}
});
//=========================================================
// Bots Events
//=========================================================
//Sends greeting message when the bot is first added to a conversation
bot.on('conversationUpdate', function (message) {
if (message.membersAdded) {
message.membersAdded.forEach(function (identity) {
if (identity.id === message.address.bot.id) {
var reply = new builder.Message()
.address(message.address)
.text('Hi! I am ImageCaption Bot. I can understand the content of any image and try to describe it as well as any human. Try sending me an image or an image URL.');
bot.send(reply);
}
});
}
});
//=========================================================
// Utilities
//=========================================================
function hasImageAttachment(session) {
return session.message.attachments.length > 0 &&
session.message.attachments[0].contentType.indexOf('image') !== -1;
}
function getImageStreamFromMessage(message) {
var headers = {};
var attachment = message.attachments[0];
if (checkRequiresToken(message)) {
// The Skype attachment URLs are secured by JwtToken,
// you should set the JwtToken of your bot as the authorization header for the GET request your bot initiates to fetch the image.
// https://github.com/Microsoft/BotBuilder/issues/662
connector.getAccessToken(function (error, token) {
var tok = token;
headers['Authorization'] = 'Bearer ' + token;
headers['Content-Type'] = 'application/octet-stream';
return needle.get(attachment.contentUrl, { headers: headers });
});
}
headers['Content-Type'] = attachment.contentType;
return needle.get(attachment.contentUrl, { headers: headers });
}
function checkRequiresToken(message) {
return message.source === 'skype' || message.source === 'msteams';
}
/**
* Gets the href value in an anchor element.
* Skype transforms raw urls to html. Here we extract the href value from the url
* @param {string} input Anchor Tag
* @return {string} Url matched or null
*/
function parseAnchorTag(input) {
var match = input.match('^<a href=\"([^\"]*)\">[^<]*</a>$');
if (match && match[1]) {
return match[1];
}
return null;
}
//=========================================================
// Response Handling
//=========================================================
function handleSuccessResponse(session, caption) {
if (caption) {
session.send('I think it\'s ' + caption);
}
else {
session.send('Couldn\'t find a caption for this one');
}
}
function handleErrorResponse(session, error) {
var clientErrorMessage = 'Oops! Something went wrong. Try again later.';
if (error.message && error.message.indexOf('Access denied') > -1) {
clientErrorMessage += "\n" + error.message;
}
console.error(error);
session.send(clientErrorMessage);
}