@bernierllc/email-webhook-events 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +29 -0
- package/README.md +349 -0
- package/__tests__/EmailWebhookEventsService.test.ts +247 -0
- package/__tests__/analytics/AnalyticsEngine.test.ts +244 -0
- package/__tests__/normalizers/MailgunNormalizer.test.ts +149 -0
- package/__tests__/normalizers/PostmarkNormalizer.test.ts +112 -0
- package/__tests__/normalizers/SESNormalizer.test.ts +168 -0
- package/__tests__/normalizers/SMTP2GONormalizer.test.ts +83 -0
- package/__tests__/normalizers/SendGridNormalizer.test.ts +181 -0
- package/__tests__/persistence/PersistenceAdapter.test.ts +103 -0
- package/coverage/clover.xml +328 -0
- package/coverage/coverage-final.json +10 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +161 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/src/EmailWebhookEventsService.ts.html +826 -0
- package/coverage/lcov-report/src/analytics/AnalyticsEngine.ts.html +775 -0
- package/coverage/lcov-report/src/analytics/index.html +116 -0
- package/coverage/lcov-report/src/index.html +131 -0
- package/coverage/lcov-report/src/normalizers/MailgunNormalizer.ts.html +301 -0
- package/coverage/lcov-report/src/normalizers/PostmarkNormalizer.ts.html +301 -0
- package/coverage/lcov-report/src/normalizers/SESNormalizer.ts.html +436 -0
- package/coverage/lcov-report/src/normalizers/SMTP2GONormalizer.ts.html +247 -0
- package/coverage/lcov-report/src/normalizers/SendGridNormalizer.ts.html +274 -0
- package/coverage/lcov-report/src/normalizers/index.html +176 -0
- package/coverage/lcov-report/src/persistence/InMemoryPersistenceAdapter.ts.html +289 -0
- package/coverage/lcov-report/src/persistence/index.html +116 -0
- package/coverage/lcov-report/src/types.ts.html +823 -0
- package/coverage/lcov.info +710 -0
- package/dist/EmailWebhookEventsService.d.ts +53 -0
- package/dist/EmailWebhookEventsService.d.ts.map +1 -0
- package/dist/EmailWebhookEventsService.js +198 -0
- package/dist/EmailWebhookEventsService.js.map +1 -0
- package/dist/analytics/AnalyticsEngine.d.ts +20 -0
- package/dist/analytics/AnalyticsEngine.d.ts.map +1 -0
- package/dist/analytics/AnalyticsEngine.js +160 -0
- package/dist/analytics/AnalyticsEngine.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/normalizers/EventNormalizer.d.ts +5 -0
- package/dist/normalizers/EventNormalizer.d.ts.map +1 -0
- package/dist/normalizers/EventNormalizer.js +10 -0
- package/dist/normalizers/EventNormalizer.js.map +1 -0
- package/dist/normalizers/MailgunNormalizer.d.ts +9 -0
- package/dist/normalizers/MailgunNormalizer.d.ts.map +1 -0
- package/dist/normalizers/MailgunNormalizer.js +73 -0
- package/dist/normalizers/MailgunNormalizer.js.map +1 -0
- package/dist/normalizers/PostmarkNormalizer.d.ts +10 -0
- package/dist/normalizers/PostmarkNormalizer.d.ts.map +1 -0
- package/dist/normalizers/PostmarkNormalizer.js +75 -0
- package/dist/normalizers/PostmarkNormalizer.js.map +1 -0
- package/dist/normalizers/SESNormalizer.d.ts +16 -0
- package/dist/normalizers/SESNormalizer.d.ts.map +1 -0
- package/dist/normalizers/SESNormalizer.js +107 -0
- package/dist/normalizers/SESNormalizer.js.map +1 -0
- package/dist/normalizers/SMTP2GONormalizer.d.ts +9 -0
- package/dist/normalizers/SMTP2GONormalizer.d.ts.map +1 -0
- package/dist/normalizers/SMTP2GONormalizer.js +55 -0
- package/dist/normalizers/SMTP2GONormalizer.js.map +1 -0
- package/dist/normalizers/SendGridNormalizer.d.ts +9 -0
- package/dist/normalizers/SendGridNormalizer.d.ts.map +1 -0
- package/dist/normalizers/SendGridNormalizer.js +64 -0
- package/dist/normalizers/SendGridNormalizer.js.map +1 -0
- package/dist/persistence/InMemoryPersistenceAdapter.d.ts +12 -0
- package/dist/persistence/InMemoryPersistenceAdapter.d.ts.map +1 -0
- package/dist/persistence/InMemoryPersistenceAdapter.js +58 -0
- package/dist/persistence/InMemoryPersistenceAdapter.js.map +1 -0
- package/dist/persistence/PersistenceAdapter.d.ts +7 -0
- package/dist/persistence/PersistenceAdapter.d.ts.map +1 -0
- package/dist/persistence/PersistenceAdapter.js +10 -0
- package/dist/persistence/PersistenceAdapter.js.map +1 -0
- package/dist/types.d.ts +178 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +41 -0
- package/dist/types.js.map +1 -0
- package/jest.config.cjs +29 -0
- package/package.json +51 -0
- package/src/EmailWebhookEventsService.ts +247 -0
- package/src/analytics/AnalyticsEngine.ts +230 -0
- package/src/index.ts +39 -0
- package/src/normalizers/EventNormalizer.ts +13 -0
- package/src/normalizers/MailgunNormalizer.ts +72 -0
- package/src/normalizers/PostmarkNormalizer.ts +72 -0
- package/src/normalizers/SESNormalizer.ts +117 -0
- package/src/normalizers/SMTP2GONormalizer.ts +54 -0
- package/src/normalizers/SendGridNormalizer.ts +63 -0
- package/src/persistence/InMemoryPersistenceAdapter.ts +68 -0
- package/src/persistence/PersistenceAdapter.ts +15 -0
- package/src/types.ts +246 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { EmailWebhookEventsConfig, EmailWebhookResult, WebhookPayload, EmailEvent, EmailAnalytics, AnalyticsFilters, EventQuery } from './types';
|
|
2
|
+
export declare class EmailWebhookEventsService {
|
|
3
|
+
private config;
|
|
4
|
+
private logger;
|
|
5
|
+
private persistenceAdapter?;
|
|
6
|
+
private analyticsEngine;
|
|
7
|
+
constructor(config: EmailWebhookEventsConfig);
|
|
8
|
+
/**
|
|
9
|
+
* Initialize the service
|
|
10
|
+
*/
|
|
11
|
+
initialize(): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Process incoming webhook
|
|
14
|
+
*/
|
|
15
|
+
processWebhook(webhook: WebhookPayload): Promise<EmailWebhookResult>;
|
|
16
|
+
/**
|
|
17
|
+
* Get analytics for date range
|
|
18
|
+
*/
|
|
19
|
+
getAnalytics(startDate: Date, endDate: Date, filters?: AnalyticsFilters): Promise<EmailAnalytics>;
|
|
20
|
+
/**
|
|
21
|
+
* Query events
|
|
22
|
+
*/
|
|
23
|
+
queryEvents(query: EventQuery): Promise<EmailEvent[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Get events for specific email
|
|
26
|
+
*/
|
|
27
|
+
getEventsForEmail(emailId: string): Promise<EmailEvent[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Normalize webhook event to unified format
|
|
30
|
+
*/
|
|
31
|
+
private normalizeEvent;
|
|
32
|
+
/**
|
|
33
|
+
* Get normalizer for provider
|
|
34
|
+
*/
|
|
35
|
+
private getNormalizerForProvider;
|
|
36
|
+
/**
|
|
37
|
+
* Check if event is critical (requires notification)
|
|
38
|
+
*/
|
|
39
|
+
private isCriticalEvent;
|
|
40
|
+
/**
|
|
41
|
+
* Publish critical event to notification channels
|
|
42
|
+
*/
|
|
43
|
+
private publishCriticalEvent;
|
|
44
|
+
/**
|
|
45
|
+
* Send notification via channel
|
|
46
|
+
*/
|
|
47
|
+
private sendNotification;
|
|
48
|
+
/**
|
|
49
|
+
* Create persistence adapter
|
|
50
|
+
*/
|
|
51
|
+
private createPersistenceAdapter;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=EmailWebhookEventsService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmailWebhookEventsService.d.ts","sourceRoot":"","sources":["../src/EmailWebhookEventsService.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,cAAc,EAGd,gBAAgB,EAChB,UAAU,EAEX,MAAM,SAAS,CAAC;AAgCjB,qBAAa,yBAAyB;IAKxB,OAAO,CAAC,MAAM;IAJ1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,kBAAkB,CAAC,CAAqB;IAChD,OAAO,CAAC,eAAe,CAAkB;gBAErB,MAAM,EAAE,wBAAwB;IAKpD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASjC;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA+C1E;;OAEG;IACG,YAAY,CAChB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,EACb,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,cAAc,CAAC;IAI1B;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAO3D;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAI/D;;OAEG;YACW,cAAc;IAY5B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAiBhC;;OAEG;IACH,OAAO,CAAC,eAAe;IASvB;;OAEG;YACW,oBAAoB;IAelC;;OAEG;YACW,gBAAgB;IAa9B;;OAEG;YACW,wBAAwB;CAWvC"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.EmailWebhookEventsService = void 0;
|
|
11
|
+
const types_1 = require("./types");
|
|
12
|
+
const AnalyticsEngine_1 = require("./analytics/AnalyticsEngine");
|
|
13
|
+
const InMemoryPersistenceAdapter_1 = require("./persistence/InMemoryPersistenceAdapter");
|
|
14
|
+
const SendGridNormalizer_1 = require("./normalizers/SendGridNormalizer");
|
|
15
|
+
const MailgunNormalizer_1 = require("./normalizers/MailgunNormalizer");
|
|
16
|
+
const SESNormalizer_1 = require("./normalizers/SESNormalizer");
|
|
17
|
+
const PostmarkNormalizer_1 = require("./normalizers/PostmarkNormalizer");
|
|
18
|
+
const SMTP2GONormalizer_1 = require("./normalizers/SMTP2GONormalizer");
|
|
19
|
+
class MockLogger {
|
|
20
|
+
info(message, meta) {
|
|
21
|
+
console.log(`[INFO] ${message}`, meta || '');
|
|
22
|
+
}
|
|
23
|
+
warn(message, meta) {
|
|
24
|
+
console.warn(`[WARN] ${message}`, meta || '');
|
|
25
|
+
}
|
|
26
|
+
error(message, meta) {
|
|
27
|
+
console.error(`[ERROR] ${message}`, meta || '');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
class EmailWebhookEventsService {
|
|
31
|
+
constructor(config) {
|
|
32
|
+
this.config = config;
|
|
33
|
+
this.logger = new MockLogger();
|
|
34
|
+
this.analyticsEngine = new AnalyticsEngine_1.AnalyticsEngine(config.analytics);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Initialize the service
|
|
38
|
+
*/
|
|
39
|
+
async initialize() {
|
|
40
|
+
// Initialize persistence
|
|
41
|
+
if (this.config.persistence?.enabled) {
|
|
42
|
+
this.persistenceAdapter = await this.createPersistenceAdapter();
|
|
43
|
+
}
|
|
44
|
+
this.logger.info('Email webhook events service initialized');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Process incoming webhook
|
|
48
|
+
*/
|
|
49
|
+
async processWebhook(webhook) {
|
|
50
|
+
try {
|
|
51
|
+
// Validate webhook signature would happen here
|
|
52
|
+
// For now, we'll assume validation passes
|
|
53
|
+
// Normalize event
|
|
54
|
+
const normalizedEvent = await this.normalizeEvent(webhook);
|
|
55
|
+
if (!normalizedEvent) {
|
|
56
|
+
this.logger.warn('Failed to normalize webhook event', {
|
|
57
|
+
provider: webhook.provider
|
|
58
|
+
});
|
|
59
|
+
return { success: false, error: 'Event normalization failed' };
|
|
60
|
+
}
|
|
61
|
+
// Persist event
|
|
62
|
+
if (this.persistenceAdapter) {
|
|
63
|
+
await this.persistenceAdapter.saveEvent(normalizedEvent);
|
|
64
|
+
}
|
|
65
|
+
// Update analytics
|
|
66
|
+
await this.analyticsEngine.recordEvent(normalizedEvent);
|
|
67
|
+
// Publish critical events
|
|
68
|
+
if (this.isCriticalEvent(normalizedEvent)) {
|
|
69
|
+
await this.publishCriticalEvent(normalizedEvent);
|
|
70
|
+
}
|
|
71
|
+
this.logger.info('Email event processed successfully', {
|
|
72
|
+
eventId: normalizedEvent.id,
|
|
73
|
+
type: normalizedEvent.type,
|
|
74
|
+
recipient: normalizedEvent.recipient
|
|
75
|
+
});
|
|
76
|
+
return { success: true, event: normalizedEvent };
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
this.logger.error('Error processing email webhook', {
|
|
80
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
81
|
+
provider: webhook.provider
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
success: false,
|
|
85
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get analytics for date range
|
|
91
|
+
*/
|
|
92
|
+
async getAnalytics(startDate, endDate, filters) {
|
|
93
|
+
return this.analyticsEngine.getAnalytics(startDate, endDate, filters);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Query events
|
|
97
|
+
*/
|
|
98
|
+
async queryEvents(query) {
|
|
99
|
+
if (!this.persistenceAdapter) {
|
|
100
|
+
throw new Error('Event persistence not enabled');
|
|
101
|
+
}
|
|
102
|
+
return this.persistenceAdapter.queryEvents(query);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get events for specific email
|
|
106
|
+
*/
|
|
107
|
+
async getEventsForEmail(emailId) {
|
|
108
|
+
return this.queryEvents({ emailId });
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Normalize webhook event to unified format
|
|
112
|
+
*/
|
|
113
|
+
async normalizeEvent(webhook) {
|
|
114
|
+
const normalizer = this.getNormalizerForProvider(webhook.provider);
|
|
115
|
+
if (!normalizer) {
|
|
116
|
+
this.logger.error('No normalizer found for provider', {
|
|
117
|
+
provider: webhook.provider
|
|
118
|
+
});
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
return normalizer.normalize(webhook);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get normalizer for provider
|
|
125
|
+
*/
|
|
126
|
+
getNormalizerForProvider(provider) {
|
|
127
|
+
switch (provider) {
|
|
128
|
+
case types_1.EmailProvider.SENDGRID:
|
|
129
|
+
return new SendGridNormalizer_1.SendGridNormalizer();
|
|
130
|
+
case types_1.EmailProvider.MAILGUN:
|
|
131
|
+
return new MailgunNormalizer_1.MailgunNormalizer();
|
|
132
|
+
case types_1.EmailProvider.AWS_SES:
|
|
133
|
+
return new SESNormalizer_1.SESNormalizer();
|
|
134
|
+
case types_1.EmailProvider.POSTMARK:
|
|
135
|
+
return new PostmarkNormalizer_1.PostmarkNormalizer();
|
|
136
|
+
case types_1.EmailProvider.SMTP2GO:
|
|
137
|
+
return new SMTP2GONormalizer_1.SMTP2GONormalizer();
|
|
138
|
+
default:
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check if event is critical (requires notification)
|
|
144
|
+
*/
|
|
145
|
+
isCriticalEvent(event) {
|
|
146
|
+
const criticalTypes = this.config.notifications?.criticalEvents || [
|
|
147
|
+
types_1.EmailEventType.BOUNCED,
|
|
148
|
+
types_1.EmailEventType.COMPLAINED,
|
|
149
|
+
types_1.EmailEventType.FAILED
|
|
150
|
+
];
|
|
151
|
+
return criticalTypes.includes(event.type);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Publish critical event to notification channels
|
|
155
|
+
*/
|
|
156
|
+
async publishCriticalEvent(event) {
|
|
157
|
+
if (!this.config.notifications?.enabled)
|
|
158
|
+
return;
|
|
159
|
+
for (const channel of this.config.notifications.channels) {
|
|
160
|
+
try {
|
|
161
|
+
await this.sendNotification(channel, event);
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
this.logger.error('Failed to send notification', {
|
|
165
|
+
channel: channel.type,
|
|
166
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Send notification via channel
|
|
173
|
+
*/
|
|
174
|
+
async sendNotification(channel, event) {
|
|
175
|
+
// In a real implementation, this would send notifications
|
|
176
|
+
// For now, just log
|
|
177
|
+
this.logger.info('Critical event notification', {
|
|
178
|
+
channel: channel.type,
|
|
179
|
+
eventType: event.type,
|
|
180
|
+
recipient: event.recipient
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Create persistence adapter
|
|
185
|
+
*/
|
|
186
|
+
async createPersistenceAdapter() {
|
|
187
|
+
const adapter = this.config.persistence?.adapter || 'memory';
|
|
188
|
+
switch (adapter) {
|
|
189
|
+
case 'memory':
|
|
190
|
+
return new InMemoryPersistenceAdapter_1.InMemoryPersistenceAdapter();
|
|
191
|
+
// Other adapters would be implemented here
|
|
192
|
+
default:
|
|
193
|
+
throw new Error(`Unsupported persistence adapter: ${adapter}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
exports.EmailWebhookEventsService = EmailWebhookEventsService;
|
|
198
|
+
//# sourceMappingURL=EmailWebhookEventsService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EmailWebhookEventsService.js","sourceRoot":"","sources":["../src/EmailWebhookEventsService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { EmailEvent, EmailAnalytics, AnalyticsFilters } from '../types';
|
|
2
|
+
export declare class AnalyticsEngine {
|
|
3
|
+
private events;
|
|
4
|
+
private config?;
|
|
5
|
+
constructor(config?: {
|
|
6
|
+
realTimeEnabled: boolean;
|
|
7
|
+
aggregationInterval: number;
|
|
8
|
+
retentionDays: number;
|
|
9
|
+
});
|
|
10
|
+
recordEvent(event: EmailEvent): Promise<void>;
|
|
11
|
+
getAnalytics(startDate: Date, endDate: Date, filters?: AnalyticsFilters): Promise<EmailAnalytics>;
|
|
12
|
+
private calculateCounts;
|
|
13
|
+
private calculateRates;
|
|
14
|
+
private calculateProviderBreakdown;
|
|
15
|
+
private calculateEventTypeBreakdown;
|
|
16
|
+
private calculateBounceTypeBreakdown;
|
|
17
|
+
private calculateTopLinks;
|
|
18
|
+
private calculateDeviceBreakdown;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=AnalyticsEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsEngine.d.ts","sourceRoot":"","sources":["../../src/analytics/AnalyticsEngine.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,UAAU,EACV,cAAc,EAId,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAElB,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,MAAM,CAAC,CAIb;gBAEU,MAAM,CAAC,EAAE;QAAE,eAAe,EAAE,OAAO,CAAC;QAAC,mBAAmB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE;IAI/F,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAW7C,YAAY,CAChB,SAAS,EAAE,IAAI,EACf,OAAO,EAAE,IAAI,EACb,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,cAAc,CAAC;IAgD1B,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,cAAc;IA8BtB,OAAO,CAAC,0BAA0B;IA0BlC,OAAO,CAAC,2BAA2B;IAWnC,OAAO,CAAC,4BAA4B;IAUpC,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,wBAAwB;CAcjC"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.AnalyticsEngine = void 0;
|
|
11
|
+
const types_1 = require("../types");
|
|
12
|
+
class AnalyticsEngine {
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.events = [];
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
async recordEvent(event) {
|
|
18
|
+
this.events.push(event);
|
|
19
|
+
// Cleanup old events based on retention policy
|
|
20
|
+
if (this.config?.retentionDays) {
|
|
21
|
+
const cutoffDate = new Date();
|
|
22
|
+
cutoffDate.setDate(cutoffDate.getDate() - this.config.retentionDays);
|
|
23
|
+
this.events = this.events.filter(e => e.timestamp >= cutoffDate);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async getAnalytics(startDate, endDate, filters) {
|
|
27
|
+
// Filter events by date range and filters
|
|
28
|
+
let filteredEvents = this.events.filter(e => e.timestamp >= startDate && e.timestamp <= endDate);
|
|
29
|
+
if (filters?.provider) {
|
|
30
|
+
filteredEvents = filteredEvents.filter(e => e.provider === filters.provider);
|
|
31
|
+
}
|
|
32
|
+
if (filters?.emailId) {
|
|
33
|
+
filteredEvents = filteredEvents.filter(e => e.emailId === filters.emailId);
|
|
34
|
+
}
|
|
35
|
+
if (filters?.recipient) {
|
|
36
|
+
filteredEvents = filteredEvents.filter(e => e.recipient === filters.recipient);
|
|
37
|
+
}
|
|
38
|
+
if (filters?.eventTypes && filters.eventTypes.length > 0) {
|
|
39
|
+
filteredEvents = filteredEvents.filter(e => filters.eventTypes.includes(e.type));
|
|
40
|
+
}
|
|
41
|
+
// Calculate counts
|
|
42
|
+
const counts = this.calculateCounts(filteredEvents);
|
|
43
|
+
// Calculate rates
|
|
44
|
+
const rates = this.calculateRates(counts);
|
|
45
|
+
// Calculate breakdowns
|
|
46
|
+
const byProvider = this.calculateProviderBreakdown(filteredEvents);
|
|
47
|
+
const byEventType = this.calculateEventTypeBreakdown(filteredEvents);
|
|
48
|
+
const byBounceType = this.calculateBounceTypeBreakdown(filteredEvents);
|
|
49
|
+
const topLinks = this.calculateTopLinks(filteredEvents);
|
|
50
|
+
const byDevice = this.calculateDeviceBreakdown(filteredEvents);
|
|
51
|
+
return {
|
|
52
|
+
startDate,
|
|
53
|
+
endDate,
|
|
54
|
+
...counts,
|
|
55
|
+
...rates,
|
|
56
|
+
byProvider,
|
|
57
|
+
byEventType,
|
|
58
|
+
byBounceType,
|
|
59
|
+
topLinks,
|
|
60
|
+
byDevice
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
calculateCounts(events) {
|
|
64
|
+
return {
|
|
65
|
+
totalSent: events.length, // Simplified - in real implementation, would track sent separately
|
|
66
|
+
totalDelivered: events.filter(e => e.type === types_1.EmailEventType.DELIVERED).length,
|
|
67
|
+
totalOpened: events.filter(e => e.type === types_1.EmailEventType.OPENED).length,
|
|
68
|
+
totalClicked: events.filter(e => e.type === types_1.EmailEventType.CLICKED).length,
|
|
69
|
+
totalBounced: events.filter(e => e.type === types_1.EmailEventType.BOUNCED).length,
|
|
70
|
+
totalComplained: events.filter(e => e.type === types_1.EmailEventType.COMPLAINED).length,
|
|
71
|
+
totalUnsubscribed: events.filter(e => e.type === types_1.EmailEventType.UNSUBSCRIBED).length,
|
|
72
|
+
totalFailed: events.filter(e => e.type === types_1.EmailEventType.FAILED).length
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
calculateRates(counts) {
|
|
76
|
+
const safeDiv = (num, denom) => (denom === 0 ? 0 : num / denom);
|
|
77
|
+
return {
|
|
78
|
+
deliveryRate: safeDiv(counts.totalDelivered, counts.totalSent),
|
|
79
|
+
openRate: safeDiv(counts.totalOpened, counts.totalDelivered),
|
|
80
|
+
clickRate: safeDiv(counts.totalClicked, counts.totalDelivered),
|
|
81
|
+
clickToOpenRate: safeDiv(counts.totalClicked, counts.totalOpened),
|
|
82
|
+
bounceRate: safeDiv(counts.totalBounced, counts.totalSent),
|
|
83
|
+
complaintRate: safeDiv(counts.totalComplained, counts.totalSent),
|
|
84
|
+
unsubscribeRate: safeDiv(counts.totalUnsubscribed, counts.totalDelivered)
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
calculateProviderBreakdown(events) {
|
|
88
|
+
const providers = Object.values(types_1.EmailProvider);
|
|
89
|
+
const breakdown = {};
|
|
90
|
+
for (const provider of providers) {
|
|
91
|
+
const providerEvents = events.filter(e => e.provider === provider);
|
|
92
|
+
const counts = this.calculateCounts(providerEvents);
|
|
93
|
+
const rates = this.calculateRates(counts);
|
|
94
|
+
breakdown[provider] = {
|
|
95
|
+
sent: counts.totalSent,
|
|
96
|
+
delivered: counts.totalDelivered,
|
|
97
|
+
opened: counts.totalOpened,
|
|
98
|
+
clicked: counts.totalClicked,
|
|
99
|
+
bounced: counts.totalBounced,
|
|
100
|
+
complained: counts.totalComplained,
|
|
101
|
+
failed: counts.totalFailed,
|
|
102
|
+
deliveryRate: rates.deliveryRate,
|
|
103
|
+
openRate: rates.openRate,
|
|
104
|
+
clickRate: rates.clickRate
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return breakdown;
|
|
108
|
+
}
|
|
109
|
+
calculateEventTypeBreakdown(events) {
|
|
110
|
+
const eventTypes = Object.values(types_1.EmailEventType);
|
|
111
|
+
const breakdown = {};
|
|
112
|
+
for (const eventType of eventTypes) {
|
|
113
|
+
breakdown[eventType] = events.filter(e => e.type === eventType).length;
|
|
114
|
+
}
|
|
115
|
+
return breakdown;
|
|
116
|
+
}
|
|
117
|
+
calculateBounceTypeBreakdown(events) {
|
|
118
|
+
const bounceEvents = events.filter(e => e.type === types_1.EmailEventType.BOUNCED);
|
|
119
|
+
if (bounceEvents.length === 0)
|
|
120
|
+
return undefined;
|
|
121
|
+
return {
|
|
122
|
+
hard: bounceEvents.filter(e => e.metadata.bounceType === 'hard').length,
|
|
123
|
+
soft: bounceEvents.filter(e => e.metadata.bounceType === 'soft').length
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
calculateTopLinks(events) {
|
|
127
|
+
const clickEvents = events.filter(e => e.type === types_1.EmailEventType.CLICKED && e.metadata.url);
|
|
128
|
+
if (clickEvents.length === 0)
|
|
129
|
+
return undefined;
|
|
130
|
+
const linkStats = new Map();
|
|
131
|
+
for (const event of clickEvents) {
|
|
132
|
+
const url = event.metadata.url;
|
|
133
|
+
const existing = linkStats.get(url) || { clicks: 0, recipients: new Set() };
|
|
134
|
+
existing.clicks++;
|
|
135
|
+
existing.recipients.add(event.recipient);
|
|
136
|
+
linkStats.set(url, existing);
|
|
137
|
+
}
|
|
138
|
+
return Array.from(linkStats.entries())
|
|
139
|
+
.map(([url, stats]) => ({
|
|
140
|
+
url,
|
|
141
|
+
clicks: stats.clicks,
|
|
142
|
+
uniqueClicks: stats.recipients.size
|
|
143
|
+
}))
|
|
144
|
+
.sort((a, b) => b.clicks - a.clicks)
|
|
145
|
+
.slice(0, 10);
|
|
146
|
+
}
|
|
147
|
+
calculateDeviceBreakdown(events) {
|
|
148
|
+
const interactionEvents = events.filter(e => (e.type === types_1.EmailEventType.OPENED || e.type === types_1.EmailEventType.CLICKED) && e.metadata.deviceType);
|
|
149
|
+
if (interactionEvents.length === 0)
|
|
150
|
+
return undefined;
|
|
151
|
+
return {
|
|
152
|
+
desktop: interactionEvents.filter(e => e.metadata.deviceType === 'desktop').length,
|
|
153
|
+
mobile: interactionEvents.filter(e => e.metadata.deviceType === 'mobile').length,
|
|
154
|
+
tablet: interactionEvents.filter(e => e.metadata.deviceType === 'tablet').length,
|
|
155
|
+
unknown: interactionEvents.filter(e => e.metadata.deviceType === 'unknown').length
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
exports.AnalyticsEngine = AnalyticsEngine;
|
|
160
|
+
//# sourceMappingURL=AnalyticsEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsEngine.js","sourceRoot":"","sources":["../../src/analytics/AnalyticsEngine.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { EmailWebhookEventsService } from './EmailWebhookEventsService';
|
|
2
|
+
export { EmailEvent, EmailEventType, EmailProvider, EmailEventMetadata, EmailAnalytics, ProviderAnalytics, EmailWebhookEventsConfig, ProviderWebhookConfig, NotificationChannel, EmailWebhookResult, WebhookPayload, AnalyticsFilters, EventQuery, EmailWebhookError, EmailWebhookErrorCode } from './types';
|
|
3
|
+
export { EventNormalizer } from './normalizers/EventNormalizer';
|
|
4
|
+
export { SendGridNormalizer } from './normalizers/SendGridNormalizer';
|
|
5
|
+
export { MailgunNormalizer } from './normalizers/MailgunNormalizer';
|
|
6
|
+
export { SESNormalizer } from './normalizers/SESNormalizer';
|
|
7
|
+
export { PostmarkNormalizer } from './normalizers/PostmarkNormalizer';
|
|
8
|
+
export { SMTP2GONormalizer } from './normalizers/SMTP2GONormalizer';
|
|
9
|
+
export { AnalyticsEngine } from './analytics/AnalyticsEngine';
|
|
10
|
+
export { PersistenceAdapter } from './persistence/PersistenceAdapter';
|
|
11
|
+
export { InMemoryPersistenceAdapter } from './persistence/InMemoryPersistenceAdapter';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,EACL,UAAU,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.InMemoryPersistenceAdapter = exports.AnalyticsEngine = exports.SMTP2GONormalizer = exports.PostmarkNormalizer = exports.SESNormalizer = exports.MailgunNormalizer = exports.SendGridNormalizer = exports.EmailWebhookErrorCode = exports.EmailProvider = exports.EmailEventType = exports.EmailWebhookEventsService = void 0;
|
|
11
|
+
var EmailWebhookEventsService_1 = require("./EmailWebhookEventsService");
|
|
12
|
+
Object.defineProperty(exports, "EmailWebhookEventsService", { enumerable: true, get: function () { return EmailWebhookEventsService_1.EmailWebhookEventsService; } });
|
|
13
|
+
var types_1 = require("./types");
|
|
14
|
+
Object.defineProperty(exports, "EmailEventType", { enumerable: true, get: function () { return types_1.EmailEventType; } });
|
|
15
|
+
Object.defineProperty(exports, "EmailProvider", { enumerable: true, get: function () { return types_1.EmailProvider; } });
|
|
16
|
+
Object.defineProperty(exports, "EmailWebhookErrorCode", { enumerable: true, get: function () { return types_1.EmailWebhookErrorCode; } });
|
|
17
|
+
var SendGridNormalizer_1 = require("./normalizers/SendGridNormalizer");
|
|
18
|
+
Object.defineProperty(exports, "SendGridNormalizer", { enumerable: true, get: function () { return SendGridNormalizer_1.SendGridNormalizer; } });
|
|
19
|
+
var MailgunNormalizer_1 = require("./normalizers/MailgunNormalizer");
|
|
20
|
+
Object.defineProperty(exports, "MailgunNormalizer", { enumerable: true, get: function () { return MailgunNormalizer_1.MailgunNormalizer; } });
|
|
21
|
+
var SESNormalizer_1 = require("./normalizers/SESNormalizer");
|
|
22
|
+
Object.defineProperty(exports, "SESNormalizer", { enumerable: true, get: function () { return SESNormalizer_1.SESNormalizer; } });
|
|
23
|
+
var PostmarkNormalizer_1 = require("./normalizers/PostmarkNormalizer");
|
|
24
|
+
Object.defineProperty(exports, "PostmarkNormalizer", { enumerable: true, get: function () { return PostmarkNormalizer_1.PostmarkNormalizer; } });
|
|
25
|
+
var SMTP2GONormalizer_1 = require("./normalizers/SMTP2GONormalizer");
|
|
26
|
+
Object.defineProperty(exports, "SMTP2GONormalizer", { enumerable: true, get: function () { return SMTP2GONormalizer_1.SMTP2GONormalizer; } });
|
|
27
|
+
var AnalyticsEngine_1 = require("./analytics/AnalyticsEngine");
|
|
28
|
+
Object.defineProperty(exports, "AnalyticsEngine", { enumerable: true, get: function () { return AnalyticsEngine_1.AnalyticsEngine; } });
|
|
29
|
+
var InMemoryPersistenceAdapter_1 = require("./persistence/InMemoryPersistenceAdapter");
|
|
30
|
+
Object.defineProperty(exports, "InMemoryPersistenceAdapter", { enumerable: true, get: function () { return InMemoryPersistenceAdapter_1.InMemoryPersistenceAdapter; } });
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;EAME;;;AAEF,yEAAwE;AAA/D,sIAAA,yBAAyB,OAAA;AAElC,iCAgBiB;AAdf,uGAAA,cAAc,OAAA;AACd,sGAAA,aAAa,OAAA;AAYb,8GAAA,qBAAqB,OAAA;AAIvB,uEAAsE;AAA7D,wHAAA,kBAAkB,OAAA;AAC3B,qEAAoE;AAA3D,sHAAA,iBAAiB,OAAA;AAC1B,6DAA4D;AAAnD,8GAAA,aAAa,OAAA;AACtB,uEAAsE;AAA7D,wHAAA,kBAAkB,OAAA;AAC3B,qEAAoE;AAA3D,sHAAA,iBAAiB,OAAA;AAE1B,+DAA8D;AAArD,kHAAA,eAAe,OAAA;AAGxB,uFAAsF;AAA7E,wIAAA,0BAA0B,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventNormalizer.d.ts","sourceRoot":"","sources":["../../src/normalizers/EventNormalizer.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,UAAU,CAAC;CAChD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
//# sourceMappingURL=EventNormalizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventNormalizer.js","sourceRoot":"","sources":["../../src/normalizers/EventNormalizer.ts"],"names":[],"mappings":";AAAA;;;;;;EAME"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { EventNormalizer } from './EventNormalizer';
|
|
2
|
+
import { EmailEvent, WebhookPayload } from '../types';
|
|
3
|
+
export declare class MailgunNormalizer implements EventNormalizer {
|
|
4
|
+
normalize(webhook: WebhookPayload): EmailEvent;
|
|
5
|
+
private mapEventType;
|
|
6
|
+
private generateEventId;
|
|
7
|
+
private detectDeviceType;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=MailgunNormalizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MailgunNormalizer.d.ts","sourceRoot":"","sources":["../../src/normalizers/MailgunNormalizer.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAiC,cAAc,EAAE,MAAM,UAAU,CAAC;AAErF,qBAAa,iBAAkB,YAAW,eAAe;IACvD,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,UAAU;IAmC9C,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,gBAAgB;CAOzB"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.MailgunNormalizer = void 0;
|
|
11
|
+
const types_1 = require("../types");
|
|
12
|
+
class MailgunNormalizer {
|
|
13
|
+
normalize(webhook) {
|
|
14
|
+
const payload = webhook.payload;
|
|
15
|
+
const event = payload['event-data'];
|
|
16
|
+
const message = event.message || {};
|
|
17
|
+
const headers = message.headers || {};
|
|
18
|
+
const deliveryStatus = event['delivery-status'];
|
|
19
|
+
const clientInfo = event['client-info'];
|
|
20
|
+
const geolocation = event.geolocation;
|
|
21
|
+
return {
|
|
22
|
+
id: this.generateEventId(event),
|
|
23
|
+
emailId: headers['message-id'] || '',
|
|
24
|
+
messageId: event.id || '',
|
|
25
|
+
type: this.mapEventType(event.event),
|
|
26
|
+
recipient: event.recipient || '',
|
|
27
|
+
timestamp: new Date(event.timestamp * 1000),
|
|
28
|
+
provider: types_1.EmailProvider.MAILGUN,
|
|
29
|
+
metadata: {
|
|
30
|
+
url: event.url,
|
|
31
|
+
bounceType: event.severity === 'permanent' ? 'hard' : 'soft',
|
|
32
|
+
bounceReason: deliveryStatus?.message,
|
|
33
|
+
bounceCode: deliveryStatus?.code?.toString(),
|
|
34
|
+
ipAddress: clientInfo?.['client-ip'],
|
|
35
|
+
userAgent: clientInfo?.['user-agent'],
|
|
36
|
+
deviceType: this.detectDeviceType(clientInfo?.['user-agent']),
|
|
37
|
+
location: {
|
|
38
|
+
country: geolocation?.country,
|
|
39
|
+
region: geolocation?.region,
|
|
40
|
+
city: geolocation?.city
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
rawEvent: event
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
mapEventType(mailgunEvent) {
|
|
47
|
+
const mapping = {
|
|
48
|
+
'delivered': types_1.EmailEventType.DELIVERED,
|
|
49
|
+
'opened': types_1.EmailEventType.OPENED,
|
|
50
|
+
'clicked': types_1.EmailEventType.CLICKED,
|
|
51
|
+
'bounced': types_1.EmailEventType.BOUNCED,
|
|
52
|
+
'complained': types_1.EmailEventType.COMPLAINED,
|
|
53
|
+
'unsubscribed': types_1.EmailEventType.UNSUBSCRIBED,
|
|
54
|
+
'failed': types_1.EmailEventType.FAILED
|
|
55
|
+
};
|
|
56
|
+
return mapping[mailgunEvent] || types_1.EmailEventType.FAILED;
|
|
57
|
+
}
|
|
58
|
+
generateEventId(event) {
|
|
59
|
+
return `mailgun-${event.id}`;
|
|
60
|
+
}
|
|
61
|
+
detectDeviceType(userAgent) {
|
|
62
|
+
if (!userAgent)
|
|
63
|
+
return 'unknown';
|
|
64
|
+
const ua = userAgent.toLowerCase();
|
|
65
|
+
if (ua.includes('mobile'))
|
|
66
|
+
return 'mobile';
|
|
67
|
+
if (ua.includes('tablet') || ua.includes('ipad'))
|
|
68
|
+
return 'tablet';
|
|
69
|
+
return 'desktop';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.MailgunNormalizer = MailgunNormalizer;
|
|
73
|
+
//# sourceMappingURL=MailgunNormalizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MailgunNormalizer.js","sourceRoot":"","sources":["../../src/normalizers/MailgunNormalizer.ts"],"names":[],"mappings":"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"}
|