pingram 1.0.10-alpha.1159 → 1.0.10-alpha.1160
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/dist/generate-client.js +1 -1
- package/dist/generated/src/models/EventsWebhookResponse.d.ts +7 -0
- package/dist/generated/src/models/EventsWebhookResponse.js +7 -2
- package/dist/generated/src/models/EventsWebhookUpsertRequest.d.ts +1 -0
- package/dist/generated/src/models/EventsWebhookUpsertRequest.js +1 -0
- package/dist/generated/src/models/LogsGetResponseLogsInner.d.ts +60 -0
- package/dist/generated/src/models/LogsGetResponseLogsInner.js +38 -0
- package/dist/generated/src/models/WebhookEvent.d.ts +105 -0
- package/dist/generated/src/models/WebhookEvent.js +103 -0
- package/dist/generated/src/models/index.d.ts +1 -0
- package/dist/generated/src/models/index.js +1 -0
- package/dist/package.json +11 -1
- package/dist/src/webhooks.d.ts +86 -0
- package/dist/src/webhooks.js +137 -0
- package/package.json +11 -1
package/dist/generate-client.js
CHANGED
|
@@ -33,6 +33,12 @@ export interface EventsWebhookResponse {
|
|
|
33
33
|
* @memberof EventsWebhookResponse
|
|
34
34
|
*/
|
|
35
35
|
events: Array<EventsWebhookResponseEventsEnum>;
|
|
36
|
+
/**
|
|
37
|
+
* HMAC secret for verifying webhook signatures. Use this with your X-Pingram-Signature verification.
|
|
38
|
+
* @type {string}
|
|
39
|
+
* @memberof EventsWebhookResponse
|
|
40
|
+
*/
|
|
41
|
+
secret: string;
|
|
36
42
|
}
|
|
37
43
|
/**
|
|
38
44
|
* @export
|
|
@@ -50,6 +56,7 @@ export declare enum EventsWebhookResponseEventsEnum {
|
|
|
50
56
|
SMS_DELIVERED = "SMS_DELIVERED",
|
|
51
57
|
SMS_FAILED = "SMS_FAILED",
|
|
52
58
|
SMS_UNSUBSCRIBE = "SMS_UNSUBSCRIBE",
|
|
59
|
+
SMS_SUBSCRIBE = "SMS_SUBSCRIBE",
|
|
53
60
|
SMS_INBOUND = "SMS_INBOUND",
|
|
54
61
|
PUSH_FAILED = "PUSH_FAILED",
|
|
55
62
|
PUSH_UNSUBSCRIBE = "PUSH_UNSUBSCRIBE",
|
|
@@ -36,6 +36,7 @@ var EventsWebhookResponseEventsEnum;
|
|
|
36
36
|
EventsWebhookResponseEventsEnum["SMS_DELIVERED"] = "SMS_DELIVERED";
|
|
37
37
|
EventsWebhookResponseEventsEnum["SMS_FAILED"] = "SMS_FAILED";
|
|
38
38
|
EventsWebhookResponseEventsEnum["SMS_UNSUBSCRIBE"] = "SMS_UNSUBSCRIBE";
|
|
39
|
+
EventsWebhookResponseEventsEnum["SMS_SUBSCRIBE"] = "SMS_SUBSCRIBE";
|
|
39
40
|
EventsWebhookResponseEventsEnum["SMS_INBOUND"] = "SMS_INBOUND";
|
|
40
41
|
EventsWebhookResponseEventsEnum["PUSH_FAILED"] = "PUSH_FAILED";
|
|
41
42
|
EventsWebhookResponseEventsEnum["PUSH_UNSUBSCRIBE"] = "PUSH_UNSUBSCRIBE";
|
|
@@ -57,6 +58,8 @@ function instanceOfEventsWebhookResponse(value) {
|
|
|
57
58
|
return false;
|
|
58
59
|
if (!('events' in value) || value['events'] === undefined)
|
|
59
60
|
return false;
|
|
61
|
+
if (!('secret' in value) || value['secret'] === undefined)
|
|
62
|
+
return false;
|
|
60
63
|
return true;
|
|
61
64
|
}
|
|
62
65
|
function EventsWebhookResponseFromJSON(json) {
|
|
@@ -69,7 +72,8 @@ function EventsWebhookResponseFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
69
72
|
return {
|
|
70
73
|
webhookId: json['webhookId'],
|
|
71
74
|
webhook: json['webhook'],
|
|
72
|
-
events: json['events']
|
|
75
|
+
events: json['events'],
|
|
76
|
+
secret: json['secret']
|
|
73
77
|
};
|
|
74
78
|
}
|
|
75
79
|
function EventsWebhookResponseToJSON(json) {
|
|
@@ -82,6 +86,7 @@ function EventsWebhookResponseToJSONTyped(value, ignoreDiscriminator = false) {
|
|
|
82
86
|
return {
|
|
83
87
|
webhookId: value['webhookId'],
|
|
84
88
|
webhook: value['webhook'],
|
|
85
|
-
events: value['events']
|
|
89
|
+
events: value['events'],
|
|
90
|
+
secret: value['secret']
|
|
86
91
|
};
|
|
87
92
|
}
|
|
@@ -44,6 +44,7 @@ export declare enum EventsWebhookUpsertRequestEventsEnum {
|
|
|
44
44
|
SMS_DELIVERED = "SMS_DELIVERED",
|
|
45
45
|
SMS_FAILED = "SMS_FAILED",
|
|
46
46
|
SMS_UNSUBSCRIBE = "SMS_UNSUBSCRIBE",
|
|
47
|
+
SMS_SUBSCRIBE = "SMS_SUBSCRIBE",
|
|
47
48
|
SMS_INBOUND = "SMS_INBOUND",
|
|
48
49
|
PUSH_FAILED = "PUSH_FAILED",
|
|
49
50
|
PUSH_UNSUBSCRIBE = "PUSH_UNSUBSCRIBE",
|
|
@@ -36,6 +36,7 @@ var EventsWebhookUpsertRequestEventsEnum;
|
|
|
36
36
|
EventsWebhookUpsertRequestEventsEnum["SMS_DELIVERED"] = "SMS_DELIVERED";
|
|
37
37
|
EventsWebhookUpsertRequestEventsEnum["SMS_FAILED"] = "SMS_FAILED";
|
|
38
38
|
EventsWebhookUpsertRequestEventsEnum["SMS_UNSUBSCRIBE"] = "SMS_UNSUBSCRIBE";
|
|
39
|
+
EventsWebhookUpsertRequestEventsEnum["SMS_SUBSCRIBE"] = "SMS_SUBSCRIBE";
|
|
39
40
|
EventsWebhookUpsertRequestEventsEnum["SMS_INBOUND"] = "SMS_INBOUND";
|
|
40
41
|
EventsWebhookUpsertRequestEventsEnum["PUSH_FAILED"] = "PUSH_FAILED";
|
|
41
42
|
EventsWebhookUpsertRequestEventsEnum["PUSH_UNSUBSCRIBE"] = "PUSH_UNSUBSCRIBE";
|
|
@@ -519,6 +519,66 @@ export interface LogsGetResponseLogsInner {
|
|
|
519
519
|
* @memberof LogsGetResponseLogsInner
|
|
520
520
|
*/
|
|
521
521
|
sms_replied_encoding?: string;
|
|
522
|
+
/**
|
|
523
|
+
*
|
|
524
|
+
* @type {string}
|
|
525
|
+
* @memberof LogsGetResponseLogsInner
|
|
526
|
+
*/
|
|
527
|
+
sms_unsubscribe_at?: string;
|
|
528
|
+
/**
|
|
529
|
+
*
|
|
530
|
+
* @type {string}
|
|
531
|
+
* @memberof LogsGetResponseLogsInner
|
|
532
|
+
*/
|
|
533
|
+
sms_unsubscribe_from?: string;
|
|
534
|
+
/**
|
|
535
|
+
*
|
|
536
|
+
* @type {string}
|
|
537
|
+
* @memberof LogsGetResponseLogsInner
|
|
538
|
+
*/
|
|
539
|
+
sms_unsubscribe_keyword?: string;
|
|
540
|
+
/**
|
|
541
|
+
*
|
|
542
|
+
* @type {boolean}
|
|
543
|
+
* @memberof LogsGetResponseLogsInner
|
|
544
|
+
*/
|
|
545
|
+
sms_unsubscribe_webhook_delivered?: boolean;
|
|
546
|
+
/**
|
|
547
|
+
*
|
|
548
|
+
* @type {string}
|
|
549
|
+
* @memberof LogsGetResponseLogsInner
|
|
550
|
+
*/
|
|
551
|
+
sms_unsubscribe_webhook_res?: string;
|
|
552
|
+
/**
|
|
553
|
+
*
|
|
554
|
+
* @type {string}
|
|
555
|
+
* @memberof LogsGetResponseLogsInner
|
|
556
|
+
*/
|
|
557
|
+
sms_subscribe_at?: string;
|
|
558
|
+
/**
|
|
559
|
+
*
|
|
560
|
+
* @type {string}
|
|
561
|
+
* @memberof LogsGetResponseLogsInner
|
|
562
|
+
*/
|
|
563
|
+
sms_subscribe_from?: string;
|
|
564
|
+
/**
|
|
565
|
+
*
|
|
566
|
+
* @type {string}
|
|
567
|
+
* @memberof LogsGetResponseLogsInner
|
|
568
|
+
*/
|
|
569
|
+
sms_subscribe_keyword?: string;
|
|
570
|
+
/**
|
|
571
|
+
*
|
|
572
|
+
* @type {boolean}
|
|
573
|
+
* @memberof LogsGetResponseLogsInner
|
|
574
|
+
*/
|
|
575
|
+
sms_subscribe_webhook_delivered?: boolean;
|
|
576
|
+
/**
|
|
577
|
+
*
|
|
578
|
+
* @type {string}
|
|
579
|
+
* @memberof LogsGetResponseLogsInner
|
|
580
|
+
*/
|
|
581
|
+
sms_subscribe_webhook_res?: string;
|
|
522
582
|
/**
|
|
523
583
|
*
|
|
524
584
|
* @type {string}
|
|
@@ -581,6 +581,34 @@ function LogsGetResponseLogsInnerFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
581
581
|
sms_replied_encoding: json['sms_replied_encoding'] == null
|
|
582
582
|
? undefined
|
|
583
583
|
: json['sms_replied_encoding'],
|
|
584
|
+
sms_unsubscribe_at: json['sms_unsubscribe_at'] == null
|
|
585
|
+
? undefined
|
|
586
|
+
: json['sms_unsubscribe_at'],
|
|
587
|
+
sms_unsubscribe_from: json['sms_unsubscribe_from'] == null
|
|
588
|
+
? undefined
|
|
589
|
+
: json['sms_unsubscribe_from'],
|
|
590
|
+
sms_unsubscribe_keyword: json['sms_unsubscribe_keyword'] == null
|
|
591
|
+
? undefined
|
|
592
|
+
: json['sms_unsubscribe_keyword'],
|
|
593
|
+
sms_unsubscribe_webhook_delivered: json['sms_unsubscribe_webhook_delivered'] == null
|
|
594
|
+
? undefined
|
|
595
|
+
: json['sms_unsubscribe_webhook_delivered'],
|
|
596
|
+
sms_unsubscribe_webhook_res: json['sms_unsubscribe_webhook_res'] == null
|
|
597
|
+
? undefined
|
|
598
|
+
: json['sms_unsubscribe_webhook_res'],
|
|
599
|
+
sms_subscribe_at: json['sms_subscribe_at'] == null ? undefined : json['sms_subscribe_at'],
|
|
600
|
+
sms_subscribe_from: json['sms_subscribe_from'] == null
|
|
601
|
+
? undefined
|
|
602
|
+
: json['sms_subscribe_from'],
|
|
603
|
+
sms_subscribe_keyword: json['sms_subscribe_keyword'] == null
|
|
604
|
+
? undefined
|
|
605
|
+
: json['sms_subscribe_keyword'],
|
|
606
|
+
sms_subscribe_webhook_delivered: json['sms_subscribe_webhook_delivered'] == null
|
|
607
|
+
? undefined
|
|
608
|
+
: json['sms_subscribe_webhook_delivered'],
|
|
609
|
+
sms_subscribe_webhook_res: json['sms_subscribe_webhook_res'] == null
|
|
610
|
+
? undefined
|
|
611
|
+
: json['sms_subscribe_webhook_res'],
|
|
584
612
|
web_push_sent_token: json['web_push_sent_token'] == null
|
|
585
613
|
? undefined
|
|
586
614
|
: json['web_push_sent_token'],
|
|
@@ -831,6 +859,16 @@ function LogsGetResponseLogsInnerToJSONTyped(value, ignoreDiscriminator = false)
|
|
|
831
859
|
sms_replied_text: value['sms_replied_text'],
|
|
832
860
|
sms_replied_segments: value['sms_replied_segments'],
|
|
833
861
|
sms_replied_encoding: value['sms_replied_encoding'],
|
|
862
|
+
sms_unsubscribe_at: value['sms_unsubscribe_at'],
|
|
863
|
+
sms_unsubscribe_from: value['sms_unsubscribe_from'],
|
|
864
|
+
sms_unsubscribe_keyword: value['sms_unsubscribe_keyword'],
|
|
865
|
+
sms_unsubscribe_webhook_delivered: value['sms_unsubscribe_webhook_delivered'],
|
|
866
|
+
sms_unsubscribe_webhook_res: value['sms_unsubscribe_webhook_res'],
|
|
867
|
+
sms_subscribe_at: value['sms_subscribe_at'],
|
|
868
|
+
sms_subscribe_from: value['sms_subscribe_from'],
|
|
869
|
+
sms_subscribe_keyword: value['sms_subscribe_keyword'],
|
|
870
|
+
sms_subscribe_webhook_delivered: value['sms_subscribe_webhook_delivered'],
|
|
871
|
+
sms_subscribe_webhook_res: value['sms_subscribe_webhook_res'],
|
|
834
872
|
web_push_sent_token: value['web_push_sent_token'],
|
|
835
873
|
web_push_sent_at: value['web_push_sent_at'],
|
|
836
874
|
web_push_sent_after: value['web_push_sent_after'],
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pingram
|
|
3
|
+
* Internal API for notification delivery and management
|
|
4
|
+
*
|
|
5
|
+
* The version of the OpenAPI document: 1.0.0
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
|
9
|
+
* https://openapi-generator.tech
|
|
10
|
+
* Do not edit the class manually.
|
|
11
|
+
*/
|
|
12
|
+
import type { ChannelsEnum } from './ChannelsEnum';
|
|
13
|
+
/**
|
|
14
|
+
* Webhook event payload sent to customer endpoints. Use this type with SDK webhook verification methods (e.g., verify from 'pingram/webhooks').
|
|
15
|
+
* @export
|
|
16
|
+
* @interface WebhookEvent
|
|
17
|
+
*/
|
|
18
|
+
export interface WebhookEvent {
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @type {string}
|
|
22
|
+
* @memberof WebhookEvent
|
|
23
|
+
*/
|
|
24
|
+
eventType: WebhookEventEventTypeEnum;
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @type {ChannelsEnum}
|
|
28
|
+
* @memberof WebhookEvent
|
|
29
|
+
*/
|
|
30
|
+
channel: ChannelsEnum;
|
|
31
|
+
/**
|
|
32
|
+
* User ID the notification was sent to.
|
|
33
|
+
* @type {string}
|
|
34
|
+
* @memberof WebhookEvent
|
|
35
|
+
*/
|
|
36
|
+
userId: string;
|
|
37
|
+
/**
|
|
38
|
+
* Notification type ID.
|
|
39
|
+
* @type {string}
|
|
40
|
+
* @memberof WebhookEvent
|
|
41
|
+
*/
|
|
42
|
+
notificationId: string;
|
|
43
|
+
/**
|
|
44
|
+
* Unique tracking ID for this notification instance.
|
|
45
|
+
* @type {string}
|
|
46
|
+
* @memberof WebhookEvent
|
|
47
|
+
*/
|
|
48
|
+
trackingId: string;
|
|
49
|
+
/**
|
|
50
|
+
* Failure code for *_FAILED events.
|
|
51
|
+
* @type {string}
|
|
52
|
+
* @memberof WebhookEvent
|
|
53
|
+
*/
|
|
54
|
+
failureCode?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Clicked URL for EMAIL_CLICK events.
|
|
57
|
+
* @type {string}
|
|
58
|
+
* @memberof WebhookEvent
|
|
59
|
+
*/
|
|
60
|
+
clickedLink?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Link tags for EMAIL_CLICK events.
|
|
63
|
+
* @type {{ [key: string]: Array<string>; }}
|
|
64
|
+
* @memberof WebhookEvent
|
|
65
|
+
*/
|
|
66
|
+
clickedLinkTags?: {
|
|
67
|
+
[key: string]: Array<string>;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* @export
|
|
72
|
+
* @enum {string}
|
|
73
|
+
*/
|
|
74
|
+
export declare enum WebhookEventEventTypeEnum {
|
|
75
|
+
EMAIL_OPEN = "EMAIL_OPEN",
|
|
76
|
+
EMAIL_CLICK = "EMAIL_CLICK",
|
|
77
|
+
EMAIL_FAILED = "EMAIL_FAILED",
|
|
78
|
+
EMAIL_DELIVERED = "EMAIL_DELIVERED",
|
|
79
|
+
EMAIL_UNSUBSCRIBE = "EMAIL_UNSUBSCRIBE",
|
|
80
|
+
EMAIL_INBOUND = "EMAIL_INBOUND",
|
|
81
|
+
INAPP_WEB_FAILED = "INAPP_WEB_FAILED",
|
|
82
|
+
INAPP_WEB_UNSUBSCRIBE = "INAPP_WEB_UNSUBSCRIBE",
|
|
83
|
+
SMS_DELIVERED = "SMS_DELIVERED",
|
|
84
|
+
SMS_FAILED = "SMS_FAILED",
|
|
85
|
+
SMS_UNSUBSCRIBE = "SMS_UNSUBSCRIBE",
|
|
86
|
+
SMS_SUBSCRIBE = "SMS_SUBSCRIBE",
|
|
87
|
+
SMS_INBOUND = "SMS_INBOUND",
|
|
88
|
+
PUSH_FAILED = "PUSH_FAILED",
|
|
89
|
+
PUSH_UNSUBSCRIBE = "PUSH_UNSUBSCRIBE",
|
|
90
|
+
CALL_FAILED = "CALL_FAILED",
|
|
91
|
+
CALL_UNSUBSCRIBE = "CALL_UNSUBSCRIBE",
|
|
92
|
+
WEB_PUSH_FAILED = "WEB_PUSH_FAILED",
|
|
93
|
+
WEB_PUSH_UNSUBSCRIBE = "WEB_PUSH_UNSUBSCRIBE",
|
|
94
|
+
SLACK_FAILED = "SLACK_FAILED",
|
|
95
|
+
SLACK_UNSUBSCRIBE = "SLACK_UNSUBSCRIBE",
|
|
96
|
+
VOICE_INBOUND = "VOICE_INBOUND"
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check if a given object implements the WebhookEvent interface.
|
|
100
|
+
*/
|
|
101
|
+
export declare function instanceOfWebhookEvent(value: object): value is WebhookEvent;
|
|
102
|
+
export declare function WebhookEventFromJSON(json: any): WebhookEvent;
|
|
103
|
+
export declare function WebhookEventFromJSONTyped(json: any, ignoreDiscriminator: boolean): WebhookEvent;
|
|
104
|
+
export declare function WebhookEventToJSON(json: any): WebhookEvent;
|
|
105
|
+
export declare function WebhookEventToJSONTyped(value?: WebhookEvent | null, ignoreDiscriminator?: boolean): any;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* tslint:disable */
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
/**
|
|
5
|
+
* Pingram
|
|
6
|
+
* Internal API for notification delivery and management
|
|
7
|
+
*
|
|
8
|
+
* The version of the OpenAPI document: 1.0.0
|
|
9
|
+
*
|
|
10
|
+
*
|
|
11
|
+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
|
12
|
+
* https://openapi-generator.tech
|
|
13
|
+
* Do not edit the class manually.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.WebhookEventEventTypeEnum = void 0;
|
|
17
|
+
exports.instanceOfWebhookEvent = instanceOfWebhookEvent;
|
|
18
|
+
exports.WebhookEventFromJSON = WebhookEventFromJSON;
|
|
19
|
+
exports.WebhookEventFromJSONTyped = WebhookEventFromJSONTyped;
|
|
20
|
+
exports.WebhookEventToJSON = WebhookEventToJSON;
|
|
21
|
+
exports.WebhookEventToJSONTyped = WebhookEventToJSONTyped;
|
|
22
|
+
const ChannelsEnum_1 = require("./ChannelsEnum");
|
|
23
|
+
/**
|
|
24
|
+
* @export
|
|
25
|
+
* @enum {string}
|
|
26
|
+
*/
|
|
27
|
+
var WebhookEventEventTypeEnum;
|
|
28
|
+
(function (WebhookEventEventTypeEnum) {
|
|
29
|
+
WebhookEventEventTypeEnum["EMAIL_OPEN"] = "EMAIL_OPEN";
|
|
30
|
+
WebhookEventEventTypeEnum["EMAIL_CLICK"] = "EMAIL_CLICK";
|
|
31
|
+
WebhookEventEventTypeEnum["EMAIL_FAILED"] = "EMAIL_FAILED";
|
|
32
|
+
WebhookEventEventTypeEnum["EMAIL_DELIVERED"] = "EMAIL_DELIVERED";
|
|
33
|
+
WebhookEventEventTypeEnum["EMAIL_UNSUBSCRIBE"] = "EMAIL_UNSUBSCRIBE";
|
|
34
|
+
WebhookEventEventTypeEnum["EMAIL_INBOUND"] = "EMAIL_INBOUND";
|
|
35
|
+
WebhookEventEventTypeEnum["INAPP_WEB_FAILED"] = "INAPP_WEB_FAILED";
|
|
36
|
+
WebhookEventEventTypeEnum["INAPP_WEB_UNSUBSCRIBE"] = "INAPP_WEB_UNSUBSCRIBE";
|
|
37
|
+
WebhookEventEventTypeEnum["SMS_DELIVERED"] = "SMS_DELIVERED";
|
|
38
|
+
WebhookEventEventTypeEnum["SMS_FAILED"] = "SMS_FAILED";
|
|
39
|
+
WebhookEventEventTypeEnum["SMS_UNSUBSCRIBE"] = "SMS_UNSUBSCRIBE";
|
|
40
|
+
WebhookEventEventTypeEnum["SMS_SUBSCRIBE"] = "SMS_SUBSCRIBE";
|
|
41
|
+
WebhookEventEventTypeEnum["SMS_INBOUND"] = "SMS_INBOUND";
|
|
42
|
+
WebhookEventEventTypeEnum["PUSH_FAILED"] = "PUSH_FAILED";
|
|
43
|
+
WebhookEventEventTypeEnum["PUSH_UNSUBSCRIBE"] = "PUSH_UNSUBSCRIBE";
|
|
44
|
+
WebhookEventEventTypeEnum["CALL_FAILED"] = "CALL_FAILED";
|
|
45
|
+
WebhookEventEventTypeEnum["CALL_UNSUBSCRIBE"] = "CALL_UNSUBSCRIBE";
|
|
46
|
+
WebhookEventEventTypeEnum["WEB_PUSH_FAILED"] = "WEB_PUSH_FAILED";
|
|
47
|
+
WebhookEventEventTypeEnum["WEB_PUSH_UNSUBSCRIBE"] = "WEB_PUSH_UNSUBSCRIBE";
|
|
48
|
+
WebhookEventEventTypeEnum["SLACK_FAILED"] = "SLACK_FAILED";
|
|
49
|
+
WebhookEventEventTypeEnum["SLACK_UNSUBSCRIBE"] = "SLACK_UNSUBSCRIBE";
|
|
50
|
+
WebhookEventEventTypeEnum["VOICE_INBOUND"] = "VOICE_INBOUND";
|
|
51
|
+
})(WebhookEventEventTypeEnum || (exports.WebhookEventEventTypeEnum = WebhookEventEventTypeEnum = {}));
|
|
52
|
+
/**
|
|
53
|
+
* Check if a given object implements the WebhookEvent interface.
|
|
54
|
+
*/
|
|
55
|
+
function instanceOfWebhookEvent(value) {
|
|
56
|
+
if (!('eventType' in value) || value['eventType'] === undefined)
|
|
57
|
+
return false;
|
|
58
|
+
if (!('channel' in value) || value['channel'] === undefined)
|
|
59
|
+
return false;
|
|
60
|
+
if (!('userId' in value) || value['userId'] === undefined)
|
|
61
|
+
return false;
|
|
62
|
+
if (!('notificationId' in value) || value['notificationId'] === undefined)
|
|
63
|
+
return false;
|
|
64
|
+
if (!('trackingId' in value) || value['trackingId'] === undefined)
|
|
65
|
+
return false;
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
function WebhookEventFromJSON(json) {
|
|
69
|
+
return WebhookEventFromJSONTyped(json, false);
|
|
70
|
+
}
|
|
71
|
+
function WebhookEventFromJSONTyped(json, ignoreDiscriminator) {
|
|
72
|
+
if (json == null) {
|
|
73
|
+
return json;
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
eventType: json['eventType'],
|
|
77
|
+
channel: (0, ChannelsEnum_1.ChannelsEnumFromJSON)(json['channel']),
|
|
78
|
+
userId: json['userId'],
|
|
79
|
+
notificationId: json['notificationId'],
|
|
80
|
+
trackingId: json['trackingId'],
|
|
81
|
+
failureCode: json['failureCode'] == null ? undefined : json['failureCode'],
|
|
82
|
+
clickedLink: json['clickedLink'] == null ? undefined : json['clickedLink'],
|
|
83
|
+
clickedLinkTags: json['clickedLinkTags'] == null ? undefined : json['clickedLinkTags']
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function WebhookEventToJSON(json) {
|
|
87
|
+
return WebhookEventToJSONTyped(json, false);
|
|
88
|
+
}
|
|
89
|
+
function WebhookEventToJSONTyped(value, ignoreDiscriminator = false) {
|
|
90
|
+
if (value == null) {
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
eventType: value['eventType'],
|
|
95
|
+
channel: (0, ChannelsEnum_1.ChannelsEnumToJSON)(value['channel']),
|
|
96
|
+
userId: value['userId'],
|
|
97
|
+
notificationId: value['notificationId'],
|
|
98
|
+
trackingId: value['trackingId'],
|
|
99
|
+
failureCode: value['failureCode'],
|
|
100
|
+
clickedLink: value['clickedLink'],
|
|
101
|
+
clickedLinkTags: value['clickedLinkTags']
|
|
102
|
+
};
|
|
103
|
+
}
|
|
@@ -216,4 +216,5 @@ __exportStar(require("./TemplatePostRequest"), exports);
|
|
|
216
216
|
__exportStar(require("./UpdateAddressRequest"), exports);
|
|
217
217
|
__exportStar(require("./User"), exports);
|
|
218
218
|
__exportStar(require("./UserSuppressionDeleteResponse"), exports);
|
|
219
|
+
__exportStar(require("./WebhookEvent"), exports);
|
|
219
220
|
__exportStar(require("./WebhookResponse"), exports);
|
package/dist/package.json
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pingram",
|
|
3
|
-
"version": "1.0.10-alpha.
|
|
3
|
+
"version": "1.0.10-alpha.1160",
|
|
4
4
|
"description": "Official Node.js SDK for Pingram - Send notifications via Email, SMS, Push, In-App, and more",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./webhooks": {
|
|
14
|
+
"types": "./dist/src/webhooks.d.ts",
|
|
15
|
+
"default": "./dist/src/webhooks.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
8
18
|
"scripts": {
|
|
9
19
|
"build": "tsc",
|
|
10
20
|
"clean": "rm -rf dist",
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook verification utilities for Pingram webhooks.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* import { verify } from 'pingram/webhooks';
|
|
7
|
+
* import type { WebhookEvent } from 'pingram';
|
|
8
|
+
*
|
|
9
|
+
* const event = verify({
|
|
10
|
+
* payload: await req.text(),
|
|
11
|
+
* headers: {
|
|
12
|
+
* id: req.headers.get('X-Pingram-Id')!,
|
|
13
|
+
* signature: req.headers.get('X-Pingram-Signature')!,
|
|
14
|
+
* timestamp: req.headers.get('X-Pingram-Timestamp')!,
|
|
15
|
+
* },
|
|
16
|
+
* secret: process.env.PINGRAM_WEBHOOK_SECRET!,
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* if (event.eventType === 'EMAIL_CLICK') {
|
|
20
|
+
* console.log('Clicked:', event.clickedLink);
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
import type { WebhookEvent } from '../generated/src/models/WebhookEvent';
|
|
25
|
+
/**
|
|
26
|
+
* Error thrown when webhook signature verification fails.
|
|
27
|
+
*/
|
|
28
|
+
export declare class WebhookSignatureError extends Error {
|
|
29
|
+
constructor(message: string);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Error thrown when webhook timestamp is outside tolerance.
|
|
33
|
+
*/
|
|
34
|
+
export declare class WebhookTimestampError extends Error {
|
|
35
|
+
constructor(message: string);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Options for verifying a webhook.
|
|
39
|
+
*/
|
|
40
|
+
export interface WebhookVerifyOptions {
|
|
41
|
+
/** Raw request body as string or Buffer */
|
|
42
|
+
payload: string | Buffer;
|
|
43
|
+
/** Headers from the webhook request */
|
|
44
|
+
headers: {
|
|
45
|
+
/** X-Pingram-Id header value */
|
|
46
|
+
id: string;
|
|
47
|
+
/** X-Pingram-Signature header value */
|
|
48
|
+
signature: string;
|
|
49
|
+
/** X-Pingram-Timestamp header value */
|
|
50
|
+
timestamp: string;
|
|
51
|
+
};
|
|
52
|
+
/** Webhook secret from your Pingram dashboard */
|
|
53
|
+
secret: string;
|
|
54
|
+
/** Maximum age of webhook in seconds (default: 300 = 5 minutes) */
|
|
55
|
+
tolerance?: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Verify webhook signature and return the parsed event.
|
|
59
|
+
*
|
|
60
|
+
* @param options - Verification options
|
|
61
|
+
* @returns Parsed webhook event
|
|
62
|
+
* @throws WebhookSignatureError if signature is invalid
|
|
63
|
+
* @throws WebhookTimestampError if timestamp is outside tolerance
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const event = verify({
|
|
68
|
+
* payload: await req.text(),
|
|
69
|
+
* headers: {
|
|
70
|
+
* id: req.headers.get('X-Pingram-Id')!,
|
|
71
|
+
* signature: req.headers.get('X-Pingram-Signature')!,
|
|
72
|
+
* timestamp: req.headers.get('X-Pingram-Timestamp')!,
|
|
73
|
+
* },
|
|
74
|
+
* secret: process.env.PINGRAM_WEBHOOK_SECRET!,
|
|
75
|
+
* });
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare function verify(options: WebhookVerifyOptions): WebhookEvent;
|
|
79
|
+
/**
|
|
80
|
+
* Webhooks helper object exporting all verification utilities.
|
|
81
|
+
*/
|
|
82
|
+
export declare const webhooks: {
|
|
83
|
+
verify: typeof verify;
|
|
84
|
+
WebhookSignatureError: typeof WebhookSignatureError;
|
|
85
|
+
WebhookTimestampError: typeof WebhookTimestampError;
|
|
86
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Webhook verification utilities for Pingram webhooks.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import { verify } from 'pingram/webhooks';
|
|
8
|
+
* import type { WebhookEvent } from 'pingram';
|
|
9
|
+
*
|
|
10
|
+
* const event = verify({
|
|
11
|
+
* payload: await req.text(),
|
|
12
|
+
* headers: {
|
|
13
|
+
* id: req.headers.get('X-Pingram-Id')!,
|
|
14
|
+
* signature: req.headers.get('X-Pingram-Signature')!,
|
|
15
|
+
* timestamp: req.headers.get('X-Pingram-Timestamp')!,
|
|
16
|
+
* },
|
|
17
|
+
* secret: process.env.PINGRAM_WEBHOOK_SECRET!,
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* if (event.eventType === 'EMAIL_CLICK') {
|
|
21
|
+
* console.log('Clicked:', event.clickedLink);
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.webhooks = exports.WebhookTimestampError = exports.WebhookSignatureError = void 0;
|
|
27
|
+
exports.verify = verify;
|
|
28
|
+
const crypto_1 = require("crypto");
|
|
29
|
+
/**
|
|
30
|
+
* Error thrown when webhook signature verification fails.
|
|
31
|
+
*/
|
|
32
|
+
class WebhookSignatureError extends Error {
|
|
33
|
+
constructor(message) {
|
|
34
|
+
super(message);
|
|
35
|
+
this.name = 'WebhookSignatureError';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.WebhookSignatureError = WebhookSignatureError;
|
|
39
|
+
/**
|
|
40
|
+
* Error thrown when webhook timestamp is outside tolerance.
|
|
41
|
+
*/
|
|
42
|
+
class WebhookTimestampError extends Error {
|
|
43
|
+
constructor(message) {
|
|
44
|
+
super(message);
|
|
45
|
+
this.name = 'WebhookTimestampError';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.WebhookTimestampError = WebhookTimestampError;
|
|
49
|
+
/**
|
|
50
|
+
* Default timestamp tolerance in seconds (5 minutes).
|
|
51
|
+
*/
|
|
52
|
+
const DEFAULT_TOLERANCE_SECONDS = 300;
|
|
53
|
+
/**
|
|
54
|
+
* Parse version prefix and signature from the signature header.
|
|
55
|
+
* Format: v1,{hex-signature}
|
|
56
|
+
*/
|
|
57
|
+
function parseSignature(signature) {
|
|
58
|
+
const [version, sig] = signature.split(',', 2);
|
|
59
|
+
if (version !== 'v1' || !sig) {
|
|
60
|
+
throw new WebhookSignatureError('Invalid signature format');
|
|
61
|
+
}
|
|
62
|
+
return sig;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Compute HMAC-SHA256 signature for a payload.
|
|
66
|
+
* Format: HMAC-SHA256(id + "." + timestamp + "." + payload)
|
|
67
|
+
*/
|
|
68
|
+
function computeSignature(payload, secret, timestamp, messageId) {
|
|
69
|
+
const signedPayload = `${messageId}.${timestamp}.${payload}`;
|
|
70
|
+
return (0, crypto_1.createHmac)('sha256', secret).update(signedPayload).digest('hex');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Constant-time string comparison to prevent timing attacks.
|
|
74
|
+
*/
|
|
75
|
+
function secureCompare(a, b) {
|
|
76
|
+
if (a.length !== b.length) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
return (0, crypto_1.timingSafeEqual)(Buffer.from(a), Buffer.from(b));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Verify webhook signature and return the parsed event.
|
|
83
|
+
*
|
|
84
|
+
* @param options - Verification options
|
|
85
|
+
* @returns Parsed webhook event
|
|
86
|
+
* @throws WebhookSignatureError if signature is invalid
|
|
87
|
+
* @throws WebhookTimestampError if timestamp is outside tolerance
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const event = verify({
|
|
92
|
+
* payload: await req.text(),
|
|
93
|
+
* headers: {
|
|
94
|
+
* id: req.headers.get('X-Pingram-Id')!,
|
|
95
|
+
* signature: req.headers.get('X-Pingram-Signature')!,
|
|
96
|
+
* timestamp: req.headers.get('X-Pingram-Timestamp')!,
|
|
97
|
+
* },
|
|
98
|
+
* secret: process.env.PINGRAM_WEBHOOK_SECRET!,
|
|
99
|
+
* });
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
function verify(options) {
|
|
103
|
+
const tolerance = options.tolerance ?? DEFAULT_TOLERANCE_SECONDS;
|
|
104
|
+
const payloadString = typeof options.payload === 'string'
|
|
105
|
+
? options.payload
|
|
106
|
+
: options.payload.toString('utf8');
|
|
107
|
+
const { id: messageId, signature, timestamp } = options.headers;
|
|
108
|
+
const { secret } = options;
|
|
109
|
+
const timestampMs = parseInt(timestamp, 10);
|
|
110
|
+
if (isNaN(timestampMs)) {
|
|
111
|
+
throw new WebhookTimestampError('Invalid timestamp format');
|
|
112
|
+
}
|
|
113
|
+
const now = Date.now();
|
|
114
|
+
const age = Math.abs(now - timestampMs) / 1000;
|
|
115
|
+
if (age > tolerance) {
|
|
116
|
+
throw new WebhookTimestampError(`Webhook timestamp is outside tolerance (${age.toFixed(0)}s > ${tolerance}s)`);
|
|
117
|
+
}
|
|
118
|
+
const rawSignature = parseSignature(signature);
|
|
119
|
+
const expectedSignature = computeSignature(payloadString, secret, timestamp, messageId);
|
|
120
|
+
if (!secureCompare(expectedSignature, rawSignature)) {
|
|
121
|
+
throw new WebhookSignatureError('Invalid webhook signature');
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
return JSON.parse(payloadString);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
throw new WebhookSignatureError('Invalid JSON payload');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Webhooks helper object exporting all verification utilities.
|
|
132
|
+
*/
|
|
133
|
+
exports.webhooks = {
|
|
134
|
+
verify,
|
|
135
|
+
WebhookSignatureError,
|
|
136
|
+
WebhookTimestampError
|
|
137
|
+
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pingram",
|
|
3
|
-
"version": "1.0.10-alpha.
|
|
3
|
+
"version": "1.0.10-alpha.1160",
|
|
4
4
|
"description": "Official Node.js SDK for Pingram - Send notifications via Email, SMS, Push, In-App, and more",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./webhooks": {
|
|
14
|
+
"types": "./dist/src/webhooks.d.ts",
|
|
15
|
+
"default": "./dist/src/webhooks.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
8
18
|
"scripts": {
|
|
9
19
|
"build": "tsc",
|
|
10
20
|
"clean": "rm -rf dist",
|