machaao
Version:
Build, develop and rapidly launch personalized chatbots on Web and Android via MessengerX.io
258 lines (239 loc) • 8.04 kB
JavaScript
let jwt = require('jsonwebtoken');
const utils = require('./utils');
const bodyParser = require('body-parser');
class MessengerxSdk {
/**
*Creates an instance of MessengerxSdk.
* @param {*} api_token The api token generated when you create a new bot in https://portal.messengerx.io
* @param {*} env The MessengerX environment you wish to use. Default will be dev. If your bot is published, use 'prod'
* @param {*} app The express server object.
* @memberof MessengerxSdk
*/
constructor(api_token, env, app) {
this.api_token = api_token || new Error('missing api token');
this.env = env || 'dev';
app.use(bodyParser.json());
app.use(
bodyParser.urlencoded({
extended: true,
})
);
}
//////////////////////////
// Sending helpers
//////////////////////////
/**
*
*
* @param {*} req Express request object
* @param {*} messageText Text you wish to respond to user
* @returns
* @memberof MessengerxSdk
*/
async sendTextMessage(req, messageText) {
const userID = this.getUserFromRequest(req);
if (!userID || userID == null) return new Error('Invalid request!');
var messageData = {
users: [userID],
message: {
text: messageText,
},
};
return utils.post(this.env, messageData, utils.services.message, this.api_token);
}
/**
*
*
* @param {*} req Express request object
* @param {*} messageText Text you wish to respond to user
* @param {*} buttons Buttons you want to display to the user. Expects an object with 3 properties: title: Display Text, type: postback | web_url, payload: text to be sent to bot.
* Format : {
* "title": "Hi",
* "type": "postback",
* "payload": "hi"
* }
* @param {*} quickReplies Quick replies you want to display to the user. Expects an object with 3 properties: title: Display Text, content_type: text, payload: text to be sent to bot.
* @returns
* @memberof MessengerxSdk
*/
async sendButtonsOrQuickRepliesMessage(req, messageText, buttons, quickReplies) {
if (!req) return new Error('missing request object');
if (!messageText) messageText = '';
if (!buttons) buttons = [];
if (!quickReplies) quickReplies = [];
if (messageText === '' && buttons.length === 0 && quickReplies.length === 0)
return new Error('cannot send empty message.');
try {
const userID = this.getUserFromRequest(req);
if (!userID || userID == null) return new Error('Invalid request! Missing User.');
let errs = [];
//more validation
if (buttons.length > 0) {
buttons.map(function (l) {
if (l.type !== 'postback' && l.type !== 'web_url') throw Error(`invalid button type: ${l.type}`);
if (!l.title) throw Error('Missing button title');
if (!l.url && !l.payload) throw Error('Missing button / url payload');
});
}
var messageData = {
users: [userID],
message: {
text: messageText,
},
};
if (buttons.length > 0) {
messageData.message = {
attachment: {
type: 'template',
payload: {
template_type: 'button',
text: messageText,
buttons: buttons,
},
},
};
if (quickReplies.length > 0) messageData.message.quick_replies = quickReplies;
} else if (quickReplies.length > 0) messageData.message.quick_replies = quickReplies;
return utils.post(this.env, messageData, utils.services.message, this.api_token);
} catch (error) {
throw error;
}
}
/**
*
*
* @param {*} req Express request object
* @param {*} messageText Text you wish to respond to user
* @param {*} payload Array of carousel objects with format as below. Visit https://messengerx.readthedocs.io/en/latest/#get-started for more info.
* Format : {
* title: 'Carousel Title',
* subtitle: 'Carousel subtitle',
* image_url: 'Carousel image url',
* buttons: Array of button objects,
* }
* @param {*} quickReplies Quick replies you want to display to the user. Expects an object with 3 properties: title: Display Text, content_type: text, payload: text to be sent to bot.
* @returns
* @memberof MessengerxSdk
*/
async sendCarousel(req, messageText, payload, quickReplies) {
if (!req) return new Error('missing request object');
if (!messageText) messageText = '';
if (!payload.buttons) payload.buttons = [];
if (!quickReplies) quickReplies = [];
if (messageText === '' && payload.buttons.length === 0 && quickReplies.length === 0)
return new Error('cannot send empty message.');
try {
const userID = this.getUserFromRequest(req);
if (!userID || userID == null) return new Error('Invalid request! Missing User.');
let errs = [];
//more validation
if (payload.length > 0) {
payload.map((p) => {
p.buttons.map(function (l) {
if (l.type !== 'postback' && l.type !== 'web_url')
throw Error(`invalid button type: ${l.type}`);
if (!l.title) throw Error('Missing button title');
if (!l.payload) throw Error('Missing button payload');
});
});
}
var messageData = {
users: [userID],
message: {
text: messageText,
},
};
if (payload.length > 0) {
messageData.message = {
attachment: {
type: 'template',
payload: {
template_type: 'generic',
elements: [],
},
},
};
if (payload.length > 0) {
payload.map((p) => {
messageData.message.attachment.payload.elements.push({
title: p.title || ' ',
subtitle: p.subtitle || ' ',
image_url: p.image_url || ' ',
buttons: p.buttons,
});
});
}
if (quickReplies.length > 0) messageData.message.quick_replies = quickReplies;
} else if (quickReplies.length > 0) messageData.message.quick_replies = quickReplies;
return utils.post(this.env, messageData, utils.services.message, this.api_token);
} catch (error) {
throw error;
}
}
async addUserTag(tag, values, req, userId) {
if (!req) throw new Error('missing express req object');
if (!tag) throw new Error('missing tag');
if (!values) throw new Error('missing values');
if (typeof values === 'string') {
if (values.length < 1) throw new Error('value cannot be empty');
else values = [values];
}
const u = userId || this.getUserFromRequest(req);
return utils.post(
this.env,
{
tag: tag,
status: 1,
values: values,
displayName: tag,
},
utils.services.tag,
this.api_token,
`${u}`
);
}
async getUserTags(req, userId) {
if (!req) throw new Error('missing express req object');
const u = userId || this.getUserFromRequest(req);
return utils.get(this.env, utils.services.userTags, `${u}`, this.api_token);
}
getUserFromRequest(req) {
if (!req) throw new Error('missing body object');
return req.headers.user_id || new Error('missing user id. please contact administrator');
}
getMessagingEntries(body) {
let self = this;
const val = body.messaging && Array.isArray(body.messaging) && body.messaging.length > 0 && body.messaging;
return val || null;
}
getUserMessages(req) {
if (!req.body) throw new Error('missing body object');
let body = req.body;
let _rawBody = req.body && req.body.raw;
let userID = this.getUserFromRequest(req);
let that = this;
if (!_rawBody || !userID)
throw new Error(
'Unauthorized Client Request, Bot is not available at this time, Please contact us at connect@machaao.com'
);
return jwt.verify(_rawBody, this.api_token, { algorithms: ['HS512'] }, function (err, decoded) {
if (err)
throw new Error(
'Unauthorized Client Request, Bot is not available at this time, Please contact us at connect@machaao.com'
);
try {
let _body =
decoded && decoded.sub && decoded.sub.messaging ? decoded.sub : JSON.parse(decoded && decoded.sub);
let resu = that.getMessagingEntries(_body);
return resu;
} catch (error) {
throw new Error(`Error while parsing incoming message: ${error}`);
}
});
}
getUser(messaging) {
const val = messaging.user;
return val || null;
}
}
module.exports = MessengerxSdk;