diff --git a/.changeset/migrate-chat-postMessage-to-AJV.md b/.changeset/migrate-chat-postMessage-to-AJV.md new file mode 100644 index 0000000000000..410c3a60ae5cb --- /dev/null +++ b/.changeset/migrate-chat-postMessage-to-AJV.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/rest-typings': minor +'@rocket.chat/meteor': minor +--- + +Migrate chat.postMessage endpoint to make it openAPI and AJV compatible diff --git a/apps/meteor/app/api/server/v1/chat.ts b/apps/meteor/app/api/server/v1/chat.ts index a00d57e46ae72..e6ea40a474913 100644 --- a/apps/meteor/app/api/server/v1/chat.ts +++ b/apps/meteor/app/api/server/v1/chat.ts @@ -1,5 +1,5 @@ import { Message } from '@rocket.chat/core-services'; -import type { IMessage, IThreadMainMessage } from '@rocket.chat/core-typings'; +import type { IMessage, MessageAttachment, IThreadMainMessage } from '@rocket.chat/core-typings'; import { MessageTypes } from '@rocket.chat/message-types'; import { Messages, Users, Rooms, Subscriptions } from '@rocket.chat/models'; import { @@ -11,7 +11,6 @@ import { isChatDeleteProps, isChatSyncMessagesProps, isChatGetMessageProps, - isChatPostMessageProps, isChatSearchProps, isChatSendMessageProps, isChatIgnoreUserProps, @@ -119,6 +118,132 @@ const ChatUnfollowMessageLocalSchema = { additionalProperties: false, }; +//chat.postMessage starts +type ChatPostMessage = + | { + roomId: string | string[]; + text?: string; + alias?: string; + emoji?: string; + avatar?: string; + attachments?: MessageAttachment[]; + customFields?: IMessage['customFields']; + } + | { + channel: string | string[]; + text?: string; + alias?: string; + emoji?: string; + avatar?: string; + attachments?: MessageAttachment[]; + customFields?: IMessage['customFields']; + }; + +const ChatPostMessageSchema = { + oneOf: [ + { + type: 'object', + properties: { + roomId: { + oneOf: [ + { type: 'string' }, + { + type: 'array', + items: { + type: 'string', + }, + }, + ], + }, + text: { + type: 'string', + nullable: true, + }, + alias: { + type: 'string', + nullable: true, + }, + emoji: { + type: 'string', + nullable: true, + }, + avatar: { + type: 'string', + nullable: true, + }, + attachments: { + type: 'array', + items: { + type: 'object', + }, + nullable: true, + }, + tmid: { + type: 'string', + }, + customFields: { + type: 'object', + nullable: true, + }, + parseUrls: { + type: 'boolean', + }, + }, + required: ['roomId'], + additionalProperties: false, + }, + { + type: 'object', + properties: { + channel: { + oneOf: [ + { type: 'string' }, + { + type: 'array', + items: { + type: 'string', + }, + }, + ], + }, + text: { + type: 'string', + nullable: true, + }, + alias: { + type: 'string', + nullable: true, + }, + emoji: { + type: 'string', + nullable: true, + }, + avatar: { + type: 'string', + nullable: true, + }, + attachments: { + type: 'array', + items: { + type: 'object', + }, + nullable: true, + }, + customFields: { + type: 'object', + nullable: true, + }, + parseUrls: { + type: 'boolean', + }, + }, + required: ['channel'], + additionalProperties: false, + }, + ], +}; +//chat.postMessage ends + const isChatStarMessageLocalProps = ajv.compile(ChatStarMessageLocalSchema); const isChatUnstarMessageLocalProps = ajv.compile(ChatUnstarMessageLocalSchema); @@ -127,6 +252,8 @@ const isChatFollowMessageLocalProps = ajv.compile(ChatFo const isChatUnfollowMessageLocalProps = ajv.compile(ChatUnfollowMessageLocalSchema); +const isChatPostMessageLocalProps = ajv.compile(ChatPostMessageSchema); + API.v1.addRoute( 'chat.delete', { authRequired: true, validateParams: isChatDeleteProps }, @@ -558,13 +685,29 @@ const chatEndpoints = API.v1 return API.v1.success(); }, - ); - -API.v1.addRoute( - 'chat.postMessage', - { authRequired: true, validateParams: isChatPostMessageProps }, - { - async post() { + ) + .post( + 'chat.postMessage', + { + authRequired: true, + body: isChatPostMessageLocalProps, + response: { + 400: validateBadRequestErrorResponse, + 401: validateUnauthorizedErrorResponse, + 200: ajv.compile({ + type: 'object', + properties: { + ts: { type: 'number' }, + channel: { type: 'string' }, + message: { $ref: '#/components/schemas/IMessage' }, + success: { type: 'boolean', enum: [true] }, + }, + required: ['ts', 'channel', 'message', 'success'], + additionalProperties: false, + }), + }, + }, + async function action() { const { text, attachments } = this.bodyParams; const maxAllowedSize = settings.get('Message_MaxAllowedSize') ?? 0; @@ -594,8 +737,7 @@ API.v1.addRoute( message, }); }, - }, -); + ); API.v1.addRoute( 'chat.search', diff --git a/packages/rest-typings/src/v1/chat.ts b/packages/rest-typings/src/v1/chat.ts index b52bba2d61ed5..ae048eda49577 100644 --- a/packages/rest-typings/src/v1/chat.ts +++ b/packages/rest-typings/src/v1/chat.ts @@ -739,132 +739,6 @@ const ChatGetDeletedMessagesSchema = { export const isChatGetDeletedMessagesProps = ajv.compile(ChatGetDeletedMessagesSchema); -type ChatPostMessage = - | { - roomId: string | string[]; - text?: string; - alias?: string; - emoji?: string; - avatar?: string; - attachments?: MessageAttachment[]; - customFields?: IMessage['customFields']; - } - | { - channel: string | string[]; - text?: string; - alias?: string; - emoji?: string; - avatar?: string; - attachments?: MessageAttachment[]; - customFields?: IMessage['customFields']; - }; - -const ChatPostMessageSchema = { - oneOf: [ - { - type: 'object', - properties: { - roomId: { - oneOf: [ - { type: 'string' }, - { - type: 'array', - items: { - type: 'string', - }, - }, - ], - }, - text: { - type: 'string', - nullable: true, - }, - alias: { - type: 'string', - nullable: true, - }, - emoji: { - type: 'string', - nullable: true, - }, - avatar: { - type: 'string', - nullable: true, - }, - attachments: { - type: 'array', - items: { - type: 'object', - }, - nullable: true, - }, - tmid: { - type: 'string', - }, - customFields: { - type: 'object', - nullable: true, - }, - parseUrls: { - type: 'boolean', - }, - }, - required: ['roomId'], - additionalProperties: false, - }, - { - type: 'object', - properties: { - channel: { - oneOf: [ - { type: 'string' }, - { - type: 'array', - items: { - type: 'string', - }, - }, - ], - }, - text: { - type: 'string', - nullable: true, - }, - alias: { - type: 'string', - nullable: true, - }, - emoji: { - type: 'string', - nullable: true, - }, - avatar: { - type: 'string', - nullable: true, - }, - attachments: { - type: 'array', - items: { - type: 'object', - }, - nullable: true, - }, - customFields: { - type: 'object', - nullable: true, - }, - parseUrls: { - type: 'boolean', - }, - }, - required: ['channel'], - additionalProperties: false, - }, - ], -}; - -export const isChatPostMessageProps = ajv.compile(ChatPostMessageSchema); - type ChatGetURLPreview = { roomId: IRoom['_id']; url: string; @@ -982,13 +856,6 @@ export type ChatEndpoints = { }; }; }; - '/v1/chat.postMessage': { - POST: (params: ChatPostMessage) => { - ts: number; - channel: IRoom; - message: IMessage; - }; - }; '/v1/chat.syncThreadMessages': { GET: (params: ChatSyncThreadMessages) => { messages: {