From 0a394e16ca4d4bf5b3c672e0b2fc30dadc65e19a Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Mon, 21 Apr 2025 14:46:51 +0530 Subject: [PATCH] chore: Audit message characters across all channels (#11343) - Audited message characters across all channels. - Replaced `isAInstagramChannel` with `isAnInstagramChannel` --- .../components-next/message/MessageMeta.vue | 6 ++--- .../widgets/WootWriter/ReplyBottomPanel.vue | 2 +- .../widgets/conversation/MessagesView.vue | 4 +-- .../widgets/conversation/ReplyBox.vue | 26 ++++++++++++++----- .../dashboard/composables/useInbox.js | 4 +-- .../dashboard/settings/inbox/Settings.vue | 2 +- .../shared/helpers/MessageTypeHelper.js | 14 +++++++++- app/javascript/shared/mixins/inboxMixin.js | 2 +- 8 files changed, 42 insertions(+), 18 deletions(-) diff --git a/app/javascript/dashboard/components-next/message/MessageMeta.vue b/app/javascript/dashboard/components-next/message/MessageMeta.vue index 8d7c22dab..e0602cb89 100644 --- a/app/javascript/dashboard/components-next/message/MessageMeta.vue +++ b/app/javascript/dashboard/components-next/message/MessageMeta.vue @@ -19,7 +19,7 @@ const { isAWebWidgetInbox, isAWhatsAppChannel, isAnEmailChannel, - isAInstagramChannel, + isAnInstagramChannel, } = useInbox(); const { @@ -60,7 +60,7 @@ const isSent = computed(() => { isAFacebookInbox.value || isASmsInbox.value || isATelegramChannel.value || - isAInstagramChannel.value + isAnInstagramChannel.value ) { return sourceId.value && status.value === MESSAGE_STATUS.SENT; } @@ -100,7 +100,7 @@ const isRead = computed(() => { isAWhatsAppChannel.value || isATwilioChannel.value || isAFacebookInbox.value || - isAInstagramChannel.value + isAnInstagramChannel.value ) { return sourceId.value && status.value === MESSAGE_STATUS.READ; } diff --git a/app/javascript/dashboard/components/widgets/WootWriter/ReplyBottomPanel.vue b/app/javascript/dashboard/components/widgets/WootWriter/ReplyBottomPanel.vue index cf59532e0..47fe01e9c 100644 --- a/app/javascript/dashboard/components/widgets/WootWriter/ReplyBottomPanel.vue +++ b/app/javascript/dashboard/components/widgets/WootWriter/ReplyBottomPanel.vue @@ -202,7 +202,7 @@ export default { if (this.isALineChannel) { return ALLOWED_FILE_TYPES_FOR_LINE; } - if (this.isAInstagramChannel || this.isInstagramDM) { + if (this.isAnInstagramChannel || this.isInstagramDM) { return ALLOWED_FILE_TYPES_FOR_INSTAGRAM; } diff --git a/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue b/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue index 77f411708..8d0c77f1b 100644 --- a/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue +++ b/app/javascript/dashboard/components/widgets/conversation/MessagesView.vue @@ -249,7 +249,7 @@ export default { return this.$t('CONVERSATION.CANNOT_REPLY'); }, replyWindowLink() { - if (this.isAFacebookInbox || this.isAInstagramChannel) { + if (this.isAFacebookInbox || this.isAnInstagramChannel) { return REPLY_POLICY.FACEBOOK; } if (this.isAWhatsAppCloudChannel) { @@ -264,7 +264,7 @@ export default { if ( this.isAWhatsAppChannel || this.isAFacebookInbox || - this.isAInstagramChannel + this.isAnInstagramChannel ) { return this.$t('CONVERSATION.24_HOURS_WINDOW'); } diff --git a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue index e70c7e1a4..4fa83e029 100644 --- a/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue +++ b/app/javascript/dashboard/components/widgets/conversation/ReplyBox.vue @@ -241,15 +241,27 @@ export default { if (this.isAFacebookInbox) { return MESSAGE_MAX_LENGTH.FACEBOOK; } - if (this.isAWhatsAppChannel) { + if (this.isAnInstagramChannel) { + return MESSAGE_MAX_LENGTH.INSTAGRAM; + } + if (this.isATwilioWhatsAppChannel) { return MESSAGE_MAX_LENGTH.TWILIO_WHATSAPP; } + if (this.isAWhatsAppCloudChannel) { + return MESSAGE_MAX_LENGTH.WHATSAPP_CLOUD; + } if (this.isASmsInbox) { return MESSAGE_MAX_LENGTH.TWILIO_SMS; } if (this.isAnEmailChannel) { return MESSAGE_MAX_LENGTH.EMAIL; } + if (this.isATwilioSMSChannel) { + return MESSAGE_MAX_LENGTH.TWILIO_SMS; + } + if (this.isAWhatsAppChannel) { + return MESSAGE_MAX_LENGTH.WHATSAPP_CLOUD; + } return MESSAGE_MAX_LENGTH.GENERAL; }, showFileUpload() { @@ -262,7 +274,7 @@ export default { this.isASmsInbox || this.isATelegramChannel || this.isALineChannel || - this.isAInstagramChannel + this.isAnInstagramChannel ); }, replyButtonLabel() { @@ -693,7 +705,7 @@ export default { // When users send messages containing both text and attachments on Instagram, Instagram treats them as separate messages. // Although Chatwoot combines these into a single message, Instagram sends separate echo events for each component. // This can create duplicate messages in Chatwoot. To prevent this issue, we'll handle text and attachments as separate messages. - const isOnInstagram = this.isAInstagramChannel; + const isOnInstagram = this.isAnInstagramChannel; if ((isOnWhatsApp || isOnInstagram) && !this.isPrivate) { this.sendMessageAsMultipleMessages(this.message); } else { @@ -947,7 +959,7 @@ export default { const multipleMessagePayload = []; if (this.attachedFiles && this.attachedFiles.length) { - let caption = this.isAInstagramChannel ? '' : message; + let caption = this.isAnInstagramChannel ? '' : message; this.attachedFiles.forEach(attachment => { const attachedFile = this.globalConfig.directUploadsEnabled ? attachment.blobSignedId @@ -963,7 +975,7 @@ export default { attachmentPayload = this.setReplyToInPayload(attachmentPayload); multipleMessagePayload.push(attachmentPayload); // For WhatsApp, only the first attachment gets a caption - if (!this.isAInstagramChannel) caption = ''; + if (!this.isAnInstagramChannel) caption = ''; }); } @@ -972,8 +984,8 @@ export default { // For Instagram, we need a separate text message // For WhatsApp, we only need a text message if there are no attachments if ( - (this.isAInstagramChannel && this.message) || - (!this.isAInstagramChannel && hasNoAttachments) + (this.isAnInstagramChannel && this.message) || + (!this.isAnInstagramChannel && hasNoAttachments) ) { let messagePayload = { conversationId: this.currentChat.id, diff --git a/app/javascript/dashboard/composables/useInbox.js b/app/javascript/dashboard/composables/useInbox.js index 2c59bc6e5..67ce11ae2 100644 --- a/app/javascript/dashboard/composables/useInbox.js +++ b/app/javascript/dashboard/composables/useInbox.js @@ -121,7 +121,7 @@ export const useInbox = () => { ); }); - const isAInstagramChannel = computed(() => { + const isAnInstagramChannel = computed(() => { return channelType.value === INBOX_TYPES.INSTAGRAM; }); @@ -141,6 +141,6 @@ export const useInbox = () => { isAWhatsAppCloudChannel, is360DialogWhatsAppChannel, isAnEmailChannel, - isAInstagramChannel, + isAnInstagramChannel, }; }; diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue index aa9eaf596..73d9963bd 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/Settings.vue @@ -204,7 +204,7 @@ export default { return false; }, instagramUnauthorized() { - return this.isAInstagramChannel && this.inbox.reauthorization_required; + return this.isAnInstagramChannel && this.inbox.reauthorization_required; }, // Check if a instagram inbox exists with the same instagram_id hasDuplicateInstagramInbox() { diff --git a/app/javascript/shared/helpers/MessageTypeHelper.js b/app/javascript/shared/helpers/MessageTypeHelper.js index 4ec3f8bbc..1e6cf454c 100644 --- a/app/javascript/shared/helpers/MessageTypeHelper.js +++ b/app/javascript/shared/helpers/MessageTypeHelper.js @@ -4,8 +4,20 @@ export const isASubmittedFormMessage = (message = {}) => export const MESSAGE_MAX_LENGTH = { GENERAL: 10000, - FACEBOOK: 1000, + // https://developers.facebook.com/docs/messenger-platform/reference/send-api#request + FACEBOOK: 2000, + // https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/messaging-api#send-a-text-message + INSTAGRAM: 1000, + // https://www.twilio.com/docs/glossary/what-sms-character-limit TWILIO_SMS: 320, + // https://help.twilio.com/articles/360033806753-Maximum-Message-Length-with-Twilio-Programmable-Messaging TWILIO_WHATSAPP: 1600, + // https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#text-object + WHATSAPP_CLOUD: 4096, + // https://support.bandwidth.com/hc/en-us/articles/360010235373-What-are-Bandwidth-s-SMS-character-limits-and-concatenation-practices + BANDWIDTH_SMS: 160, + // https://core.telegram.org/bots/api#sendmessage + TELEGRAM: 4096, + LINE: 2000, EMAIL: 25000, }; diff --git a/app/javascript/shared/mixins/inboxMixin.js b/app/javascript/shared/mixins/inboxMixin.js index 94f5997f7..273e9f8b4 100644 --- a/app/javascript/shared/mixins/inboxMixin.js +++ b/app/javascript/shared/mixins/inboxMixin.js @@ -121,7 +121,7 @@ export default { this.isATwilioWhatsAppChannel ); }, - isAInstagramChannel() { + isAnInstagramChannel() { return this.channelType === INBOX_TYPES.INSTAGRAM; }, },