The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/app/sms/server/services/twilio.js

138 lines
3.3 KiB

import { Meteor } from 'meteor/meteor';
import twilio from 'twilio';
import { Random } from 'meteor/random';
import { TAPi18n } from 'meteor/rocketchat:tap-i18n';
import filesize from 'filesize';
import { settings } from '../../../settings';
import { SMS } from '../SMS';
import { Notifications } from '../../../notifications';
import { fileUploadIsValidContentType } from '../../../utils/lib/fileUploadRestrictions';
const MAX_FILE_SIZE = 5242880;
const notifyAgent = (userId, rid, msg) => Notifications.notifyUser(userId, 'message', {
_id: Random.id(),
rid,
ts: new Date(),
msg,
});
class Twilio {
constructor() {
this.accountSid = settings.get('SMS_Twilio_Account_SID');
this.authToken = settings.get('SMS_Twilio_authToken');
this.fileUploadEnabled = settings.get('SMS_Twilio_FileUpload_Enabled');
this.mediaTypeWhiteList = settings.get('SMS_Twilio_FileUpload_MediaTypeWhiteList');
}
parse(data) {
let numMedia = 0;
const returnData = {
from: data.From,
to: data.To,
body: data.Body,
extra: {
toCountry: data.ToCountry,
toState: data.ToState,
toCity: data.ToCity,
toZip: data.ToZip,
fromCountry: data.FromCountry,
fromState: data.FromState,
fromCity: data.FromCity,
fromZip: data.FromZip,
},
};
if (data.NumMedia) {
numMedia = parseInt(data.NumMedia, 10);
}
if (isNaN(numMedia)) {
console.error(`Error parsing NumMedia ${ data.NumMedia }`);
return returnData;
}
returnData.media = [];
for (let mediaIndex = 0; mediaIndex < numMedia; mediaIndex++) {
const media = {
url: '',
contentType: '',
};
const mediaUrl = data[`MediaUrl${ mediaIndex }`];
const contentType = data[`MediaContentType${ mediaIndex }`];
media.url = mediaUrl;
media.contentType = contentType;
returnData.media.push(media);
}
return returnData;
}
send(fromNumber, toNumber, message, extraData) {
const client = twilio(this.accountSid, this.authToken);
let mediaUrl;
if (extraData && extraData.fileUpload) {
const { rid, userId, fileUpload: { size, type, publicFilePath } } = extraData;
const user = userId ? Meteor.users.findOne(userId) : null;
const lng = (user && user.language) || settings.get('Language') || 'en';
let reason;
if (!this.fileUploadEnabled) {
reason = TAPi18n.__('FileUpload_Disabled', { lng });
} else if (size > MAX_FILE_SIZE) {
reason = TAPi18n.__('File_exceeds_allowed_size_of_bytes', {
size: filesize(MAX_FILE_SIZE),
lng,
});
} else if (!fileUploadIsValidContentType(type, this.fileUploadMediaTypeWhiteList)) {
reason = TAPi18n.__('File_type_is_not_accepted', { lng });
}
if (reason) {
rid && userId && notifyAgent(userId, rid, reason);
return console.error(`(Twilio) -> ${ reason }`);
}
mediaUrl = [publicFilePath];
}
// return
client.messages.create({
to: toNumber,
from: fromNumber,
body: message,
...mediaUrl && { mediaUrl },
});
}
response(/* message */) {
return {
headers: {
'Content-Type': 'text/xml',
},
body: '<Response></Response>',
};
}
error(error) {
let message = '';
if (error.reason) {
message = `<Message>${ error.reason }</Message>`;
}
return {
headers: {
'Content-Type': 'text/xml',
},
body: `<Response>${ message }</Response>`,
};
}
}
SMS.registerService('twilio', Twilio);