Skip to content

Commit

Permalink
Merge pull request #8807 from RocketChat/facebook-livechat-integration
Browse files Browse the repository at this point in the history
[NEW] Facebook livechat integration
  • Loading branch information
rodrigok authored Dec 8, 2017
2 parents 1501286 + f703fec commit 683792a
Show file tree
Hide file tree
Showing 21 changed files with 547 additions and 337 deletions.
18 changes: 15 additions & 3 deletions packages/rocketchat-i18n/i18n/en.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@
"Accounts_Registration_AuthenticationServices_Default_Roles_Description": "Default roles (comma-separated) users will be given when registering through authentication services",
"Accounts_Registration_AuthenticationServices_Enabled": "Registration with Authentication Services",
"Accounts_RegistrationForm": "Registration Form",
"Accounts_RegistrationForm_Disabled": "Disabled",
"Accounts_RegistrationForm_LinkReplacementText": "Registration Form Link Replacement Text",
"Accounts_RegistrationForm_Public": "Public",
"Accounts_RegistrationForm_Secret_URL": "Secret URL",
Expand Down Expand Up @@ -245,6 +244,7 @@
"are_typing": "are typing",
"Are_you_sure": "Are you sure?",
"Are_you_sure_you_want_to_delete_your_account": "Are you sure you want to delete your account?",
"Are_you_sure_you_want_to_disable_Facebook_integration": "Are you sure you want to disable Facebook integration?",
"assign-admin-role": "Assign Admin Role",
"assign-admin-role_description": "Permission to assign the admin role to other users",
"Assign_admin": "Assigning admin",
Expand Down Expand Up @@ -518,9 +518,11 @@
"Direct_Reply_Separator_Description": "[Alter only if you know exactly what you are doing, refer docs]<br/>Separator between base & tag part of email",
"Direct_Reply_Username": "Username",
"Direct_Reply_Username_Description": "Please use absolute email, tagging is not allowed, it would be over-written",
"Disable_Facebook_integration": "Disable Facebook integration",
"Disable_Notifications": "Disable Notifications",
"Disable_two-factor_authentication": "Disable two-factor authentication",
"Display_offline_form": "Display Offline Form",
"Disabled": "Disabled",
"Display_offline_form": "Display offline form",
"Displays_action_text": "Displays action text",
"Do_you_want_to_change_to_s_question": "Do you want to change to <strong>%s</strong>?",
"Domain": "Domain",
Expand Down Expand Up @@ -567,7 +569,6 @@
"Email_Header_Description": "You may use the following placeholders: <br /><ul><li>[Site_Name] and [Site_URL] for the Application Name and URL respectively.</li></ul>",
"Email_Notification_Mode": "Offline Email Notifications",
"Email_Notification_Mode_All": "Every Mention/DM",
"Email_Notification_Mode_Disabled": "Disabled",
"Email_or_username": "Email or username",
"Email_Placeholder": "Please enter your email address...",
"Email_subject": "Subject",
Expand Down Expand Up @@ -667,6 +668,7 @@
"error-user-registration-secret": "User registration is only allowed via Secret URL",
"error-you-are-last-owner": "You are the last owner. Please set new owner before leaving the room.",
"Error_changing_password": "Error changing password",
"Error_loading_pages": "Error loading pages",
"Error_RocketChat_requires_oplog_tailing_when_running_in_multiple_instances": "Error: Rocket.Chat requires oplog tailing when running in multiple instances",
"Error_RocketChat_requires_oplog_tailing_when_running_in_multiple_instances_details": "Please make sure your MongoDB is on ReplicaSet mode and MONGO_OPLOG_URL environment variable is defined correctly on the application server",
"Esc_to": "Esc to",
Expand All @@ -679,6 +681,7 @@
"Example_s": "Example: <code class=\"inline\">%s</code>",
"Exclude_Botnames": "Exclude Bots",
"Exclude_Botnames_Description": "Do not propagate messages from bots whose name matches the regular expression above. If left empty, all messages from bots will be propagated.",
"Facebook_Page": "Facebook Page",
"False": "False",
"Favorite_Rooms": "Enable Favorite Rooms",
"Favorites": "Favorites",
Expand Down Expand Up @@ -807,6 +810,7 @@
"If_this_email_is_registered": "If this email is registered, we'll send instructions on how to reset your password. If you do not receive an email shortly, please come back and try again.",
"If_you_are_sure_type_in_your_password": "If you are sure type in your password:",
"If_you_are_sure_type_in_your_username": "If you are sure type in your username:",
"If_you_dont_have_one_send_an_email_to_omni_rocketchat_to_get_yours": "If you don't have one send an email to [[email protected]](mailto:[email protected]) to get yours.",
"Iframe_Integration": "Iframe Integration",
"Iframe_Integration_receive_enable": "Enable Receive",
"Iframe_Integration_receive_enable_Description": "Allow parent window to send commands to Rocket.Chat.",
Expand Down Expand Up @@ -859,6 +863,7 @@
"Instructions_to_your_visitor_fill_the_form_to_send_a_message": "Instructions to your visitor fill the form to send a message",
"Integration_added": "Integration has been added",
"Integration_Advanced_Settings": "Advanced Settings",
"Integration_disabled": "Integration disabled",
"Integration_History_Cleared": "Integration History Successfully Cleared",
"Integration_Incoming_WebHook": "Incoming WebHook Integration",
"Integration_New": "New Integration",
Expand Down Expand Up @@ -1090,6 +1095,9 @@
"Livechat_AllowedDomainsList": "Livechat Allowed Domains",
"Livechat_Dashboard": "Livechat Dashboard",
"Livechat_enabled": "Livechat enabled",
"Livechat_Facebook_Enabled": "Facebook integration enabled",
"Livechat_Facebook_API_Key": "Facebook API Key",
"Livechat_Facebook_API_Secret": "Facebook API Secret",
"Livechat_forward_open_chats": "Forward open chats",
"Livechat_forward_open_chats_timeout": "Timeout (in seconds) to forward chats",
"Livechat_guest_count": "Guest Counter",
Expand Down Expand Up @@ -1291,6 +1299,7 @@
"No_integration_found": "No integration found by the provided id.",
"No_livechats": "You have no livechats",
"No_mentions_found": "No mentions found",
"No_pages_yet_Try_hitting_Reload_Pages_button": "No pages yet. Try hitting \"Reload Pages\" button.",
"No_messages_yet": "No messages yet",
"No_pinned_messages": "No pinned messages",
"No_results_found": "No results found",
Expand Down Expand Up @@ -1414,6 +1423,7 @@
"Please_fill_a_username": "Please fill a username",
"Please_fill_all_the_information": "Please fill all the information",
"Please_fill_name_and_email": "Please fill name and email",
"Please_go_to_the_Administration_page_then_Livechat_Facebook": "Please go to the Administration page then Livechat > Facebook",
"Please_select_an_user": "Please select an user",
"Please_select_enabled_yes_or_no": "Please select an option for Enabled",
"Please_wait": "Please wait",
Expand Down Expand Up @@ -1489,6 +1499,7 @@
"Regular_Expressions": "Regular Expressions",
"Release": "Release",
"Reload": "Reload",
"Reload_Pages": "Reload Pages",
"Remove": "Remove",
"remove-user": "Remove User",
"remove-user_description": "Permission to remove a user from a room",
Expand Down Expand Up @@ -2089,6 +2100,7 @@
"You_have_n_codes_remaining": "You have __number__ codes remaining.",
"You_have_not_verified_your_email": "You have not verified your email.",
"You_have_successfully_unsubscribed": "You have successfully unsubscribed from our Mailling List.",
"You_have_to_set_an_API_token_first_in_order_to_use_the_integration": "You have to set an API token first in order to use the integration.",
"You_must_join_to_view_messages_in_this_channel": "You must join to view messages in this channel",
"You_need_confirm_email": "You need to confirm your email to login!",
"You_need_install_an_extension_to_allow_screen_sharing": "You need install an extension to allow screen sharing",
Expand Down
16 changes: 12 additions & 4 deletions packages/rocketchat-livechat/client/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,19 @@ AccountBox.addRoute({
}, livechatManagerRoutes);

AccountBox.addRoute({
name: 'livechat-integrations',
path: '/integrations',
name: 'livechat-webhooks',
path: '/webhooks',
sideNav: 'livechatFlex',
i18nPageTitle: 'Integrations',
pageTemplate: 'livechatIntegrations'
i18nPageTitle: 'Webhooks',
pageTemplate: 'livechatIntegrationWebhook'
}, livechatManagerRoutes);

AccountBox.addRoute({
name: 'livechat-facebook',
path: '/facebook',
sideNav: 'livechatFlex',
i18nPageTitle: 'Facebook Messenger',
pageTemplate: 'livechatIntegrationFacebook'
}, livechatManagerRoutes);

AccountBox.addRoute({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<template name="livechatIntegrationFacebook">
<form id="profile" autocomplete="off" class="container">
<fieldset class="rc-form-legend">
<div class="rc-form-group">
{{#if enabled}}
<button class="button reload">{{_ "Reload_Pages"}}</button>
<button class="button danger disable">{{_ "Disable"}}</button>
{{else}}
<button class="button primary enable" {{enableButtonDisabled}}>{{_ "Enable"}}</button>
{{#unless hasToken}}
<p>{{_ "You_have_to_set_an_API_token_first_in_order_to_use_the_integration"}}</p>
<p>{{_ "Please_go_to_the_Administration_page_then_Livechat_Facebook"}}</p>
{{/unless}}
{{/if}}
</div>
{{#if isLoading}}
{{> loading}}
{{else}}
{{#each pages}}
<div class="rc-form-group">
<div class="rc-switch">
<label class="rc-switch__label" tabindex="-1">
<input type="checkbox" class="rc-switch__input" name="subscribe" value="true" {{subscribed}}>
<span class="rc-switch__button">
<span class="rc-switch__button-inside"></span>
</span>
<span class="rc-switch__text">{{name}}</span>
</label>
</div>
</div>
{{else}}
{{#if enabled}}
<p>{{_ "No_pages_yet_Try_hitting_Reload_Pages_button"}}</p>
{{/if}}
{{/each}}
{{/if}}
</fieldset>
</form>
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
Template.livechatIntegrationFacebook.helpers({
pages() {
return Template.instance().pages.get();
},
subscribed() {
return this.subscribed ? 'checked' : '';
},
enabled() {
return Template.instance().enabled.get();
},
hasToken() {
return Template.instance().hasToken.get();
},
enableButtonDisabled() {
return !Template.instance().hasToken.get() ? 'disabled' : '';
},
isLoading() {
return Template.instance().loading.get();
}
});

Template.livechatIntegrationFacebook.onCreated(function() {
this.enabled = new ReactiveVar(false);
this.hasToken = new ReactiveVar(false);
this.pages = new ReactiveVar([]);
this.loading = new ReactiveVar(false);

this.autorun(() => {
if (this.enabled.get()) {
this.loadPages();
}
});

this.result = (successFn, errorFn = () => {}) => {
return (error, result) => {
if (result.success === false && (result.type === 'OAuthException' || typeof result.url !== 'undefined')) {
const oauthWindow = window.open(result.url, 'facebook-integration-oauth', 'width=600,height=400');

const checkInterval = setInterval(() => {
if (oauthWindow.closed) {
clearInterval(checkInterval);
errorFn(error);
}
}, 300);
return;
}
if (error) {
errorFn(error);
return swal({
title: t('Error_loading_pages'),
text: error.reason,
type: 'error'
});
}
successFn(result);
};
};

this.loadPages = () => {
this.pages.set([]);
this.loading.set(true);
Meteor.call('livechat:facebook', { action: 'list-pages' }, this.result((result) => {
this.pages.set(result.pages);
this.loading.set(false);
}, () => this.loading.set(false)));
};
});

Template.livechatIntegrationFacebook.onRendered(function() {
this.loading.set(true);
Meteor.call('livechat:facebook', { action: 'initialState' }, this.result((result) => {
this.enabled.set(result.enabled);
this.hasToken.set(result.hasToken);
this.loading.set(false);
}));
});

Template.livechatIntegrationFacebook.events({
'click .reload'(event, instance) {
event.preventDefault();

instance.loadPages();
},
'click .enable'(event, instance) {
event.preventDefault();

Meteor.call('livechat:facebook', { action: 'enable' }, instance.result(() => {
instance.enabled.set(true);
}, () => instance.enabled.set(true)));
},
'click .disable'(event, instance) {
event.preventDefault();

swal({
title: t('Disable_Facebook_integration'),
text: t('Are_you_sure_you_want_to_disable_Facebook_integration'),
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#DD6B55',
confirmButtonText: t('Yes'),
cancelButtonText: t('Cancel'),
closeOnConfirm: false,
html: false
}, () => {
Meteor.call('livechat:facebook', { action: 'disable' }, (err) => {
if (err) {
return handleError(err);
}
instance.enabled.set(false);
instance.pages.set([]);

swal({
title: t('Disabled'),
text: t('Integration_disabled'),
type: 'success',
timer: 2000,
showConfirmButton: false
});
});
});
},
'change [name=subscribe]'(event, instance) {
Meteor.call('livechat:facebook', {
action: !event.currentTarget.checked ? 'unsubscribe' : 'subscribe',
page: this.id
}, (err, result) => {
if (result.success) {
const pages = instance.pages.get();
pages.forEach(page => {
if (page.id === this.id) {
page.subscribed = event.currentTarget.checked;
}
});
instance.pages.set(pages);
}
});
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template name="livechatIntegrationWebhook">
{{#requiresPermission 'view-livechat-manager'}}
<div class="rocket-form">
<h2>{{_ "Webhooks"}}</h2>
<p>
{{_ "You_can_use_webhooks_to_easily_integrate_livechat_with_your_CRM"}}
<a href="https://rocket.chat/docs/administrator-guides/livechat/#integrations">{{_ "Click_here"}}</a> {{_ "to_see_more_details_on_how_to_integrate"}}
</p>

<form id="integration-form">
<div class="input-line">
<label for="webhookUrl">{{_ "Webhook_URL"}}</label>
<div>
<input type="url" name="webhookUrl" id="webhookUrl" value="{{webhookUrl}}" placeholder="https://yourdomain.com/webhook/entrypoint">
</div>
</div>
<div class="input-line">
<label for="secretToken">{{_ "Secret_token"}}</label>
<div>
<input type="text" name="secretToken" id="secretToken" value="{{secretToken}}">
</div>
</div>
<div class="input-line">
<label for="sendOnClose">
<input type="checkbox" name="sendOnClose" id="sendOnClose" value="1" checked="{{sendOnCloseChecked}}">
{{_ "Send_request_on_chat_close"}}
</label>
</div>
<div class="input-line">
<label for="sendOnOffline">
<input type="checkbox" name="sendOnOffline" id="sendOnOffline" value="1" checked="{{sendOnOfflineChecked}}">
{{_ "Send_request_on_offline_messages"}}
</label>
</div>
<div class="submit">
<button class="button danger reset-settings" type="button"><i class="icon-ccw"></i>{{_ "Reset"}}</button>
<button class="button secondary test" type="button" disabled="{{disableTest}}">{{_ "Send_Test"}}</button>
<button class="button primary save"><i class="icon-floppy"></i>{{_ "Save"}}</button>
</div>
</form>
</div>
{{/requiresPermission}}
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import _ from 'underscore';
import s from 'underscore.string';
import toastr from 'toastr';

Template.livechatIntegrations.helpers({
Template.livechatIntegrationWebhook.helpers({
webhookUrl() {
const setting = LivechatIntegration.findOne('Livechat_webhookUrl');
return setting && setting.value;
Expand All @@ -25,7 +25,7 @@ Template.livechatIntegrations.helpers({
}
});

Template.livechatIntegrations.onCreated(function() {
Template.livechatIntegrationWebhook.onCreated(function() {
this.disableTest = new ReactiveVar(true);

this.autorun(() => {
Expand All @@ -36,7 +36,7 @@ Template.livechatIntegrations.onCreated(function() {
this.subscribe('livechat:integration');
});

Template.livechatIntegrations.events({
Template.livechatIntegrationWebhook.events({
'change #webhookUrl, blur #webhookUrl'(e, instance) {
const setting = LivechatIntegration.findOne('Livechat_webhookUrl');
instance.disableTest.set(!setting || e.currentTarget.value !== setting.value);
Expand Down
Loading

0 comments on commit 683792a

Please sign in to comment.