@dotbots-boutique/server-sdk 0.4.2 → 0.5.3
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 +38 -12
- package/dist/client.d.ts +3 -2
- package/dist/client.js +39 -1
- package/dist/index.d.ts +1 -1
- package/dist/types.d.ts +14 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,13 +16,13 @@ For user-facing interactions in the browser, use the frontend SDK (`@dotbots-bou
|
|
|
16
16
|
## Installation
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
npm install @dotbots-boutique/server-sdk
|
|
19
|
+
npm install @dotbots-boutique/server-sdk@0.4.0
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
Or in Deno:
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
|
-
import { DotBotsBackend } from 'npm:@dotbots-boutique/server-sdk';
|
|
25
|
+
import { DotBotsBackend } from 'npm:@dotbots-boutique/server-sdk@0.4.0';
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## Environment variables
|
|
@@ -32,8 +32,7 @@ These are injected automatically by the DotBots platform — no manual configura
|
|
|
32
32
|
```
|
|
33
33
|
DOTBOTS_APP_ID=uuid
|
|
34
34
|
DOTBOTS_APP_SECRET=...
|
|
35
|
-
|
|
36
|
-
DOTBOTS_PROXY_URL=https://proxy.dotbots.ai
|
|
35
|
+
DOTBOTS_API_URL=https://api.dotbots.boutique
|
|
37
36
|
ENVIRONMENT=test|prod
|
|
38
37
|
```
|
|
39
38
|
|
|
@@ -42,12 +41,12 @@ ENVIRONMENT=test|prod
|
|
|
42
41
|
Initialise once at app startup, before handling any requests:
|
|
43
42
|
|
|
44
43
|
```typescript
|
|
45
|
-
import { DotBotsBackend } from 'npm:@dotbots-boutique/server-sdk';
|
|
44
|
+
import { DotBotsBackend } from 'npm:@dotbots-boutique/server-sdk@0.4.0';
|
|
46
45
|
|
|
47
46
|
const dotbots = new DotBotsBackend({
|
|
48
47
|
appId: Deno.env.get('DOTBOTS_APP_ID')!,
|
|
49
48
|
appSecret: Deno.env.get('DOTBOTS_APP_SECRET')!,
|
|
50
|
-
apiUrl: Deno.env.get('
|
|
49
|
+
apiUrl: Deno.env.get('DOTBOTS_API_URL') ?? 'https://api.dotbots.boutique',
|
|
51
50
|
environment: Deno.env.get('ENVIRONMENT') ?? 'prod'
|
|
52
51
|
});
|
|
53
52
|
|
|
@@ -55,7 +54,7 @@ const dotbots = new DotBotsBackend({
|
|
|
55
54
|
await dotbots.initialize();
|
|
56
55
|
```
|
|
57
56
|
|
|
58
|
-
`initialize()`
|
|
57
|
+
`initialize()` fetches the proxy URL from the platform. It must complete before any AI calls, payments or user lookups are made.
|
|
59
58
|
|
|
60
59
|
## AI calls
|
|
61
60
|
|
|
@@ -103,16 +102,17 @@ await dotbots.aiStream(
|
|
|
103
102
|
The `paidBy` value is configured per feature in the platform — default is `org`. Your code only needs to provide `orgId` when the feature charges the organisation:
|
|
104
103
|
|
|
105
104
|
```typescript
|
|
106
|
-
//
|
|
105
|
+
// orgId is optional — SDK sends default org from app secret context
|
|
106
|
+
await dotbots.charge('data-export', { quantity: 1 });
|
|
107
|
+
|
|
108
|
+
// Explicitly provide orgId when charging a specific org
|
|
107
109
|
await dotbots.charge('data-export', {
|
|
108
110
|
orgId: user.orgId,
|
|
109
111
|
quantity: 1
|
|
110
112
|
});
|
|
111
113
|
|
|
112
114
|
// Feature paidBy = 'app' — no orgId needed
|
|
113
|
-
await dotbots.charge('internal-job'
|
|
114
|
-
quantity: 1
|
|
115
|
-
});
|
|
115
|
+
await dotbots.charge('internal-job');
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
## Getting user info
|
|
@@ -125,7 +125,7 @@ console.log(user.name, user.orgId, user.roles);
|
|
|
125
125
|
## Error handling
|
|
126
126
|
|
|
127
127
|
```typescript
|
|
128
|
-
import { DotBotsBackend, DotBotsBackendError } from 'npm:@dotbots-boutique/server-sdk';
|
|
128
|
+
import { DotBotsBackend, DotBotsBackendError } from 'npm:@dotbots-boutique/server-sdk@0.4.0';
|
|
129
129
|
|
|
130
130
|
try {
|
|
131
131
|
const response = await dotbots.ai('generate-text', { messages, orgId });
|
|
@@ -150,6 +150,30 @@ try {
|
|
|
150
150
|
}
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
+
## Sending notifications
|
|
154
|
+
|
|
155
|
+
Send a notification to a user. The notification type (email, SMS, platform), templates and placeholders are configured in the DotBots platform — your code only provides the parameters.
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
await dotbots.sendNotification({
|
|
159
|
+
userExternalId: user.id,
|
|
160
|
+
userOrganisationExternalId: user.orgId,
|
|
161
|
+
code: 'invoice.created', // as defined in the platform
|
|
162
|
+
language: 'nl', // optional
|
|
163
|
+
parameters: { // optional — key-values for {{placeholders}}
|
|
164
|
+
invoiceNr: 'INV-42',
|
|
165
|
+
amount: '99,50'
|
|
166
|
+
},
|
|
167
|
+
important: false // optional — marks as important
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Use `code` to identify the notification — it is the recommended approach. In the platform admin you can copy a ready-made example payload per notification with the correct `code` and parameter keys already filled in.
|
|
172
|
+
|
|
173
|
+
**Always call this server-to-server** — the app secret must never appear in the browser.
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
153
177
|
## Error codes
|
|
154
178
|
|
|
155
179
|
| Code | Description |
|
|
@@ -161,6 +185,8 @@ try {
|
|
|
161
185
|
| `CHARGE_FAILED` | Payment failed |
|
|
162
186
|
| `USER_NOT_FOUND` | User not found |
|
|
163
187
|
| `UNAUTHORIZED` | Invalid app secret |
|
|
188
|
+
| `NOTIFICATION_NOT_FOUND` | Notification code does not belong to this app |
|
|
189
|
+
| `NO_TEMPLATE_CONFIGURED` | No template configured for this notification |
|
|
164
190
|
|
|
165
191
|
## Frontend SDK vs Backend SDK
|
|
166
192
|
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AiResponse, BackendAiRequest, DotBotsBackendConfig, DotBotsUser } from './types';
|
|
1
|
+
import type { AiResponse, BackendAiRequest, DotBotsBackendConfig, DotBotsUser, SendNotificationRequest, SendNotificationResponse } from './types';
|
|
2
2
|
export declare class DotBotsBackend {
|
|
3
3
|
private appId;
|
|
4
4
|
private appSecret;
|
|
@@ -9,7 +9,7 @@ export declare class DotBotsBackend {
|
|
|
9
9
|
initialize(): Promise<void>;
|
|
10
10
|
ai(feature: string, request: BackendAiRequest, onDelta?: (delta: string) => void): Promise<AiResponse>;
|
|
11
11
|
aiStream(feature: string, request: BackendAiRequest, onDelta: (delta: string) => void, onDone?: (response: AiResponse) => void): Promise<void>;
|
|
12
|
-
charge(featureCode: string, options
|
|
12
|
+
charge(featureCode: string, options?: {
|
|
13
13
|
paidBy?: 'org' | 'app';
|
|
14
14
|
orgId?: string;
|
|
15
15
|
quantity?: number;
|
|
@@ -18,6 +18,7 @@ export declare class DotBotsBackend {
|
|
|
18
18
|
amount: bigint;
|
|
19
19
|
}>;
|
|
20
20
|
getUser(userId: string): Promise<DotBotsUser>;
|
|
21
|
+
sendNotification(request: SendNotificationRequest): Promise<SendNotificationResponse>;
|
|
21
22
|
private baseHeaders;
|
|
22
23
|
private getProxyUrl;
|
|
23
24
|
}
|
package/dist/client.js
CHANGED
|
@@ -84,7 +84,7 @@ class DotBotsBackend {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
async charge(featureCode, options) {
|
|
87
|
+
async charge(featureCode, options = {}) {
|
|
88
88
|
const response = await fetch(`${this.getProxyUrl()}/payments/charge`, {
|
|
89
89
|
method: 'POST',
|
|
90
90
|
headers: this.baseHeaders(),
|
|
@@ -108,6 +108,44 @@ class DotBotsBackend {
|
|
|
108
108
|
}
|
|
109
109
|
return (await response.json());
|
|
110
110
|
}
|
|
111
|
+
async sendNotification(request) {
|
|
112
|
+
const url = 'https://dotnotifications-dotbots-api.apps.dotbots.boutique/notifications/send';
|
|
113
|
+
const body = JSON.stringify(request);
|
|
114
|
+
console.log(JSON.stringify({
|
|
115
|
+
level: 'info',
|
|
116
|
+
message: `[DotBotsBackend] sendNotification → ${url}`,
|
|
117
|
+
code: request.code,
|
|
118
|
+
userExternalId: request.userExternalId,
|
|
119
|
+
userOrganisationExternalId: request.userOrganisationExternalId,
|
|
120
|
+
language: request.language,
|
|
121
|
+
important: request.important,
|
|
122
|
+
parameterKeys: request.parameters ? Object.keys(request.parameters) : [],
|
|
123
|
+
}));
|
|
124
|
+
const response = await fetch(url, {
|
|
125
|
+
method: 'POST',
|
|
126
|
+
headers: { 'Content-Type': 'application/json' },
|
|
127
|
+
body,
|
|
128
|
+
});
|
|
129
|
+
if (!response.ok) {
|
|
130
|
+
const responseBody = (await response.json().catch(() => ({})));
|
|
131
|
+
console.log(JSON.stringify({
|
|
132
|
+
level: 'error',
|
|
133
|
+
message: `[DotBotsBackend] sendNotification failed`,
|
|
134
|
+
status: response.status,
|
|
135
|
+
error: responseBody.error,
|
|
136
|
+
}));
|
|
137
|
+
throw new errors_1.DotBotsBackendError(responseBody.error ?? 'NOTIFICATION_FAILED', response.status);
|
|
138
|
+
}
|
|
139
|
+
const result = (await response.json());
|
|
140
|
+
console.log(JSON.stringify({
|
|
141
|
+
level: 'info',
|
|
142
|
+
message: `[DotBotsBackend] sendNotification OK`,
|
|
143
|
+
id: result.id,
|
|
144
|
+
type: result.type,
|
|
145
|
+
status: result.status,
|
|
146
|
+
}));
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
111
149
|
baseHeaders() {
|
|
112
150
|
return {
|
|
113
151
|
'Content-Type': 'application/json',
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { DotBotsBackend } from './client';
|
|
2
2
|
export { DotBotsBackendError } from './errors';
|
|
3
|
-
export type { AiImage, AiMessage, AiResponse, AiTool, AiToolCall, AiToolParameter, BackendAiRequest, DotBotsBackendConfig, DotBotsUser, } from './types';
|
|
3
|
+
export type { AiImage, AiMessage, AiResponse, AiTool, AiToolCall, AiToolParameter, BackendAiRequest, DotBotsBackendConfig, DotBotsUser, SendNotificationRequest, SendNotificationResponse, } from './types';
|
|
4
4
|
export { AppSecretsStore } from './proxy/app-secrets';
|
|
5
5
|
export { handleAiCall, handleCharge, handleGetUser, handleInternalAppSecrets, resolveAuth, } from './proxy/handlers';
|
|
6
6
|
export type { AuthResult, CryptoHelpers, DbClient, FeatureConfig, JwtPayload, UserRecord, } from './proxy/types';
|
package/dist/types.d.ts
CHANGED
|
@@ -65,3 +65,17 @@ export interface DotBotsUser {
|
|
|
65
65
|
email?: string;
|
|
66
66
|
name?: string;
|
|
67
67
|
}
|
|
68
|
+
export interface SendNotificationRequest {
|
|
69
|
+
userExternalId: string;
|
|
70
|
+
userOrganisationExternalId: string;
|
|
71
|
+
code?: string;
|
|
72
|
+
notificationDescriptionId?: string;
|
|
73
|
+
language?: string;
|
|
74
|
+
parameters?: Record<string, string>;
|
|
75
|
+
important?: boolean;
|
|
76
|
+
}
|
|
77
|
+
export interface SendNotificationResponse {
|
|
78
|
+
id: string;
|
|
79
|
+
type: string;
|
|
80
|
+
status: string;
|
|
81
|
+
}
|
package/package.json
CHANGED