Skip to content

Commit

Permalink
Merge pull request #11 from WideChat/sms-invite
Browse files Browse the repository at this point in the history
[New] SMS & Email Invite for Contacts
  • Loading branch information
ear-dev authored Dec 12, 2018
2 parents 3f4fe53 + bd69cc1 commit 1b6074b
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 1 deletion.
35 changes: 35 additions & 0 deletions packages/rocketchat-api/server/v1/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,38 @@ RocketChat.API.v1.addRoute('directory', { authRequired: true }, {
});
},
});

RocketChat.API.v1.addRoute('invite.email', { authRequired: true }, {
post() {
if (!this.bodyParams.email) {
throw new Meteor.Error('error-email-param-not-provided', 'The required "email" param is required.');
}

Meteor.runAsUser(this.userId, () => Meteor.call('sendInvitationEmail', [this.bodyParams.email]));
return RocketChat.API.v1.success();

// sendInvitationEmail always returns an empty list
/*
if(this.bodyParams.email in result){
return RocketChat.API.v1.success();
}else{
return RocketChat.API.v1.failure('Email Invite Failed');
}
*/
},
});

RocketChat.API.v1.addRoute('invite.sms', { authRequired: true }, {
post() {
if (!this.bodyParams.phone) {
throw new Meteor.Error('error-phone-param-not-provided', 'The required "phone" param is required.');
}
const phone = this.bodyParams.phone.replace(/-|\s/g, '');
const result = Meteor.runAsUser(this.userId, () => Meteor.call('sendInvitationSMS', [phone]));
if (result.indexOf(phone) >= 0) {
return RocketChat.API.v1.success();
} else {
return RocketChat.API.v1.failure('SMS Invite Failed');
}
},
});
1 change: 1 addition & 0 deletions packages/rocketchat-lib/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ Package.onUse(function(api) {
api.addFiles('server/methods/robotMethods.js', 'server');
api.addFiles('server/methods/saveSetting.js', 'server');
api.addFiles('server/methods/sendInvitationEmail.js', 'server');
api.addFiles('server/methods/sendInvitationSMS.js', 'server');
api.addFiles('server/methods/sendMessage.js', 'server');
api.addFiles('server/methods/sendSMTPTestEmail.js', 'server');
api.addFiles('server/methods/setAdminStatus.js', 'server');
Expand Down
64 changes: 64 additions & 0 deletions packages/rocketchat-lib/server/methods/sendInvitationSMS.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Meteor } from 'meteor/meteor';
import { TAPi18n } from 'meteor/tap:i18n';
import { check } from 'meteor/check';
import _ from 'underscore';

Meteor.methods({
sendInvitationSMS(phones) {
const twilioService = RocketChat.SMS.getService('twilio');
if (!RocketChat.SMS.enabled || !twilioService) {
throw new Meteor.Error('error-twilio-not-active', 'Twilio service not active', {
method: 'sendInvitationSMS',
});
}

const messageFrom = RocketChat.settings.get('Invitation_SMS_Twilio_From');
if (!twilioService.accountSid || ! twilioService.authToken || !messageFrom) {
throw new Meteor.Error('error-twilio-not-configured', 'Twilio service not configured', {
method: 'sendInvitationSMS',
});
}

check(phones, [String]);
if (!Meteor.userId()) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', {
method: 'sendInvitationSMS',
});
}

// to be replaced by a seperate permission specific to SMS later
if (!RocketChat.authz.hasPermission(Meteor.userId(), 'bulk-register-user')) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', {
method: 'sendInvitationSMS',
});
}
const phonePattern = /^\+?[1-9]\d{1,14}$/;
const validPhones = _.compact(_.map(phones, function(phone) {
if (phonePattern.test(phone)) {
return phone;
}
}));
const user = Meteor.user();
let body;
if (RocketChat.settings.get('Invitation_SMS_Customized')) {
body = RocketChat.settings.get('Invitation_SMS_Customized_Body');
} else {
const lng = user.language || RocketChat.settings.get('language') || 'en';
body = TAPi18n.__('Invitation_SMS_Default_Body', {
lng,
});
}
body = RocketChat.placeholders.replace(body);
validPhones.forEach((phone) => {
try {
twilioService.send(messageFrom, phone, body);
} catch ({ message }) {
throw new Meteor.Error('error-sms-send-failed', `Error trying to send SMS: ${ message }`, {
method: 'sendInvitationSMS',
message,
});
}
});
return validPhones;
},
});
2 changes: 1 addition & 1 deletion packages/rocketchat-sms/server/services/twilio.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class Twilio {
send(fromNumber, toNumber, message) {
const client = twilio(this.accountSid, this.authToken);

client.messages.create({
return client.messages.create({
to: toNumber,
from: fromNumber,
body: message,
Expand Down
26 changes: 26 additions & 0 deletions packages/rocketchat-sms/server/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,31 @@ Meteor.startup(function() {
i18nLabel: 'Auth_Token',
});
});

this.section('Invitation', function() {
this.add('Invitation_SMS_Twilio_From', '', {
type: 'string',
i18nLabel: 'Invitation_SMS_Twilio_From',
});
this.add('Invitation_SMS_Customized', false, {
type: 'boolean',
i18nLabel: 'Custom_SMS',
});
return this.add('Invitation_SMS_Customized_Body', '', {
type: 'code',
code: 'text',
multiline: true,
i18nLabel: 'Body',
i18nDescription: 'Invitation_SMS_Customized_Body',
enableQuery: {
_id: 'Invitation_SMS_Customized',
value: true,
},
i18nDefaultQuery: {
_id: 'Invitation_SMS_Default_Body',
value: false,
},
});
});
});
});

0 comments on commit 1b6074b

Please sign in to comment.