Files
leadchat/app/javascript/dashboard/components-next/message/MessageMeta.vue
Shivam Mishra 8d85a02ca9 feat: handle Channel errors (#11015)
This PR adds missing error handlers for the following channels and cases

1. WhatsApp - Generic Handlers for both Cloud and 360Dialog (Deprecated)
2. Instagram - Handler for a case where there is an HTTP error instead
of an `:error` in the 200 response
3. Facebook - Errors from the two sentry issues
([Net::OpenTimeout](https://chatwoot-p3.sentry.io/issues/6164805227) &
[JSON::ParserError](https://chatwoot-p3.sentry.io/issues/5903200786))
4. SMS: Generic handlers for Bandwidth SMS

#### Checklist

- [x] Bandwidth SMS
- [x] Whatsapp Cloud + 360 Dialog
- [x] Twilio SMS
- [x] Line
- [x] Telegram
- [x] Instagram
- [x] Facebook
- [x] GMail
- [x] 365 Mail
- [x] SMTP Mail

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2025-03-06 20:09:47 +05:30

121 lines
3.1 KiB
Vue

<script setup>
import { computed } from 'vue';
import { messageTimestamp } from 'shared/helpers/timeHelper';
import MessageStatus from './MessageStatus.vue';
import Icon from 'next/icon/Icon.vue';
import { useInbox } from 'dashboard/composables/useInbox';
import { useMessageContext } from './provider.js';
import { MESSAGE_STATUS, MESSAGE_TYPES } from './constants';
const {
isAFacebookInbox,
isALineChannel,
isAPIInbox,
isASmsInbox,
isATelegramChannel,
isATwilioChannel,
isAWebWidgetInbox,
isAWhatsAppChannel,
isAnEmailChannel,
} = useInbox();
const { status, isPrivate, createdAt, sourceId, messageType } =
useMessageContext();
const readableTime = computed(() =>
messageTimestamp(createdAt.value, 'LLL d, h:mm a')
);
const showStatusIndicator = computed(() => {
if (isPrivate.value) return false;
if (messageType.value === MESSAGE_TYPES.OUTGOING) return true;
if (messageType.value === MESSAGE_TYPES.TEMPLATE) return true;
return false;
});
const isSent = computed(() => {
if (!showStatusIndicator.value) return false;
// Messages will be marked as sent for the Email channel if they have a source ID.
if (isAnEmailChannel.value) return !!sourceId.value;
if (
isAWhatsAppChannel.value ||
isATwilioChannel.value ||
isAFacebookInbox.value ||
isASmsInbox.value ||
isATelegramChannel.value
) {
return sourceId.value && status.value === MESSAGE_STATUS.SENT;
}
// All messages will be mark as sent for the Line channel, as there is no source ID.
if (isALineChannel.value) return true;
return false;
});
const isDelivered = computed(() => {
if (!showStatusIndicator.value) return false;
if (
isAWhatsAppChannel.value ||
isATwilioChannel.value ||
isASmsInbox.value ||
isAFacebookInbox.value
) {
return sourceId.value && status.value === MESSAGE_STATUS.DELIVERED;
}
// All messages marked as delivered for the web widget inbox and API inbox once they are sent.
if (isAWebWidgetInbox.value || isAPIInbox.value) {
return status.value === MESSAGE_STATUS.SENT;
}
if (isALineChannel.value) {
return status.value === MESSAGE_STATUS.DELIVERED;
}
return false;
});
const isRead = computed(() => {
if (!showStatusIndicator.value) return false;
if (
isAWhatsAppChannel.value ||
isATwilioChannel.value ||
isAFacebookInbox.value
) {
return sourceId.value && status.value === MESSAGE_STATUS.READ;
}
if (isAWebWidgetInbox.value || isAPIInbox.value) {
return status.value === MESSAGE_STATUS.READ;
}
return false;
});
const statusToShow = computed(() => {
if (isRead.value) return MESSAGE_STATUS.READ;
if (isDelivered.value) return MESSAGE_STATUS.DELIVERED;
if (isSent.value) return MESSAGE_STATUS.SENT;
if (status.value === MESSAGE_STATUS.FAILED) return MESSAGE_STATUS.FAILED;
return MESSAGE_STATUS.PROGRESS;
});
</script>
<template>
<div class="text-xs flex items-center gap-1.5">
<div class="inline">
<time class="inline">{{ readableTime }}</time>
</div>
<Icon v-if="isPrivate" icon="i-lucide-lock-keyhole" class="size-3" />
<MessageStatus v-if="showStatusIndicator" :status="statusToShow" />
</div>
</template>
`