chatwoot-router 0.5.2 → 0.6.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 +14 -6
- package/README.md +1 -0
- package/lib/packages/chatwoot-router/scripts/store-config.js +6 -1
- package/lib/packages/chatwoot-router/scripts/stored-config.js +6 -1
- package/lib/packages/chatwoot-router/src/config.d.ts +1 -0
- package/lib/packages/chatwoot-router/src/index.js +18 -2
- package/lib/shared/chatwoot/api.d.ts +2 -0
- package/lib/shared/types.d.ts +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,8 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.6.0] - 2026-10-05
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `routing.kinds.<id>.<name>.label` (default `true`): `false` handles the kind without giving the ticket its label,
|
|
15
|
+
for a kind that is not a kind of ticket, such as a thank-you that is only resolved.
|
|
16
|
+
|
|
10
17
|
## [0.5.2] - 2026-10-05
|
|
11
18
|
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Clear a request's timeout once its response has been read. The pending `AbortSignal.timeout` timer kept a
|
|
22
|
+
Durable Object invocation open until it fired, so most alarms were billed and reported at about 60 seconds.
|
|
23
|
+
|
|
12
24
|
## [0.5.1] - 2026-10-05
|
|
13
25
|
|
|
14
26
|
### Fixed
|
|
@@ -17,11 +29,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
17
29
|
(`Contact#webhook_data`; users and bots have one), and the router required `type: "contact"`, so it ignored
|
|
18
30
|
every customer message and a new ticket waited for the five-minute sweep.
|
|
19
31
|
|
|
20
|
-
### Fixed
|
|
21
|
-
|
|
22
|
-
- Clear a request's timeout once its response has been read. The pending `AbortSignal.timeout` timer kept a
|
|
23
|
-
Durable Object invocation open until it fired, so most alarms were billed and reported at about 60 seconds.
|
|
24
|
-
|
|
25
32
|
## [0.5.0] - 2026-10-05
|
|
26
33
|
|
|
27
34
|
### Fixed
|
|
@@ -127,7 +134,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
127
134
|
`routing_kind`.
|
|
128
135
|
- The `chatwoot-router-store-config` command and `chatwoot-router/stored-config`, for a configuration in KV.
|
|
129
136
|
|
|
130
|
-
[Unreleased]: https://github.com/Phala-Network/chatwoot-workers/compare/chatwoot-router@0.
|
|
137
|
+
[Unreleased]: https://github.com/Phala-Network/chatwoot-workers/compare/chatwoot-router@0.6.0...HEAD
|
|
138
|
+
[0.6.0]: https://github.com/Phala-Network/chatwoot-workers/compare/chatwoot-router@0.5.2...chatwoot-router@0.6.0
|
|
131
139
|
[0.5.2]: https://github.com/Phala-Network/chatwoot-workers/compare/chatwoot-router@0.5.1...chatwoot-router@0.5.2
|
|
132
140
|
[0.5.1]: https://github.com/Phala-Network/chatwoot-workers/compare/chatwoot-router@0.5.0...chatwoot-router@0.5.1
|
|
133
141
|
[0.5.0]: https://github.com/Phala-Network/chatwoot-workers/compare/chatwoot-router@0.4.0...chatwoot-router@0.5.0
|
package/README.md
CHANGED
|
@@ -126,6 +126,7 @@ no unpublished shared package needs installing.
|
|
|
126
126
|
| `routing.kinds.<id>.<name>.covers` | 1–1000 characters | required | What the kind is: Jev's criterion for recognizing it. |
|
|
127
127
|
| `routing.kinds.<id>.<name>.cannedResponse` | short code | unset | The account's Chatwoot canned response sent to the customer once, by the account's agent bot (`CHATWOOT_AGENT_BOT_TOKENS`); handoff if it is missing. |
|
|
128
128
|
| `routing.kinds.<id>.<name>.status` | `resolved` or `snoozed` | unset | Set instead of routing the ticket (`snoozed`: until the customer's next message), after the reply of a `cannedResponse`; a new customer message reopens it. |
|
|
129
|
+
| `routing.kinds.<id>.<name>.label` | boolean | `true` | Whether the ticket gets the kind's label; `false` for a kind that is not a kind of ticket, such as a thank-you that is only resolved. |
|
|
129
130
|
|
|
130
131
|
### Secrets
|
|
131
132
|
|
|
@@ -141,7 +141,12 @@ var configSchema = z2.strictObject({
|
|
|
141
141
|
* or `snoozed` until the customer's next message. A new message from the customer
|
|
142
142
|
* reopens either.
|
|
143
143
|
*/
|
|
144
|
-
status: z2.enum(["resolved", "snoozed"]).optional()
|
|
144
|
+
status: z2.enum(["resolved", "snoozed"]).optional(),
|
|
145
|
+
/**
|
|
146
|
+
* Whether the ticket gets the kind's label (the default). False for a kind that is not a kind of
|
|
147
|
+
* ticket, such as a thank-you that is only resolved.
|
|
148
|
+
*/
|
|
149
|
+
label: z2.boolean().default(true)
|
|
145
150
|
})
|
|
146
151
|
)
|
|
147
152
|
).optional()
|
|
@@ -93,7 +93,12 @@ var configSchema = z2.strictObject({
|
|
|
93
93
|
* or `snoozed` until the customer's next message. A new message from the customer
|
|
94
94
|
* reopens either.
|
|
95
95
|
*/
|
|
96
|
-
status: z2.enum(["resolved", "snoozed"]).optional()
|
|
96
|
+
status: z2.enum(["resolved", "snoozed"]).optional(),
|
|
97
|
+
/**
|
|
98
|
+
* Whether the ticket gets the kind's label (the default). False for a kind that is not a kind of
|
|
99
|
+
* ticket, such as a thank-you that is only resolved.
|
|
100
|
+
*/
|
|
101
|
+
label: z2.boolean().default(true)
|
|
97
102
|
})
|
|
98
103
|
)
|
|
99
104
|
).optional()
|
|
@@ -363,6 +363,16 @@ function chatwootClient(baseUrl, token, fetch2) {
|
|
|
363
363
|
);
|
|
364
364
|
},
|
|
365
365
|
/** The account's label names (Chatwoot saves them in lower case). */
|
|
366
|
+
/** The contact's latest 25 conversations, newest first, that this user may see. */
|
|
367
|
+
async contactConversations(accountId2, contactId) {
|
|
368
|
+
const list = await data(
|
|
369
|
+
"list contact conversations",
|
|
370
|
+
client.GET("/api/v1/accounts/{account_id}/contacts/{id}/conversations", {
|
|
371
|
+
params: { path: { account_id: accountId2, id: contactId } }
|
|
372
|
+
})
|
|
373
|
+
);
|
|
374
|
+
return list.payload ?? [];
|
|
375
|
+
},
|
|
366
376
|
async listLabels(accountId2) {
|
|
367
377
|
const list = await data(
|
|
368
378
|
"list labels",
|
|
@@ -450,6 +460,7 @@ function toRelayConversation(conversationId, conversation) {
|
|
|
450
460
|
priority: conversation.priority ?? null,
|
|
451
461
|
labels: conversation.labels ?? [],
|
|
452
462
|
contact: {
|
|
463
|
+
id: meta?.sender?.id ?? null,
|
|
453
464
|
name: meta?.sender?.name ?? null,
|
|
454
465
|
email: meta?.sender?.email ?? null,
|
|
455
466
|
phone: meta?.sender?.phone_number ?? null,
|
|
@@ -875,7 +886,7 @@ async function routeConversation(ctx, accountId2, conversationId) {
|
|
|
875
886
|
const labels = [
|
|
876
887
|
.../* @__PURE__ */ new Set([
|
|
877
888
|
...current.conversation.labels,
|
|
878
|
-
...[topic, kind ? decision.kind : null].filter((label) => label !== null)
|
|
889
|
+
...[topic, kind?.label ? decision.kind : null].filter((label) => label !== null)
|
|
879
890
|
])
|
|
880
891
|
];
|
|
881
892
|
if (labels.length !== current.conversation.labels.length) await bot.setLabels(accountId2, conversationId, labels);
|
|
@@ -1083,7 +1094,12 @@ var configSchema = z5.strictObject({
|
|
|
1083
1094
|
* or `snoozed` until the customer's next message. A new message from the customer
|
|
1084
1095
|
* reopens either.
|
|
1085
1096
|
*/
|
|
1086
|
-
status: z5.enum(["resolved", "snoozed"]).optional()
|
|
1097
|
+
status: z5.enum(["resolved", "snoozed"]).optional(),
|
|
1098
|
+
/**
|
|
1099
|
+
* Whether the ticket gets the kind's label (the default). False for a kind that is not a kind of
|
|
1100
|
+
* ticket, such as a thank-you that is only resolved.
|
|
1101
|
+
*/
|
|
1102
|
+
label: z5.boolean().default(true)
|
|
1087
1103
|
})
|
|
1088
1104
|
)
|
|
1089
1105
|
).optional()
|
|
@@ -185,6 +185,8 @@ export declare function chatwootClient(baseUrl: string, token: string, fetch: Fe
|
|
|
185
185
|
*/
|
|
186
186
|
unassign(accountId: number, conversationId: number): Promise<void>;
|
|
187
187
|
/** The account's label names (Chatwoot saves them in lower case). */
|
|
188
|
+
/** The contact's latest 25 conversations, newest first, that this user may see. */
|
|
189
|
+
contactConversations(accountId: number, contactId: number): Promise<ChatwootConversation[]>;
|
|
188
190
|
listLabels(accountId: number): Promise<string[]>;
|
|
189
191
|
conversationLabels(accountId: number, conversationId: number): Promise<string[]>;
|
|
190
192
|
/** Replaces the conversation's labels (the spec's "Add Labels" overwrites the list). */
|
package/lib/shared/types.d.ts
CHANGED
|
@@ -43,6 +43,8 @@ export interface RelayConversation {
|
|
|
43
43
|
priority?: string | null;
|
|
44
44
|
labels: string[];
|
|
45
45
|
contact: {
|
|
46
|
+
/** The contact's Chatwoot id. */
|
|
47
|
+
id?: number | null;
|
|
46
48
|
name?: string | null;
|
|
47
49
|
email?: string | null;
|
|
48
50
|
phone?: string | null;
|
|
@@ -80,6 +82,8 @@ export interface RelayMessage {
|
|
|
80
82
|
/** The Discord avatar of the linked agent who sent the message, if any. */
|
|
81
83
|
discordAvatarUrl?: string;
|
|
82
84
|
sender?: {
|
|
85
|
+
/** The Chatwoot id of the contact, user, or agent bot (see `type`). */
|
|
86
|
+
id?: number | null | undefined;
|
|
83
87
|
name?: string | null | undefined;
|
|
84
88
|
email?: string | null | undefined;
|
|
85
89
|
type?: string | null | undefined;
|