chatwoot-router 0.3.0 → 0.5.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 +25 -1
- package/README.md +25 -107
- package/lib/packages/chatwoot-router/src/config.d.ts +1 -1
- package/lib/packages/chatwoot-router/src/env.d.ts +0 -2
- package/lib/packages/chatwoot-router/src/index.d.ts +0 -1
- package/lib/packages/chatwoot-router/src/index.js +171 -372
- package/lib/packages/chatwoot-router/src/reply.d.ts +1 -1
- package/lib/packages/chatwoot-router/src/router.d.ts +5 -1
- package/lib/packages/chatwoot-router/src/turn.d.ts +0 -52
- package/lib/shared/budget.d.ts +3 -14
- package/lib/shared/chatwoot/api.d.ts +6 -5
- package/lib/shared/store.d.ts +8 -11
- package/lib/shared/types.d.ts +6 -2
- package/package.json +1 -1
- package/lib/packages/chatwoot-router/src/coordinator.d.ts +0 -10
- package/lib/shared/alarm.d.ts +0 -2
- package/lib/shared/concurrent.d.ts +0 -4
- package/lib/shared/deadline.d.ts +0 -6
- package/lib/shared/rate-limit.d.ts +0 -5
|
@@ -2,4 +2,4 @@ import { type ChatwootClient, type ChatwootMessage } from "../../../shared/chatw
|
|
|
2
2
|
/** A Chatwoot creation receipt, not a channel delivery receipt. */
|
|
3
3
|
export declare function confirmedReply(message: ChatwootMessage | undefined, botId: number | undefined): boolean;
|
|
4
4
|
/** Read past turn boundaries, including replies made by the former relay's brand bot. */
|
|
5
|
-
export declare function replyHistory(chatwoot: ChatwootClient, accountId: number, conversationId: number, botId: number | undefined
|
|
5
|
+
export declare function replyHistory(chatwoot: ChatwootClient, accountId: number, conversationId: number, botId: number | undefined): Promise<"found" | "complete-none" | "unknown">;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { DurableObject } from "cloudflare:workers";
|
|
2
2
|
import type { Env } from "./env.ts";
|
|
3
3
|
import type { Transition } from "./webhook.ts";
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function sweeper(env: Env): DurableObjectStub<Router>;
|
|
5
|
+
export declare function conversationRouter(env: Env, accountId: number, conversationId: number): DurableObjectStub<Router>;
|
|
5
6
|
export declare class Router extends DurableObject<Env> {
|
|
6
7
|
private readonly store;
|
|
7
8
|
constructor(context: DurableObjectState, env: Env);
|
|
8
9
|
enqueueConversation(accountId: number, conversationId: number, transition?: Transition): Promise<void>;
|
|
10
|
+
requestSweep(): Promise<void>;
|
|
9
11
|
alarm(): Promise<void>;
|
|
12
|
+
private sweep;
|
|
10
13
|
private enqueue;
|
|
14
|
+
private schedule;
|
|
11
15
|
}
|
|
@@ -9,58 +9,6 @@ export declare function requestHandoff(store: RoutingStore, accountId: number, c
|
|
|
9
9
|
export declare function recordFailure(store: RoutingStore, accountId: number, conversationId: number): number;
|
|
10
10
|
export declare function clearFailures(store: RoutingStore, accountId: number, conversationId: number): void;
|
|
11
11
|
export declare function readTurn(chatwoot: ChatwootClient, store: RoutingStore, accountId: number, conversationId: number): Promise<{
|
|
12
|
-
pages: {
|
|
13
|
-
id: number;
|
|
14
|
-
conversation_id?: number | undefined;
|
|
15
|
-
content?: string | null | undefined;
|
|
16
|
-
message_type: number;
|
|
17
|
-
content_type?: string | null | undefined;
|
|
18
|
-
status?: string | null | undefined;
|
|
19
|
-
created_at?: number | null | undefined;
|
|
20
|
-
private?: boolean | null | undefined;
|
|
21
|
-
content_attributes?: {
|
|
22
|
-
email?: {
|
|
23
|
-
subject?: string | null | undefined;
|
|
24
|
-
auto_reply?: boolean | null | undefined;
|
|
25
|
-
text_content?: {
|
|
26
|
-
quoted?: string | null | undefined;
|
|
27
|
-
} | null | undefined;
|
|
28
|
-
html_content?: {
|
|
29
|
-
quoted?: string | null | undefined;
|
|
30
|
-
} | null | undefined;
|
|
31
|
-
} | null | undefined;
|
|
32
|
-
deleted?: boolean | null | undefined;
|
|
33
|
-
external_error?: string | null | undefined;
|
|
34
|
-
activity?: {
|
|
35
|
-
type?: string | null | undefined;
|
|
36
|
-
status?: string | null | undefined;
|
|
37
|
-
} | null | undefined;
|
|
38
|
-
submitted_values?: unknown;
|
|
39
|
-
submitted_email?: unknown;
|
|
40
|
-
items?: unknown;
|
|
41
|
-
} | null | undefined;
|
|
42
|
-
sender?: {
|
|
43
|
-
id?: number | null | undefined;
|
|
44
|
-
name?: string | null | undefined;
|
|
45
|
-
email?: string | null | undefined;
|
|
46
|
-
type?: string | null | undefined;
|
|
47
|
-
thumbnail?: string | null | undefined;
|
|
48
|
-
avatar_url?: string | null | undefined;
|
|
49
|
-
} | null | undefined;
|
|
50
|
-
attachments?: {
|
|
51
|
-
file_type?: string | null | undefined;
|
|
52
|
-
data_url?: string | null | undefined;
|
|
53
|
-
fallback_title?: string | null | undefined;
|
|
54
|
-
coordinates_lat?: number | null | undefined;
|
|
55
|
-
coordinates_long?: number | null | undefined;
|
|
56
|
-
meta?: {
|
|
57
|
-
firstName?: string | null | undefined;
|
|
58
|
-
lastName?: string | null | undefined;
|
|
59
|
-
first_name?: string | null | undefined;
|
|
60
|
-
last_name?: string | null | undefined;
|
|
61
|
-
} | null | undefined;
|
|
62
|
-
}[] | null | undefined;
|
|
63
|
-
}[][];
|
|
64
12
|
messages: {
|
|
65
13
|
id: number;
|
|
66
14
|
conversation_id?: number | undefined;
|
package/lib/shared/budget.d.ts
CHANGED
|
@@ -2,25 +2,14 @@ import type { Fetch } from "./chatwoot/api.ts";
|
|
|
2
2
|
export declare class BudgetExhaustedError extends Error {
|
|
3
3
|
constructor();
|
|
4
4
|
}
|
|
5
|
-
export { JobDeadlineError } from "./deadline.ts";
|
|
6
|
-
export declare const METADATA_TIMEOUT_MS = 1500;
|
|
7
|
-
export declare const TRANSFER_TIMEOUT_MS = 8000;
|
|
8
|
-
export declare const JOB_SLICE_MS = 10000;
|
|
9
5
|
export declare class Budget {
|
|
10
6
|
readonly limit: number;
|
|
11
7
|
private readonly fetchImpl;
|
|
8
|
+
private readonly timeoutMs;
|
|
12
9
|
private used;
|
|
13
|
-
|
|
14
|
-
private sliceEnds;
|
|
15
|
-
constructor(limit: number, fetchImpl?: Fetch);
|
|
10
|
+
constructor(limit: number, fetchImpl?: Fetch, timeoutMs?: number);
|
|
16
11
|
get remaining(): number;
|
|
17
|
-
|
|
18
|
-
requireTime(ms: number): void;
|
|
19
|
-
checkpoint(): void;
|
|
12
|
+
/** Counts a request that is not a fetch, such as a call to another Durable Object. */
|
|
20
13
|
consume(): void;
|
|
21
|
-
require(requests: number): void;
|
|
22
|
-
controlSignal(ms: number): AbortSignal;
|
|
23
|
-
fetchWith(timeoutMs: number): Fetch;
|
|
24
14
|
readonly fetch: Fetch;
|
|
25
|
-
private request;
|
|
26
15
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type { RateLimitStore } from "../rate-limit.ts";
|
|
3
2
|
import type { RelayConversation, RelayMessage } from "../types.ts";
|
|
4
3
|
import type { components, operations } from "./schema.ts";
|
|
5
4
|
export type Fetch = (input: Request) => Promise<Response>;
|
|
@@ -7,18 +6,20 @@ export type Fetch = (input: Request) => Promise<Response>;
|
|
|
7
6
|
export declare class ChatwootError extends Error {
|
|
8
7
|
readonly status: number;
|
|
9
8
|
readonly conversationMissing: boolean;
|
|
10
|
-
|
|
11
|
-
constructor(status: number, operation: string, conversationMissing?: boolean, retryAfterMs?: number);
|
|
9
|
+
constructor(status: number, operation: string, conversationMissing?: boolean);
|
|
12
10
|
}
|
|
13
11
|
/**
|
|
14
12
|
* A conversation as returned by GET conversations/{id} and in the conversation list. The spec's
|
|
15
13
|
* `status` enum omits `snoozed`, which the API does return, so the relay treats it as a string.
|
|
16
14
|
*/
|
|
17
|
-
export type ChatwootConversation = components["schemas"]["conversation_show"] & {
|
|
15
|
+
export type ChatwootConversation = Omit<components["schemas"]["conversation_show"], "snoozed_until"> & {
|
|
18
16
|
meta?: {
|
|
19
17
|
assignee_type?: string | null;
|
|
20
18
|
};
|
|
19
|
+
snoozed_until?: string | number | null;
|
|
21
20
|
};
|
|
21
|
+
/** Unix seconds when a snoozed conversation reopens; null unless it is snoozed until a time. */
|
|
22
|
+
export declare function snoozedUntil(conversation: ChatwootConversation): number | null;
|
|
22
23
|
declare const messageSchema: z.ZodObject<{
|
|
23
24
|
id: z.ZodNumber;
|
|
24
25
|
conversation_id: z.ZodOptional<z.ZodNumber>;
|
|
@@ -99,7 +100,7 @@ export type ChatwootClient = ReturnType<typeof chatwootClient>;
|
|
|
99
100
|
type MessageQuery = NonNullable<operations["list-all-messages"]["parameters"]["query"]> & {
|
|
100
101
|
filter_internal_messages?: true;
|
|
101
102
|
};
|
|
102
|
-
export declare function chatwootClient(baseUrl: string, token: string, fetch: Fetch
|
|
103
|
+
export declare function chatwootClient(baseUrl: string, token: string, fetch: Fetch): {
|
|
103
104
|
/** The conversation, or undefined when it does not exist (it was deleted). */
|
|
104
105
|
getConversation(accountId: number, conversationId: number): Promise<ChatwootConversation | undefined>;
|
|
105
106
|
/** Messages with an id above `after`, oldest first; without `after`, the latest page. */
|
package/lib/shared/store.d.ts
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
export declare function retryDelay(attempts: number): number;
|
|
2
|
-
export
|
|
2
|
+
export interface Job {
|
|
3
3
|
key: string;
|
|
4
4
|
payload: string;
|
|
5
5
|
version: number;
|
|
6
6
|
attempts: number;
|
|
7
7
|
/** When the job was first queued (ms since the epoch). */
|
|
8
8
|
createdAt: number;
|
|
9
|
-
}
|
|
9
|
+
}
|
|
10
10
|
export declare class QueueStore {
|
|
11
11
|
protected readonly sql: SqlStorage;
|
|
12
12
|
protected readonly now: () => number;
|
|
13
|
-
|
|
14
|
-
constructor(sql: SqlStorage, now?: () => number, atomic?: <T>(write: () => T) => T);
|
|
15
|
-
transaction<T>(write: () => T): T;
|
|
13
|
+
constructor(sql: SqlStorage, now?: () => number);
|
|
16
14
|
migrate(): void;
|
|
17
15
|
get(key: string): string | undefined;
|
|
18
16
|
set(key: string, value: string, ttlMs?: number): void;
|
|
@@ -23,8 +21,6 @@ export declare class QueueStore {
|
|
|
23
21
|
*/
|
|
24
22
|
enqueue(key: string, priority: number, payload: string, notBefore?: number): void;
|
|
25
23
|
nextDueJob(): Job | undefined;
|
|
26
|
-
/** A bounded due batch; independent scan and delivery work can select their own keys. */
|
|
27
|
-
nextDueJobs(limit: number, prefix?: string): Job[];
|
|
28
24
|
/** Earliest due time. */
|
|
29
25
|
nextWakeup(): number | undefined;
|
|
30
26
|
/** Removes a finished job unless it was enqueued again while running. */
|
|
@@ -36,9 +32,10 @@ export declare class QueueStore {
|
|
|
36
32
|
* budget, or Discord rate limits it.
|
|
37
33
|
*/
|
|
38
34
|
deferJob(job: Job, delayMs?: number): void;
|
|
39
|
-
/**
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Makes a job due again after `delayMs`, unless it was queued again while it ran (it is due
|
|
37
|
+
* then), clearing its failures.
|
|
38
|
+
*/
|
|
39
|
+
postponeJob(job: Job, delayMs: number): void;
|
|
43
40
|
prune(): void;
|
|
44
41
|
}
|
package/lib/shared/types.d.ts
CHANGED
|
@@ -51,6 +51,10 @@ export interface RelayConversation {
|
|
|
51
51
|
};
|
|
52
52
|
/** Person only; agent bots are represented as unassigned. */
|
|
53
53
|
assignee?: RelayAssignee | null;
|
|
54
|
+
/** Unix seconds since the customer has waited for a reply (Chatwoot's `waiting_since`); null when they do not. */
|
|
55
|
+
waitingSince?: number | null;
|
|
56
|
+
/** Unix seconds when a snoozed conversation reopens; null when not snoozed or snoozed until the next reply. */
|
|
57
|
+
snoozedUntil?: number | null;
|
|
54
58
|
assigneeType?: string | null;
|
|
55
59
|
customAttributes: Record<string, unknown>;
|
|
56
60
|
}
|
|
@@ -66,8 +70,8 @@ export interface RelayMessage {
|
|
|
66
70
|
emailSubject?: string | null;
|
|
67
71
|
/** An automatic email reply (out of office, for example): relayed without notifications. */
|
|
68
72
|
autoReply?: boolean;
|
|
69
|
-
/** A
|
|
70
|
-
|
|
73
|
+
/** A public reply that answers the customer (see isAnsweringReply). */
|
|
74
|
+
answers?: boolean;
|
|
71
75
|
attachments: RelayAttachment[];
|
|
72
76
|
/** A bot's options to pick, cards, or articles, with a link each when they have one. */
|
|
73
77
|
items?: RelayItem[];
|
package/package.json
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { DurableObject } from "cloudflare:workers";
|
|
2
|
-
import type { Env } from "./env.ts";
|
|
3
|
-
export declare const COORDINATOR_NAME = "global";
|
|
4
|
-
/** Lists one page per alarm. Conversation state belongs exclusively to the conversation's Router. */
|
|
5
|
-
export declare class Coordinator extends DurableObject<Env> {
|
|
6
|
-
private readonly store;
|
|
7
|
-
constructor(ctx: DurableObjectState, env: Env);
|
|
8
|
-
requestSweep(): Promise<void>;
|
|
9
|
-
alarm(): Promise<void>;
|
|
10
|
-
}
|
package/lib/shared/alarm.d.ts
DELETED
package/lib/shared/deadline.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/** Bounds non-fetch dependencies too, including an RPC whose enqueue outcome can be unknown. */
|
|
2
|
-
export declare function within<T>(pending: Promise<T>, signal: AbortSignal): Promise<T>;
|
|
3
|
-
export declare class JobDeadlineError extends Error {
|
|
4
|
-
readonly requestStarted: boolean;
|
|
5
|
-
constructor(requestStarted?: boolean);
|
|
6
|
-
}
|