From 394511e0bdbda63198c4a37bdc16bef066ef6aca Mon Sep 17 00:00:00 2001 From: kb0304 Date: Wed, 8 Aug 2018 03:02:48 +0530 Subject: [PATCH 1/7] Add Invite via SMS method --- packages/rocketchat-lib/package.js | 1 + .../server/methods/sendInvitationSMS.js | 54 +++++++++++++++++++ packages/rocketchat-sms/services/twilio.js | 2 +- packages/rocketchat-sms/settings.js | 26 +++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 packages/rocketchat-lib/server/methods/sendInvitationSMS.js diff --git a/packages/rocketchat-lib/package.js b/packages/rocketchat-lib/package.js index d4d6f80adc84..5968f3810dae 100644 --- a/packages/rocketchat-lib/package.js +++ b/packages/rocketchat-lib/package.js @@ -181,6 +181,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'); diff --git a/packages/rocketchat-lib/server/methods/sendInvitationSMS.js b/packages/rocketchat-lib/server/methods/sendInvitationSMS.js new file mode 100644 index 000000000000..fd51093d5827 --- /dev/null +++ b/packages/rocketchat-lib/server/methods/sendInvitationSMS.js @@ -0,0 +1,54 @@ +import _ from 'underscore'; +import s from 'underscore.string'; + +Meteor.methods({ + sendInvitationSMS(phones) { + const twilioService = RocketChat.SMS.getService('twilio'); + if (!twilioService){ + throw new Meteor.Error('error-twilio-not-active', 'Twilio service not active', { + 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 { + let message = twilioService.send(RocketChat.settings.get('Invitation_SMS_Twilio_From'), phone, body); + } catch ({ message }) { + throw new Meteor.Error('error-sms-send-failed', `Error trying to send SMS: ${ message }`, { + method: 'sendInvitationSMS', + message, + }); + } + }); + return validPhones; + }, +}); diff --git a/packages/rocketchat-sms/services/twilio.js b/packages/rocketchat-sms/services/twilio.js index 23faf37bd0e7..aeb49f812728 100644 --- a/packages/rocketchat-sms/services/twilio.js +++ b/packages/rocketchat-sms/services/twilio.js @@ -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, diff --git a/packages/rocketchat-sms/settings.js b/packages/rocketchat-sms/settings.js index 9c91346d8355..a9d34865c68b 100644 --- a/packages/rocketchat-sms/settings.js +++ b/packages/rocketchat-sms/settings.js @@ -32,5 +32,31 @@ Meteor.startup(function() { i18nLabel: 'Auth_Token', }); }); + + this.section('Invitation', function() { + this.add('Invitation_SMS_Customized', false, { + type: 'boolean', + i18nLabel: 'Custom_SMS', + }); + this.add('Invitation_SMS_Twilio_From', '', { + type: 'string', + i18nLabel: 'Invitation_SMS_Twilio_From', + }) + 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, + }, + }); + }); }); }); From 12a5eb1387143d977d7989f3c77789142c0dc962 Mon Sep 17 00:00:00 2001 From: kb0304 Date: Tue, 9 Oct 2018 17:35:43 +0530 Subject: [PATCH 2/7] Fix lint --- .../server/methods/sendInvitationSMS.js | 26 +++++++++---------- packages/rocketchat-sms/settings.js | 12 ++++----- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/rocketchat-lib/server/methods/sendInvitationSMS.js b/packages/rocketchat-lib/server/methods/sendInvitationSMS.js index fd51093d5827..6f449366226e 100644 --- a/packages/rocketchat-lib/server/methods/sendInvitationSMS.js +++ b/packages/rocketchat-lib/server/methods/sendInvitationSMS.js @@ -1,39 +1,38 @@ import _ from 'underscore'; -import s from 'underscore.string'; Meteor.methods({ sendInvitationSMS(phones) { - const twilioService = RocketChat.SMS.getService('twilio'); - if (!twilioService){ - throw new Meteor.Error('error-twilio-not-active', 'Twilio service not active', { - method: 'sendInvitationSMS', - }); - } - check(phones, [String]); + const twilioService = RocketChat.SMS.getService('twilio'); + if (!twilioService) { + throw new Meteor.Error('error-twilio-not-active', 'Twilio service not active', { + 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 + // 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) { + const validPhones = _.compact(_.map(phones, function(phone) { if (phonePattern.test(phone)) { return phone; } })); const user = Meteor.user(); - let body; + 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'; + const lng = user.language || RocketChat.settings.get('language') || 'en'; body = TAPi18n.__('Invitation_SMS_Default_Body', { lng, }); @@ -41,7 +40,8 @@ Meteor.methods({ body = RocketChat.placeholders.replace(body); validPhones.forEach((phone) => { try { - let message = twilioService.send(RocketChat.settings.get('Invitation_SMS_Twilio_From'), phone, body); + // validate response + twilioService.send(RocketChat.settings.get('Invitation_SMS_Twilio_From'), phone, body); } catch ({ message }) { throw new Meteor.Error('error-sms-send-failed', `Error trying to send SMS: ${ message }`, { method: 'sendInvitationSMS', diff --git a/packages/rocketchat-sms/settings.js b/packages/rocketchat-sms/settings.js index a9d34865c68b..46e24c2c5ec7 100644 --- a/packages/rocketchat-sms/settings.js +++ b/packages/rocketchat-sms/settings.js @@ -33,15 +33,15 @@ Meteor.startup(function() { }); }); - this.section('Invitation', function() { + this.section('Invitation', function() { this.add('Invitation_SMS_Customized', false, { type: 'boolean', i18nLabel: 'Custom_SMS', }); - this.add('Invitation_SMS_Twilio_From', '', { - type: 'string', - i18nLabel: 'Invitation_SMS_Twilio_From', - }) + this.add('Invitation_SMS_Twilio_From', '', { + type: 'string', + i18nLabel: 'Invitation_SMS_Twilio_From', + }); return this.add('Invitation_SMS_Customized_Body', '', { type: 'code', code: 'text', @@ -57,6 +57,6 @@ Meteor.startup(function() { value: false, }, }); - }); + }); }); }); From 493d7844f442cff4b903eb5c939a67bbc5a97adf Mon Sep 17 00:00:00 2001 From: kb0304 Date: Tue, 9 Oct 2018 18:53:43 +0530 Subject: [PATCH 3/7] fix checks for sms invite --- .../server/methods/sendInvitationSMS.js | 13 ++++++++++--- packages/rocketchat-sms/settings.js | 8 ++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/rocketchat-lib/server/methods/sendInvitationSMS.js b/packages/rocketchat-lib/server/methods/sendInvitationSMS.js index 6f449366226e..89b677f25815 100644 --- a/packages/rocketchat-lib/server/methods/sendInvitationSMS.js +++ b/packages/rocketchat-lib/server/methods/sendInvitationSMS.js @@ -3,11 +3,19 @@ import _ from 'underscore'; Meteor.methods({ sendInvitationSMS(phones) { const twilioService = RocketChat.SMS.getService('twilio'); - if (!twilioService) { + 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', { @@ -40,8 +48,7 @@ Meteor.methods({ body = RocketChat.placeholders.replace(body); validPhones.forEach((phone) => { try { - // validate response - twilioService.send(RocketChat.settings.get('Invitation_SMS_Twilio_From'), phone, body); + twilioService.send(messageFrom, phone, body); } catch ({ message }) { throw new Meteor.Error('error-sms-send-failed', `Error trying to send SMS: ${ message }`, { method: 'sendInvitationSMS', diff --git a/packages/rocketchat-sms/settings.js b/packages/rocketchat-sms/settings.js index 46e24c2c5ec7..228e06664de4 100644 --- a/packages/rocketchat-sms/settings.js +++ b/packages/rocketchat-sms/settings.js @@ -34,14 +34,14 @@ Meteor.startup(function() { }); this.section('Invitation', function() { - this.add('Invitation_SMS_Customized', false, { - type: 'boolean', - i18nLabel: 'Custom_SMS', - }); 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', From d92164b6b54cc0c26cc8c4006d20f647684305a3 Mon Sep 17 00:00:00 2001 From: kb0304 Date: Tue, 9 Oct 2018 18:55:51 +0530 Subject: [PATCH 4/7] fix lint --- packages/rocketchat-lib/server/methods/sendInvitationSMS.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rocketchat-lib/server/methods/sendInvitationSMS.js b/packages/rocketchat-lib/server/methods/sendInvitationSMS.js index 89b677f25815..25b8bbb883bf 100644 --- a/packages/rocketchat-lib/server/methods/sendInvitationSMS.js +++ b/packages/rocketchat-lib/server/methods/sendInvitationSMS.js @@ -9,11 +9,11 @@ Meteor.methods({ }); } - const messageFrom = RocketChat.settings.get('Invitation_SMS_Twilio_From') + 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', - }); + method: 'sendInvitationSMS', + }); } check(phones, [String]); From 00552d67728e94455957bdc4c1db50f0451ce3a7 Mon Sep 17 00:00:00 2001 From: kb0304 Date: Wed, 24 Oct 2018 11:41:47 +0530 Subject: [PATCH 5/7] Add API endpoints for send invite sms & email --- packages/rocketchat-api/server/v1/misc.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/rocketchat-api/server/v1/misc.js b/packages/rocketchat-api/server/v1/misc.js index d29c230b2d96..7d62d3afef81 100644 --- a/packages/rocketchat-api/server/v1/misc.js +++ b/packages/rocketchat-api/server/v1/misc.js @@ -171,3 +171,25 @@ RocketChat.API.v1.addRoute('directory', { authRequired: true }, { }); }, }); + +RocketChat.API.v1.addRoute('invite.email', { authRequired: true }, { + post() { + if (!this.bodyParams.emails || !this.bodyParams.emails.length) { + throw new Meteor.Error('error-emails-param-not-provided', 'The required "emails" param is required.'); + } + + const result = Meteor.runAsUser(this.userId, () => Meteor.call('sendInvitationEmail', this.bodyParams.emails)); + return RocketChat.API.v1.success(result); + }, +}); + +RocketChat.API.v1.addRoute('invite.sms', { authRequired: true }, { + post() { + if (!this.bodyParams.phones || !this.bodyParams.phones.length) { + throw new Meteor.Error('error-phones-param-not-provided', 'The required "phones" param is required.'); + } + + const result = Meteor.runAsUser(this.userId, () => Meteor.call('sendInvitationSMS', this.bodyParams.phones)); + return RocketChat.API.v1.success(result); + }, +}); From 0efc2060f7c38cd35a6985451190c30628d1976d Mon Sep 17 00:00:00 2001 From: kb0304 Date: Sat, 10 Nov 2018 02:10:16 +0530 Subject: [PATCH 6/7] Update invite.sms and invite.email --- packages/rocketchat-api/server/v1/misc.js | 31 ++++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/packages/rocketchat-api/server/v1/misc.js b/packages/rocketchat-api/server/v1/misc.js index 7d62d3afef81..02b5599ad7a5 100644 --- a/packages/rocketchat-api/server/v1/misc.js +++ b/packages/rocketchat-api/server/v1/misc.js @@ -174,22 +174,35 @@ RocketChat.API.v1.addRoute('directory', { authRequired: true }, { RocketChat.API.v1.addRoute('invite.email', { authRequired: true }, { post() { - if (!this.bodyParams.emails || !this.bodyParams.emails.length) { - throw new Meteor.Error('error-emails-param-not-provided', 'The required "emails" param is required.'); + if (!this.bodyParams.email) { + throw new Meteor.Error('error-email-param-not-provided', 'The required "email" param is required.'); } - const result = Meteor.runAsUser(this.userId, () => Meteor.call('sendInvitationEmail', this.bodyParams.emails)); - return RocketChat.API.v1.success(result); + 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.phones || !this.bodyParams.phones.length) { - throw new Meteor.Error('error-phones-param-not-provided', 'The required "phones" param is required.'); + 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'); } - - const result = Meteor.runAsUser(this.userId, () => Meteor.call('sendInvitationSMS', this.bodyParams.phones)); - return RocketChat.API.v1.success(result); }, }); From bd69cc1f6aa540cf564950f4e70a988bd8945b8c Mon Sep 17 00:00:00 2001 From: Karan Bedi Date: Sat, 8 Dec 2018 01:20:49 +0530 Subject: [PATCH 7/7] fix lint --- packages/rocketchat-lib/server/methods/sendInvitationSMS.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/rocketchat-lib/server/methods/sendInvitationSMS.js b/packages/rocketchat-lib/server/methods/sendInvitationSMS.js index 25b8bbb883bf..f796f23e910c 100644 --- a/packages/rocketchat-lib/server/methods/sendInvitationSMS.js +++ b/packages/rocketchat-lib/server/methods/sendInvitationSMS.js @@ -1,3 +1,6 @@ +import { Meteor } from 'meteor/meteor'; +import { TAPi18n } from 'meteor/tap:i18n'; +import { check } from 'meteor/check'; import _ from 'underscore'; Meteor.methods({