[BREAK] Remove legacy FB Messenger integration (#27760)

Co-authored-by: Kevin Aleman <11577696+KevLehman@users.noreply.github.com>
pull/27898/head^2
Murtaza Patrawala 3 years ago committed by GitHub
parent ebbb8471a8
commit 344809bda0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      apps/meteor/app/authorization/server/functions/upsertPermissions.ts
  2. 119
      apps/meteor/app/livechat/imports/server/rest/facebook.ts
  3. 1
      apps/meteor/app/livechat/server/api.ts
  4. 23
      apps/meteor/app/livechat/server/config.ts
  5. 49
      apps/meteor/app/livechat/server/hooks/sendToFacebook.js
  6. 2
      apps/meteor/app/livechat/server/index.js
  7. 70
      apps/meteor/app/livechat/server/lib/OmniChannel.js
  8. 68
      apps/meteor/app/livechat/server/methods/facebook.js
  9. 80
      apps/meteor/client/views/omnichannel/facebook/FacebookPage.tsx
  10. 135
      apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx
  11. 36
      apps/meteor/client/views/omnichannel/facebook/PageToggle.tsx
  12. 30
      apps/meteor/client/views/omnichannel/facebook/PageToggleAssembler.tsx
  13. 5
      apps/meteor/client/views/omnichannel/routes.ts
  14. 5
      apps/meteor/client/views/omnichannel/sidebarItems.ts
  15. 15
      apps/meteor/definition/methods/omnichannel.ts
  16. 8
      apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json
  17. 1
      apps/meteor/server/modules/watchers/publishFields.ts
  18. 1
      apps/meteor/server/startup/migrations/index.ts
  19. 49
      apps/meteor/server/startup/migrations/v283.ts
  20. 50
      packages/rest-typings/src/v1/omnichannel.ts

@ -152,7 +152,6 @@ export const upsertPermissions = async (): Promise<void> => {
{ _id: 'view-livechat-installation', roles: ['livechat-manager', 'admin'] },
{ _id: 'view-livechat-appearance', roles: ['livechat-manager', 'admin'] },
{ _id: 'view-livechat-webhooks', roles: ['livechat-manager', 'admin'] },
{ _id: 'view-livechat-facebook', roles: ['livechat-manager', 'admin'] },
{
_id: 'view-livechat-business-hours',
roles: ['livechat-manager', 'livechat-monitor', 'admin'],

@ -1,119 +0,0 @@
import crypto from 'crypto';
import { isPOSTLivechatFacebookParams } from '@rocket.chat/rest-typings';
import { Random } from 'meteor/random';
import { LivechatVisitors } from '@rocket.chat/models';
import type { ILivechatVisitor } from '@rocket.chat/core-typings';
import { API } from '../../../../api/server';
import { LivechatRooms } from '../../../../models/server';
import { settings } from '../../../../settings/server';
import { Livechat } from '../../../server/lib/Livechat';
type SentMessage = {
message: {
_id: string;
rid?: string;
token?: string;
msg?: string;
};
roomInfo: {
facebook: {
page: string;
};
};
guest?: ILivechatVisitor | null;
};
/**
* @api {post} /livechat/facebook Send Facebook message
* @apiName Facebook
* @apiGroup Livechat
*
* @apiParam {String} mid Facebook message id
* @apiParam {String} page Facebook pages id
* @apiParam {String} token Facebook user's token
* @apiParam {String} first_name Facebook user's first name
* @apiParam {String} last_name Facebook user's last name
* @apiParam {String} [text] Facebook message text
* @apiParam {String} [attachments] Facebook message attachments
*/
API.v1.addRoute(
'livechat/facebook',
{ validateParams: isPOSTLivechatFacebookParams },
{
async post() {
if (!this.bodyParams.text && !this.bodyParams.attachments) {
return API.v1.failure('Invalid request');
}
if (!this.request.headers['x-hub-signature']) {
return API.v1.unauthorized();
}
if (!settings.get<boolean>('Livechat_Facebook_Enabled')) {
return API.v1.failure('Facebook integration is disabled');
}
// validate if request come from omni
const signature = crypto
.createHmac('sha1', settings.get<string>('Livechat_Facebook_API_Secret'))
.update(JSON.stringify(this.request.body))
.digest('hex');
if (this.request.headers['x-hub-signature'] !== `sha1=${signature}`) {
return API.v1.unauthorized();
}
const sendMessage: SentMessage = {
message: {
_id: this.bodyParams.mid,
msg: this.bodyParams.text,
},
roomInfo: {
facebook: {
page: this.bodyParams.page,
},
},
};
let visitor = await LivechatVisitors.getVisitorByToken(this.bodyParams.token, {});
if (visitor) {
const rooms = LivechatRooms.findOpenByVisitorToken(visitor.token).fetch();
if (rooms && rooms.length > 0) {
sendMessage.message.rid = rooms[0]._id;
} else {
sendMessage.message.rid = Random.id();
}
sendMessage.message.token = visitor.token;
} else {
sendMessage.message.rid = Random.id();
sendMessage.message.token = this.bodyParams.token;
const userId = await Livechat.registerGuest({
token: sendMessage.message.token,
name: `${this.bodyParams.first_name} ${this.bodyParams.last_name}`,
// TODO: type livechat big file :(
id: undefined,
email: undefined,
phone: undefined,
department: undefined,
username: undefined,
connectionData: undefined,
});
visitor = await LivechatVisitors.findOneById(userId);
}
sendMessage.guest = visitor;
try {
return API.v1.success({
// @ts-expect-error - Typings on Livechat.sendMessage are wrong
message: await Livechat.sendMessage(sendMessage),
});
} catch (err) {
Livechat.logger.error({ msg: 'Error using Facebook ->', err });
return API.v1.failure(err);
}
},
},
);

@ -1,6 +1,5 @@
import '../imports/server/rest/agent';
import '../imports/server/rest/departments';
import '../imports/server/rest/facebook';
import '../imports/server/rest/sms.js';
import '../imports/server/rest/users';
import '../imports/server/rest/upload';

@ -449,29 +449,6 @@ Meteor.startup(function () {
i18nLabel: 'Channel_name',
});
this.add('Livechat_Facebook_Enabled', false, {
type: 'boolean',
group: 'Omnichannel',
section: 'Facebook',
enableQuery: omnichannelEnabledQuery,
});
this.add('Livechat_Facebook_API_Key', '', {
type: 'string',
group: 'Omnichannel',
section: 'Facebook',
i18nDescription: 'If_you_dont_have_one_send_an_email_to_omni_rocketchat_to_get_yours',
enableQuery: omnichannelEnabledQuery,
});
this.add('Livechat_Facebook_API_Secret', '', {
type: 'string',
group: 'Omnichannel',
section: 'Facebook',
i18nDescription: 'If_you_dont_have_one_send_an_email_to_omni_rocketchat_to_get_yours',
enableQuery: omnichannelEnabledQuery,
});
this.add('Livechat_Routing_Method', 'Auto_Selection', {
type: 'select',
group: 'Omnichannel',

@ -1,49 +0,0 @@
import { isOmnichannelRoom } from '@rocket.chat/core-typings';
import { callbacks } from '../../../../lib/callbacks';
import { settings } from '../../../settings/server';
import OmniChannel from '../lib/OmniChannel';
import { normalizeMessageFileUpload } from '../../../utils/server/functions/normalizeMessageFileUpload';
callbacks.add(
'afterSaveMessage',
function (message, room) {
// skips this callback if the message was edited
if (message.editedAt) {
return message;
}
// only send the sms by SMS if it is a livechat room with SMS set to true
if (!(isOmnichannelRoom(room) && room.facebook && room.v && room.v.token)) {
return message;
}
if (!settings.get('Livechat_Facebook_Enabled') || !settings.get('Livechat_Facebook_API_Key')) {
return message;
}
// if the message has a token, it was sent from the visitor, so ignore it
if (message.token) {
return message;
}
// if the message has a type means it is a special message (like the closing comment), so skips
if (message.t) {
return message;
}
if (message.file) {
message = Promise.await(normalizeMessageFileUpload(message));
}
OmniChannel.reply({
page: room.facebook.page.id,
token: room.v.token,
text: message.msg,
});
return message;
},
callbacks.priority.LOW,
'sendMessageToFacebook',
);

@ -10,7 +10,6 @@ import './hooks/offlineMessage';
import './hooks/offlineMessageToChannel';
import './hooks/saveAnalyticsData';
import './hooks/sendToCRM';
import './hooks/sendToFacebook';
import './hooks/processRoomAbandonment';
import './hooks/saveLastVisitorMessageTs';
import './hooks/markRoomNotResponded';
@ -24,7 +23,6 @@ import './methods/changeLivechatStatus';
import './methods/closeByVisitor';
import './methods/closeRoom';
import './methods/discardTranscript';
import './methods/facebook';
import './methods/getCustomFields';
import './methods/getAgentData';
import './methods/getAgentOverviewData';

@ -1,70 +0,0 @@
import { HTTP } from 'meteor/http';
import { settings } from '../../../settings/server';
const gatewayURL = 'https://omni.rocket.chat';
export default {
enable() {
const result = HTTP.call('POST', `${gatewayURL}/facebook/enable`, {
headers: {
'authorization': `Bearer ${settings.get('Livechat_Facebook_API_Key')}`,
'content-type': 'application/json',
},
data: {
url: settings.get('Site_Url'),
},
});
return result.data;
},
disable() {
const result = HTTP.call('DELETE', `${gatewayURL}/facebook/enable`, {
headers: {
'authorization': `Bearer ${settings.get('Livechat_Facebook_API_Key')}`,
'content-type': 'application/json',
},
});
return result.data;
},
listPages() {
const result = HTTP.call('GET', `${gatewayURL}/facebook/pages`, {
headers: {
authorization: `Bearer ${settings.get('Livechat_Facebook_API_Key')}`,
},
});
return result.data;
},
subscribe(pageId) {
const result = HTTP.call('POST', `${gatewayURL}/facebook/page/${pageId}/subscribe`, {
headers: {
authorization: `Bearer ${settings.get('Livechat_Facebook_API_Key')}`,
},
});
return result.data;
},
unsubscribe(pageId) {
const result = HTTP.call('DELETE', `${gatewayURL}/facebook/page/${pageId}/subscribe`, {
headers: {
authorization: `Bearer ${settings.get('Livechat_Facebook_API_Key')}`,
},
});
return result.data;
},
reply({ page, token, text }) {
return HTTP.call('POST', `${gatewayURL}/facebook/reply`, {
headers: {
authorization: `Bearer ${settings.get('Livechat_Facebook_API_Key')}`,
},
data: {
page,
token,
text,
},
});
},
};

@ -1,68 +0,0 @@
import { Meteor } from 'meteor/meteor';
import { Settings } from '@rocket.chat/models';
import { hasPermission } from '../../../authorization';
import { SystemLogger } from '../../../../server/lib/logger/system';
import { settings } from '../../../settings/server';
import OmniChannel from '../lib/OmniChannel';
Meteor.methods({
'livechat:facebook'(options) {
if (!Meteor.userId() || !hasPermission(Meteor.userId(), 'view-livechat-manager')) {
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'livechat:addAgent' });
}
try {
switch (options.action) {
case 'initialState': {
return {
enabled: settings.get('Livechat_Facebook_Enabled'),
hasToken: !!settings.get('Livechat_Facebook_API_Key'),
};
}
case 'enable': {
const result = OmniChannel.enable();
if (!result.success) {
return result;
}
return Settings.updateValueById('Livechat_Facebook_Enabled', true);
}
case 'disable': {
OmniChannel.disable();
return Settings.updateValueById('Livechat_Facebook_Enabled', false);
}
case 'list-pages': {
return OmniChannel.listPages();
}
case 'subscribe': {
return OmniChannel.subscribe(options.page);
}
case 'unsubscribe': {
return OmniChannel.unsubscribe(options.page);
}
}
} catch (err) {
if (err.response && err.response.data && err.response.data.error) {
if (err.response.data.error.error) {
throw new Meteor.Error(err.response.data.error.error, err.response.data.error.message);
}
if (err.response.data.error.response) {
throw new Meteor.Error('integration-error', err.response.data.error.response.error.message);
}
if (err.response.data.error.message) {
throw new Meteor.Error('integration-error', err.response.data.error.message);
}
}
SystemLogger.error({ msg: 'Error contacting omni.rocket.chat:', err });
throw new Meteor.Error('integration-error', err.error);
}
},
});

@ -1,80 +0,0 @@
import { Box, Button, ButtonGroup, FieldGroup, Divider } from '@rocket.chat/fuselage';
import { useTranslation } from '@rocket.chat/ui-contexts';
import type { FC, Dispatch } from 'react';
import React from 'react';
import Page from '../../../components/Page';
import PageToggleAssembler from './PageToggleAssembler';
type OnToggleProps = {
onToggle: (id: string, isSubscribed: boolean, setSubscribed: Dispatch<boolean>) => void;
};
type PageItem = {
name: string;
subscribed: boolean;
id: string;
};
type FacebookPageProps = OnToggleProps & {
enabled: boolean;
hasToken: boolean;
pages: PageItem[];
onRefresh: () => void;
onDisable: () => void;
onEnable: () => void;
};
const FacebookPage: FC<FacebookPageProps> = ({ pages, enabled, hasToken, onToggle, onRefresh, onEnable, onDisable }) => {
const t = useTranslation();
return (
<Page>
<Page.Header title={t('Facebook')} />
<Page.ScrollableContentWithShadow>
<Box maxWidth='x600' w='full' alignSelf='center'>
{!enabled && (
<>
<ButtonGroup stretch mb='x8'>
<Button primary onClick={onEnable} disabled={!hasToken}>
{t('Enable')}
</Button>
</ButtonGroup>
{!hasToken && (
<>
<p>{t('You_have_to_set_an_API_token_first_in_order_to_use_the_integration')}</p>
<p>{t('Please_go_to_the_Administration_page_then_Livechat_Facebook')}</p>
</>
)}
</>
)}
{enabled && (
<>
<Box fontScale='h2' mbe='x8'>
{t('Pages')}
</Box>
{pages?.length ? (
<FieldGroup>
<PageToggleAssembler pages={pages} onToggle={onToggle} />
</FieldGroup>
) : (
t('No_pages_yet_Try_hitting_Reload_Pages_button')
)}
<Box w='full' mb='x16'>
<Divider />
</Box>
<ButtonGroup stretch vertical>
<Button onClick={onRefresh}>{t('Reload_Pages')}</Button>
<Button secondary danger onClick={onDisable}>
{t('Disable')}
</Button>
</ButtonGroup>
</>
)}
</Box>
</Page.ScrollableContentWithShadow>
</Page>
);
};
export default FacebookPage;

@ -1,135 +0,0 @@
import { Callout } from '@rocket.chat/fuselage';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import { useToastMessageDispatch, useMethod, useTranslation } from '@rocket.chat/ui-contexts';
import { useQuery } from '@tanstack/react-query';
import type { ReactElement } from 'react';
import React from 'react';
import Page from '../../../components/Page';
import PageSkeleton from '../../../components/PageSkeleton';
import FacebookPage from './FacebookPage';
type PageItem = {
name: string;
subscribed: boolean;
id: string;
};
type PageData = {
pages: PageItem[];
};
type InitialStateData = {
enabled: boolean;
hasToken: boolean;
};
const FacebookPageContainer = (): ReactElement => {
const t = useTranslation();
const dispatchToastMessage = useToastMessageDispatch();
const livechatFacebook = useMethod('livechat:facebook');
const initialStateResult = useQuery(
['omnichannel/facebook/initial-state'],
async () => livechatFacebook({ action: 'initialState' }) as unknown as Promise<InitialStateData>,
{
initialData: { enabled: false, hasToken: false },
},
);
const listPagesResult = useQuery(
['omnichannel/facebook/list-pages'],
async () => livechatFacebook({ action: 'list-pages' }) as unknown as Promise<PageData>,
{
initialData: { pages: [] },
},
);
const { enabled, hasToken } = initialStateResult.data ?? { enabled: false, hasToken: false };
const { pages } = listPagesResult.data ?? { pages: [] };
const onToggle = useMutableCallback(async (id, isSubscribed, setSubscribed) => {
setSubscribed(!isSubscribed);
try {
const action = isSubscribed ? 'unsubscribe' : 'subscribe';
await livechatFacebook({
action,
page: id,
});
} catch (error: unknown) {
dispatchToastMessage({ type: 'error', message: error });
setSubscribed(isSubscribed);
}
});
const onDisable = useMutableCallback(async () => {
try {
await livechatFacebook({ action: 'disable' });
dispatchToastMessage({ type: 'success', message: t('Integration_disabled') });
initialStateResult.refetch();
listPagesResult.refetch();
} catch (error) {
dispatchToastMessage({ type: 'error', message: error });
}
});
const openOauthWindow = (url: string, callback: () => void): void => {
const oauthWindow = window.open(url, 'facebook-integration-oauth', 'width=600,height=400');
const checkInterval = setInterval(() => {
if (oauthWindow?.closed) {
clearInterval(checkInterval);
callback();
}
}, 300);
};
const onEnable = useMutableCallback(async () => {
try {
const result = await livechatFacebook({ action: 'enable' });
if (result && 'url' in result) {
openOauthWindow(result.url, () => {
onEnable();
});
} else {
initialStateResult.refetch();
listPagesResult.refetch();
}
} catch (error: unknown) {
dispatchToastMessage({ type: 'error', message: error });
}
});
if (initialStateResult.isLoading || listPagesResult.isLoading) {
return <PageSkeleton />;
}
if (initialStateResult.isError) {
return (
<Page>
<Page.Header title={t('Edit_Custom_Field')} />
<Page.ScrollableContentWithShadow>
<Callout type='danger'>{t('Error')}</Callout>
</Page.ScrollableContentWithShadow>
</Page>
);
}
if (enabled && hasToken && listPagesResult.isError) {
onEnable();
}
return (
<FacebookPage
pages={pages}
enabled={enabled}
hasToken={hasToken}
onToggle={onToggle}
onRefresh={listPagesResult.refetch}
onDisable={onDisable}
onEnable={onEnable}
/>
);
};
export default FacebookPageContainer;

@ -1,36 +0,0 @@
import { Box, Field, ToggleSwitch } from '@rocket.chat/fuselage';
import { useMutableCallback } from '@rocket.chat/fuselage-hooks';
import type { FC, Dispatch, ComponentProps } from 'react';
import React, { useState } from 'react';
type OnToggleProps = {
onToggle: (id: string, isSubscribed: boolean, setSubscribed: Dispatch<boolean>) => void;
};
type PageItem = {
name: string;
subscribed: boolean;
id: string;
};
type PageToggleProps = OnToggleProps &
PageItem & {
className?: ComponentProps<typeof Field>['className'];
};
const PageToggle: FC<PageToggleProps> = ({ name, id, subscribed, onToggle, className }) => {
const [isSubscribed, setIsSubscribed] = useState(subscribed);
const handleToggle = useMutableCallback(() => onToggle(id, isSubscribed, setIsSubscribed));
return (
<Field className={className}>
<Box display='flex' flexDirection='row'>
<Field.Label>{name}</Field.Label>
<Field.Row>
<ToggleSwitch checked={isSubscribed} onChange={handleToggle} />
</Field.Row>
</Box>
</Field>
);
};
export default PageToggle;

@ -1,30 +0,0 @@
import { FieldGroup } from '@rocket.chat/fuselage';
import type { FC, Dispatch, ComponentProps } from 'react';
import React from 'react';
import PageToggle from './PageToggle';
type OnToggleProps = {
onToggle: (id: string, isSubscribed: boolean, setSubscribed: Dispatch<boolean>) => void;
};
type PageItem = {
name: string;
subscribed: boolean;
id: string;
};
type PageToggleAssemblerProps = OnToggleProps & {
pages: PageItem[];
className?: ComponentProps<typeof PageToggle>['className'];
};
const PageToggleAssembler: FC<PageToggleAssemblerProps> = ({ pages, onToggle, className }) => (
<FieldGroup>
{pages.map((page) => (
<PageToggle key={page.id} {...page} onToggle={onToggle} className={className} />
))}
</FieldGroup>
);
export default PageToggleAssembler;

@ -63,11 +63,6 @@ registerOmnichannelRoute('/triggers/:context?/:id?', {
component: lazy(() => import('./triggers/TriggersPage')),
});
registerOmnichannelRoute('/facebook', {
name: 'omnichannel-facebook',
component: lazy(() => import('./facebook/FacebookPageContainer')),
});
registerOmnichannelRoute('/current/:id?/:tab?/:context?', {
name: 'omnichannel-current-chats',
component: lazy(() => import('./currentChats/CurrentChatsRoute')),

@ -62,11 +62,6 @@ export const {
i18nLabel: 'Webhooks',
permissionGranted: (): boolean => hasPermission('view-livechat-webhooks'),
},
{
href: 'omnichannel-facebook',
i18nLabel: 'Facebook Messenger',
permissionGranted: (): boolean => hasPermission('view-livechat-facebook'),
},
{
href: 'omnichannel-businessHours',
i18nLabel: 'Business_Hours',

@ -7,21 +7,6 @@ declare module '@rocket.chat/ui-contexts' {
'livechat:addMonitor': (...args: any[]) => any;
'livechat:closeRoom': (...args: any[]) => any;
'livechat:discardTranscript': (...args: any[]) => any;
// TODO: chapter day backend - enhance/deprecate
'livechat:facebook':
| ((...args: [{ action: 'initialState' }]) => {
enabled: boolean;
hasToken: boolean;
})
| ((...args: [{ action: 'list-pages' }]) => {
name: string;
subscribed: boolean;
id: string;
}[])
| ((...args: [{ action: 'subscribe' | 'unsubscribe'; page: string }]) => void)
| ((...args: [{ action: 'enable' }]) => { url: string } | undefined)
| ((...args: [{ action: 'disable' }]) => void);
'livechat:getAgentOverviewData': (...args: any[]) => any;
'livechat:getAnalyticsChartData': (...args: any[]) => any;
'livechat:getAnalyticsOverviewData': (...args: any[]) => any;

@ -2392,7 +2392,6 @@
"If_you_are_sure_type_in_your_username": "If you are sure type in your username:",
"If_you_didnt_ask_for_reset_ignore_this_email": "If you didn't ask for your password reset, you can ignore this email.",
"If_you_didnt_try_to_login_in_your_account_please_ignore_this_email": "If you didn't try to login in your account please ignore this email.",
"If_you_dont_have_one_send_an_email_to_omni_rocketchat_to_get_yours": "If you don't have one send an email to [omni@rocket.chat](mailto:omni@rocket.chat) 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.",
@ -2921,9 +2920,6 @@
"Livechat_DepartmentOfflineMessageToChannel": "Send this department's Livechat offline messages to a channel",
"Livechat_enable_message_character_limit": "Enable message character limit",
"Livechat_enabled": "Omnichannel enabled",
"Livechat_Facebook_API_Key": "OmniChannel API Key",
"Livechat_Facebook_API_Secret": "OmniChannel API Secret",
"Livechat_Facebook_Enabled": "Facebook integration enabled",
"Livechat_forward_open_chats": "Forward open chats",
"Livechat_forward_open_chats_timeout": "Timeout (in seconds) to forward chats",
"Livechat_guest_count": "Guest Counter",
@ -3758,7 +3754,6 @@
"Please_fill_all_the_information": "Please fill all the information",
"Please_fill_an_email": "Please fill an email",
"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 Omnichannel > Facebook",
"Please_select_an_user": "Please select an user",
"Please_select_enabled_yes_or_no": "Please select an option for Enabled",
"Please_select_visibility": "Please select a visibility",
@ -5215,8 +5210,6 @@
"view-livechat-customfields_description": "Permission to view Omnichannel custom fields",
"view-livechat-departments": "View Omnichannel Departments",
"view-livechat-departments_description": "Permission to view Omnichannel departments",
"view-livechat-facebook": "View Omnichannel Facebook",
"view-livechat-facebook_description": "Permission to view Omnichannel Facebook",
"view-livechat-installation": "View Omnichannel Installation",
"view-livechat-installation_description": "Permission to view Omnichannel installation",
"view-livechat-manager": "View Omnichannel Manager",
@ -5409,7 +5402,6 @@
"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",

@ -78,7 +78,6 @@ export const roomFields = {
// @TODO create an API to register this fields based on room type
tags: 1,
sms: 1,
facebook: 1,
code: 1,
joinCodeRequired: 1,
open: 1,

@ -41,4 +41,5 @@ import './v279';
import './v280';
import './v281';
import './v282';
import './v283';
import './xrun';

@ -0,0 +1,49 @@
import { Settings, Permissions, LivechatRooms, LivechatInquiry, Subscriptions } from '@rocket.chat/models';
import { addMigration } from '../../lib/migrations';
addMigration({
version: 283,
async up() {
// Removing all settings & permissions related to Legacy FB Messenger integration
await Promise.all([
Settings.deleteMany({
_id: {
$in: ['Livechat_Facebook_Enabled', 'Livechat_Facebook_API_Key', 'Livechat_Facebook_API_Secret'],
},
}),
Permissions.removeById('view-livechat-facebook'),
]);
// close all open Fb Messenger rooms since the integration is no longer available
const openRoomsIds = (
await LivechatRooms.find(
{
open: true,
facebook: { $exists: true },
},
{ projection: { _id: 1 } },
).toArray()
).map((room) => room._id);
await Promise.all([
LivechatRooms.updateMany(
{
_id: {
$in: openRoomsIds,
},
},
{
$unset: {
open: 1,
},
},
),
LivechatInquiry.deleteMany({
rid: {
$in: openRoomsIds,
},
}),
...openRoomsIds.map((room) => Subscriptions.removeByRoomId(room)),
]);
},
});

@ -2497,53 +2497,6 @@ const GETLivechatQueueParamsSchema = {
export const isGETLivechatQueueParams = ajv.compile<GETLivechatQueueParams>(GETLivechatQueueParamsSchema);
type POSTLivechatFacebookParams = {
text?: string;
attachments?: unknown[];
mid: string;
page: string;
token: string;
first_name: string;
last_name: string;
};
const POSTLivechatFacebookParamsSchema = {
type: 'object',
properties: {
text: {
type: 'string',
nullable: true,
},
attachments: {
type: 'array',
items: {
type: 'object',
},
nullable: true,
},
mid: {
type: 'string',
},
page: {
type: 'string',
},
token: {
type: 'string',
},
first_name: {
type: 'string',
},
last_name: {
type: 'string',
},
},
// Facebook may send additional props
additionalProperties: true,
required: ['mid', 'page', 'token', 'first_name', 'last_name'],
};
export const isPOSTLivechatFacebookParams = ajv.compile<POSTLivechatFacebookParams>(POSTLivechatFacebookParamsSchema);
type GETLivechatInquiriesListParams = PaginatedRequest<{ department?: string }>;
const GETLivechatInquiriesListParamsSchema = {
@ -3062,9 +3015,6 @@ export type OmnichannelEndpoints = {
'/v1/livechat/upload/:rid': {
POST: () => IMessage & { newRoom: boolean; showConnecting: boolean };
};
'/v1/livechat/facebook': {
POST: (params: POSTLivechatFacebookParams) => { message: IMessage };
};
'/v1/livechat/inquiries.list': {
GET: (params: GETLivechatInquiriesListParams) => PaginatedResult<{ inquiries: ILivechatInquiryRecord[] }>;
};

Loading…
Cancel
Save