podverse-external-services 1.0.0 → 5.0.1
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/README.md +18 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +0 -1
- package/dist/services/aws/index.d.ts +1 -13
- package/dist/services/aws/index.d.ts.map +1 -0
- package/dist/services/aws/index.js +29 -23
- package/dist/services/aws/s3.d.ts +1 -0
- package/dist/services/aws/s3.d.ts.map +1 -0
- package/dist/services/aws/s3.js +21 -0
- package/dist/services/aws/sqs.d.ts +1 -0
- package/dist/services/aws/sqs.d.ts.map +1 -0
- package/dist/services/aws/sqs.js +81 -0
- package/dist/services/google/fcm.d.ts +1 -0
- package/dist/services/google/fcm.d.ts.map +1 -0
- package/dist/services/google/fcm.js +155 -0
- package/dist/services/google/index.d.ts +1 -0
- package/dist/services/google/index.d.ts.map +1 -0
- package/dist/services/google/index.js +13 -0
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +5 -3
- package/dist/services/notifications/index.d.ts +1 -0
- package/dist/services/notifications/index.d.ts.map +1 -0
- package/dist/services/notifications/index.js +42 -0
- package/dist/services/podcast-index/index.d.ts +11 -8
- package/dist/services/podcast-index/index.d.ts.map +1 -0
- package/dist/services/podcast-index/index.js +118 -163
- package/dist/services/unifiedpush/index.d.ts +1 -0
- package/dist/services/unifiedpush/index.d.ts.map +1 -0
- package/dist/services/unifiedpush/index.js +108 -0
- package/package.json +15 -19
- package/dist/config.d.ts +0 -1
- package/dist/config.js +0 -7
- package/dist/lib/aws.d.ts +0 -3
- package/dist/lib/aws.js +0 -19
package/README.md
CHANGED
|
@@ -1,2 +1,19 @@
|
|
|
1
1
|
# podverse-external-services
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
A collection of helpers for interacting with 3rd party external services, like AWS and Podcast Index API.
|
|
4
|
+
|
|
5
|
+
## Developing Podverse modules
|
|
6
|
+
|
|
7
|
+
Podverse maintains several different modules which are imported across apps. Please read [Developing Podverse modules](https://github.com/podverse/podverse-ops/blob/master/docs/how-to-develop-podverse-modules.md) for a workflow you can use to make code changes to this module locally.
|
|
8
|
+
|
|
9
|
+
## Setup
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
yarn
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Development
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
yarn dev:watch
|
|
19
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -14,5 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./config"), exports);
|
|
18
17
|
__exportStar(require("./services/index"), exports);
|
|
@@ -1,13 +1 @@
|
|
|
1
|
-
|
|
2
|
-
type Constructor = {
|
|
3
|
-
key: string;
|
|
4
|
-
region: string;
|
|
5
|
-
};
|
|
6
|
-
export declare class AWSService {
|
|
7
|
-
key: string;
|
|
8
|
-
region: string;
|
|
9
|
-
constructor({ region }: Constructor);
|
|
10
|
-
s3: aws.S3;
|
|
11
|
-
sqs: aws.SQS;
|
|
12
|
-
}
|
|
13
|
-
export {};
|
|
1
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/aws/index.ts"],"names":[],"mappings":""}
|
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
2
|
+
// import aws from 'aws-sdk'
|
|
3
|
+
// type Constructor = {
|
|
4
|
+
// accessKeyId: string
|
|
5
|
+
// region: string
|
|
6
|
+
// secretAccessKey: string
|
|
7
|
+
// }
|
|
8
|
+
// export class AWSService {
|
|
9
|
+
// declare accessKeyId: string
|
|
10
|
+
// declare region: string
|
|
11
|
+
// declare secretAccessKey: string
|
|
12
|
+
// constructor ({ accessKeyId, region, secretAccessKey }: Constructor) {
|
|
13
|
+
// this.accessKeyId = accessKeyId
|
|
14
|
+
// this.region = region
|
|
15
|
+
// this.secretAccessKey = secretAccessKey
|
|
16
|
+
// aws.config.update({
|
|
17
|
+
// region: this.region,
|
|
18
|
+
// httpOptions: {
|
|
19
|
+
// connectTimeout: 5000,
|
|
20
|
+
// timeout: 5000
|
|
21
|
+
// },
|
|
22
|
+
// credentials: {
|
|
23
|
+
// accessKeyId: this.accessKeyId,
|
|
24
|
+
// secretAccessKey: this.secretAccessKey
|
|
25
|
+
// }
|
|
26
|
+
// })
|
|
27
|
+
// }
|
|
28
|
+
// }
|
|
29
|
+
// export { AWSSQSService } from './sqs'
|
|
30
|
+
// export { AWSS3Service } from './s3'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=s3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../../src/services/aws/s3.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import aws from 'aws-sdk'
|
|
3
|
+
// import { AWSService } from '.'
|
|
4
|
+
// type Constructor = {
|
|
5
|
+
// accessKeyId: string
|
|
6
|
+
// region: string
|
|
7
|
+
// secretAccessKey: string
|
|
8
|
+
// }
|
|
9
|
+
// export class AWSS3Service extends AWSService {
|
|
10
|
+
// declare accessKeyId: string
|
|
11
|
+
// declare region: string
|
|
12
|
+
// declare secretAccessKey: string
|
|
13
|
+
// declare s3: aws.S3
|
|
14
|
+
// constructor ({ accessKeyId, region, secretAccessKey }: Constructor) {
|
|
15
|
+
// super({ accessKeyId, region, secretAccessKey })
|
|
16
|
+
// this.accessKeyId = accessKeyId
|
|
17
|
+
// this.region = region
|
|
18
|
+
// this.secretAccessKey = secretAccessKey
|
|
19
|
+
// this.s3 = new aws.S3()
|
|
20
|
+
// }
|
|
21
|
+
// }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=sqs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqs.d.ts","sourceRoot":"","sources":["../../../src/services/aws/sqs.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import aws from 'aws-sdk'
|
|
3
|
+
// import { AWSService } from '.'
|
|
4
|
+
// type Constructor = {
|
|
5
|
+
// accessKeyId: string
|
|
6
|
+
// region: string
|
|
7
|
+
// secretAccessKey: string
|
|
8
|
+
// }
|
|
9
|
+
// export class AWSSQSService extends AWSService {
|
|
10
|
+
// declare accessKeyId: string
|
|
11
|
+
// declare region: string
|
|
12
|
+
// declare secretAccessKey: string
|
|
13
|
+
// declare sqs: aws.SQS
|
|
14
|
+
// constructor ({ accessKeyId, region, secretAccessKey }: Constructor) {
|
|
15
|
+
// super({ accessKeyId, region, secretAccessKey })
|
|
16
|
+
// this.accessKeyId = accessKeyId
|
|
17
|
+
// this.region = region
|
|
18
|
+
// this.secretAccessKey = secretAccessKey
|
|
19
|
+
// this.sqs = new aws.SQS()
|
|
20
|
+
// }
|
|
21
|
+
// deleteMessage = async (queueUrl: string, receiptHandle: string) => {
|
|
22
|
+
// if (receiptHandle) {
|
|
23
|
+
// const params = {
|
|
24
|
+
// QueueUrl: queueUrl,
|
|
25
|
+
// ReceiptHandle: receiptHandle
|
|
26
|
+
// }
|
|
27
|
+
// await this.sqs
|
|
28
|
+
// .deleteMessage(params)
|
|
29
|
+
// .promise()
|
|
30
|
+
// .catch((error: any) => {
|
|
31
|
+
// console.error('deleteMessage:sqs.deleteMessage error', error)
|
|
32
|
+
// })
|
|
33
|
+
// }
|
|
34
|
+
// }
|
|
35
|
+
// purgeQueue = async (queueUrl: string) => {
|
|
36
|
+
// const params = { QueueUrl: queueUrl }
|
|
37
|
+
// await this.sqs
|
|
38
|
+
// .purgeQueue(params)
|
|
39
|
+
// .promise()
|
|
40
|
+
// .catch((error) => {
|
|
41
|
+
// console.error('purgeQueue.sqs.purgeQueue error', error)
|
|
42
|
+
// })
|
|
43
|
+
// }
|
|
44
|
+
// receiveMessageFromQueue = async (queueUrl: string) => {
|
|
45
|
+
// const params = {
|
|
46
|
+
// QueueUrl: queueUrl,
|
|
47
|
+
// MessageAttributeNames: ['All'],
|
|
48
|
+
// VisibilityTimeout: 30
|
|
49
|
+
// }
|
|
50
|
+
// const message = await this.sqs
|
|
51
|
+
// .receiveMessage(params)
|
|
52
|
+
// .promise()
|
|
53
|
+
// .then((data) => {
|
|
54
|
+
// if (!data.Messages || data.Messages.length === 0) {
|
|
55
|
+
// console.log('receiveMessageFromQueue: No messages found.')
|
|
56
|
+
// return
|
|
57
|
+
// }
|
|
58
|
+
// const message = data.Messages[0]
|
|
59
|
+
// return message
|
|
60
|
+
// })
|
|
61
|
+
// .catch((error) => {
|
|
62
|
+
// console.error('receiveMessageFromQueue: sqs.receiveMessage error', error)
|
|
63
|
+
// })
|
|
64
|
+
// return message
|
|
65
|
+
// }
|
|
66
|
+
// sendMessageBatch = (chunkParams: any) => {
|
|
67
|
+
// return this.sqs.sendMessageBatch(chunkParams)
|
|
68
|
+
// }
|
|
69
|
+
// // TODO: replace any
|
|
70
|
+
// sendMessageToQueue = async (attrs: any, queueUrl: string) => {
|
|
71
|
+
// const message = {
|
|
72
|
+
// MessageAttributes: attrs,
|
|
73
|
+
// MessageBody: 'aws sqs requires a message body - podverse rules',
|
|
74
|
+
// QueueUrl: queueUrl
|
|
75
|
+
// }
|
|
76
|
+
// await this.sqs
|
|
77
|
+
// .sendMessage(message)
|
|
78
|
+
// .promise()
|
|
79
|
+
// .catch((error) => console.error('sendMessageToQueue:sqs.sendMessage', error))
|
|
80
|
+
// }
|
|
81
|
+
// }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=fcm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fcm.d.ts","sourceRoot":"","sources":["../../../src/services/google/fcm.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import axios, { AxiosRequestConfig } from 'axios'
|
|
3
|
+
// import { getFCMTokensForPodcastId } from 'podverse-orm'
|
|
4
|
+
// import { SendNotificationOptions } from '../notifications'
|
|
5
|
+
// import { GoogleService } from '.'
|
|
6
|
+
// const fcmGoogleApiPath = 'https://fcm.googleapis.com/fcm/send'
|
|
7
|
+
// type Constructor = {
|
|
8
|
+
// authToken: string
|
|
9
|
+
// userAgent: string
|
|
10
|
+
// }
|
|
11
|
+
// export class GoogleFCMService extends GoogleService {
|
|
12
|
+
// declare authToken: string
|
|
13
|
+
// declare userAgent: string
|
|
14
|
+
// constructor ({ authToken, userAgent }: Constructor) {
|
|
15
|
+
// super({ authToken, userAgent })
|
|
16
|
+
// this.authToken = authToken
|
|
17
|
+
// this.userAgent = userAgent
|
|
18
|
+
// }
|
|
19
|
+
// request = (options: AxiosRequestConfig) => {
|
|
20
|
+
// return axios({
|
|
21
|
+
// ...options,
|
|
22
|
+
// headers: {
|
|
23
|
+
// ...options.headers,
|
|
24
|
+
// "User-Agent": this.userAgent
|
|
25
|
+
// }
|
|
26
|
+
// })
|
|
27
|
+
// }
|
|
28
|
+
// sendFcmNewEpisodeDetectedNotification = async (options: SendNotificationOptions) => {
|
|
29
|
+
// const { podcastId, podcastShrunkImageUrl, podcastFullImageUrl, episodeFullImageUrl, episodeId } = options
|
|
30
|
+
// const fcmTokens = await getFCMTokensForPodcastId(podcastId)
|
|
31
|
+
// const podcastTitle = options.podcastTitle || 'Untitled Podcast'
|
|
32
|
+
// const episodeTitle = options.episodeTitle || 'Untitled Episode'
|
|
33
|
+
// const title = podcastTitle
|
|
34
|
+
// const body = episodeTitle
|
|
35
|
+
// const finalPodcastImageUrl = podcastShrunkImageUrl || podcastFullImageUrl
|
|
36
|
+
// const finalEpisodeImageUrl = episodeFullImageUrl
|
|
37
|
+
// return this.sendFCMGoogleApiNotification(
|
|
38
|
+
// fcmTokens,
|
|
39
|
+
// title,
|
|
40
|
+
// body,
|
|
41
|
+
// podcastId,
|
|
42
|
+
// 'new-episode',
|
|
43
|
+
// podcastTitle,
|
|
44
|
+
// episodeTitle,
|
|
45
|
+
// finalPodcastImageUrl,
|
|
46
|
+
// finalEpisodeImageUrl,
|
|
47
|
+
// episodeId
|
|
48
|
+
// )
|
|
49
|
+
// }
|
|
50
|
+
// sendFcmLiveItemLiveDetectedNotification = async (options: SendNotificationOptions) => {
|
|
51
|
+
// const { podcastId, podcastShrunkImageUrl, podcastFullImageUrl, episodeFullImageUrl, episodeId } = options
|
|
52
|
+
// const fcmTokens = await getFCMTokensForPodcastId(podcastId)
|
|
53
|
+
// const podcastTitle = options.podcastTitle || 'Untitled Podcast'
|
|
54
|
+
// const episodeTitle = options.episodeTitle || 'Livestream starting'
|
|
55
|
+
// const title = `LIVE: ${podcastTitle}`
|
|
56
|
+
// const body = episodeTitle
|
|
57
|
+
// const finalPodcastImageUrl = podcastShrunkImageUrl || podcastFullImageUrl
|
|
58
|
+
// const finalEpisodeImageUrl = episodeFullImageUrl
|
|
59
|
+
// return this.sendFCMGoogleApiNotification(
|
|
60
|
+
// fcmTokens,
|
|
61
|
+
// title,
|
|
62
|
+
// body,
|
|
63
|
+
// podcastId,
|
|
64
|
+
// 'live',
|
|
65
|
+
// podcastTitle,
|
|
66
|
+
// episodeTitle,
|
|
67
|
+
// finalPodcastImageUrl,
|
|
68
|
+
// finalEpisodeImageUrl,
|
|
69
|
+
// episodeId
|
|
70
|
+
// )
|
|
71
|
+
// }
|
|
72
|
+
// sendFCMGoogleApiNotification = async (
|
|
73
|
+
// fcmTokens: string[],
|
|
74
|
+
// title: string,
|
|
75
|
+
// body: string,
|
|
76
|
+
// podcastId: string,
|
|
77
|
+
// notificationType: 'live' | 'new-episode',
|
|
78
|
+
// podcastTitle: string,
|
|
79
|
+
// episodeTitle: string,
|
|
80
|
+
// podcastImage?: string | null,
|
|
81
|
+
// episodeImage?: string | null,
|
|
82
|
+
// episodeId?: string
|
|
83
|
+
// ) => {
|
|
84
|
+
// if (!fcmTokens || fcmTokens.length === 0) return
|
|
85
|
+
// const fcmTokenBatches: any[] = []
|
|
86
|
+
// const size = 1000
|
|
87
|
+
// for (let i = 0; i < fcmTokens.length; i += size) {
|
|
88
|
+
// fcmTokenBatches.push(fcmTokens.slice(i, i + size))
|
|
89
|
+
// }
|
|
90
|
+
// for (const fcmTokenBatch of fcmTokenBatches) {
|
|
91
|
+
// if (fcmTokenBatch?.length > 0) {
|
|
92
|
+
// const imageUrl = episodeImage || podcastImage
|
|
93
|
+
// try {
|
|
94
|
+
// await this.request({
|
|
95
|
+
// url: fcmGoogleApiPath,
|
|
96
|
+
// method: 'POST',
|
|
97
|
+
// headers: {
|
|
98
|
+
// Authorization: `key=${this.authToken}`,
|
|
99
|
+
// 'Content-Type': 'application/json'
|
|
100
|
+
// },
|
|
101
|
+
// data: {
|
|
102
|
+
// // eslint-disable-next-line @typescript-eslint/camelcase
|
|
103
|
+
// registration_ids: fcmTokenBatch || [],
|
|
104
|
+
// notification: {
|
|
105
|
+
// body,
|
|
106
|
+
// title,
|
|
107
|
+
// podcastId,
|
|
108
|
+
// episodeId,
|
|
109
|
+
// podcastTitle: podcastTitle,
|
|
110
|
+
// episodeTitle: episodeTitle,
|
|
111
|
+
// notificationType,
|
|
112
|
+
// timeSent: new Date(),
|
|
113
|
+
// image: imageUrl
|
|
114
|
+
// },
|
|
115
|
+
// data: {
|
|
116
|
+
// body,
|
|
117
|
+
// title,
|
|
118
|
+
// podcastId,
|
|
119
|
+
// episodeId,
|
|
120
|
+
// podcastTitle: podcastTitle,
|
|
121
|
+
// episodeTitle: episodeTitle,
|
|
122
|
+
// notificationType,
|
|
123
|
+
// timeSent: new Date()
|
|
124
|
+
// },
|
|
125
|
+
// android: {
|
|
126
|
+
// notification: {
|
|
127
|
+
// imageUrl
|
|
128
|
+
// }
|
|
129
|
+
// },
|
|
130
|
+
// apns: {
|
|
131
|
+
// payload: {
|
|
132
|
+
// aps: {
|
|
133
|
+
// 'mutable-content': 1
|
|
134
|
+
// }
|
|
135
|
+
// },
|
|
136
|
+
// // eslint-disable-next-line @typescript-eslint/camelcase
|
|
137
|
+
// fcm_options: {
|
|
138
|
+
// image: imageUrl
|
|
139
|
+
// }
|
|
140
|
+
// },
|
|
141
|
+
// webpush: {
|
|
142
|
+
// headers: {
|
|
143
|
+
// image: imageUrl
|
|
144
|
+
// }
|
|
145
|
+
// }
|
|
146
|
+
// },
|
|
147
|
+
// responseType: 'json'
|
|
148
|
+
// })
|
|
149
|
+
// } catch (error) {
|
|
150
|
+
// console.log('sendFCMGoogleApiNotification error', error)
|
|
151
|
+
// }
|
|
152
|
+
// }
|
|
153
|
+
// }
|
|
154
|
+
// }
|
|
155
|
+
// }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/google/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// type Constructor = {
|
|
3
|
+
// authToken: string
|
|
4
|
+
// userAgent: string
|
|
5
|
+
// }
|
|
6
|
+
// export class GoogleService {
|
|
7
|
+
// declare authToken: string
|
|
8
|
+
// declare userAgent: string
|
|
9
|
+
// constructor ({ authToken, userAgent }: Constructor) {
|
|
10
|
+
// this.authToken = authToken
|
|
11
|
+
// this.userAgent = userAgent
|
|
12
|
+
// }
|
|
13
|
+
// }
|
package/dist/services/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA"}
|
package/dist/services/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PodcastIndexService =
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
exports.PodcastIndexService = void 0;
|
|
4
|
+
// export { AWSS3Service, AWSSQSService } from './aws'
|
|
5
|
+
// export { GoogleService } from './google'
|
|
6
|
+
// export * from './notifications'
|
|
6
7
|
var podcast_index_1 = require("./podcast-index");
|
|
7
8
|
Object.defineProperty(exports, "PodcastIndexService", { enumerable: true, get: function () { return podcast_index_1.PodcastIndexService; } });
|
|
9
|
+
// export { UnifiedPushService } from './unifiedpush'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/notifications/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import { UnifiedPushService } from '..'
|
|
3
|
+
// import { GoogleFCMService } from '../google/fcm'
|
|
4
|
+
// export interface SendNotificationOptions {
|
|
5
|
+
// episodeFullImageUrl?: string | null
|
|
6
|
+
// episodeGuid?: string
|
|
7
|
+
// episodeId?: string
|
|
8
|
+
// episodeTitle?: string | null
|
|
9
|
+
// podcastId: string
|
|
10
|
+
// podcastFullImageUrl?: string | null
|
|
11
|
+
// podcastShrunkImageUrl?: string | null
|
|
12
|
+
// podcastTitle?: string | null
|
|
13
|
+
// }
|
|
14
|
+
// type Constructor = {
|
|
15
|
+
// googleAuthToken: string
|
|
16
|
+
// userAgent: string
|
|
17
|
+
// }
|
|
18
|
+
// export class NotificationsService {
|
|
19
|
+
// declare fcmAuthToken: string
|
|
20
|
+
// declare userAgent: string
|
|
21
|
+
// declare GoogleFCMService: GoogleFCMService
|
|
22
|
+
// declare UnifiedPushService: UnifiedPushService
|
|
23
|
+
// constructor ({ googleAuthToken, userAgent }: Constructor) {
|
|
24
|
+
// this.GoogleFCMService = new GoogleFCMService({
|
|
25
|
+
// authToken: googleAuthToken,
|
|
26
|
+
// userAgent
|
|
27
|
+
// })
|
|
28
|
+
// this.UnifiedPushService = new UnifiedPushService()
|
|
29
|
+
// }
|
|
30
|
+
// sendNewEpisodeDetectedNotification = async (options: SendNotificationOptions) => {
|
|
31
|
+
// return Promise.all([
|
|
32
|
+
// this.GoogleFCMService.sendFcmNewEpisodeDetectedNotification(options),
|
|
33
|
+
// this.UnifiedPushService.sendUpNewEpisodeDetectedNotification(options)
|
|
34
|
+
// ])
|
|
35
|
+
// }
|
|
36
|
+
// sendLiveItemLiveDetectedNotification = async (options: SendNotificationOptions) => {
|
|
37
|
+
// return Promise.all([
|
|
38
|
+
// this.GoogleFCMService.sendFcmLiveItemLiveDetectedNotification(options),
|
|
39
|
+
// this.UnifiedPushService.sendUpLiveItemLiveDetectedNotification(options)
|
|
40
|
+
// ])
|
|
41
|
+
// }
|
|
42
|
+
// }
|
|
@@ -9,33 +9,36 @@ type PIValueDestination = {
|
|
|
9
9
|
type: string;
|
|
10
10
|
address: string;
|
|
11
11
|
split: number;
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
custom_key?: string;
|
|
13
|
+
custom_value?: string;
|
|
14
14
|
fee?: boolean;
|
|
15
15
|
};
|
|
16
16
|
type PIValueTag = {
|
|
17
17
|
model: PIValueModel;
|
|
18
18
|
destinations: PIValueDestination[];
|
|
19
|
-
|
|
19
|
+
value_time_splits: Phase6ValueTimeSplit[];
|
|
20
20
|
};
|
|
21
21
|
type Constructor = {
|
|
22
22
|
authKey: string;
|
|
23
23
|
baseUrl: string;
|
|
24
24
|
secretKey: string;
|
|
25
|
-
userAgent: string;
|
|
26
25
|
};
|
|
27
26
|
export declare class PodcastIndexService {
|
|
28
27
|
authKey: string;
|
|
29
28
|
baseUrl: string;
|
|
30
29
|
secretKey: string;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
constructor({ authKey, baseUrl, secretKey }: Constructor);
|
|
31
|
+
podcastIndexAPIRequest: (url: string) => Promise<any>;
|
|
32
|
+
getRecentlyUpdatedData: () => Promise<any[]>;
|
|
34
33
|
getAllEpisodesFromPodcastIndexById: (podcastIndexId: string) => Promise<any>;
|
|
35
34
|
getAllEpisodeValueTagsFromPodcastIndexById: (podcastIndexId: string) => Promise<any>;
|
|
36
35
|
getEpisodesFromPodcastIndexById: (podcastIndexId: string) => Promise<any>;
|
|
37
36
|
getPodcastFromPodcastIndexById: (id: string) => Promise<any>;
|
|
38
37
|
getPodcastValueTagForPodcastIndexId: (id: string) => Promise<any[]>;
|
|
38
|
+
getValueTagEnabledPodcastIdsFromPIRecursively: (accumulatedPodcastIndexIds: number[], startAt?: number) => Promise<number[]>;
|
|
39
|
+
getValueTagEnabledPodcastIdsFromPI: () => Promise<number[]>;
|
|
40
|
+
convertPIValueTagToPVValueTagArray: (piValueTag: PIValueTag) => any[];
|
|
41
|
+
getPodcastFromPodcastIndexByGuid: (podcastGuid: string) => Promise<any>;
|
|
39
42
|
}
|
|
40
|
-
export declare const convertPIValueTagToPVValueTagArray: (piValueTag: PIValueTag) => any[];
|
|
41
43
|
export {};
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/podcast-index/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAA;AAIlF,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,OAAO,CAAA;CACd,CAAA;AAED,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,YAAY,CAAA;IACnB,YAAY,EAAE,kBAAkB,EAAE,CAAA;IAClC,iBAAiB,EAAE,oBAAoB,EAAE,CAAA;CAC1C,CAAA;AAED,KAAK,WAAW,GAAG;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AASD,qBAAa,mBAAmB;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;gBAEZ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,WAAW;IAMzD,sBAAsB,QAAe,MAAM,kBAa1C;IAED,sBAAsB,uBAuBrB;IAED,kCAAkC,mBAA0B,MAAM,kBAIjE;IAED,0CAA0C,mBAA0B,MAAM,kBAYzE;IAED,+BAA+B,mBAA0B,MAAM,kBAG9D;IAED,8BAA8B,OAAc,MAAM,kBAGjD;IAED,mCAAmC,OAAc,MAAM,oBAItD;IAED,6CAA6C,+BACf,MAAM,EAAE,uBAAgB,QAAQ,MAAM,EAAE,CAAC,CAatE;IAED,kCAAkC,0BAMjC;IAED,kCAAkC,eAAgB,UAAU,WAoB3D;IAED,gCAAgC,gBAAuB,MAAM,kBAe5D;CACF"}
|
|
@@ -8,187 +8,142 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var __values = (this && this.__values) || function(o) {
|
|
39
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
40
|
-
if (m) return m.call(o);
|
|
41
|
-
if (o && typeof o.length === "number") return {
|
|
42
|
-
next: function () {
|
|
43
|
-
if (o && i >= o.length) o = void 0;
|
|
44
|
-
return { value: o && o[i++], done: !o };
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
48
|
-
};
|
|
49
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
50
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
13
|
};
|
|
52
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
-
exports.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
15
|
+
exports.PodcastIndexService = void 0;
|
|
16
|
+
const sha1_1 = __importDefault(require("crypto-js/sha1"));
|
|
17
|
+
const enc_hex_1 = __importDefault(require("crypto-js/enc-hex"));
|
|
18
|
+
const http_errors_1 = __importDefault(require("http-errors"));
|
|
19
|
+
const podverse_helpers_1 = require("podverse-helpers");
|
|
20
|
+
console.log('podcast index!!!');
|
|
57
21
|
/*
|
|
58
22
|
NOTE!!!
|
|
59
23
|
The episodeGuid needs to be encoded both on the client-side and server side if it is an http url guid.
|
|
60
24
|
Koa will automatically decode the encoded url param, and then Podcast Index API needs it
|
|
61
25
|
encoded once again before sending the request to PI API.
|
|
62
26
|
*/
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
url: url,
|
|
74
|
-
method: 'GET',
|
|
75
|
-
headers: {
|
|
76
|
-
'User-Agent': this.userAgent,
|
|
77
|
-
'X-Auth-Key': this.authKey,
|
|
78
|
-
'X-Auth-Date': apiHeaderTime,
|
|
79
|
-
Authorization: hash
|
|
80
|
-
}
|
|
81
|
-
})];
|
|
82
|
-
});
|
|
83
|
-
}); };
|
|
84
|
-
this.getAllEpisodesFromPodcastIndexById = function (podcastIndexId) { return __awaiter(_this, void 0, void 0, function () {
|
|
85
|
-
var response, allEpisodes;
|
|
86
|
-
return __generator(this, function (_a) {
|
|
87
|
-
switch (_a.label) {
|
|
88
|
-
case 0: return [4 /*yield*/, this.getEpisodesFromPodcastIndexById(podcastIndexId)];
|
|
89
|
-
case 1:
|
|
90
|
-
response = _a.sent();
|
|
91
|
-
allEpisodes = response === null || response === void 0 ? void 0 : response.items;
|
|
92
|
-
return [2 /*return*/, allEpisodes];
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
}); };
|
|
96
|
-
this.getAllEpisodeValueTagsFromPodcastIndexById = function (podcastIndexId) { return __awaiter(_this, void 0, void 0, function () {
|
|
97
|
-
var episodes, pvEpisodesValueTagsByGuid, episodes_1, episodes_1_1, episode, pvValueTagArray;
|
|
98
|
-
var e_1, _a;
|
|
99
|
-
return __generator(this, function (_b) {
|
|
100
|
-
switch (_b.label) {
|
|
101
|
-
case 0: return [4 /*yield*/, this.getAllEpisodesFromPodcastIndexById(podcastIndexId)];
|
|
102
|
-
case 1:
|
|
103
|
-
episodes = _b.sent();
|
|
104
|
-
pvEpisodesValueTagsByGuid = {};
|
|
105
|
-
try {
|
|
106
|
-
for (episodes_1 = __values(episodes), episodes_1_1 = episodes_1.next(); !episodes_1_1.done; episodes_1_1 = episodes_1.next()) {
|
|
107
|
-
episode = episodes_1_1.value;
|
|
108
|
-
if ((episode === null || episode === void 0 ? void 0 : episode.value) && (episode === null || episode === void 0 ? void 0 : episode.guid)) {
|
|
109
|
-
pvValueTagArray = (0, exports.convertPIValueTagToPVValueTagArray)(episode.value);
|
|
110
|
-
if ((pvValueTagArray === null || pvValueTagArray === void 0 ? void 0 : pvValueTagArray.length) > 0) {
|
|
111
|
-
pvEpisodesValueTagsByGuid[episode.guid] = pvValueTagArray;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
117
|
-
finally {
|
|
118
|
-
try {
|
|
119
|
-
if (episodes_1_1 && !episodes_1_1.done && (_a = episodes_1.return)) _a.call(episodes_1);
|
|
120
|
-
}
|
|
121
|
-
finally { if (e_1) throw e_1.error; }
|
|
122
|
-
}
|
|
123
|
-
return [2 /*return*/, pvEpisodesValueTagsByGuid];
|
|
27
|
+
class PodcastIndexService {
|
|
28
|
+
constructor({ authKey, baseUrl, secretKey }) {
|
|
29
|
+
this.podcastIndexAPIRequest = (url) => __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
const apiHeaderTime = new Date().getTime() / 1000;
|
|
31
|
+
const hash = (0, sha1_1.default)(this.authKey + this.secretKey + apiHeaderTime).toString(enc_hex_1.default);
|
|
32
|
+
return (0, podverse_helpers_1.request)(url, {
|
|
33
|
+
headers: {
|
|
34
|
+
'X-Auth-Key': this.authKey,
|
|
35
|
+
'X-Auth-Date': apiHeaderTime,
|
|
36
|
+
Authorization: hash
|
|
124
37
|
}
|
|
125
38
|
});
|
|
126
|
-
});
|
|
127
|
-
this.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
39
|
+
});
|
|
40
|
+
this.getRecentlyUpdatedData = () => __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
const currentTimeInSeconds = Math.floor(Date.now() / 1000);
|
|
42
|
+
const sinceRange = 1800; // 30 minutes
|
|
43
|
+
const sinceTimeInSeconds = currentTimeInSeconds - sinceRange;
|
|
44
|
+
const fetchData = (since, allData = []) => __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
const url = `${this.baseUrl}/recent/data?max=5000&since=${since}`;
|
|
46
|
+
const response = yield this.podcastIndexAPIRequest(url);
|
|
47
|
+
const updatedFeeds = response.data.feeds;
|
|
48
|
+
const nextSince = response.nextSince;
|
|
49
|
+
allData = allData.concat(updatedFeeds);
|
|
50
|
+
console.log('nextSince', nextSince);
|
|
51
|
+
console.log('currentTimeInSeconds', currentTimeInSeconds);
|
|
52
|
+
if (nextSince && nextSince <= currentTimeInSeconds) {
|
|
53
|
+
console.log('fetching more...');
|
|
54
|
+
return fetchData(nextSince, allData);
|
|
137
55
|
}
|
|
56
|
+
return allData;
|
|
138
57
|
});
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
58
|
+
return fetchData(sinceTimeInSeconds);
|
|
59
|
+
});
|
|
60
|
+
this.getAllEpisodesFromPodcastIndexById = (podcastIndexId) => __awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
const response = yield this.getEpisodesFromPodcastIndexById(podcastIndexId);
|
|
62
|
+
const allEpisodes = response === null || response === void 0 ? void 0 : response.items;
|
|
63
|
+
return allEpisodes;
|
|
64
|
+
});
|
|
65
|
+
this.getAllEpisodeValueTagsFromPodcastIndexById = (podcastIndexId) => __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const episodes = yield this.getAllEpisodesFromPodcastIndexById(podcastIndexId);
|
|
67
|
+
const pvEpisodesValueTagsByGuid = {};
|
|
68
|
+
for (const episode of episodes) {
|
|
69
|
+
if ((episode === null || episode === void 0 ? void 0 : episode.value) && (episode === null || episode === void 0 ? void 0 : episode.guid)) {
|
|
70
|
+
const pvValueTagArray = this.convertPIValueTagToPVValueTagArray(episode.value);
|
|
71
|
+
if ((pvValueTagArray === null || pvValueTagArray === void 0 ? void 0 : pvValueTagArray.length) > 0) {
|
|
72
|
+
pvEpisodesValueTagsByGuid[episode.guid] = pvValueTagArray;
|
|
73
|
+
}
|
|
150
74
|
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
75
|
+
}
|
|
76
|
+
return pvEpisodesValueTagsByGuid;
|
|
77
|
+
});
|
|
78
|
+
this.getEpisodesFromPodcastIndexById = (podcastIndexId) => __awaiter(this, void 0, void 0, function* () {
|
|
79
|
+
const url = `${this.baseUrl}/episodes/byfeedid?id=${podcastIndexId}&max=1000`;
|
|
80
|
+
return this.podcastIndexAPIRequest(url);
|
|
81
|
+
});
|
|
82
|
+
this.getPodcastFromPodcastIndexById = (id) => __awaiter(this, void 0, void 0, function* () {
|
|
83
|
+
const url = `${this.baseUrl}/podcasts/byfeedid?id=${id}`;
|
|
84
|
+
return this.podcastIndexAPIRequest(url);
|
|
85
|
+
});
|
|
86
|
+
this.getPodcastValueTagForPodcastIndexId = (id) => __awaiter(this, void 0, void 0, function* () {
|
|
87
|
+
const podcast = yield this.getPodcastFromPodcastIndexById(id);
|
|
88
|
+
const pvValueTagArray = this.convertPIValueTagToPVValueTagArray(podcast.feed.value);
|
|
89
|
+
return pvValueTagArray;
|
|
90
|
+
});
|
|
91
|
+
this.getValueTagEnabledPodcastIdsFromPIRecursively = (accumulatedPodcastIndexIds, startAt = 1) => __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
const url = `${this.baseUrl}/podcasts/bytag?podcast-value=true&max=5000&start_at=${startAt}`;
|
|
93
|
+
const data = yield this.podcastIndexAPIRequest(url);
|
|
94
|
+
for (const feed of data.feeds) {
|
|
95
|
+
accumulatedPodcastIndexIds.push(feed.id);
|
|
96
|
+
}
|
|
97
|
+
if (data.nextStartAt) {
|
|
98
|
+
return yield this.getValueTagEnabledPodcastIdsFromPIRecursively(accumulatedPodcastIndexIds, data.nextStartAt);
|
|
99
|
+
}
|
|
100
|
+
return accumulatedPodcastIndexIds;
|
|
101
|
+
});
|
|
102
|
+
this.getValueTagEnabledPodcastIdsFromPI = () => __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const accumulatedPodcastIndexIds = [];
|
|
104
|
+
const nextStartAt = 1;
|
|
105
|
+
const podcastIndexIds = yield this.getValueTagEnabledPodcastIdsFromPIRecursively(accumulatedPodcastIndexIds, nextStartAt);
|
|
106
|
+
return podcastIndexIds;
|
|
107
|
+
});
|
|
108
|
+
this.convertPIValueTagToPVValueTagArray = (piValueTag) => {
|
|
109
|
+
return [
|
|
110
|
+
{
|
|
111
|
+
method: piValueTag.model.method,
|
|
112
|
+
suggested: piValueTag.model.suggested,
|
|
113
|
+
type: piValueTag.model.type,
|
|
114
|
+
recipients: piValueTag.destinations.map((destination) => {
|
|
115
|
+
return {
|
|
116
|
+
address: destination.address,
|
|
117
|
+
customKey: destination.custom_key || '',
|
|
118
|
+
customValue: destination.custom_value || '',
|
|
119
|
+
fee: destination.fee || false,
|
|
120
|
+
name: destination.name || '',
|
|
121
|
+
split: destination.split || 0,
|
|
122
|
+
type: destination.type || ''
|
|
123
|
+
};
|
|
124
|
+
}),
|
|
125
|
+
valueTimeSplits: piValueTag.value_time_splits
|
|
162
126
|
}
|
|
163
|
-
|
|
164
|
-
}
|
|
127
|
+
];
|
|
128
|
+
};
|
|
129
|
+
this.getPodcastFromPodcastIndexByGuid = (podcastGuid) => __awaiter(this, void 0, void 0, function* () {
|
|
130
|
+
const url = `${this.baseUrl}/podcasts/byguid?guid=${podcastGuid}`;
|
|
131
|
+
let podcastIndexPodcast = null;
|
|
132
|
+
try {
|
|
133
|
+
const data = yield this.podcastIndexAPIRequest(url);
|
|
134
|
+
podcastIndexPodcast = data;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
// assume a 404
|
|
138
|
+
}
|
|
139
|
+
if (!podcastIndexPodcast) {
|
|
140
|
+
throw new http_errors_1.default.NotFound('Podcast not found in Podcast Index');
|
|
141
|
+
}
|
|
142
|
+
return podcastIndexPodcast;
|
|
143
|
+
});
|
|
165
144
|
this.authKey = authKey;
|
|
166
145
|
this.baseUrl = baseUrl;
|
|
167
146
|
this.secretKey = secretKey;
|
|
168
|
-
this.userAgent = userAgent;
|
|
169
147
|
}
|
|
170
|
-
|
|
171
|
-
}());
|
|
148
|
+
}
|
|
172
149
|
exports.PodcastIndexService = PodcastIndexService;
|
|
173
|
-
var convertPIValueTagToPVValueTagArray = function (piValueTag) {
|
|
174
|
-
return [
|
|
175
|
-
{
|
|
176
|
-
method: piValueTag.model.method,
|
|
177
|
-
suggested: piValueTag.model.suggested,
|
|
178
|
-
type: piValueTag.model.type,
|
|
179
|
-
recipients: piValueTag.destinations.map(function (destination) {
|
|
180
|
-
return {
|
|
181
|
-
address: destination.address,
|
|
182
|
-
customKey: destination.customKey || '',
|
|
183
|
-
customValue: destination.customValue || '',
|
|
184
|
-
fee: destination.fee || false,
|
|
185
|
-
name: destination.name || '',
|
|
186
|
-
split: destination.split || 0,
|
|
187
|
-
type: destination.type || ''
|
|
188
|
-
};
|
|
189
|
-
}),
|
|
190
|
-
valueTimeSplits: piValueTag.valueTimeSplits
|
|
191
|
-
}
|
|
192
|
-
];
|
|
193
|
-
};
|
|
194
|
-
exports.convertPIValueTagToPVValueTagArray = convertPIValueTagToPVValueTagArray;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/unifiedpush/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// import { getUPDevicesForPodcastId, UPEndpointData } from 'podverse-orm'
|
|
3
|
+
// import { promiseAllSkippingErrors } from 'podverse-shared'
|
|
4
|
+
// import { SendNotificationOptions } from '../notifications'
|
|
5
|
+
// const webpush = require('web-push')
|
|
6
|
+
// export class UnifiedPushService {
|
|
7
|
+
// sendUpNewEpisodeDetectedNotification = async (options: SendNotificationOptions) => {
|
|
8
|
+
// const { podcastId, podcastShrunkImageUrl, episodeId } = options
|
|
9
|
+
// const upDevices = await getUPDevicesForPodcastId(podcastId)
|
|
10
|
+
// const podcastTitle = options.podcastTitle || 'Untitled Podcast'
|
|
11
|
+
// const episodeTitle = options.episodeTitle || 'Untitled Episode'
|
|
12
|
+
// const title = podcastTitle
|
|
13
|
+
// const body = episodeTitle
|
|
14
|
+
// // NOTE: Only allow shrunk image urls to be used, in case large image sizes
|
|
15
|
+
// // cause issues with UnifiedPush distributors.
|
|
16
|
+
// const finalPodcastImageUrl = podcastShrunkImageUrl
|
|
17
|
+
// const finalEpisodeImageUrl = ''
|
|
18
|
+
// return this.sendUPNotification(
|
|
19
|
+
// upDevices,
|
|
20
|
+
// title,
|
|
21
|
+
// body,
|
|
22
|
+
// podcastId,
|
|
23
|
+
// 'new-episode',
|
|
24
|
+
// podcastTitle,
|
|
25
|
+
// episodeTitle,
|
|
26
|
+
// finalPodcastImageUrl,
|
|
27
|
+
// finalEpisodeImageUrl,
|
|
28
|
+
// episodeId
|
|
29
|
+
// )
|
|
30
|
+
// }
|
|
31
|
+
// sendUpLiveItemLiveDetectedNotification = async (options: SendNotificationOptions) => {
|
|
32
|
+
// const { podcastId, podcastShrunkImageUrl, episodeId } = options
|
|
33
|
+
// const upDevices = await getUPDevicesForPodcastId(podcastId)
|
|
34
|
+
// const podcastTitle = options.podcastTitle || 'Untitled Podcast'
|
|
35
|
+
// const episodeTitle = options.episodeTitle || 'Livestream starting'
|
|
36
|
+
// const title = `LIVE: ${podcastTitle}`
|
|
37
|
+
// const body = episodeTitle
|
|
38
|
+
// // NOTE: Only allow shrunk image urls to be used, in case large image sizes
|
|
39
|
+
// // cause issues with UnifiedPush distributors.
|
|
40
|
+
// const finalPodcastImageUrl = podcastShrunkImageUrl
|
|
41
|
+
// const finalEpisodeImageUrl = ''
|
|
42
|
+
// return this.sendUPNotification(
|
|
43
|
+
// upDevices,
|
|
44
|
+
// title,
|
|
45
|
+
// body,
|
|
46
|
+
// podcastId,
|
|
47
|
+
// 'live',
|
|
48
|
+
// podcastTitle,
|
|
49
|
+
// episodeTitle,
|
|
50
|
+
// finalPodcastImageUrl,
|
|
51
|
+
// finalEpisodeImageUrl,
|
|
52
|
+
// episodeId
|
|
53
|
+
// )
|
|
54
|
+
// }
|
|
55
|
+
// sendUPNotification = async (
|
|
56
|
+
// upDevices: UPEndpointData[],
|
|
57
|
+
// title: string,
|
|
58
|
+
// body: string,
|
|
59
|
+
// podcastId: string,
|
|
60
|
+
// notificationType: 'live' | 'new-episode',
|
|
61
|
+
// podcastTitle: string,
|
|
62
|
+
// episodeTitle: string,
|
|
63
|
+
// podcastImage?: string | null,
|
|
64
|
+
// episodeImage?: string,
|
|
65
|
+
// episodeId?: string
|
|
66
|
+
// ) => {
|
|
67
|
+
// if (!upDevices || upDevices.length === 0) return
|
|
68
|
+
// const upDeviceBatches: UPEndpointData[][] = []
|
|
69
|
+
// const size = 100
|
|
70
|
+
// for (let i = 0; i < upDevices.length; i += size) {
|
|
71
|
+
// upDeviceBatches.push(upDevices.slice(i, i + size))
|
|
72
|
+
// }
|
|
73
|
+
// const data = {
|
|
74
|
+
// body,
|
|
75
|
+
// title,
|
|
76
|
+
// podcastId,
|
|
77
|
+
// episodeId,
|
|
78
|
+
// podcastTitle: podcastTitle,
|
|
79
|
+
// episodeTitle: episodeTitle,
|
|
80
|
+
// notificationType,
|
|
81
|
+
// timeSent: new Date().toISOString(),
|
|
82
|
+
// image: episodeImage || podcastImage
|
|
83
|
+
// }
|
|
84
|
+
// const jsonPayload = JSON.stringify(data)
|
|
85
|
+
// for (const upDeviceBatch of upDeviceBatches) {
|
|
86
|
+
// if (upDeviceBatch?.length > 0) {
|
|
87
|
+
// try {
|
|
88
|
+
// await promiseAllSkippingErrors(
|
|
89
|
+
// upDeviceBatch.map((upd: UPEndpointData) =>
|
|
90
|
+
// webpush.sendNotification(
|
|
91
|
+
// {
|
|
92
|
+
// endpoint: upd.upEndpoint,
|
|
93
|
+
// keys: {
|
|
94
|
+
// auth: upd.upAuthKey,
|
|
95
|
+
// p256dh: upd.upPublicKey
|
|
96
|
+
// }
|
|
97
|
+
// },
|
|
98
|
+
// jsonPayload
|
|
99
|
+
// )
|
|
100
|
+
// )
|
|
101
|
+
// )
|
|
102
|
+
// } catch (error) {
|
|
103
|
+
// console.log('sendUPNotification error', error)
|
|
104
|
+
// }
|
|
105
|
+
// }
|
|
106
|
+
// }
|
|
107
|
+
// }
|
|
108
|
+
// }
|
package/package.json
CHANGED
|
@@ -1,31 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "podverse-external-services",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
|
+
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/**/*"
|
|
9
|
+
],
|
|
7
10
|
"scripts": {
|
|
8
|
-
"dev:watch": "nodemon --watch 'src' --watch $(realpath node_modules/podverse-
|
|
11
|
+
"dev:watch": "nodemon --watch 'src' --watch $(realpath node_modules/podverse-helpers) --delay 500ms -x \"npm run build\"",
|
|
9
12
|
"build": "tsc",
|
|
10
13
|
"lint": "eslint ./src --ext .ts",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
},
|
|
14
|
-
"files": [
|
|
15
|
-
"/dist"
|
|
16
|
-
],
|
|
17
|
-
"repository": {
|
|
18
|
-
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/podverse/podverse-external-services.git"
|
|
14
|
+
"prepare": "npm run build",
|
|
15
|
+
"start": "ts-node ./dist/index.js"
|
|
20
16
|
},
|
|
17
|
+
"author": "",
|
|
21
18
|
"license": "AGPLv3",
|
|
22
|
-
"bugs": {
|
|
23
|
-
"url": "https://github.com/podverse/podverse-external-services/issues"
|
|
24
|
-
},
|
|
25
|
-
"homepage": "https://github.com/podverse/podverse-external-services#readme",
|
|
26
19
|
"devDependencies": {
|
|
27
20
|
"@types/crypto-js": "^4.2.1",
|
|
21
|
+
"@types/http-errors": "^2.0.4",
|
|
28
22
|
"@types/node": "^20.10.4",
|
|
23
|
+
"@types/web-push": "^3.3.2",
|
|
29
24
|
"@typescript-eslint/eslint-plugin": "^6.13.0",
|
|
30
25
|
"@typescript-eslint/parser": "^6.13.0",
|
|
31
26
|
"eslint": "^8.54.0",
|
|
@@ -35,9 +30,10 @@
|
|
|
35
30
|
"dependencies": {
|
|
36
31
|
"@types/aws-sdk": "^2.7.0",
|
|
37
32
|
"aws-sdk": "2.814.0",
|
|
38
|
-
"axios": "^1.6.2",
|
|
39
33
|
"crypto-js": "^4.2.0",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
34
|
+
"http-errors": "1.7.3",
|
|
35
|
+
"podcast-partytime": "^4.8.3",
|
|
36
|
+
"podverse-helpers": "^5.0.1",
|
|
37
|
+
"web-push": "^3.6.3"
|
|
42
38
|
}
|
|
43
39
|
}
|
package/dist/config.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const config: any;
|
package/dist/config.js
DELETED
package/dist/lib/aws.d.ts
DELETED
package/dist/lib/aws.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.s3 = exports.sqs = void 0;
|
|
7
|
-
var aws_sdk_1 = __importDefault(require("aws-sdk"));
|
|
8
|
-
var config_1 = require("../config");
|
|
9
|
-
var awsConfig = config_1.config.awsConfig;
|
|
10
|
-
var awsRegion = awsConfig.region;
|
|
11
|
-
aws_sdk_1.default.config.update({
|
|
12
|
-
region: awsRegion,
|
|
13
|
-
httpOptions: {
|
|
14
|
-
connectTimeout: 5000,
|
|
15
|
-
timeout: 5000
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
exports.sqs = new aws_sdk_1.default.SQS();
|
|
19
|
-
exports.s3 = new aws_sdk_1.default.S3();
|