diff --git a/.changeset/nice-balloons-relax.md b/.changeset/nice-balloons-relax.md new file mode 100644 index 0000000000000..951859657182c --- /dev/null +++ b/.changeset/nice-balloons-relax.md @@ -0,0 +1,6 @@ +--- +"@rocket.chat/meteor": patch +"@rocket.chat/rest-typings": patch +--- + +Adds deprecation warning on `livechat:removeRoom`, use `livechat/inquiries.take` instead diff --git a/apps/meteor/app/livechat/imports/server/rest/inquiries.ts b/apps/meteor/app/livechat/imports/server/rest/inquiries.ts index 2432e55054f52..13ecab3df9037 100644 --- a/apps/meteor/app/livechat/imports/server/rest/inquiries.ts +++ b/apps/meteor/app/livechat/imports/server/rest/inquiries.ts @@ -10,7 +10,7 @@ import { import { API } from '../../../../api/server'; import { getPaginationItems } from '../../../../api/server/helpers/getPaginationItems'; import { findInquiries, findOneInquiryByRoomId } from '../../../server/api/lib/inquiries'; -import { takeInquiry } from '../../../server/methods/takeInquiry'; +import { takeInquiry } from '../../../server/lib/takeInquiry'; API.v1.addRoute( 'livechat/inquiries.list', diff --git a/apps/meteor/app/livechat/server/lib/takeInquiry.ts b/apps/meteor/app/livechat/server/lib/takeInquiry.ts new file mode 100644 index 0000000000000..c046768ea92c0 --- /dev/null +++ b/apps/meteor/app/livechat/server/lib/takeInquiry.ts @@ -0,0 +1,59 @@ +import { Omnichannel } from '@rocket.chat/core-services'; +import { LivechatInquiry, LivechatRooms, Users } from '@rocket.chat/models'; +import { Meteor } from 'meteor/meteor'; + +import { RoutingManager } from './RoutingManager'; +import { isAgentAvailableToTakeContactInquiry } from './contacts/isAgentAvailableToTakeContactInquiry'; +import { migrateVisitorIfMissingContact } from './contacts/migrateVisitorIfMissingContact'; +import { settings } from '../../../settings/server'; + +export const takeInquiry = async ( + userId: string, + inquiryId: string, + options?: { clientAction: boolean; forwardingToDepartment?: { oldDepartmentId: string; transferData: any } }, +): Promise => { + const inquiry = await LivechatInquiry.findOneById(inquiryId); + + if (!inquiry) { + throw new Meteor.Error('error-not-found', 'Inquiry not found', { + method: 'livechat:takeInquiry', + }); + } + + if (inquiry.status === 'taken') { + throw new Meteor.Error('error-inquiry-taken', 'Inquiry already taken', { + method: 'livechat:takeInquiry', + }); + } + + const user = await Users.findOneOnlineAgentById(userId, settings.get('Livechat_enabled_when_agent_idle')); + if (!user) { + throw new Meteor.Error('error-agent-status-service-offline', 'Agent status is offline or Omnichannel service is not active', { + method: 'livechat:takeInquiry', + }); + } + + const room = await LivechatRooms.findOneById(inquiry.rid); + if (!room || !(await Omnichannel.isWithinMACLimit(room))) { + throw new Meteor.Error('error-mac-limit-reached'); + } + + const contactId = room.contactId ?? (await migrateVisitorIfMissingContact(room.v._id, room.source)); + if (contactId) { + const isAgentAvailableToTakeContactInquiryResult = await isAgentAvailableToTakeContactInquiry(inquiry.v._id, room.source, contactId); + if (!isAgentAvailableToTakeContactInquiryResult.value) { + throw new Meteor.Error(isAgentAvailableToTakeContactInquiryResult.error); + } + } + + const agent = { + agentId: user._id, + username: user.username, + }; + + try { + await RoutingManager.takeInquiry(inquiry, agent, options ?? {}, room); + } catch (e: any) { + throw new Meteor.Error(e.message); + } +}; diff --git a/apps/meteor/app/livechat/server/methods/takeInquiry.ts b/apps/meteor/app/livechat/server/methods/takeInquiry.ts index 19a08761c6145..52336e91d08e3 100644 --- a/apps/meteor/app/livechat/server/methods/takeInquiry.ts +++ b/apps/meteor/app/livechat/server/methods/takeInquiry.ts @@ -1,13 +1,9 @@ -import { Omnichannel } from '@rocket.chat/core-services'; import type { ServerMethods } from '@rocket.chat/ddp-client'; -import { LivechatInquiry, LivechatRooms, Users } from '@rocket.chat/models'; import { Meteor } from 'meteor/meteor'; import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission'; -import { settings } from '../../../settings/server'; -import { RoutingManager } from '../lib/RoutingManager'; -import { isAgentAvailableToTakeContactInquiry } from '../lib/contacts/isAgentAvailableToTakeContactInquiry'; -import { migrateVisitorIfMissingContact } from '../lib/contacts/migrateVisitorIfMissingContact'; +import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger'; +import { takeInquiry } from '../lib/takeInquiry'; declare module '@rocket.chat/ddp-client' { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -19,65 +15,9 @@ declare module '@rocket.chat/ddp-client' { } } -export const takeInquiry = async ( - userId: string, - inquiryId: string, - options?: { clientAction: boolean; forwardingToDepartment?: { oldDepartmentId: string; transferData: any } }, -): Promise => { - if (!userId || !(await hasPermissionAsync(userId, 'view-l-room'))) { - throw new Meteor.Error('error-not-allowed', 'Not allowed', { - method: 'livechat:takeInquiry', - }); - } - - const inquiry = await LivechatInquiry.findOneById(inquiryId); - - if (!inquiry) { - throw new Meteor.Error('error-not-found', 'Inquiry not found', { - method: 'livechat:takeInquiry', - }); - } - - if (inquiry.status === 'taken') { - throw new Meteor.Error('error-inquiry-taken', 'Inquiry already taken', { - method: 'livechat:takeInquiry', - }); - } - - const user = await Users.findOneOnlineAgentById(userId, settings.get('Livechat_enabled_when_agent_idle')); - if (!user) { - throw new Meteor.Error('error-agent-status-service-offline', 'Agent status is offline or Omnichannel service is not active', { - method: 'livechat:takeInquiry', - }); - } - - const room = await LivechatRooms.findOneById(inquiry.rid); - if (!room || !(await Omnichannel.isWithinMACLimit(room))) { - throw new Meteor.Error('error-mac-limit-reached'); - } - - const contactId = room.contactId ?? (await migrateVisitorIfMissingContact(room.v._id, room.source)); - if (contactId) { - const isAgentAvailableToTakeContactInquiryResult = await isAgentAvailableToTakeContactInquiry(inquiry.v._id, room.source, contactId); - if (!isAgentAvailableToTakeContactInquiryResult.value) { - throw new Meteor.Error(isAgentAvailableToTakeContactInquiryResult.error); - } - } - - const agent = { - agentId: user._id, - username: user.username, - }; - - try { - await RoutingManager.takeInquiry(inquiry, agent, options ?? {}, room); - } catch (e: any) { - throw new Meteor.Error(e.message); - } -}; - Meteor.methods({ async 'livechat:takeInquiry'(inquiryId, options) { + methodDeprecationLogger.method('livechat:takeInquiry', '8.0.0', '/v1/livechat/inquiries.take'); const uid = Meteor.userId(); if (!uid) { throw new Meteor.Error('error-not-allowed', 'Invalid User', { @@ -85,6 +25,12 @@ Meteor.methods({ }); } + if (!(await hasPermissionAsync(uid, 'view-l-room'))) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { + method: 'livechat:takeInquiry', + }); + } + return takeInquiry(uid, inquiryId, options); }, }); diff --git a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelInquiry.tsx b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelInquiry.tsx index 785f274183abb..2d79085971ec3 100644 --- a/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelInquiry.tsx +++ b/apps/meteor/client/views/room/composer/ComposerOmnichannel/ComposerOmnichannelInquiry.tsx @@ -1,5 +1,5 @@ import { MessageFooterCallout, MessageFooterCalloutAction, MessageFooterCalloutContent } from '@rocket.chat/ui-composer'; -import { useEndpoint, useMethod, useToastMessageDispatch, useTranslation, useUser } from '@rocket.chat/ui-contexts'; +import { useEndpoint, useToastMessageDispatch, useTranslation, useUser } from '@rocket.chat/ui-contexts'; import { useQuery } from '@tanstack/react-query'; import type { ReactElement } from 'react'; import { useMemo } from 'react'; @@ -23,7 +23,7 @@ export const ComposerOmnichannelInquiry = (): ReactElement => { }), }); - const takeInquiry = useMethod('livechat:takeInquiry'); + const takeInquiry = useEndpoint('POST', '/v1/livechat/inquiries.take'); const handleTakeInquiry = async (): Promise => { if (!result.isSuccess) { @@ -33,7 +33,7 @@ export const ComposerOmnichannelInquiry = (): ReactElement => { return; } try { - await takeInquiry(result.data.inquiry._id, { clientAction: true }); + await takeInquiry({ inquiryId: result.data.inquiry._id, options: { clientAction: true } }); } catch (error) { dispatchToastMessage({ type: 'error', message: error }); } diff --git a/packages/rest-typings/src/v1/omnichannel.ts b/packages/rest-typings/src/v1/omnichannel.ts index 149d72b754ef1..26e3cb146e775 100644 --- a/packages/rest-typings/src/v1/omnichannel.ts +++ b/packages/rest-typings/src/v1/omnichannel.ts @@ -3366,6 +3366,13 @@ export const isGETLivechatInquiriesListParams = ajv.compile