wingbot 3.68.18 → 3.69.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/package.json +1 -1
- package/src/Request.js +7 -1
- package/src/graphApi/conversationsApi.js +29 -8
- package/src/graphApi/schema.gql +17 -0
- package/src/notifications/Notifications.js +57 -27
- package/src/notifications/NotificationsStorage.js +95 -16
- package/src/notifications/api/notificationsApiFactory.js +82 -0
package/package.json
CHANGED
package/src/Request.js
CHANGED
|
@@ -1541,7 +1541,8 @@ It looks like the bot isn't connected to class BotApp or the Processor is used w
|
|
|
1541
1541
|
campaign,
|
|
1542
1542
|
timestamp = makeTimestamp(),
|
|
1543
1543
|
data = null,
|
|
1544
|
-
taskId = null
|
|
1544
|
+
taskId = null,
|
|
1545
|
+
setState = null
|
|
1545
1546
|
) {
|
|
1546
1547
|
const postback = Request.postBack(
|
|
1547
1548
|
senderId,
|
|
@@ -1551,6 +1552,11 @@ It looks like the bot isn't connected to class BotApp or the Processor is used w
|
|
|
1551
1552
|
{},
|
|
1552
1553
|
timestamp
|
|
1553
1554
|
);
|
|
1555
|
+
|
|
1556
|
+
if (setState) {
|
|
1557
|
+
Object.assign(postback.postback.payload, { setState });
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1554
1560
|
return Object.assign(postback, {
|
|
1555
1561
|
campaign,
|
|
1556
1562
|
taskId
|
|
@@ -7,6 +7,7 @@ const apiAuthorizer = require('./apiAuthorizer');
|
|
|
7
7
|
const { apiTextOutputFilter, mapObject, defaultMapperFactory } = require('../utils/deepMapTools');
|
|
8
8
|
|
|
9
9
|
/** @typedef {import('../utils/deepMapTools').Mapper} Mapper */
|
|
10
|
+
/** @typedef {import('../notifications/Notifications')} Notifications */
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* @typedef {object} ConversationsAPI
|
|
@@ -20,11 +21,6 @@ const { apiTextOutputFilter, mapObject, defaultMapperFactory } = require('../uti
|
|
|
20
21
|
* @prop {Function} getState
|
|
21
22
|
*/
|
|
22
23
|
|
|
23
|
-
/**
|
|
24
|
-
* @typedef {object} Notifications
|
|
25
|
-
* @prop {Function} getSubscribtions
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
24
|
/**
|
|
29
25
|
* @typedef {object} ChatLogStorage
|
|
30
26
|
* @prop {Function} getInteractions
|
|
@@ -92,6 +88,28 @@ function conversationsApi (
|
|
|
92
88
|
return data;
|
|
93
89
|
}
|
|
94
90
|
|
|
91
|
+
async function subscriptions () {
|
|
92
|
+
const { pageId, senderId } = this;
|
|
93
|
+
|
|
94
|
+
if (!notifications) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (typeof notifications.getSubscriptions === 'function') {
|
|
99
|
+
return notifications.getSubscriptions(senderId, pageId);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (typeof notifications.getSubscribtions === 'function') {
|
|
103
|
+
const sups = await notifications.getSubscribtions(senderId, pageId);
|
|
104
|
+
return sups.map((s) => ({
|
|
105
|
+
tag: s,
|
|
106
|
+
meta: {}
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
|
|
95
113
|
async function subscribtions () {
|
|
96
114
|
if (!notifications || typeof notifications.getSubscribtions !== 'function') {
|
|
97
115
|
return null;
|
|
@@ -107,21 +125,24 @@ function conversationsApi (
|
|
|
107
125
|
state: apiTextOutputFilter(d.state, options.stateTextFilter),
|
|
108
126
|
lastInteraction: d.lastInteraction || (new Date(0)),
|
|
109
127
|
history,
|
|
110
|
-
subscribtions
|
|
128
|
+
subscribtions,
|
|
129
|
+
subscriptions
|
|
111
130
|
});
|
|
112
131
|
} else if (options.mapper) {
|
|
113
132
|
mapState = (d) => ({
|
|
114
133
|
...mapObject(d, defaultMapperFactory(options.mapper)),
|
|
115
134
|
lastInteraction: d.lastInteraction || (new Date(0)),
|
|
116
135
|
history,
|
|
117
|
-
subscribtions
|
|
136
|
+
subscribtions,
|
|
137
|
+
subscriptions
|
|
118
138
|
});
|
|
119
139
|
} else {
|
|
120
140
|
mapState = (d) => ({
|
|
121
141
|
...d,
|
|
122
142
|
lastInteraction: d.lastInteraction || (new Date(0)),
|
|
123
143
|
history,
|
|
124
|
-
subscribtions
|
|
144
|
+
subscribtions,
|
|
145
|
+
subscriptions
|
|
125
146
|
});
|
|
126
147
|
}
|
|
127
148
|
|
package/src/graphApi/schema.gql
CHANGED
|
@@ -121,6 +121,11 @@ type UserInteraction {
|
|
|
121
121
|
err: String
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
type Subscription {
|
|
125
|
+
tag: String!
|
|
126
|
+
meta: Any
|
|
127
|
+
}
|
|
128
|
+
|
|
124
129
|
type Conversation {
|
|
125
130
|
senderId: String!
|
|
126
131
|
pageId: String!
|
|
@@ -128,6 +133,7 @@ type Conversation {
|
|
|
128
133
|
name: String
|
|
129
134
|
state: Any!
|
|
130
135
|
subscribtions: [String]
|
|
136
|
+
subscriptions: [Subscription!]
|
|
131
137
|
history (
|
|
132
138
|
limit: Int! = 10
|
|
133
139
|
startTimestamp: Float
|
|
@@ -190,6 +196,14 @@ input CreateCampaignInput {
|
|
|
190
196
|
condition: String
|
|
191
197
|
}
|
|
192
198
|
|
|
199
|
+
input SubscriptionData {
|
|
200
|
+
pageId: String!
|
|
201
|
+
senderId: String!
|
|
202
|
+
tags: [String!]!
|
|
203
|
+
remove: Boolean = false
|
|
204
|
+
meta: Any
|
|
205
|
+
}
|
|
206
|
+
|
|
193
207
|
input UpdateCampaignInput {
|
|
194
208
|
name: String
|
|
195
209
|
action: String
|
|
@@ -303,4 +317,7 @@ type Mutation {
|
|
|
303
317
|
|
|
304
318
|
"subscribe users"
|
|
305
319
|
subscribeUsers(pageId:String!, senderIds:[String!]!, tag: String): Boolean
|
|
320
|
+
|
|
321
|
+
"subscribe with metadata"
|
|
322
|
+
subscribeWithData (subscriptions: [SubscriptionData!]!): Boolean
|
|
306
323
|
}
|
|
@@ -104,25 +104,26 @@ const DEFAULT_CAMPAIGN_DATA = {
|
|
|
104
104
|
*/
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
|
-
* @typedef {object}
|
|
108
|
-
* @prop {string}
|
|
109
|
-
* @prop {
|
|
110
|
-
* @prop {string} [meta]
|
|
107
|
+
* @typedef {object} SenderSubscription
|
|
108
|
+
* @prop {string} tag
|
|
109
|
+
* @prop {object} meta
|
|
111
110
|
*/
|
|
112
111
|
|
|
113
112
|
/**
|
|
114
|
-
* @
|
|
115
|
-
* @
|
|
116
|
-
* @
|
|
117
|
-
* @returns {Promise<Subscription[]>|Subscription[]}
|
|
113
|
+
* @typedef {object} Logger
|
|
114
|
+
* @prop {Function} log
|
|
115
|
+
* @prop {Function} error
|
|
118
116
|
*/
|
|
119
117
|
|
|
118
|
+
/** @typedef {import('./api/notificationsApiFactory').NotificationsApiOptions} ApiOptions */
|
|
119
|
+
|
|
120
120
|
/**
|
|
121
|
-
* @
|
|
122
|
-
* @
|
|
123
|
-
* @
|
|
124
|
-
* @
|
|
125
|
-
*
|
|
121
|
+
* @typedef {object} NotificationsServiceOptions
|
|
122
|
+
* @prop {Logger} [log]
|
|
123
|
+
* @prop {number} [options.default24Clearance] - use this clearance to ensure delivery in 24h
|
|
124
|
+
* @prop {string} [options.allAudienceTag] - tag to mark all users
|
|
125
|
+
*
|
|
126
|
+
* @typedef {ApiOptions & NotificationsServiceOptions} NotificationsOptions
|
|
126
127
|
*/
|
|
127
128
|
|
|
128
129
|
/**
|
|
@@ -139,12 +140,7 @@ class Notifications extends EventEmitter {
|
|
|
139
140
|
* @memberof Notifications
|
|
140
141
|
*
|
|
141
142
|
* @param {NotificationsStorage} notificationStorage
|
|
142
|
-
* @param {
|
|
143
|
-
* @param {console} [options.log] - logger
|
|
144
|
-
* @param {number} [options.default24Clearance] - use this clearance to ensure delivery in 24h
|
|
145
|
-
* @param {string} [options.allAudienceTag] - tag to mark all users
|
|
146
|
-
* @param {PreprocessSubscribers} [options.preprocessSubscribers] - preprocess senderIds import
|
|
147
|
-
* @param {PreprocessSubscriptions} [options.preprocessSubscriptions]
|
|
143
|
+
* @param {NotificationsOptions} options
|
|
148
144
|
*/
|
|
149
145
|
constructor (notificationStorage = new NotificationsStorage(), options = {}) {
|
|
150
146
|
super();
|
|
@@ -407,6 +403,18 @@ class Notifications extends EventEmitter {
|
|
|
407
403
|
return this._storage.getSenderSubscribtions(senderId, pageId);
|
|
408
404
|
}
|
|
409
405
|
|
|
406
|
+
/**
|
|
407
|
+
*
|
|
408
|
+
* Get user subscribtions
|
|
409
|
+
*
|
|
410
|
+
* @param {string} senderId
|
|
411
|
+
* @param {string} pageId
|
|
412
|
+
* @returns {Promise<SenderSubscription[]>}
|
|
413
|
+
*/
|
|
414
|
+
async getSubscriptions (senderId, pageId) {
|
|
415
|
+
return this._storage.getSenderSubscriptions(senderId, pageId);
|
|
416
|
+
}
|
|
417
|
+
|
|
410
418
|
async _preloadSubscribtions (req, res) {
|
|
411
419
|
if (res.data._requestSubscribtions) {
|
|
412
420
|
req.subscribtions = res.data._requestSubscribtions;
|
|
@@ -788,24 +796,38 @@ class Notifications extends EventEmitter {
|
|
|
788
796
|
|
|
789
797
|
let queued = 0;
|
|
790
798
|
|
|
799
|
+
const campaignData = campaign.data || {};
|
|
800
|
+
|
|
791
801
|
while (hasUsers) {
|
|
792
802
|
const { data: targets, lastKey: key } = await this._storage
|
|
793
803
|
.getSubscribtions(include, exclude, this.limit, campaign.pageId, lastKey);
|
|
794
804
|
|
|
795
805
|
lastKey = key;
|
|
796
806
|
|
|
797
|
-
const campaignTargets = targets.map((target) =>
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
807
|
+
const campaignTargets = targets.map((target) => {
|
|
808
|
+
const data = include.length === 0
|
|
809
|
+
? campaignData
|
|
810
|
+
: Object.assign(
|
|
811
|
+
{},
|
|
812
|
+
campaignData,
|
|
813
|
+
// @ts-ignore
|
|
814
|
+
...include.map((t) => (target.meta && target.meta[t]) || {})
|
|
815
|
+
);
|
|
816
|
+
|
|
817
|
+
return {
|
|
818
|
+
senderId: target.senderId,
|
|
819
|
+
pageId: target.pageId,
|
|
820
|
+
campaignId: campaign.id,
|
|
821
|
+
enqueue,
|
|
822
|
+
data
|
|
823
|
+
};
|
|
824
|
+
});
|
|
803
825
|
|
|
804
826
|
const actions = await this.pushTasksToQueue(campaignTargets);
|
|
805
827
|
|
|
806
828
|
queued += actions.length;
|
|
807
829
|
|
|
808
|
-
hasUsers = targets.length > 0 && lastKey;
|
|
830
|
+
hasUsers = targets.length > 0 && !!lastKey;
|
|
809
831
|
}
|
|
810
832
|
|
|
811
833
|
return { queued };
|
|
@@ -910,7 +932,15 @@ class Notifications extends EventEmitter {
|
|
|
910
932
|
return { status: 204 };
|
|
911
933
|
}
|
|
912
934
|
|
|
913
|
-
const message = Request.campaignPostBack(
|
|
935
|
+
const message = Request.campaignPostBack(
|
|
936
|
+
task.senderId,
|
|
937
|
+
campaign,
|
|
938
|
+
ts,
|
|
939
|
+
task.data,
|
|
940
|
+
task.id,
|
|
941
|
+
task.data
|
|
942
|
+
);
|
|
943
|
+
|
|
914
944
|
let status;
|
|
915
945
|
let mid;
|
|
916
946
|
|
|
@@ -6,26 +6,28 @@
|
|
|
6
6
|
const uuid = require('uuid');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* @typedef
|
|
9
|
+
* @typedef {object} Tag
|
|
10
10
|
* @prop {string} tag
|
|
11
11
|
* @prop {number} subscribtions
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* @typedef
|
|
15
|
+
* @typedef {object} Target
|
|
16
16
|
* @prop {string} senderId
|
|
17
17
|
* @prop {string} pageId
|
|
18
|
+
* @prop {{ [key: string]: object }} [meta]
|
|
18
19
|
*/
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
|
-
* @typedef
|
|
22
|
+
* @typedef {object} Subscribtion
|
|
22
23
|
* @prop {string} senderId
|
|
23
24
|
* @prop {string} pageId
|
|
24
25
|
* @prop {string[]} subs
|
|
26
|
+
* @prop {{ [key: string]: object }} [meta]
|
|
25
27
|
*/
|
|
26
28
|
|
|
27
29
|
/**
|
|
28
|
-
* @typedef
|
|
30
|
+
* @typedef {object} Campaign
|
|
29
31
|
* @prop {string} id
|
|
30
32
|
* @prop {string} name
|
|
31
33
|
*
|
|
@@ -63,7 +65,7 @@ const uuid = require('uuid');
|
|
|
63
65
|
*/
|
|
64
66
|
|
|
65
67
|
/**
|
|
66
|
-
* @typedef
|
|
68
|
+
* @typedef {object} Task
|
|
67
69
|
* @prop {string} id
|
|
68
70
|
* @prop {string} pageId
|
|
69
71
|
* @prop {string} senderId
|
|
@@ -77,6 +79,21 @@ const uuid = require('uuid');
|
|
|
77
79
|
* @prop {number} [leaved] - time the event was not sent because user left
|
|
78
80
|
*/
|
|
79
81
|
|
|
82
|
+
/**
|
|
83
|
+
* @typedef {object} Subscription
|
|
84
|
+
* @prop {string} tag
|
|
85
|
+
* @prop {object} meta
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @typedef {object} SubscriptionData
|
|
90
|
+
* @prop {string} pageId
|
|
91
|
+
* @prop {string} senderId
|
|
92
|
+
* @prop {string[]} tags
|
|
93
|
+
* @prop {boolean} [remove]
|
|
94
|
+
* @prop {{ [key: string]: object }} [meta]
|
|
95
|
+
*/
|
|
96
|
+
|
|
80
97
|
const MAX_TS = 9999999999999;
|
|
81
98
|
|
|
82
99
|
class NotificationsStorage {
|
|
@@ -450,9 +467,9 @@ class NotificationsStorage {
|
|
|
450
467
|
* @param {string} senderId
|
|
451
468
|
* @param {string} pageId
|
|
452
469
|
* @param {string} tag
|
|
453
|
-
* @
|
|
470
|
+
* @param {{}} [meta={}]
|
|
454
471
|
*/
|
|
455
|
-
_subscribe (senderId, pageId, tag) {
|
|
472
|
+
_subscribe (senderId, pageId, tag, meta = {}) {
|
|
456
473
|
const key = `${senderId}|${pageId}`;
|
|
457
474
|
let subscribtion = this._subscribtions.get(key);
|
|
458
475
|
if (!subscribtion) {
|
|
@@ -463,20 +480,60 @@ class NotificationsStorage {
|
|
|
463
480
|
};
|
|
464
481
|
}
|
|
465
482
|
if (!subscribtion.subs.includes(tag)) {
|
|
466
|
-
subscribtion = {
|
|
483
|
+
subscribtion = {
|
|
484
|
+
...subscribtion,
|
|
485
|
+
subs: [...subscribtion.subs, tag]
|
|
486
|
+
};
|
|
487
|
+
if (meta && Object.keys(meta).length) {
|
|
488
|
+
Object.assign(subscribtion, {
|
|
489
|
+
meta: {
|
|
490
|
+
...subscribtion.meta,
|
|
491
|
+
[tag]: meta
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
} else if (subscribtion.meta && subscribtion.meta[tag]) {
|
|
495
|
+
delete subscribtion.meta;
|
|
496
|
+
}
|
|
467
497
|
}
|
|
468
498
|
|
|
469
499
|
this._subscribtions.set(key, subscribtion);
|
|
470
500
|
}
|
|
471
501
|
|
|
502
|
+
/**
|
|
503
|
+
*
|
|
504
|
+
* @param {SubscriptionData[]} subscriptionData
|
|
505
|
+
* @param {boolean} [onlyToKnown]
|
|
506
|
+
* @returns {Promise}
|
|
507
|
+
*/
|
|
508
|
+
// eslint-disable-next-line no-unused-vars
|
|
509
|
+
async batchSubscribe (subscriptionData, onlyToKnown = null) {
|
|
510
|
+
subscriptionData.forEach(({
|
|
511
|
+
senderId, pageId, tags, remove = false, meta = {}
|
|
512
|
+
}) => {
|
|
513
|
+
if (remove) {
|
|
514
|
+
tags.forEach((tag) => {
|
|
515
|
+
this._unsubscribe(senderId, pageId, tag);
|
|
516
|
+
});
|
|
517
|
+
} else {
|
|
518
|
+
tags.forEach((tag) => {
|
|
519
|
+
this._subscribe(senderId, pageId, tag, meta[tag]);
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
return Promise.resolve();
|
|
525
|
+
}
|
|
526
|
+
|
|
472
527
|
/**
|
|
473
528
|
*
|
|
474
529
|
* @param {string|string[]} senderId
|
|
475
530
|
* @param {string} pageId
|
|
476
531
|
* @param {string} tag
|
|
532
|
+
* @param {boolean} [onlyToKnown]
|
|
477
533
|
* @returns {Promise}
|
|
478
534
|
*/
|
|
479
|
-
|
|
535
|
+
// eslint-disable-next-line no-unused-vars
|
|
536
|
+
subscribe (senderId, pageId, tag, onlyToKnown = null) {
|
|
480
537
|
const insert = Array.isArray(senderId) ? senderId : [senderId];
|
|
481
538
|
insert.forEach((sender) => this._subscribe(sender, pageId, tag));
|
|
482
539
|
return Promise.resolve();
|
|
@@ -490,9 +547,14 @@ class NotificationsStorage {
|
|
|
490
547
|
* @returns {Promise<string[]>}
|
|
491
548
|
*/
|
|
492
549
|
unsubscribe (senderId, pageId, tag = null) {
|
|
550
|
+
const unsubscribtions = this._unsubscribe(senderId, pageId, tag);
|
|
551
|
+
return Promise.resolve(unsubscribtions);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
_unsubscribe (senderId, pageId, tag = null) {
|
|
493
555
|
const key = `${senderId}|${pageId}`;
|
|
494
556
|
if (!this._subscribtions.has(key)) {
|
|
495
|
-
return
|
|
557
|
+
return [];
|
|
496
558
|
}
|
|
497
559
|
const unsubscribtions = [];
|
|
498
560
|
let subscribtion = this._subscribtions.get(key);
|
|
@@ -507,12 +569,15 @@ class NotificationsStorage {
|
|
|
507
569
|
return !out;
|
|
508
570
|
})
|
|
509
571
|
};
|
|
572
|
+
if ('meta' in subscribtion && subscribtion.meta[tag]) {
|
|
573
|
+
delete subscribtion.meta[tag];
|
|
574
|
+
}
|
|
510
575
|
if (subscribtion.subs.length === 0) {
|
|
511
576
|
this._subscribtions.delete(key);
|
|
512
577
|
} else {
|
|
513
578
|
this._subscribtions.set(key, subscribtion);
|
|
514
579
|
}
|
|
515
|
-
return
|
|
580
|
+
return unsubscribtions;
|
|
516
581
|
}
|
|
517
582
|
|
|
518
583
|
/**
|
|
@@ -581,7 +646,8 @@ class NotificationsStorage {
|
|
|
581
646
|
|
|
582
647
|
const data = ret.map((sub) => ({
|
|
583
648
|
senderId: sub.senderId,
|
|
584
|
-
pageId: sub.pageId
|
|
649
|
+
pageId: sub.pageId,
|
|
650
|
+
...(sub.meta ? { meta: sub.meta } : {})
|
|
585
651
|
}));
|
|
586
652
|
|
|
587
653
|
let nextLastKey = null;
|
|
@@ -598,12 +664,11 @@ class NotificationsStorage {
|
|
|
598
664
|
}
|
|
599
665
|
|
|
600
666
|
/**
|
|
601
|
-
*
|
|
602
667
|
* @param {string} senderId
|
|
603
668
|
* @param {string} pageId
|
|
604
|
-
* @returns {Promise<
|
|
669
|
+
* @returns {Promise<Subscription[]>}
|
|
605
670
|
*/
|
|
606
|
-
|
|
671
|
+
async getSenderSubscriptions (senderId, pageId) {
|
|
607
672
|
const key = `${senderId}|${pageId}`;
|
|
608
673
|
|
|
609
674
|
if (!this._subscribtions.has(key)) {
|
|
@@ -612,7 +677,21 @@ class NotificationsStorage {
|
|
|
612
677
|
|
|
613
678
|
const sub = this._subscribtions.get(key);
|
|
614
679
|
|
|
615
|
-
return
|
|
680
|
+
return sub.subs.map((tag) => ({
|
|
681
|
+
tag,
|
|
682
|
+
meta: (sub.meta && sub.meta[tag]) || {}
|
|
683
|
+
}));
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
*
|
|
688
|
+
* @param {string} senderId
|
|
689
|
+
* @param {string} pageId
|
|
690
|
+
* @returns {Promise<string[]>}
|
|
691
|
+
*/
|
|
692
|
+
async getSenderSubscribtions (senderId, pageId) {
|
|
693
|
+
const subs = await this.getSenderSubscriptions(senderId, pageId);
|
|
694
|
+
return subs.map((s) => s.tag);
|
|
616
695
|
}
|
|
617
696
|
|
|
618
697
|
/**
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
const apiAuthorizer = require('../../graphApi/apiAuthorizer');
|
|
7
7
|
|
|
8
|
+
/** @typedef {import('../NotificationsStorage')} NotificationsStorage */
|
|
9
|
+
/** @typedef {import('../Notifications')} Notifications */
|
|
10
|
+
|
|
8
11
|
/**
|
|
9
12
|
*
|
|
10
13
|
* @param {*} info
|
|
@@ -38,6 +41,59 @@ function getFields (info) {
|
|
|
38
41
|
}, {});
|
|
39
42
|
}
|
|
40
43
|
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {object} Target
|
|
46
|
+
* @prop {string} senderId
|
|
47
|
+
* @prop {string} pageId
|
|
48
|
+
*/
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @typedef {object} SubscriptionData
|
|
52
|
+
* @prop {string} pageId
|
|
53
|
+
* @prop {string} senderId
|
|
54
|
+
* @prop {string[]} tags
|
|
55
|
+
* @prop {boolean} [remove]
|
|
56
|
+
* @prop {{ [key: string]: object }} [meta]
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
*
|
|
61
|
+
* @callback PreprocessSubscribe
|
|
62
|
+
* @param {SubscriptionData[]} subscriptions
|
|
63
|
+
* @returns {Promise<SubscriptionData[]>}
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
* @callback PreprocessSubscriptions
|
|
69
|
+
* @param {Target[]} subscriptions
|
|
70
|
+
* @param {string} [pageId]
|
|
71
|
+
* @returns {Promise<Target[]>|Target[]}
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
*
|
|
76
|
+
* @callback PreprocessSubscribers
|
|
77
|
+
* @param {string[]} senderIds
|
|
78
|
+
* @param {string} pageId
|
|
79
|
+
* @param {string} tag
|
|
80
|
+
* @returns {Promise<string[]>|string[]}
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @typedef {object} NotificationsApiOptions
|
|
85
|
+
* @prop {PreprocessSubscribe} [preprocessSubscribe]
|
|
86
|
+
* @prop {PreprocessSubscriptions} [preprocessSubscriptions]
|
|
87
|
+
* @prop {PreprocessSubscribers} [preprocessSubscribers]
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
*
|
|
92
|
+
* @param {NotificationsStorage} storage
|
|
93
|
+
* @param {Notifications} notifications
|
|
94
|
+
* @param {*} acl
|
|
95
|
+
* @param {NotificationsApiOptions} options
|
|
96
|
+
*/
|
|
41
97
|
function notificationsApiFactory (storage, notifications, acl, options = {}) {
|
|
42
98
|
return {
|
|
43
99
|
async campaigns (args, ctx) {
|
|
@@ -213,6 +269,32 @@ function notificationsApiFactory (storage, notifications, acl, options = {}) {
|
|
|
213
269
|
return true;
|
|
214
270
|
},
|
|
215
271
|
|
|
272
|
+
/**
|
|
273
|
+
* @typedef {object} SubscriptionData
|
|
274
|
+
* @prop {string} pageId
|
|
275
|
+
* @prop {string} senderId
|
|
276
|
+
* @prop {string[]} tags
|
|
277
|
+
* @prop {boolean} [remove]
|
|
278
|
+
* @prop {{ [key: string]: object }} [meta]
|
|
279
|
+
*/
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
*
|
|
283
|
+
* @param {{ subscriptions: SubscriptionData[] }} args
|
|
284
|
+
* @param {*} ctx
|
|
285
|
+
* @returns {Promise<boolean>}
|
|
286
|
+
*/
|
|
287
|
+
async subscribeWithData (args, ctx) {
|
|
288
|
+
if (!apiAuthorizer(args, ctx, acl)) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const { subscriptions } = args;
|
|
293
|
+
|
|
294
|
+
await storage.batchSubscribe(subscriptions, true);
|
|
295
|
+
return true;
|
|
296
|
+
},
|
|
297
|
+
|
|
216
298
|
async tags (args, ctx) {
|
|
217
299
|
if (!apiAuthorizer(args, ctx, acl)) {
|
|
218
300
|
return null;
|