feat: Add dedicated received type
This commit is contained in:
@@ -154,7 +154,7 @@ export class Webhooks {
|
||||
body: '', // Inbound emails don't have body content in our system
|
||||
from: recipientEmail, // The recipient address that received the email
|
||||
sourceType: EmailSourceType.INBOUND,
|
||||
status: EmailStatus.DELIVERED, // Inbound emails are already delivered
|
||||
status: EmailStatus.RECEIVED, // Inbound emails use RECEIVED status
|
||||
deliveredAt: new Date(body.mail?.timestamp || new Date()),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -376,6 +376,9 @@ export class ActivityService {
|
||||
if (!types || types.includes(ActivityType.EMAIL_DELIVERED)) {
|
||||
orConditions.push({deliveredAt: {not: null, ...dateFilter}});
|
||||
}
|
||||
if (!types || types.includes(ActivityType.EMAIL_RECEIVED)) {
|
||||
orConditions.push({deliveredAt: {not: null, ...dateFilter}, sourceType: 'INBOUND'});
|
||||
}
|
||||
if (!types || types.includes(ActivityType.EMAIL_OPENED)) {
|
||||
orConditions.push({openedAt: {not: null, ...dateFilter}});
|
||||
}
|
||||
@@ -485,6 +488,22 @@ export class ActivityService {
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
email.deliveredAt &&
|
||||
email.sourceType === 'INBOUND' &&
|
||||
(!types || types.includes(ActivityType.EMAIL_RECEIVED)) &&
|
||||
isInDateRange(email.deliveredAt)
|
||||
) {
|
||||
activities.push({
|
||||
id: `${email.id}_received`,
|
||||
type: ActivityType.EMAIL_RECEIVED,
|
||||
timestamp: email.deliveredAt,
|
||||
contactEmail: email.contact.email,
|
||||
contactId: email.contactId,
|
||||
metadata: baseMetadata,
|
||||
});
|
||||
}
|
||||
|
||||
if (email.openedAt && (!types || types.includes(ActivityType.EMAIL_OPENED)) && isInDateRange(email.openedAt)) {
|
||||
activities.push({
|
||||
id: `${email.id}_opened`,
|
||||
|
||||
@@ -585,10 +585,11 @@ export class EmailService {
|
||||
: {}),
|
||||
};
|
||||
|
||||
const [total, sent, delivered, opened, clicked, bounced, failed] = await Promise.all([
|
||||
const [total, sent, delivered, received, opened, clicked, bounced, failed] = await Promise.all([
|
||||
prisma.email.count({where}),
|
||||
prisma.email.count({where: {...where, status: EmailStatus.SENT}}),
|
||||
prisma.email.count({where: {...where, status: EmailStatus.DELIVERED}}),
|
||||
prisma.email.count({where: {...where, status: EmailStatus.RECEIVED}}),
|
||||
prisma.email.count({where: {...where, status: EmailStatus.OPENED}}),
|
||||
prisma.email.count({where: {...where, status: EmailStatus.CLICKED}}),
|
||||
prisma.email.count({where: {...where, status: EmailStatus.BOUNCED}}),
|
||||
@@ -599,6 +600,7 @@ export class EmailService {
|
||||
total,
|
||||
sent,
|
||||
delivered,
|
||||
received,
|
||||
opened,
|
||||
clicked,
|
||||
bounced,
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
CheckCircle,
|
||||
ChevronRight,
|
||||
Eye,
|
||||
Inbox,
|
||||
MousePointerClick,
|
||||
Send,
|
||||
ShieldAlert,
|
||||
@@ -99,6 +100,7 @@ function isEmailActivity(type: string): boolean {
|
||||
return [
|
||||
'email.sent',
|
||||
'email.delivered',
|
||||
'email.received',
|
||||
'email.opened',
|
||||
'email.clicked',
|
||||
'email.bounced',
|
||||
@@ -181,6 +183,19 @@ function getActivityConfig(activity: Activity): ActivityConfig {
|
||||
},
|
||||
};
|
||||
|
||||
case 'email.received':
|
||||
return {
|
||||
icon: Inbox,
|
||||
color: 'text-blue-600',
|
||||
bgColor: 'bg-blue-100',
|
||||
title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email received',
|
||||
description: typeof metadata.from === 'string' ? `From: ${metadata.from}` : 'Inbound email',
|
||||
badge: {
|
||||
label: 'Received',
|
||||
variant: 'default',
|
||||
},
|
||||
};
|
||||
|
||||
case 'email.opened':
|
||||
return {
|
||||
icon: Eye,
|
||||
|
||||
@@ -119,10 +119,12 @@ export default function ActivityPage() {
|
||||
<SelectContent>
|
||||
<SelectItem value="ALL">All Activity Types</SelectItem>
|
||||
<SelectItem value="event.triggered">Events</SelectItem>
|
||||
<SelectItem value="email.sent,email.delivered,email.opened,email.clicked,email.bounced,email.complaint">
|
||||
<SelectItem value="email.sent,email.delivered,email.received,email.opened,email.clicked,email.bounced,email.complaint">
|
||||
Emails
|
||||
</SelectItem>
|
||||
<SelectItem value="email.sent">Emails Sent</SelectItem>
|
||||
<SelectItem value="email.delivered">Emails Delivered</SelectItem>
|
||||
<SelectItem value="email.received">Emails Received</SelectItem>
|
||||
<SelectItem value="email.opened">Emails Opened</SelectItem>
|
||||
<SelectItem value="email.clicked">Emails Clicked</SelectItem>
|
||||
<SelectItem value="email.bounced">Emails Bounced</SelectItem>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterEnum
|
||||
ALTER TYPE "EmailStatus" ADD VALUE 'RECEIVED';
|
||||
@@ -759,6 +759,7 @@ enum EmailStatus {
|
||||
SENDING // Currently being sent
|
||||
SENT // Successfully sent to provider
|
||||
DELIVERED // Confirmed delivered
|
||||
RECEIVED // Received by platform (inbound)
|
||||
OPENED // Recipient opened email
|
||||
CLICKED // Recipient clicked link
|
||||
BOUNCED // Bounced (hard or soft)
|
||||
|
||||
@@ -9,6 +9,7 @@ export enum ActivityType {
|
||||
EVENT_TRIGGERED = 'event.triggered',
|
||||
EMAIL_SENT = 'email.sent',
|
||||
EMAIL_DELIVERED = 'email.delivered',
|
||||
EMAIL_RECEIVED = 'email.received',
|
||||
EMAIL_OPENED = 'email.opened',
|
||||
EMAIL_CLICKED = 'email.clicked',
|
||||
EMAIL_BOUNCED = 'email.bounced',
|
||||
|
||||
Reference in New Issue
Block a user