diff --git a/apps/meteor/app/authorization/server/functions/upsertPermissions.ts b/apps/meteor/app/authorization/server/functions/upsertPermissions.ts index 48ee4745742..90c3bb7b4a7 100644 --- a/apps/meteor/app/authorization/server/functions/upsertPermissions.ts +++ b/apps/meteor/app/authorization/server/functions/upsertPermissions.ts @@ -152,7 +152,6 @@ export const upsertPermissions = async (): Promise => { { _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'], diff --git a/apps/meteor/app/livechat/imports/server/rest/facebook.ts b/apps/meteor/app/livechat/imports/server/rest/facebook.ts deleted file mode 100644 index 2e03507fa37..00000000000 --- a/apps/meteor/app/livechat/imports/server/rest/facebook.ts +++ /dev/null @@ -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('Livechat_Facebook_Enabled')) { - return API.v1.failure('Facebook integration is disabled'); - } - - // validate if request come from omni - const signature = crypto - .createHmac('sha1', settings.get('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); - } - }, - }, -); diff --git a/apps/meteor/app/livechat/server/api.ts b/apps/meteor/app/livechat/server/api.ts index eaf38ff18eb..865b4308b94 100644 --- a/apps/meteor/app/livechat/server/api.ts +++ b/apps/meteor/app/livechat/server/api.ts @@ -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'; diff --git a/apps/meteor/app/livechat/server/config.ts b/apps/meteor/app/livechat/server/config.ts index 6fedc78bb64..a815b0e2106 100644 --- a/apps/meteor/app/livechat/server/config.ts +++ b/apps/meteor/app/livechat/server/config.ts @@ -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', diff --git a/apps/meteor/app/livechat/server/hooks/sendToFacebook.js b/apps/meteor/app/livechat/server/hooks/sendToFacebook.js deleted file mode 100644 index 2b77c18e5b5..00000000000 --- a/apps/meteor/app/livechat/server/hooks/sendToFacebook.js +++ /dev/null @@ -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', -); diff --git a/apps/meteor/app/livechat/server/index.js b/apps/meteor/app/livechat/server/index.js index b8d507f7494..c64dd5b181f 100644 --- a/apps/meteor/app/livechat/server/index.js +++ b/apps/meteor/app/livechat/server/index.js @@ -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'; diff --git a/apps/meteor/app/livechat/server/lib/OmniChannel.js b/apps/meteor/app/livechat/server/lib/OmniChannel.js deleted file mode 100644 index 0a465111489..00000000000 --- a/apps/meteor/app/livechat/server/lib/OmniChannel.js +++ /dev/null @@ -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, - }, - }); - }, -}; diff --git a/apps/meteor/app/livechat/server/methods/facebook.js b/apps/meteor/app/livechat/server/methods/facebook.js deleted file mode 100644 index 66131e4c5c7..00000000000 --- a/apps/meteor/app/livechat/server/methods/facebook.js +++ /dev/null @@ -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); - } - }, -}); diff --git a/apps/meteor/client/views/omnichannel/facebook/FacebookPage.tsx b/apps/meteor/client/views/omnichannel/facebook/FacebookPage.tsx deleted file mode 100644 index 04d00a90dc8..00000000000 --- a/apps/meteor/client/views/omnichannel/facebook/FacebookPage.tsx +++ /dev/null @@ -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) => 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 = ({ pages, enabled, hasToken, onToggle, onRefresh, onEnable, onDisable }) => { - const t = useTranslation(); - - return ( - - - - - {!enabled && ( - <> - - - - {!hasToken && ( - <> -

{t('You_have_to_set_an_API_token_first_in_order_to_use_the_integration')}

-

{t('Please_go_to_the_Administration_page_then_Livechat_Facebook')}

- - )} - - )} - {enabled && ( - <> - - {t('Pages')} - - {pages?.length ? ( - - - - ) : ( - t('No_pages_yet_Try_hitting_Reload_Pages_button') - )} - - - - - - - - - )} -
-
-
- ); -}; - -export default FacebookPage; diff --git a/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx b/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx deleted file mode 100644 index 16241f40f0b..00000000000 --- a/apps/meteor/client/views/omnichannel/facebook/FacebookPageContainer.tsx +++ /dev/null @@ -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, - { - initialData: { enabled: false, hasToken: false }, - }, - ); - - const listPagesResult = useQuery( - ['omnichannel/facebook/list-pages'], - async () => livechatFacebook({ action: 'list-pages' }) as unknown as Promise, - { - 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 ; - } - - if (initialStateResult.isError) { - return ( - - - - {t('Error')} - - - ); - } - - if (enabled && hasToken && listPagesResult.isError) { - onEnable(); - } - - return ( - - ); -}; - -export default FacebookPageContainer; diff --git a/apps/meteor/client/views/omnichannel/facebook/PageToggle.tsx b/apps/meteor/client/views/omnichannel/facebook/PageToggle.tsx deleted file mode 100644 index e924cb5f60e..00000000000 --- a/apps/meteor/client/views/omnichannel/facebook/PageToggle.tsx +++ /dev/null @@ -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) => void; -}; - -type PageItem = { - name: string; - subscribed: boolean; - id: string; -}; - -type PageToggleProps = OnToggleProps & - PageItem & { - className?: ComponentProps['className']; - }; - -const PageToggle: FC = ({ name, id, subscribed, onToggle, className }) => { - const [isSubscribed, setIsSubscribed] = useState(subscribed); - const handleToggle = useMutableCallback(() => onToggle(id, isSubscribed, setIsSubscribed)); - return ( - - - {name} - - - - - - ); -}; - -export default PageToggle; diff --git a/apps/meteor/client/views/omnichannel/facebook/PageToggleAssembler.tsx b/apps/meteor/client/views/omnichannel/facebook/PageToggleAssembler.tsx deleted file mode 100644 index f79ba6950ba..00000000000 --- a/apps/meteor/client/views/omnichannel/facebook/PageToggleAssembler.tsx +++ /dev/null @@ -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) => void; -}; - -type PageItem = { - name: string; - subscribed: boolean; - id: string; -}; - -type PageToggleAssemblerProps = OnToggleProps & { - pages: PageItem[]; - className?: ComponentProps['className']; -}; - -const PageToggleAssembler: FC = ({ pages, onToggle, className }) => ( - - {pages.map((page) => ( - - ))} - -); - -export default PageToggleAssembler; diff --git a/apps/meteor/client/views/omnichannel/routes.ts b/apps/meteor/client/views/omnichannel/routes.ts index 0ff9756b311..c189a4e95c3 100644 --- a/apps/meteor/client/views/omnichannel/routes.ts +++ b/apps/meteor/client/views/omnichannel/routes.ts @@ -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')), diff --git a/apps/meteor/client/views/omnichannel/sidebarItems.ts b/apps/meteor/client/views/omnichannel/sidebarItems.ts index 2cda8c2c9e3..450680c05d1 100644 --- a/apps/meteor/client/views/omnichannel/sidebarItems.ts +++ b/apps/meteor/client/views/omnichannel/sidebarItems.ts @@ -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', diff --git a/apps/meteor/definition/methods/omnichannel.ts b/apps/meteor/definition/methods/omnichannel.ts index 3a2f1a30c22..fb354098155 100644 --- a/apps/meteor/definition/methods/omnichannel.ts +++ b/apps/meteor/definition/methods/omnichannel.ts @@ -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; diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index c50af61a9d2..baf23096e17 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -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", diff --git a/apps/meteor/server/modules/watchers/publishFields.ts b/apps/meteor/server/modules/watchers/publishFields.ts index 42bca8ea05b..668ecdf7925 100644 --- a/apps/meteor/server/modules/watchers/publishFields.ts +++ b/apps/meteor/server/modules/watchers/publishFields.ts @@ -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, diff --git a/apps/meteor/server/startup/migrations/index.ts b/apps/meteor/server/startup/migrations/index.ts index 958502f8166..377fcb8e446 100644 --- a/apps/meteor/server/startup/migrations/index.ts +++ b/apps/meteor/server/startup/migrations/index.ts @@ -41,4 +41,5 @@ import './v279'; import './v280'; import './v281'; import './v282'; +import './v283'; import './xrun'; diff --git a/apps/meteor/server/startup/migrations/v283.ts b/apps/meteor/server/startup/migrations/v283.ts new file mode 100644 index 00000000000..8771b152a0c --- /dev/null +++ b/apps/meteor/server/startup/migrations/v283.ts @@ -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)), + ]); + }, +}); diff --git a/packages/rest-typings/src/v1/omnichannel.ts b/packages/rest-typings/src/v1/omnichannel.ts index c1fa4a1f2ae..a8e8d92cf44 100644 --- a/packages/rest-typings/src/v1/omnichannel.ts +++ b/packages/rest-typings/src/v1/omnichannel.ts @@ -2497,53 +2497,6 @@ const GETLivechatQueueParamsSchema = { export const isGETLivechatQueueParams = ajv.compile(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(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[] }>; };