@robono/server 0.15.0 → 0.17.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/CHANGELOG.md +11 -1
- package/NOTIFICATIONS.md +149 -0
- package/README.md +8 -1
- package/SBOM.spdx.json +8 -8
- package/SCREENING.md +73 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/managed-media.d.ts.map +1 -1
- package/dist/managed-media.js +2 -0
- package/dist/managed-media.js.map +1 -1
- package/dist/messaging-notification-postgres.d.ts +7 -0
- package/dist/messaging-notification-postgres.d.ts.map +1 -0
- package/dist/messaging-notification-postgres.js +32 -0
- package/dist/messaging-notification-postgres.js.map +1 -0
- package/dist/messaging-notification-providers.d.ts +26 -0
- package/dist/messaging-notification-providers.d.ts.map +1 -0
- package/dist/messaging-notification-providers.js +107 -0
- package/dist/messaging-notification-providers.js.map +1 -0
- package/dist/messaging-notifications.d.ts +66 -0
- package/dist/messaging-notifications.d.ts.map +1 -0
- package/dist/messaging-notifications.js +128 -0
- package/dist/messaging-notifications.js.map +1 -0
- package/dist/messaging.d.ts +7 -0
- package/dist/messaging.d.ts.map +1 -1
- package/dist/messaging.js +40 -2
- package/dist/messaging.js.map +1 -1
- package/dist/messenger.d.ts +53 -0
- package/dist/messenger.d.ts.map +1 -0
- package/dist/messenger.js +89 -0
- package/dist/messenger.js.map +1 -0
- package/dist/screening.d.ts +53 -0
- package/dist/screening.d.ts.map +1 -0
- package/dist/screening.js +52 -0
- package/dist/screening.js.map +1 -0
- package/package.json +5 -2
- package/sql/messaging-notifications.sql +41 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.0 — 2026-11-03
|
|
4
|
+
|
|
5
|
+
- Add optional photo/video screening for connected networks and return attachment screening status without holding server requests open.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
## 0.16.0 — 2026-11-03
|
|
9
|
+
|
|
10
|
+
Add createRobonoMessengerServer for one authenticated messaging/media route, plus optional signed-event notification delivery using customer Apple/Google credentials and a durable private PostgreSQL queue. Announce supported group controls; keep actor identity server-verified and recheck customer permissions on search results. Include NOTIFICATIONS.md and the notification schema.
|
|
11
|
+
|
|
12
|
+
Requires matching service migrations 181–186 and coordinated package publication. Physical-device notification delivery is a separate acceptance check.
|
|
13
|
+
|
|
3
14
|
## 0.15.0
|
|
4
15
|
|
|
5
16
|
Add authenticated social previews, bounded private thumbnail requests, media replacement, per-user mute/delete-chat operations, and source-revision-aware translation caching.
|
|
@@ -25,7 +36,6 @@ Add network-triggered call countdowns, selected-recipient or all-participant war
|
|
|
25
36
|
Managed messaging and attachments, Maps and location sessions, movement consent, geofence rules, usage reporting and backend adapters. Existing Bridge and calling entry points remain available.
|
|
26
37
|
|
|
27
38
|
|
|
28
|
-
## Unreleased
|
|
29
39
|
|
|
30
40
|
- Group admission and relationship helpers, separate screen-sharing permission, group webhook verification/push routing, and an authenticated on-demand message transcription/translation adapter. Source content and private media are resolved server-side; access is rechecked after conversion.
|
|
31
41
|
|
package/NOTIFICATIONS.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Mobile message notifications
|
|
2
|
+
|
|
3
|
+
This installation uses your app's Apple/Google credentials. Robono's own app
|
|
4
|
+
credentials cannot send alerts for a customer's app. Chat in an open screen works
|
|
5
|
+
without push credentials; alerts with the app closed do not.
|
|
6
|
+
|
|
7
|
+
This guide requires `@robono/server` 0.16.0 and messaging packages 0.3.0,
|
|
8
|
+
with the matching Robono notification service. Older packages do not include
|
|
9
|
+
these helpers.
|
|
10
|
+
|
|
11
|
+
## Required once per app
|
|
12
|
+
|
|
13
|
+
| Platform | App configuration | Private server configuration |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| iPhone | Enable Push Notifications for the Bundle ID and provision the app accordingly. | Apple Team ID, APNs Key ID, `.p8` private key, Bundle ID, sandbox/production environment. |
|
|
16
|
+
| Android | Firebase project, Android application ID and `google-services.json`; configure the notifications plugin and rebuild. | Google project ID and service account authorized for Firebase Cloud Messaging. Prefer your existing secret manager; never bundle its private key in the app. |
|
|
17
|
+
|
|
18
|
+
Apple setup: https://developer.apple.com/documentation/usernotifications/establishing-a-token-based-connection-to-apns
|
|
19
|
+
|
|
20
|
+
Expo native-token setup: https://docs.expo.dev/push-notifications/sending-notifications-custom/
|
|
21
|
+
|
|
22
|
+
Google setup: https://firebase.google.com/docs/cloud-messaging/send/v1-api
|
|
23
|
+
|
|
24
|
+
The supplied Expo connector uses native APNs tokens on iPhone and FCM tokens on
|
|
25
|
+
Android. It does not use Expo Push tokens. Development iPhone builds use the APNs
|
|
26
|
+
sandbox; TestFlight and App Store builds use production. Keep test/live credentials,
|
|
27
|
+
notification scopes and webhook secrets separate.
|
|
28
|
+
|
|
29
|
+
## Server
|
|
30
|
+
|
|
31
|
+
Apply `@robono/server/sql/messaging-notifications.sql` to your **own PostgreSQL
|
|
32
|
+
database**, using the private server role. The tables have row security enabled and
|
|
33
|
+
no public grants. They must not be exposed through your browser/mobile database API.
|
|
34
|
+
Use your database's encrypted storage and normal backup policy. Device tokens are
|
|
35
|
+
private routing identifiers; the notification signing keys remain in server secrets.
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import {createRobonoMessengerServer} from '@robono/server';
|
|
39
|
+
|
|
40
|
+
const messenger = createRobonoMessengerServer({
|
|
41
|
+
apiKey: process.env.ROBONO_API_KEY!,
|
|
42
|
+
allowedOrigins: ['https://your-company.com'],
|
|
43
|
+
authenticate: request => accounts.verifySession(request),
|
|
44
|
+
authorize: access => permissions.allowMessaging(access),
|
|
45
|
+
notifications: {
|
|
46
|
+
scope: 'your-app-production',
|
|
47
|
+
webhookSecret: process.env.ROBONO_WEBHOOK_SECRET!,
|
|
48
|
+
workerSecret: process.env.ROBONO_NOTIFICATION_WORKER_SECRET!,
|
|
49
|
+
query: (sql, values) => database.query(sql, values),
|
|
50
|
+
title: 'Your company',
|
|
51
|
+
apple: {
|
|
52
|
+
teamId: process.env.APNS_TEAM_ID!,
|
|
53
|
+
keyId: process.env.APNS_KEY_ID!,
|
|
54
|
+
privateKey: process.env.APNS_PRIVATE_KEY!,
|
|
55
|
+
bundleId: 'com.yourcompany.app',
|
|
56
|
+
sandbox: false,
|
|
57
|
+
},
|
|
58
|
+
google: {
|
|
59
|
+
projectId: process.env.FIREBASE_PROJECT_ID!,
|
|
60
|
+
clientEmail: process.env.FIREBASE_CLIENT_EMAIL!,
|
|
61
|
+
privateKey: process.env.FIREBASE_PRIVATE_KEY!,
|
|
62
|
+
},
|
|
63
|
+
authorizeRecipient: ({userId, conversationId}) =>
|
|
64
|
+
accounts.isActive(userId).then(active => active &&
|
|
65
|
+
permissions.mayReadConversation(userId, conversationId)),
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Your framework mounts this single POST route at /api/robono.
|
|
70
|
+
export const POST = (request: Request) => messenger.handle(request);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`accounts`, `permissions`, and `database` are the customer's existing services.
|
|
74
|
+
Their checks must return a verified user ID or an explicit permission decision.
|
|
75
|
+
Do not replace them with unconditional approval. Omit `apple` or `google` only if
|
|
76
|
+
you do not support that platform. Missing credentials produce a registration error.
|
|
77
|
+
|
|
78
|
+
Set your Robono integration's signed event URL to:
|
|
79
|
+
`https://your-company.com/api/robono?service=events`.
|
|
80
|
+
If you already process other Robono events at one endpoint, verify/route those
|
|
81
|
+
events in your existing handler; this notification handler acknowledges unrelated
|
|
82
|
+
events without processing them and must not replace your cleanup/billing handler.
|
|
83
|
+
|
|
84
|
+
Schedule a POST to `/api/robono?service=notification-worker` at your chosen alert
|
|
85
|
+
interval, with `Authorization: Bearer <ROBONO_NOTIFICATION_WORKER_SECRET>`.
|
|
86
|
+
Use an independent random secret of at least 32 characters. A one-minute schedule
|
|
87
|
+
can delay an alert by a minute; use a continuously running worker for prompt alerts.
|
|
88
|
+
The worker processes up to 20 due jobs per invocation. Multiple workers safely
|
|
89
|
+
claim different jobs. Run the SQL file's cleanup statements daily.
|
|
90
|
+
|
|
91
|
+
The signed event is acknowledged only after it is durably queued. Every send
|
|
92
|
+
checks the current account, conversation, message, blocks, mute preference and
|
|
93
|
+
device ownership. Transient failures retry with backoff; permanent failures remain
|
|
94
|
+
in the private `jobs` table with a safe error code. Monitor failed jobs and credential
|
|
95
|
+
errors. Old alerts expire after 24 hours. Apple/Google acceptance does not mean the
|
|
96
|
+
phone displayed the alert; do not use it as a delivered/read receipt. Provider
|
|
97
|
+
timeouts can leave delivery uncertain; stable collapse identifiers reduce repeated
|
|
98
|
+
alerts, but exact-once OS notification display cannot be promised.
|
|
99
|
+
|
|
100
|
+
## Expo / React Native
|
|
101
|
+
|
|
102
|
+
Install `expo-notifications`, `expo-secure-store` and the package's existing
|
|
103
|
+
`expo-crypto` dependency using `npx expo install`. Configure the Expo notifications
|
|
104
|
+
plugin, then build the app; Expo Go is not the production verification target.
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import {connectExpoMessagingNotifications} from
|
|
108
|
+
'@robono/messaging-react-native/expo-notifications';
|
|
109
|
+
|
|
110
|
+
const notifications = await connectExpoMessagingNotifications({
|
|
111
|
+
url: 'https://your-company.com/api/robono?service=notifications',
|
|
112
|
+
userId: signedInUser.id,
|
|
113
|
+
getAccessToken: () => accounts.accessToken(),
|
|
114
|
+
authorize: event => messagingClient.canOpenNotification(event),
|
|
115
|
+
open: event => navigation.openConversation(event.conversationId),
|
|
116
|
+
refresh: () => inbox.refresh(),
|
|
117
|
+
onError: error => showNotificationSetupError(error.message),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// When the person taps your "Enable notifications" button:
|
|
121
|
+
await notifications.enable();
|
|
122
|
+
|
|
123
|
+
// On logout, before destroying the session:
|
|
124
|
+
await Promise.allSettled([notifications.signOut(), messagingClient.signOut()]);
|
|
125
|
+
await accounts.signOut();
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Connect once per restored account. On navigation, keep the connector at app level;
|
|
129
|
+
do not recreate it for every chat. `dispose()` only removes listeners; use
|
|
130
|
+
`signOut()` to unregister the old account's device. If unregistering fails while
|
|
131
|
+
offline, clear local session data anyway and revoke that server session/account
|
|
132
|
+
access according to your existing sign-out policy. Alerts contain no message text,
|
|
133
|
+
media URLs or credentials. New registration moves the native token to the new
|
|
134
|
+
account, and notification opening always rechecks authorization.
|
|
135
|
+
|
|
136
|
+
The helper does not replace your app's global notification presentation handler
|
|
137
|
+
or interfere with calling notifications. Compose
|
|
138
|
+
`withMessagingNotificationPresentation` with that existing handler to suppress an
|
|
139
|
+
alert for the conversation already on screen. Set its active conversation to null
|
|
140
|
+
when the app is backgrounded. Browser background alerts are a separate capability;
|
|
141
|
+
these mobile credentials do not enable them.
|
|
142
|
+
|
|
143
|
+
## Ready means a device received an alert
|
|
144
|
+
|
|
145
|
+
Check both a foreground and background alert, a tap from a closed app, sign-out,
|
|
146
|
+
account switching, revoked chat access, muted conversations and token rotation.
|
|
147
|
+
Do not label notification setup complete merely because open-chat messages work
|
|
148
|
+
or Apple/Google accepted a request. The local automated tests use simulated provider
|
|
149
|
+
responses; they do not prove that a customer's credentials are provisioned correctly.
|
package/README.md
CHANGED
|
@@ -341,7 +341,7 @@ See [calling limits, billing rules and recovery](https://robono.com/docs#calling
|
|
|
341
341
|
for defaults, alert fields, revision conflicts, retry timing and active-call behavior.
|
|
342
342
|
|
|
343
343
|
|
|
344
|
-
### Sender message changes
|
|
344
|
+
### Sender message changes
|
|
345
345
|
|
|
346
346
|
The updated messaging adapter passes `edit`, `delete`, and `consume` through your
|
|
347
347
|
existing `authenticate` and `authorize` callbacks, always overriding caller-supplied
|
|
@@ -373,3 +373,10 @@ synchronizing messages, but do not show a banner, play a sound or send a push wh
|
|
|
373
373
|
this flag is true. Its value is refreshed on webhook retries. Do not treat mute as
|
|
374
374
|
loss of membership or stop delivery. The host owns OS push notifications and must
|
|
375
375
|
honor this field in its notification sender.
|
|
376
|
+
|
|
377
|
+
## Optional photo and video screening
|
|
378
|
+
|
|
379
|
+
Connected networks can use Robono-hosted Amazon screening with their existing
|
|
380
|
+
Processing API key, including apps with their own storage. See [screening setup](https://robono.com/docs#screening)
|
|
381
|
+
for the private-upload flow, prices, spending controls and pending-result handling.
|
|
382
|
+
This addition is not in server 0.16.0; update to the screening release before use.
|
package/SBOM.spdx.json
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
"spdxVersion": "SPDX-2.3",
|
|
3
3
|
"dataLicense": "CC0-1.0",
|
|
4
4
|
"SPDXID": "SPDXRef-DOCUMENT",
|
|
5
|
-
"name": "@robono/server@0.
|
|
6
|
-
"documentNamespace": "http://spdx.org/spdxdocs/@robono%2fserver-0.
|
|
5
|
+
"name": "@robono/server@0.17.0",
|
|
6
|
+
"documentNamespace": "http://spdx.org/spdxdocs/@robono%2fserver-0.17.0-***",
|
|
7
7
|
"creationInfo": {
|
|
8
|
-
"created": "2026-11-
|
|
8
|
+
"created": "2026-11-03T15:35:51.400Z",
|
|
9
9
|
"creators": [
|
|
10
10
|
"Tool: npm/cli-11.6.2"
|
|
11
11
|
]
|
|
12
12
|
},
|
|
13
13
|
"documentDescribes": [
|
|
14
|
-
"SPDXRef-Package-robono.server-0.
|
|
14
|
+
"SPDXRef-Package-robono.server-0.17.0"
|
|
15
15
|
],
|
|
16
16
|
"packages": [
|
|
17
17
|
{
|
|
18
18
|
"name": "@robono/server",
|
|
19
|
-
"SPDXID": "SPDXRef-Package-robono.server-0.
|
|
20
|
-
"versionInfo": "0.
|
|
19
|
+
"SPDXID": "SPDXRef-Package-robono.server-0.17.0",
|
|
20
|
+
"versionInfo": "0.17.0",
|
|
21
21
|
"packageFileName": "",
|
|
22
22
|
"description": "Provider-neutral server SDK for the Robono Bridge API.",
|
|
23
23
|
"primaryPackagePurpose": "LIBRARY",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
{
|
|
30
30
|
"referenceCategory": "PACKAGE-MANAGER",
|
|
31
31
|
"referenceType": "purl",
|
|
32
|
-
"referenceLocator": "pkg:npm/%40robono/server@0.
|
|
32
|
+
"referenceLocator": "pkg:npm/%40robono/server@0.17.0"
|
|
33
33
|
}
|
|
34
34
|
]
|
|
35
35
|
}
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"relationships": [
|
|
38
38
|
{
|
|
39
39
|
"spdxElementId": "SPDXRef-DOCUMENT",
|
|
40
|
-
"relatedSpdxElement": "SPDXRef-Package-robono.server-0.
|
|
40
|
+
"relatedSpdxElement": "SPDXRef-Package-robono.server-0.17.0",
|
|
41
41
|
"relationshipType": "DESCRIBES"
|
|
42
42
|
}
|
|
43
43
|
]
|
package/SCREENING.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Photo and video screening for connected networks
|
|
2
|
+
|
|
3
|
+
Available in the upcoming server release (not present in server 0.16.0).
|
|
4
|
+
|
|
5
|
+
A connected network can use Robono's Amazon screening without replacing its own
|
|
6
|
+
chat interface or attachment storage. Do not put your network API key in a phone
|
|
7
|
+
app or website. No customer AWS account, Amazon keys or extra AWS server is needed.
|
|
8
|
+
|
|
9
|
+
1. In Robono's **Features & preview → Photo and video screening**, choose categories,
|
|
10
|
+
sensitivity and a monthly limit, then accept the prices and processing terms.
|
|
11
|
+
2. Use an existing backend API key with **Processing** permission.
|
|
12
|
+
3. Keep attachments private until screening returns `allowed` for the exact bytes.
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import {RobonoScreening} from '@robono/server';
|
|
16
|
+
const screening = new RobonoScreening({apiKey: process.env.ROBONO_API_KEY!});
|
|
17
|
+
// Authenticate your own user and authorize their upload before this call.
|
|
18
|
+
const job = await screening.upload(stableUploadId, {
|
|
19
|
+
kind: 'image', fileName: 'photo.jpg', mimeType: 'image/jpeg', byteSize: bytes.length,
|
|
20
|
+
}, bytes);
|
|
21
|
+
// Store job.id against your private upload. Return promptly; poll status later.
|
|
22
|
+
const result = await screening.status(job.id);
|
|
23
|
+
if (result.state === 'allowed') {
|
|
24
|
+
await screening.assertAllowed(job.id, bytes); // checks current policy + SHA-256
|
|
25
|
+
// Publish these exact bytes to the recipients your app has authorized.
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Videos use `kind: 'video'`, `mimeType: 'video/mp4'` or `video/quicktime`, and
|
|
30
|
+
`durationMs`. Server verification checks duration; a false short duration fails.
|
|
31
|
+
Video analysis can take minutes. Show "Checking attachment" while pending, allow
|
|
32
|
+
canceling, and keep ordinary chat usable. `blocked` and `failed` must never release
|
|
33
|
+
the file. Store a stable request ID across network retries. A changed file needs a
|
|
34
|
+
new request ID. A policy change invalidates approval for future publication.
|
|
35
|
+
|
|
36
|
+
For direct HTTPS integration, POST to `https://api.robono.com/v1/screening` with
|
|
37
|
+
`Authorization: Bearer YOUR_SERVER_KEY`. Operations:
|
|
38
|
+
|
|
39
|
+
- `prepare`: `{operation:'prepare', requestId, file}`. Returns job and private PUT
|
|
40
|
+
upload instructions. Send only the returned storage headers to the upload URL.
|
|
41
|
+
- `submit`: `{operation:'submit', id}` after upload.
|
|
42
|
+
- `status`: `{operation:'status', id}`. Pending is not approval.
|
|
43
|
+
|
|
44
|
+
Responses include `id`, `state`, `categories`, `sha256`, `chargedMicros`,
|
|
45
|
+
`reservedMicros` and timestamps. Amounts are USD millionths. Do not trust a client
|
|
46
|
+
phone's claim that it passed screening; read the result on your backend. Never
|
|
47
|
+
publish a mutable URL whose contents can change after the check.
|
|
48
|
+
|
|
49
|
+
## Robono-hosted attachments
|
|
50
|
+
|
|
51
|
+
With the updated server and supplied web/mobile packages, existing managed uploads
|
|
52
|
+
are automatically checked before delivery. The database also rejects direct sends
|
|
53
|
+
of unchecked photos/videos. Enabled screening requires managed storage for hosted
|
|
54
|
+
messaging; private external storage can use the standalone flow above. Older SDKs
|
|
55
|
+
must be updated before enabling screening. No extra per-chat switches.
|
|
56
|
+
|
|
57
|
+
## Formats, costs and privacy
|
|
58
|
+
|
|
59
|
+
JPEG/PNG up to 15 MiB. MP4/MOV up to 32 MiB and 15 minutes. Other formats fail rather
|
|
60
|
+
than bypass screening. These are visual checks, not audio/profanity checks, and
|
|
61
|
+
can produce missed content or mistaken blocks.
|
|
62
|
+
|
|
63
|
+
Release prices: $3/1,000 photos and $0.20 per started video minute, no monthly fee.
|
|
64
|
+
Successful checks count even if blocked. Failed checks are uncharged. The same
|
|
65
|
+
accepted job is not billed twice. New work stops at the network screening cap or
|
|
66
|
+
overall spending cap. Job status expires after 30 days; upload a new copy for a new
|
|
67
|
+
check. Keep the originally screened bytes private while a check is pending.
|
|
68
|
+
|
|
69
|
+
Only selected media goes to Amazon Rekognition in Northern Virginia. Robono opts
|
|
70
|
+
out of AWS using it for AI-service improvement. Private temporary screening copies
|
|
71
|
+
are removed after completion, with a one-day S3 expiry backstop. File names and
|
|
72
|
+
hashes are cleared after 30 days; aggregate usage/billing records remain. AWS
|
|
73
|
+
operational retention follows its terms. See Robono's provider disclosure.
|
package/dist/index.d.ts
CHANGED
|
@@ -19,4 +19,11 @@ export { createMessagingTransformBackendAdapter } from './messaging-transforms.j
|
|
|
19
19
|
export { RobonoLocationBackend, createLocationBackendAdapter } from './location.js';
|
|
20
20
|
export type { LocationGrantInput } from './location.js';
|
|
21
21
|
export { RobonoLocationChatBackend } from './location-chat.js';
|
|
22
|
+
export { createRobonoMessengerServer } from './messenger.js';
|
|
23
|
+
export type { RobonoMessengerServerOptions, MessengerAccess } from './messenger.js';
|
|
24
|
+
export * from './messaging-notifications.js';
|
|
25
|
+
export * from './messaging-notification-providers.js';
|
|
26
|
+
export * from './messaging-notification-postgres.js';
|
|
27
|
+
export { RobonoScreening } from './screening.js';
|
|
28
|
+
export type { ScreeningFile, ScreeningResult } from './screening.js';
|
|
22
29
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACrI,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,YAAY,EACV,yBAAyB,EACzB,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,yBAAyB,EACzB,WAAW,EACX,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtE,mBAAmB,YAAY,CAAC;AAEhC,OAAO,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AACvF,YAAY,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEpF,OAAO,EAAC,kCAAkC,EAAC,MAAM,sBAAsB,CAAC;AACxE,YAAY,EAAC,uBAAuB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AACtI,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAC,sCAAsC,EAAC,MAAM,2BAA2B,CAAC;AAEjF,OAAO,EAAC,qBAAqB,EAAC,4BAA4B,EAAC,MAAM,eAAe,CAAC;AACjF,YAAY,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACtD,OAAO,EAAC,yBAAyB,EAAC,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,YAAY,EAAE,2BAA2B,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACrI,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,YAAY,EACV,yBAAyB,EACzB,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,yBAAyB,EACzB,WAAW,EACX,kBAAkB,GACnB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtE,mBAAmB,YAAY,CAAC;AAEhC,OAAO,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AACvF,YAAY,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEpF,OAAO,EAAC,kCAAkC,EAAC,MAAM,sBAAsB,CAAC;AACxE,YAAY,EAAC,uBAAuB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AACtI,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAC,sCAAsC,EAAC,MAAM,2BAA2B,CAAC;AAEjF,OAAO,EAAC,qBAAqB,EAAC,4BAA4B,EAAC,MAAM,eAAe,CAAC;AACjF,YAAY,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AACtD,OAAO,EAAC,yBAAyB,EAAC,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAC,2BAA2B,EAAC,MAAM,gBAAgB,CAAC;AAC3D,YAAY,EAAC,4BAA4B,EAAC,eAAe,EAAC,MAAM,gBAAgB,CAAC;AAEjF,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,sCAAsC,CAAC;AAErD,OAAO,EAAC,eAAe,EAAC,MAAM,gBAAgB,CAAC;AAC/C,YAAY,EAAC,aAAa,EAAC,eAAe,EAAC,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -11,4 +11,9 @@ export { RobonoManagedMedia } from './managed-media.js';
|
|
|
11
11
|
export { createMessagingTransformBackendAdapter } from './messaging-transforms.js';
|
|
12
12
|
export { RobonoLocationBackend, createLocationBackendAdapter } from './location.js';
|
|
13
13
|
export { RobonoLocationChatBackend } from './location-chat.js';
|
|
14
|
+
export { createRobonoMessengerServer } from './messenger.js';
|
|
15
|
+
export * from './messaging-notifications.js';
|
|
16
|
+
export * from './messaging-notification-providers.js';
|
|
17
|
+
export * from './messaging-notification-postgres.js';
|
|
18
|
+
export { RobonoScreening } from './screening.js';
|
|
14
19
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAM1D,OAAO,EACL,yBAAyB,EACzB,WAAW,EACX,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGtE,OAAO,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAGvF,OAAO,EAAC,kCAAkC,EAAC,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAC,sCAAsC,EAAC,MAAM,2BAA2B,CAAC;AAEjF,OAAO,EAAC,qBAAqB,EAAC,4BAA4B,EAAC,MAAM,eAAe,CAAC;AAEjF,OAAO,EAAC,yBAAyB,EAAC,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAM1D,OAAO,EACL,yBAAyB,EACzB,WAAW,EACX,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGtE,OAAO,EAAE,sBAAsB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAGvF,OAAO,EAAC,kCAAkC,EAAC,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAC,sCAAsC,EAAC,MAAM,2BAA2B,CAAC;AAEjF,OAAO,EAAC,qBAAqB,EAAC,4BAA4B,EAAC,MAAM,eAAe,CAAC;AAEjF,OAAO,EAAC,yBAAyB,EAAC,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAC,2BAA2B,EAAC,MAAM,gBAAgB,CAAC;AAG3D,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uCAAuC,CAAC;AACtD,cAAc,sCAAsC,CAAC;AAErD,OAAO,EAAC,eAAe,EAAC,MAAM,gBAAgB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-media.d.ts","sourceRoot":"","sources":["../src/managed-media.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,uBAAuB,EAAC,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AACvF,yFAAyF;AACzF,qBAAa,kBAAmB,YAAW,uBAAuB;IAErD,OAAO,CAAC,OAAO;IAD3B,OAAO,CAAC,GAAG,CAAQ;gBACC,OAAO,EAAC;QAAC,MAAM,EAAC,MAAM,CAAC;QAAA,OAAO,CAAC,EAAC,MAAM,CAAC;QAAA,KAAK,CAAC,EAAC,OAAO,KAAK,CAAA;KAAC;YAKjE,OAAO;
|
|
1
|
+
{"version":3,"file":"managed-media.d.ts","sourceRoot":"","sources":["../src/managed-media.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,uBAAuB,EAAC,oBAAoB,EAAC,MAAM,sBAAsB,CAAC;AACvF,yFAAyF;AACzF,qBAAa,kBAAmB,YAAW,uBAAuB;IAErD,OAAO,CAAC,OAAO;IAD3B,OAAO,CAAC,GAAG,CAAQ;gBACC,OAAO,EAAC;QAAC,MAAM,EAAC,MAAM,CAAC;QAAA,OAAO,CAAC,EAAC,MAAM,CAAC;QAAA,KAAK,CAAC,EAAC,OAAO,KAAK,CAAA;KAAC;YAKjE,OAAO;IAOrB,OAAO,CAAC,KAAK,EAAC,UAAU,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAAE,UAAU,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACzG,QAAQ,CAAC,KAAK,EAAC,UAAU,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAE,UAAU,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAKxH,QAAQ,CAAC,KAAK,EAAC,UAAU,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAE,UAAU,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAClH,iBAAiB,CAAC,KAAK,EAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAA,cAAc,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAA;KAAC,GAAE,OAAO,CAAC;QAAC,GAAG,EAAC,MAAM,CAAC;QAAA,OAAO,CAAC,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC;QAAA,KAAK,EAAC,oBAAoB,CAAA;KAAC,CAAC;IAChK,SAAS,CAAC,KAAK,EAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAA,cAAc,EAAC,MAAM,CAAC;QAAA,SAAS,EAAC,MAAM,CAAA;KAAC,GAAE,OAAO,CAAC;QAAC,GAAG,EAAC,MAAM,CAAC;QAAA,OAAO,CAAC,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC;QAAA,KAAK,EAAC,oBAAoB,CAAA;KAAC,GAAC,IAAI,CAAC;IACvJ,OAAO,CAAC,KAAK,EAAC,UAAU,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,KAAK,EAAC;QAAC,OAAO,EAAC,MAAM,CAAC;QAAA,cAAc,EAAC,MAAM,CAAC;QAAA,OAAO,EAAC,MAAM,CAAA;KAAC,GAAE,OAAO,CAAC,oBAAoB,GAAC,IAAI,CAAC;CAG7G"}
|
package/dist/managed-media.js
CHANGED
|
@@ -13,6 +13,8 @@ export class RobonoManagedMedia {
|
|
|
13
13
|
async request(operation, input) {
|
|
14
14
|
const response = await (this.options.fetch ?? fetch)(this.url, { method: 'POST', redirect: 'error', signal: AbortSignal.timeout(operation === 'complete' ? 120000 : 15000), headers: { authorization: `Bearer ${this.options.apiKey}`, 'content-type': 'application/json' }, body: JSON.stringify({ ...input, operation }) });
|
|
15
15
|
const data = await response.json().catch(() => null);
|
|
16
|
+
if (response.status === 202 && data?.error?.code === 'screening_pending')
|
|
17
|
+
throw new RobonoError('This attachment is being checked before delivery.', { status: 202, code: 'screening_pending', retryable: true });
|
|
16
18
|
if (!response.ok)
|
|
17
19
|
throw new RobonoError(data?.error?.message ?? 'Attachment request failed.', { status: response.status, code: data?.error?.code ?? 'media_unavailable', retryable: response.status === 429 || response.status >= 500 });
|
|
18
20
|
return data;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-media.js","sourceRoot":"","sources":["../src/managed-media.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"managed-media.js","sourceRoot":"","sources":["../src/managed-media.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MessagingNotificationStore } from './messaging-notifications.js';
|
|
2
|
+
/** Compatible with pg Pool.query; keep this database connection exclusively on your server. */
|
|
3
|
+
export type MessagingNotificationQuery = (sql: string, parameters: unknown[]) => Promise<{
|
|
4
|
+
rows: Record<string, any>[];
|
|
5
|
+
}>;
|
|
6
|
+
export declare function createPostgresMessagingNotificationStore(query: MessagingNotificationQuery): MessagingNotificationStore;
|
|
7
|
+
//# sourceMappingURL=messaging-notification-postgres.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging-notification-postgres.d.ts","sourceRoot":"","sources":["../src/messaging-notification-postgres.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,0BAA0B,EAAsC,MAAM,8BAA8B,CAAC;AAElH,+FAA+F;AAC/F,MAAM,MAAM,0BAA0B,GAAC,CAAC,GAAG,EAAC,MAAM,EAAC,UAAU,EAAC,OAAO,EAAE,KAAG,OAAO,CAAC;IAAC,IAAI,EAAC,MAAM,CAAC,MAAM,EAAC,GAAG,CAAC,EAAE,CAAA;CAAC,CAAE,CAAC;AAChH,wBAAgB,wCAAwC,CAAC,KAAK,EAAC,0BAA0B,GAAE,0BAA0B,CA8BpH"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export function createPostgresMessagingNotificationStore(query) {
|
|
2
|
+
return {
|
|
3
|
+
async register(scope, device) {
|
|
4
|
+
// Serialize registrations for this token; move it away from a previous signed-in account.
|
|
5
|
+
await query(`select robono_notifications.register_device($1,$2,$3,$4,$5)`, [scope, device.id, device.userId, device.provider, device.token]);
|
|
6
|
+
},
|
|
7
|
+
async remove(scope, userId, id, token) { await query('delete from robono_notifications.devices where scope=$1 and user_id=$2 and device_id=$3 and ($4::text is null or token=$4)', [scope, userId, id, token ?? null]); },
|
|
8
|
+
async enqueue(scope, event) {
|
|
9
|
+
await query(`insert into robono_notifications.jobs(scope,event_id,device_id,user_id,provider,token,event)
|
|
10
|
+
select $1,$2,device_id,user_id,provider,token,$4::jsonb from robono_notifications.devices
|
|
11
|
+
where scope=$1 and user_id=$3 and updated_at>now()-interval '90 days'
|
|
12
|
+
on conflict(scope,event_id,device_id,user_id) do nothing`, [scope, event.event_id, event.recipient_external_user_id, JSON.stringify(event)]);
|
|
13
|
+
},
|
|
14
|
+
async claim(scope, limit, lease) {
|
|
15
|
+
const result = await query(`with ready as (
|
|
16
|
+
select id from robono_notifications.jobs where scope=$1 and
|
|
17
|
+
((state='pending' and next_attempt_at<=now()) or (state='running' and lease_until<=now()))
|
|
18
|
+
order by next_attempt_at,id for update skip locked limit $2
|
|
19
|
+
) update robono_notifications.jobs j set state='running',lease=$3,lease_until=now()+interval '10 minutes',attempt=attempt+1
|
|
20
|
+
from ready where j.id=ready.id returning j.*`, [scope, limit, lease]);
|
|
21
|
+
return result.rows.map(row => ({ id: String(row.id), lease, event: row.event, attempt: row.attempt,
|
|
22
|
+
device: { id: row.device_id, userId: row.user_id, provider: row.provider, token: row.token } }));
|
|
23
|
+
},
|
|
24
|
+
async current(scope, device) { return (await query(`select 1 from robono_notifications.devices where scope=$1 and device_id=$2 and user_id=$3 and provider=$4 and token=$5 and updated_at>now()-interval '90 days'`, [scope, device.id, device.userId, device.provider, device.token])).rows.length === 1; },
|
|
25
|
+
async finish(scope, job, result) {
|
|
26
|
+
await query(`update robono_notifications.jobs set state=$4,next_attempt_at=coalesce($5,next_attempt_at),lease=null,lease_until=null,
|
|
27
|
+
last_code=$6,finished_at=case when $4 in ('sent','skipped','failed') then now() else null end
|
|
28
|
+
where scope=$1 and id=$2 and lease=$3 and state='running'`, [scope, job.id, job.lease, result.state === 'retry' ? 'pending' : result.state, result.retryAt ?? null, result.code ?? null]);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=messaging-notification-postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging-notification-postgres.js","sourceRoot":"","sources":["../src/messaging-notification-postgres.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,wCAAwC,CAAC,KAAgC;IACvF,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAC,MAAM;YACzB,0FAA0F;YAC1F,MAAM,KAAK,CAAC,6DAA6D,EAAC,CAAC,KAAK,EAAC,MAAM,CAAC,EAAE,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,QAAQ,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1I,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE,EAAC,KAAK,IAAE,MAAM,KAAK,CAAC,4HAA4H,EAAC,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE,EAAC,KAAK,IAAE,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC;QAC7M,KAAK,CAAC,OAAO,CAAC,KAAK,EAAC,KAAK;YACvB,MAAM,KAAK,CAAC;;;iEAG+C,EAAC,CAAC,KAAK,EAAC,KAAK,CAAC,QAAQ,EAAC,KAAK,CAAC,0BAA0B,EAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7I,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,KAAK,EAAC,KAAK,EAAC,KAAK;YAC3B,MAAM,MAAM,GAAC,MAAM,KAAK,CAAC;;;;;qDAKsB,EAAC,CAAC,KAAK,EAAC,KAAK,EAAC,KAAK,CAAC,CAAC,CAAC;YACrE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA,EAAE,CAAA,CAAC,EAAC,EAAE,EAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAC,KAAK,EAAC,KAAK,EAAC,GAAG,CAAC,KAAK,EAAC,OAAO,EAAC,GAAG,CAAC,OAAO;gBACvF,MAAM,EAAC,EAAC,EAAE,EAAC,GAAG,CAAC,SAAS,EAAC,MAAM,EAAC,GAAG,CAAC,OAAO,EAAC,QAAQ,EAAC,GAAG,CAAC,QAAQ,EAAC,KAAK,EAAC,GAAG,CAAC,KAAK,EAAC,EAAC,CAAC,CAAuB,CAAC;QAChH,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,KAAK,EAAC,MAAM,IAAE,OAAO,CAAC,MAAM,KAAK,CAAC,gKAAgK,EAAC,CAAC,KAAK,EAAC,MAAM,CAAC,EAAE,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,QAAQ,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAG,CAAC,CAAC,CAAA,CAAC;QACjS,KAAK,CAAC,MAAM,CAAC,KAAK,EAAC,GAAG,EAAC,MAAM;YAC3B,MAAM,KAAK,CAAC;;kEAEgD,EAAC,CAAC,KAAK,EAAC,GAAG,CAAC,EAAE,EAAC,GAAG,CAAC,KAAK,EAAC,MAAM,CAAC,KAAK,KAAG,OAAO,CAAA,CAAC,CAAA,SAAS,CAAA,CAAC,CAAA,MAAM,CAAC,KAAK,EAAC,MAAM,CAAC,OAAO,IAAE,IAAI,EAAC,MAAM,CAAC,IAAI,IAAE,IAAI,CAAC,CAAC,CAAC;QAC9K,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { MessagingPushDevice, MessagingPushData, MessagingNotificationOptions } from './messaging-notifications.js';
|
|
2
|
+
export interface AppleMessagingCredentials {
|
|
3
|
+
teamId: string;
|
|
4
|
+
keyId: string;
|
|
5
|
+
privateKey: string;
|
|
6
|
+
bundleId: string;
|
|
7
|
+
sandbox?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface GoogleMessagingCredentials {
|
|
10
|
+
projectId: string;
|
|
11
|
+
clientEmail: string;
|
|
12
|
+
privateKey: string;
|
|
13
|
+
}
|
|
14
|
+
type SendResult = Awaited<ReturnType<MessagingNotificationOptions['send']>>;
|
|
15
|
+
/** Uses only fixed Apple/Google endpoints. Private keys never enter notification payloads. */
|
|
16
|
+
export declare function createMessagingPushSender(options: {
|
|
17
|
+
apple?: AppleMessagingCredentials;
|
|
18
|
+
google?: GoogleMessagingCredentials;
|
|
19
|
+
title?: string;
|
|
20
|
+
fetch?: typeof fetch;
|
|
21
|
+
}): {
|
|
22
|
+
providers: ("apns" | "fcm")[];
|
|
23
|
+
send(device: MessagingPushDevice, data: MessagingPushData): Promise<SendResult>;
|
|
24
|
+
};
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=messaging-notification-providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging-notification-providers.d.ts","sourceRoot":"","sources":["../src/messaging-notification-providers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,mBAAmB,EAAC,iBAAiB,EAAC,4BAA4B,EAAC,MAAM,8BAA8B,CAAC;AAErH,MAAM,WAAW,yBAAyB;IAAE,MAAM,EAAC,MAAM,CAAC;IAAA,KAAK,EAAC,MAAM,CAAC;IAAA,UAAU,EAAC,MAAM,CAAC;IAAA,QAAQ,EAAC,MAAM,CAAC;IAAA,OAAO,CAAC,EAAC,OAAO,CAAA;CAAC;AAC1H,MAAM,WAAW,0BAA0B;IAAE,SAAS,EAAC,MAAM,CAAC;IAAA,WAAW,EAAC,MAAM,CAAC;IAAA,UAAU,EAAC,MAAM,CAAA;CAAC;AACnG,KAAK,UAAU,GAAC,OAAO,CAAC,UAAU,CAAC,4BAA4B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAS1E,8FAA8F;AAC9F,wBAAgB,yBAAyB,CAAC,OAAO,EAAC;IAAC,KAAK,CAAC,EAAC,yBAAyB,CAAC;IAAA,MAAM,CAAC,EAAC,0BAA0B,CAAC;IAAA,KAAK,CAAC,EAAC,MAAM,CAAC;IAAA,KAAK,CAAC,EAAC,OAAO,KAAK,CAAA;CAAC;;iBAsDrI,mBAAmB,QAAM,iBAAiB,GAAE,OAAO,CAAC,UAAU,CAAC;EAKlF"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { createHash, createPrivateKey, sign } from 'node:crypto';
|
|
2
|
+
import { connect } from 'node:http2';
|
|
3
|
+
const b64 = (data) => Buffer.from(JSON.stringify(data)).toString('base64url');
|
|
4
|
+
function jwt(header, claims, key, algorithm, p1363 = false) {
|
|
5
|
+
const body = b64(header) + '.' + b64(claims);
|
|
6
|
+
const signature = sign(algorithm, Buffer.from(body), { key: createPrivateKey(key), ...(p1363 ? { dsaEncoding: 'ieee-p1363' } : {}) });
|
|
7
|
+
return body + '.' + signature.toString('base64url');
|
|
8
|
+
}
|
|
9
|
+
function collapse(data) { return createHash('sha256').update(data.accountScope + ':' + data.conversationId).digest('hex'); }
|
|
10
|
+
/** Uses only fixed Apple/Google endpoints. Private keys never enter notification payloads. */
|
|
11
|
+
export function createMessagingPushSender(options) {
|
|
12
|
+
const title = options.title?.trim() || 'New message';
|
|
13
|
+
if (title.length > 80)
|
|
14
|
+
throw Error('Use a notification title of 80 characters or fewer.');
|
|
15
|
+
const apple = options.apple, google = options.google;
|
|
16
|
+
if (apple && (!/^[A-Z\d]{10}$/.test(apple.teamId) || !/^[A-Z\d]{10}$/.test(apple.keyId) || !/^[-\w]+(?:\.[-\w]+)+$/.test(apple.bundleId)))
|
|
17
|
+
throw Error('Check the Apple Team ID, Key ID and app bundle ID.');
|
|
18
|
+
if (google && (!/^[a-z][a-z\d-]{4,61}[a-z\d]$/.test(google.projectId) || !/^[^\s@]+@[^\s@]+\.gserviceaccount\.com$/.test(google.clientEmail)))
|
|
19
|
+
throw Error('Check the Google project ID and service-account email.');
|
|
20
|
+
if (apple && (createPrivateKey(apple.privateKey).asymmetricKeyType !== 'ec' || createPrivateKey(apple.privateKey).asymmetricKeyDetails?.namedCurve !== 'prime256v1'))
|
|
21
|
+
throw Error('Use the Apple APNs .p8 signing key.');
|
|
22
|
+
if (google && createPrivateKey(google.privateKey).asymmetricKeyType !== 'rsa')
|
|
23
|
+
throw Error('Use the Google service-account private key.');
|
|
24
|
+
let appleToken = { value: '', expires: 0 }, googleToken = { value: '', expires: 0 }, googlePending;
|
|
25
|
+
const request = options.fetch ?? fetch;
|
|
26
|
+
async function googleAccess() {
|
|
27
|
+
if (googleToken.expires > Date.now())
|
|
28
|
+
return googleToken.value;
|
|
29
|
+
if (googlePending)
|
|
30
|
+
return googlePending;
|
|
31
|
+
googlePending = (async () => {
|
|
32
|
+
const now = Math.floor(Date.now() / 1000), assertion = jwt({ alg: 'RS256', typ: 'JWT' }, { iss: google.clientEmail, scope: 'https://www.googleapis.com/auth/firebase.messaging', aud: 'https://oauth2.googleapis.com/token', iat: now, exp: now + 3600 }, google.privateKey, 'RSA-SHA256');
|
|
33
|
+
const response = await request('https://oauth2.googleapis.com/token', { method: 'POST', redirect: 'error', signal: AbortSignal.timeout(15000), headers: { 'content-type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', assertion }) });
|
|
34
|
+
const data = await response.json();
|
|
35
|
+
if (!response.ok || !data.access_token || typeof data.expires_in !== 'number')
|
|
36
|
+
throw Error('Google notification authentication failed.');
|
|
37
|
+
googleToken = { value: data.access_token, expires: Date.now() + Math.max(0, Math.min(data.expires_in, 3600) - 60) * 1000 };
|
|
38
|
+
return data.access_token;
|
|
39
|
+
})();
|
|
40
|
+
try {
|
|
41
|
+
return await googlePending;
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
googlePending = undefined;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function sendApple(device, data) {
|
|
48
|
+
if (!apple)
|
|
49
|
+
return { accepted: false, retryable: false, code: 'apple_credentials_missing' };
|
|
50
|
+
if (!/^[a-f\d]{64,200}$/i.test(device.token))
|
|
51
|
+
return { accepted: false, invalidDevice: true, code: 'invalid_token' };
|
|
52
|
+
if (appleToken.expires <= Date.now())
|
|
53
|
+
appleToken = { value: jwt({ alg: 'ES256', kid: apple.keyId }, { iss: apple.teamId, iat: Math.floor(Date.now() / 1000) }, apple.privateKey, 'sha256', true), expires: Date.now() + 45 * 60000 };
|
|
54
|
+
const payload = JSON.stringify({ aps: { alert: { title, body: 'Open the app to read your message.' }, sound: 'default', 'thread-id': collapse(data) }, body: data });
|
|
55
|
+
return new Promise(resolve => {
|
|
56
|
+
const session = connect(apple.sandbox ? 'https://api.sandbox.push.apple.com' : 'https://api.push.apple.com');
|
|
57
|
+
let finished = false;
|
|
58
|
+
const finish = (result) => { if (finished)
|
|
59
|
+
return; finished = true; clearTimeout(timer); session.destroy(); resolve(result); };
|
|
60
|
+
const timer = setTimeout(() => finish({ accepted: false, retryable: true, code: 'apple_timeout' }), 15000);
|
|
61
|
+
session.on('error', () => finish({ accepted: false, retryable: true, code: 'apple_connection_failed' }));
|
|
62
|
+
const stream = session.request({ ':method': 'POST', ':path': '/3/device/' + device.token, authorization: 'bearer ' + appleToken.value, 'apns-topic': apple.bundleId, 'apns-push-type': 'alert', 'apns-priority': '10', 'apns-expiration': String(Math.floor(Date.now() / 1000) + 3600), 'apns-collapse-id': collapse(data), 'content-type': 'application/json' });
|
|
63
|
+
let status = 0, body = '';
|
|
64
|
+
stream.setEncoding('utf8');
|
|
65
|
+
stream.on('response', headers => { status = Number(headers[':status']); });
|
|
66
|
+
stream.on('data', chunk => { if (body.length < 8192)
|
|
67
|
+
body += chunk; });
|
|
68
|
+
stream.on('error', () => finish({ accepted: false, retryable: true, code: 'apple_connection_failed' }));
|
|
69
|
+
stream.on('end', () => {
|
|
70
|
+
let reason = '';
|
|
71
|
+
try {
|
|
72
|
+
reason = JSON.parse(body).reason;
|
|
73
|
+
}
|
|
74
|
+
catch { }
|
|
75
|
+
if (status === 403)
|
|
76
|
+
appleToken = { value: '', expires: 0 };
|
|
77
|
+
finish({ accepted: status === 200, invalidDevice: status === 410 || reason === 'BadDeviceToken', retryable: reason === 'ExpiredProviderToken' || status === 429 || status >= 500, code: status === 200 ? 'accepted' : status === 403 ? 'apple_credentials_rejected' : 'apple_rejected' });
|
|
78
|
+
});
|
|
79
|
+
stream.end(payload);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async function sendGoogle(device, data) {
|
|
83
|
+
if (!google)
|
|
84
|
+
return { accepted: false, retryable: false, code: 'google_credentials_missing' };
|
|
85
|
+
const response = await request('https://fcm.googleapis.com/v1/projects/' + encodeURIComponent(google.projectId) + '/messages:send', {
|
|
86
|
+
method: 'POST', redirect: 'error', signal: AbortSignal.timeout(15000), headers: { authorization: 'Bearer ' + await googleAccess(), 'content-type': 'application/json' },
|
|
87
|
+
body: JSON.stringify({ message: { token: device.token, notification: { title, body: 'Open the app to read your message.' }, data,
|
|
88
|
+
android: { priority: 'high', ttl: '3600s', collapse_key: collapse(data), notification: { tag: collapse(data), channel_id: 'robono-messages' } } } }),
|
|
89
|
+
});
|
|
90
|
+
const result = await response.json().catch(() => null);
|
|
91
|
+
if (response.status === 401)
|
|
92
|
+
googleToken = { value: '', expires: 0 };
|
|
93
|
+
return { accepted: response.ok, invalidDevice: result?.error?.details?.some(detail => detail.errorCode === 'UNREGISTERED') ?? false,
|
|
94
|
+
retryable: response.status === 401 || response.status === 429 || response.status >= 500, code: response.ok ? 'accepted' : response.status === 401 || response.status === 403 ? 'google_credentials_rejected' : 'google_rejected' };
|
|
95
|
+
}
|
|
96
|
+
return { providers: [...(apple ? ['apns'] : []), ...(google ? ['fcm'] : [])],
|
|
97
|
+
async send(device, data) {
|
|
98
|
+
try {
|
|
99
|
+
return device.provider === 'apns' ? await sendApple(device, data) : await sendGoogle(device, data);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
return { accepted: false, retryable: true, code: 'provider_unavailable' };
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=messaging-notification-providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messaging-notification-providers.js","sourceRoot":"","sources":["../src/messaging-notification-providers.ts"],"names":[],"mappings":"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"}
|