@iveri/contracts 0.7.0 → 0.9.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/README.md +24 -4
- package/dist/cjs/api/unibox/canned-reply.type.d.ts +49 -0
- package/dist/cjs/api/unibox/canned-reply.type.d.ts.map +1 -0
- package/dist/cjs/api/unibox/canned-reply.type.js +3 -0
- package/dist/cjs/api/unibox/canned-reply.type.js.map +1 -0
- package/dist/cjs/api/unibox/channel-platform.enum.d.ts +32 -0
- package/dist/cjs/api/unibox/channel-platform.enum.d.ts.map +1 -0
- package/dist/cjs/api/unibox/channel-platform.enum.js +36 -0
- package/dist/cjs/api/unibox/channel-platform.enum.js.map +1 -0
- package/dist/cjs/api/unibox/channel.type.d.ts +110 -0
- package/dist/cjs/api/unibox/channel.type.d.ts.map +1 -0
- package/dist/cjs/api/unibox/channel.type.js +3 -0
- package/dist/cjs/api/unibox/channel.type.js.map +1 -0
- package/dist/cjs/api/unibox/contact.type.d.ts +102 -0
- package/dist/cjs/api/unibox/contact.type.d.ts.map +1 -0
- package/dist/cjs/api/unibox/contact.type.js +3 -0
- package/dist/cjs/api/unibox/contact.type.js.map +1 -0
- package/dist/cjs/api/unibox/conversation-status.enum.d.ts +39 -0
- package/dist/cjs/api/unibox/conversation-status.enum.d.ts.map +1 -0
- package/dist/cjs/api/unibox/conversation-status.enum.js +43 -0
- package/dist/cjs/api/unibox/conversation-status.enum.js.map +1 -0
- package/dist/cjs/api/unibox/conversation.type.d.ts +134 -0
- package/dist/cjs/api/unibox/conversation.type.d.ts.map +1 -0
- package/dist/cjs/api/unibox/conversation.type.js +3 -0
- package/dist/cjs/api/unibox/conversation.type.js.map +1 -0
- package/dist/cjs/api/unibox/index.d.ts +13 -0
- package/dist/cjs/api/unibox/index.d.ts.map +1 -0
- package/dist/cjs/api/unibox/index.js +29 -0
- package/dist/cjs/api/unibox/index.js.map +1 -0
- package/dist/cjs/api/unibox/message-author-type.enum.d.ts +26 -0
- package/dist/cjs/api/unibox/message-author-type.enum.d.ts.map +1 -0
- package/dist/cjs/api/unibox/message-author-type.enum.js +30 -0
- package/dist/cjs/api/unibox/message-author-type.enum.js.map +1 -0
- package/dist/cjs/api/unibox/message-content-type.enum.d.ts +29 -0
- package/dist/cjs/api/unibox/message-content-type.enum.d.ts.map +1 -0
- package/dist/cjs/api/unibox/message-content-type.enum.js +33 -0
- package/dist/cjs/api/unibox/message-content-type.enum.js.map +1 -0
- package/dist/cjs/api/unibox/message-direction.enum.d.ts +23 -0
- package/dist/cjs/api/unibox/message-direction.enum.d.ts.map +1 -0
- package/dist/cjs/api/unibox/message-direction.enum.js +27 -0
- package/dist/cjs/api/unibox/message-direction.enum.js.map +1 -0
- package/dist/cjs/api/unibox/message-status.enum.d.ts +40 -0
- package/dist/cjs/api/unibox/message-status.enum.d.ts.map +1 -0
- package/dist/cjs/api/unibox/message-status.enum.js +44 -0
- package/dist/cjs/api/unibox/message-status.enum.js.map +1 -0
- package/dist/cjs/api/unibox/message.type.d.ts +120 -0
- package/dist/cjs/api/unibox/message.type.d.ts.map +1 -0
- package/dist/cjs/api/unibox/message.type.js +3 -0
- package/dist/cjs/api/unibox/message.type.js.map +1 -0
- package/dist/cjs/api/unibox/team.type.d.ts +50 -0
- package/dist/cjs/api/unibox/team.type.d.ts.map +1 -0
- package/dist/cjs/api/unibox/team.type.js +3 -0
- package/dist/cjs/api/unibox/team.type.js.map +1 -0
- package/dist/cjs/enum/user-permission.enum.d.ts +52 -1
- package/dist/cjs/enum/user-permission.enum.d.ts.map +1 -1
- package/dist/cjs/enum/user-permission.enum.js +60 -0
- package/dist/cjs/enum/user-permission.enum.js.map +1 -1
- package/dist/esm/api/unibox/canned-reply.type.d.ts +49 -0
- package/dist/esm/api/unibox/canned-reply.type.d.ts.map +1 -0
- package/dist/esm/api/unibox/canned-reply.type.js +2 -0
- package/dist/esm/api/unibox/canned-reply.type.js.map +1 -0
- package/dist/esm/api/unibox/channel-platform.enum.d.ts +32 -0
- package/dist/esm/api/unibox/channel-platform.enum.d.ts.map +1 -0
- package/dist/esm/api/unibox/channel-platform.enum.js +33 -0
- package/dist/esm/api/unibox/channel-platform.enum.js.map +1 -0
- package/dist/esm/api/unibox/channel.type.d.ts +110 -0
- package/dist/esm/api/unibox/channel.type.d.ts.map +1 -0
- package/dist/esm/api/unibox/channel.type.js +2 -0
- package/dist/esm/api/unibox/channel.type.js.map +1 -0
- package/dist/esm/api/unibox/contact.type.d.ts +102 -0
- package/dist/esm/api/unibox/contact.type.d.ts.map +1 -0
- package/dist/esm/api/unibox/contact.type.js +2 -0
- package/dist/esm/api/unibox/contact.type.js.map +1 -0
- package/dist/esm/api/unibox/conversation-status.enum.d.ts +39 -0
- package/dist/esm/api/unibox/conversation-status.enum.d.ts.map +1 -0
- package/dist/esm/api/unibox/conversation-status.enum.js +40 -0
- package/dist/esm/api/unibox/conversation-status.enum.js.map +1 -0
- package/dist/esm/api/unibox/conversation.type.d.ts +134 -0
- package/dist/esm/api/unibox/conversation.type.d.ts.map +1 -0
- package/dist/esm/api/unibox/conversation.type.js +2 -0
- package/dist/esm/api/unibox/conversation.type.js.map +1 -0
- package/dist/esm/api/unibox/index.d.ts +13 -0
- package/dist/esm/api/unibox/index.d.ts.map +1 -0
- package/dist/esm/api/unibox/index.js +13 -0
- package/dist/esm/api/unibox/index.js.map +1 -0
- package/dist/esm/api/unibox/message-author-type.enum.d.ts +26 -0
- package/dist/esm/api/unibox/message-author-type.enum.d.ts.map +1 -0
- package/dist/esm/api/unibox/message-author-type.enum.js +27 -0
- package/dist/esm/api/unibox/message-author-type.enum.js.map +1 -0
- package/dist/esm/api/unibox/message-content-type.enum.d.ts +29 -0
- package/dist/esm/api/unibox/message-content-type.enum.d.ts.map +1 -0
- package/dist/esm/api/unibox/message-content-type.enum.js +30 -0
- package/dist/esm/api/unibox/message-content-type.enum.js.map +1 -0
- package/dist/esm/api/unibox/message-direction.enum.d.ts +23 -0
- package/dist/esm/api/unibox/message-direction.enum.d.ts.map +1 -0
- package/dist/esm/api/unibox/message-direction.enum.js +24 -0
- package/dist/esm/api/unibox/message-direction.enum.js.map +1 -0
- package/dist/esm/api/unibox/message-status.enum.d.ts +40 -0
- package/dist/esm/api/unibox/message-status.enum.d.ts.map +1 -0
- package/dist/esm/api/unibox/message-status.enum.js +41 -0
- package/dist/esm/api/unibox/message-status.enum.js.map +1 -0
- package/dist/esm/api/unibox/message.type.d.ts +120 -0
- package/dist/esm/api/unibox/message.type.d.ts.map +1 -0
- package/dist/esm/api/unibox/message.type.js +2 -0
- package/dist/esm/api/unibox/message.type.js.map +1 -0
- package/dist/esm/api/unibox/team.type.d.ts +50 -0
- package/dist/esm/api/unibox/team.type.d.ts.map +1 -0
- package/dist/esm/api/unibox/team.type.js +2 -0
- package/dist/esm/api/unibox/team.type.js.map +1 -0
- package/dist/esm/enum/user-permission.enum.d.ts +52 -1
- package/dist/esm/enum/user-permission.enum.d.ts.map +1 -1
- package/dist/esm/enum/user-permission.enum.js +60 -0
- package/dist/esm/enum/user-permission.enum.js.map +1 -1
- package/package.json +9 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where one conversation is in an agent's working day.
|
|
3
|
+
*
|
|
4
|
+
* These are **workflow** states, not delivery states — nothing here says whether a message
|
|
5
|
+
* reached anyone. `MessageStatus` answers that, and conflating the two is how an inbox ends up
|
|
6
|
+
* showing a conversation as "failed".
|
|
7
|
+
*
|
|
8
|
+
* There is deliberately no `ARCHIVED`. Closing is already the "I am done with this" state, and a
|
|
9
|
+
* second one just moves the question of which list a conversation belongs in from the filter to
|
|
10
|
+
* the operator.
|
|
11
|
+
*/
|
|
12
|
+
export var ConversationStatus;
|
|
13
|
+
(function (ConversationStatus) {
|
|
14
|
+
/** Needs a human. The default for anything with an unanswered inbound message. */
|
|
15
|
+
ConversationStatus["OPEN"] = "open";
|
|
16
|
+
/**
|
|
17
|
+
* Answered, waiting on the contact.
|
|
18
|
+
*
|
|
19
|
+
* Distinct from `OPEN` because an inbox sorted only by "has unread" hides the conversations
|
|
20
|
+
* an agent is actually running. A new inbound message moves this back to `OPEN`.
|
|
21
|
+
*/
|
|
22
|
+
ConversationStatus["PENDING"] = "pending";
|
|
23
|
+
/**
|
|
24
|
+
* Deliberately out of sight until `snoozedUntil`.
|
|
25
|
+
*
|
|
26
|
+
* The only status carrying a time. It exists because "I will deal with this on Monday" is
|
|
27
|
+
* otherwise expressed by closing something that is not finished, and a closed conversation is
|
|
28
|
+
* one nobody looks at again.
|
|
29
|
+
*/
|
|
30
|
+
ConversationStatus["SNOOZED"] = "snoozed";
|
|
31
|
+
/**
|
|
32
|
+
* Finished. Reopened automatically by a new inbound message.
|
|
33
|
+
*
|
|
34
|
+
* That automatic reopen is the important half: a contact replying to a closed conversation is
|
|
35
|
+
* continuing it, and starting a second thread would split one person's history across two
|
|
36
|
+
* rows for no reason a customer would recognise.
|
|
37
|
+
*/
|
|
38
|
+
ConversationStatus["CLOSED"] = "closed";
|
|
39
|
+
})(ConversationStatus || (ConversationStatus = {}));
|
|
40
|
+
//# sourceMappingURL=conversation-status.enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation-status.enum.js","sourceRoot":"","sources":["../../../../src/api/unibox/conversation-status.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAN,IAAY,kBA6BX;AA7BD,WAAY,kBAAkB;IAC1B,kFAAkF;IAClF,mCAAa,CAAA;IAEb;;;;;OAKG;IACH,yCAAmB,CAAA;IAEnB;;;;;;OAMG;IACH,yCAAmB,CAAA;IAEnB;;;;;;OAMG;IACH,uCAAiB,CAAA;AACrB,CAAC,EA7BW,kBAAkB,KAAlB,kBAAkB,QA6B7B"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { CursorPage } from '../../type/cursor-page.type.js';
|
|
2
|
+
import type { IsoDateTime } from '../../type/iso-date-time.type.js';
|
|
3
|
+
import type { Nullable } from '../../type/nil.type.js';
|
|
4
|
+
import type { UUID } from '../../type/uuid.type.js';
|
|
5
|
+
import type { ChannelPlatform } from './channel-platform.enum.js';
|
|
6
|
+
import type { ConversationStatus } from './conversation-status.enum.js';
|
|
7
|
+
import type { Message } from './message.type.js';
|
|
8
|
+
/**
|
|
9
|
+
* One thread between a tenant and a contact, on one channel.
|
|
10
|
+
*
|
|
11
|
+
* **One open conversation per `(channel, contact)`, never more.** A second one would split a
|
|
12
|
+
* person's history in half at the exact moment two agents are both replying, and the customer
|
|
13
|
+
* would see one conversation while the inbox showed two. A closed conversation reopens on the
|
|
14
|
+
* next inbound message rather than a new row being created, for the same reason.
|
|
15
|
+
*
|
|
16
|
+
* The denormalized fields below — `contactDisplayName`, `lastMessagePreview`, `unreadCount` — are
|
|
17
|
+
* here because an inbox list renders fifty of these at once and joining to messages for each one
|
|
18
|
+
* is the query that makes the product feel slow. They are maintained in the same transaction as
|
|
19
|
+
* the message that changes them, so they cannot drift.
|
|
20
|
+
*/
|
|
21
|
+
export interface Conversation {
|
|
22
|
+
id: UUID;
|
|
23
|
+
channelId: UUID;
|
|
24
|
+
/** Snapshotted so the list renders without a join. */
|
|
25
|
+
channelKey: string;
|
|
26
|
+
platform: ChannelPlatform;
|
|
27
|
+
contactId: UUID;
|
|
28
|
+
contactDisplayName: string;
|
|
29
|
+
status: ConversationStatus;
|
|
30
|
+
/** The agent responsible. Null means unassigned, which is a queue an inbox filters on. */
|
|
31
|
+
assigneeUserId: Nullable<UUID>;
|
|
32
|
+
/** The team it was routed to, if any. Independent of the assignee. */
|
|
33
|
+
teamId: Nullable<UUID>;
|
|
34
|
+
/**
|
|
35
|
+
* Messages the contact sent that no agent has opened.
|
|
36
|
+
*
|
|
37
|
+
* Per conversation, not per agent. A shared inbox is shared: two agents looking at the same
|
|
38
|
+
* queue should see the same numbers, and per-agent unread counts turn "has anyone dealt with
|
|
39
|
+
* this" into a question the UI cannot answer.
|
|
40
|
+
*/
|
|
41
|
+
unreadCount: number;
|
|
42
|
+
/** First ~200 characters of the last message, for the list. Null on an empty conversation. */
|
|
43
|
+
lastMessagePreview: Nullable<string>;
|
|
44
|
+
/** Sorts the inbox. Null only for a conversation created before its first message. */
|
|
45
|
+
lastMessageAt: Nullable<IsoDateTime>;
|
|
46
|
+
/** When the contact last said something. Drives "waiting on us" without reading the messages. */
|
|
47
|
+
lastInboundAt: Nullable<IsoDateTime>;
|
|
48
|
+
/** Set only while `SNOOZED`. The conversation returns to `OPEN` at this time. */
|
|
49
|
+
snoozedUntil: Nullable<IsoDateTime>;
|
|
50
|
+
/**
|
|
51
|
+
* When a human took over from the AI, and who.
|
|
52
|
+
*
|
|
53
|
+
* §12 makes handover a launch requirement, and these two fields are what make it a fact rather
|
|
54
|
+
* than a convention: once set, `unibox-ai` must not answer in this conversation again. Nothing
|
|
55
|
+
* writes them from an AI side yet, and the guarantee is the same either way — the flag is what
|
|
56
|
+
* a future agent loop reads, and it exists before there is a loop to read it.
|
|
57
|
+
*/
|
|
58
|
+
handedOverAt: Nullable<IsoDateTime>;
|
|
59
|
+
handedOverToUserId: Nullable<UUID>;
|
|
60
|
+
closedAt: Nullable<IsoDateTime>;
|
|
61
|
+
createdAt: IsoDateTime;
|
|
62
|
+
updatedAt: IsoDateTime;
|
|
63
|
+
}
|
|
64
|
+
/** One conversation with the head of its thread, for a detail view that opens in one request. */
|
|
65
|
+
export interface ConversationWithMessages {
|
|
66
|
+
conversation: Conversation;
|
|
67
|
+
/** Newest first, same order as `MessagesPage`. */
|
|
68
|
+
messages: Message[];
|
|
69
|
+
/** Cursor for the next (older) page, or null when the thread is fully loaded. */
|
|
70
|
+
nextCursor: Nullable<string>;
|
|
71
|
+
}
|
|
72
|
+
/** `GET /api/v1/conversations`. Cursor-paged — this is the busiest list in the product. */
|
|
73
|
+
export type ConversationsPage = CursorPage<Conversation>;
|
|
74
|
+
/**
|
|
75
|
+
* Query for `GET /api/v1/conversations` — the inbox itself.
|
|
76
|
+
*
|
|
77
|
+
* Every filter is optional and they compose with AND. `assigneeUserId` accepting the literal
|
|
78
|
+
* `'unassigned'` is the one piece of overloading here, and it earns its place: "nobody has picked
|
|
79
|
+
* this up" is the single most-used view in a shared inbox, and expressing it as a separate boolean
|
|
80
|
+
* would make it silently combine with an assignee filter that contradicts it.
|
|
81
|
+
*/
|
|
82
|
+
export interface GetConversationsQuery {
|
|
83
|
+
limit?: number;
|
|
84
|
+
/** Opaque cursor from the previous page's `nextCursor`. Never parse it. */
|
|
85
|
+
after?: Nullable<string>;
|
|
86
|
+
status?: Nullable<ConversationStatus>;
|
|
87
|
+
/** A user id, or `'unassigned'`. */
|
|
88
|
+
assigneeUserId?: Nullable<string>;
|
|
89
|
+
teamId?: Nullable<UUID>;
|
|
90
|
+
channelId?: Nullable<UUID>;
|
|
91
|
+
platform?: Nullable<ChannelPlatform>;
|
|
92
|
+
/** Only conversations with at least one unread inbound message. */
|
|
93
|
+
hasUnread?: Nullable<boolean>;
|
|
94
|
+
/** Case-insensitive substring of the contact's display name. */
|
|
95
|
+
search?: Nullable<string>;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* `PATCH /api/v1/conversations/:id/status`.
|
|
99
|
+
*
|
|
100
|
+
* Its own endpoint rather than a field on a general update, because a status change is an event
|
|
101
|
+
* with side effects — closing stamps `closedAt` and writes a system message, snoozing schedules a
|
|
102
|
+
* reopen — and folding it into a PATCH that also renames things makes those side effects a
|
|
103
|
+
* surprise.
|
|
104
|
+
*/
|
|
105
|
+
export interface UpdateConversationStatusBody {
|
|
106
|
+
status: ConversationStatus;
|
|
107
|
+
/** Required when `status` is `snoozed`, refused otherwise. Must be in the future. */
|
|
108
|
+
snoozedUntil?: Nullable<IsoDateTime>;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* `PATCH /api/v1/conversations/:id/assignee`.
|
|
112
|
+
*
|
|
113
|
+
* `null` unassigns, which is a deliberate act and not the absence of one — hence a body with an
|
|
114
|
+
* explicitly nullable field rather than an optional one. Assigning to a user who is not an active
|
|
115
|
+
* member of the tenant is refused: identity is the authority on who exists, and an inbox that can
|
|
116
|
+
* assign work to a removed employee is an inbox with invisible work in it.
|
|
117
|
+
*/
|
|
118
|
+
export interface UpdateConversationAssigneeBody {
|
|
119
|
+
assigneeUserId: Nullable<UUID>;
|
|
120
|
+
/** Set the routing team at the same time. Omit to leave it alone; `null` clears it. */
|
|
121
|
+
teamId?: Nullable<UUID>;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* `POST /api/v1/conversations/:id/handover` — a human takes over.
|
|
125
|
+
*
|
|
126
|
+
* Idempotent: taking over a conversation already handed over to you is a no-op rather than an
|
|
127
|
+
* error, because the button will be pressed twice and the second press must not read as a failure.
|
|
128
|
+
* Taking over one handed to *somebody else* reassigns it and says so in the thread.
|
|
129
|
+
*/
|
|
130
|
+
export interface HandoverConversationBody {
|
|
131
|
+
/** Defaults to the caller. Naming someone else is a handover *to* them. */
|
|
132
|
+
userId?: Nullable<UUID>;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=conversation.type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.type.d.ts","sourceRoot":"","sources":["../../../../src/api/unibox/conversation.type.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conversation.type.js","sourceRoot":"","sources":["../../../../src/api/unibox/conversation.type.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './canned-reply.type.js';
|
|
2
|
+
export * from './channel-platform.enum.js';
|
|
3
|
+
export * from './channel.type.js';
|
|
4
|
+
export * from './contact.type.js';
|
|
5
|
+
export * from './conversation-status.enum.js';
|
|
6
|
+
export * from './conversation.type.js';
|
|
7
|
+
export * from './message-author-type.enum.js';
|
|
8
|
+
export * from './message-content-type.enum.js';
|
|
9
|
+
export * from './message-direction.enum.js';
|
|
10
|
+
export * from './message-status.enum.js';
|
|
11
|
+
export * from './message.type.js';
|
|
12
|
+
export * from './team.type.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/api/unibox/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './canned-reply.type.js';
|
|
2
|
+
export * from './channel-platform.enum.js';
|
|
3
|
+
export * from './channel.type.js';
|
|
4
|
+
export * from './contact.type.js';
|
|
5
|
+
export * from './conversation-status.enum.js';
|
|
6
|
+
export * from './conversation.type.js';
|
|
7
|
+
export * from './message-author-type.enum.js';
|
|
8
|
+
export * from './message-content-type.enum.js';
|
|
9
|
+
export * from './message-direction.enum.js';
|
|
10
|
+
export * from './message-status.enum.js';
|
|
11
|
+
export * from './message.type.js';
|
|
12
|
+
export * from './team.type.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/api/unibox/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who produced a message.
|
|
3
|
+
*
|
|
4
|
+
* `AI` is a member here even though `unibox-ai` is build-order step 9 and does not exist. That is
|
|
5
|
+
* not speculation — it is the field an agent taking over mid-conversation reads to know what the
|
|
6
|
+
* customer has already been told, and §12 makes human handoff a launch requirement rather than a
|
|
7
|
+
* v2 feature. Adding the member later would mean every message written before it was added is
|
|
8
|
+
* indistinguishable from a human's, retroactively and unfixably.
|
|
9
|
+
*/
|
|
10
|
+
export declare enum MessageAuthorType {
|
|
11
|
+
/** The person on the other end. `authorUserId` is null. */
|
|
12
|
+
CONTACT = "contact",
|
|
13
|
+
/** A human agent. `authorUserId` names them. */
|
|
14
|
+
AGENT = "agent",
|
|
15
|
+
/**
|
|
16
|
+
* The AI agent. Reserved for `unibox-ai`; nothing writes it yet.
|
|
17
|
+
*
|
|
18
|
+
* Distinct from `AGENT` because "did a person say this?" is the question a human asks before
|
|
19
|
+
* taking over, and because a customer who later asks whether they were talking to a bot
|
|
20
|
+
* deserves an answer the data can actually give.
|
|
21
|
+
*/
|
|
22
|
+
AI = "ai",
|
|
23
|
+
/** Unibox itself — assignment changes, status changes. Always `INTERNAL`. */
|
|
24
|
+
SYSTEM = "system"
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=message-author-type.enum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-author-type.enum.d.ts","sourceRoot":"","sources":["../../../../src/api/unibox/message-author-type.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,oBAAY,iBAAiB;IACzB,2DAA2D;IAC3D,OAAO,YAAY;IAEnB,gDAAgD;IAChD,KAAK,UAAU;IAEf;;;;;;OAMG;IACH,EAAE,OAAO;IAET,6EAA6E;IAC7E,MAAM,WAAW;CACpB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who produced a message.
|
|
3
|
+
*
|
|
4
|
+
* `AI` is a member here even though `unibox-ai` is build-order step 9 and does not exist. That is
|
|
5
|
+
* not speculation — it is the field an agent taking over mid-conversation reads to know what the
|
|
6
|
+
* customer has already been told, and §12 makes human handoff a launch requirement rather than a
|
|
7
|
+
* v2 feature. Adding the member later would mean every message written before it was added is
|
|
8
|
+
* indistinguishable from a human's, retroactively and unfixably.
|
|
9
|
+
*/
|
|
10
|
+
export var MessageAuthorType;
|
|
11
|
+
(function (MessageAuthorType) {
|
|
12
|
+
/** The person on the other end. `authorUserId` is null. */
|
|
13
|
+
MessageAuthorType["CONTACT"] = "contact";
|
|
14
|
+
/** A human agent. `authorUserId` names them. */
|
|
15
|
+
MessageAuthorType["AGENT"] = "agent";
|
|
16
|
+
/**
|
|
17
|
+
* The AI agent. Reserved for `unibox-ai`; nothing writes it yet.
|
|
18
|
+
*
|
|
19
|
+
* Distinct from `AGENT` because "did a person say this?" is the question a human asks before
|
|
20
|
+
* taking over, and because a customer who later asks whether they were talking to a bot
|
|
21
|
+
* deserves an answer the data can actually give.
|
|
22
|
+
*/
|
|
23
|
+
MessageAuthorType["AI"] = "ai";
|
|
24
|
+
/** Unibox itself — assignment changes, status changes. Always `INTERNAL`. */
|
|
25
|
+
MessageAuthorType["SYSTEM"] = "system";
|
|
26
|
+
})(MessageAuthorType || (MessageAuthorType = {}));
|
|
27
|
+
//# sourceMappingURL=message-author-type.enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-author-type.enum.js","sourceRoot":"","sources":["../../../../src/api/unibox/message-author-type.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAN,IAAY,iBAkBX;AAlBD,WAAY,iBAAiB;IACzB,2DAA2D;IAC3D,wCAAmB,CAAA;IAEnB,gDAAgD;IAChD,oCAAe,CAAA;IAEf;;;;;;OAMG;IACH,8BAAS,CAAA;IAET,6EAA6E;IAC7E,sCAAiB,CAAA;AACrB,CAAC,EAlBW,iBAAiB,KAAjB,iBAAiB,QAkB5B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What kind of thing a message carries.
|
|
3
|
+
*
|
|
4
|
+
* A small closed set that every platform can be normalized into, rather than a union of what each
|
|
5
|
+
* one supports. A per-platform vocabulary would put "is this an Instagram story reply or a
|
|
6
|
+
* WhatsApp interactive button" in front of the inbox UI, and the inbox's whole promise is that it
|
|
7
|
+
* does not care.
|
|
8
|
+
*/
|
|
9
|
+
export declare enum MessageContentType {
|
|
10
|
+
TEXT = "text",
|
|
11
|
+
IMAGE = "image",
|
|
12
|
+
VIDEO = "video",
|
|
13
|
+
AUDIO = "audio",
|
|
14
|
+
/** A file — PDF, spreadsheet, anything not one of the media types above. */
|
|
15
|
+
DOCUMENT = "document",
|
|
16
|
+
LOCATION = "location",
|
|
17
|
+
/** A sticker or a bare emoji reaction, kept distinct so it can be rendered small. */
|
|
18
|
+
STICKER = "sticker",
|
|
19
|
+
/**
|
|
20
|
+
* Something arrived that this version cannot represent.
|
|
21
|
+
*
|
|
22
|
+
* **A first-class member, not an error.** A message we cannot render is still evidence that
|
|
23
|
+
* the contact said something, and dropping it leaves an agent replying to a gap. The raw
|
|
24
|
+
* provider payload is retained on the message so the same row can be re-read once a
|
|
25
|
+
* normalizer learns the type.
|
|
26
|
+
*/
|
|
27
|
+
UNSUPPORTED = "unsupported"
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=message-content-type.enum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-content-type.enum.d.ts","sourceRoot":"","sources":["../../../../src/api/unibox/message-content-type.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,oBAAY,kBAAkB;IAC1B,IAAI,SAAS;IACb,KAAK,UAAU;IACf,KAAK,UAAU;IACf,KAAK,UAAU;IACf,4EAA4E;IAC5E,QAAQ,aAAa;IACrB,QAAQ,aAAa;IACrB,qFAAqF;IACrF,OAAO,YAAY;IAEnB;;;;;;;OAOG;IACH,WAAW,gBAAgB;CAC9B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What kind of thing a message carries.
|
|
3
|
+
*
|
|
4
|
+
* A small closed set that every platform can be normalized into, rather than a union of what each
|
|
5
|
+
* one supports. A per-platform vocabulary would put "is this an Instagram story reply or a
|
|
6
|
+
* WhatsApp interactive button" in front of the inbox UI, and the inbox's whole promise is that it
|
|
7
|
+
* does not care.
|
|
8
|
+
*/
|
|
9
|
+
export var MessageContentType;
|
|
10
|
+
(function (MessageContentType) {
|
|
11
|
+
MessageContentType["TEXT"] = "text";
|
|
12
|
+
MessageContentType["IMAGE"] = "image";
|
|
13
|
+
MessageContentType["VIDEO"] = "video";
|
|
14
|
+
MessageContentType["AUDIO"] = "audio";
|
|
15
|
+
/** A file — PDF, spreadsheet, anything not one of the media types above. */
|
|
16
|
+
MessageContentType["DOCUMENT"] = "document";
|
|
17
|
+
MessageContentType["LOCATION"] = "location";
|
|
18
|
+
/** A sticker or a bare emoji reaction, kept distinct so it can be rendered small. */
|
|
19
|
+
MessageContentType["STICKER"] = "sticker";
|
|
20
|
+
/**
|
|
21
|
+
* Something arrived that this version cannot represent.
|
|
22
|
+
*
|
|
23
|
+
* **A first-class member, not an error.** A message we cannot render is still evidence that
|
|
24
|
+
* the contact said something, and dropping it leaves an agent replying to a gap. The raw
|
|
25
|
+
* provider payload is retained on the message so the same row can be re-read once a
|
|
26
|
+
* normalizer learns the type.
|
|
27
|
+
*/
|
|
28
|
+
MessageContentType["UNSUPPORTED"] = "unsupported";
|
|
29
|
+
})(MessageContentType || (MessageContentType = {}));
|
|
30
|
+
//# sourceMappingURL=message-content-type.enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-content-type.enum.js","sourceRoot":"","sources":["../../../../src/api/unibox/message-content-type.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,kBAoBX;AApBD,WAAY,kBAAkB;IAC1B,mCAAa,CAAA;IACb,qCAAe,CAAA;IACf,qCAAe,CAAA;IACf,qCAAe,CAAA;IACf,4EAA4E;IAC5E,2CAAqB,CAAA;IACrB,2CAAqB,CAAA;IACrB,qFAAqF;IACrF,yCAAmB,CAAA;IAEnB;;;;;;;OAOG;IACH,iDAA2B,CAAA;AAC/B,CAAC,EApBW,kBAAkB,KAAlB,kBAAkB,QAoB7B"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which way a message travelled.
|
|
3
|
+
*
|
|
4
|
+
* Separate from {@link MessageAuthorType} on purpose, because they answer different questions and
|
|
5
|
+
* the mapping is not one-to-one. A `SYSTEM` note ("conversation assigned to Dana") is outbound in
|
|
6
|
+
* neither sense — it was never sent anywhere — so it is `INTERNAL`, and collapsing the two fields
|
|
7
|
+
* would make every internal note look like something a customer received.
|
|
8
|
+
*/
|
|
9
|
+
export declare enum MessageDirection {
|
|
10
|
+
/** From the contact to us, through a provider. */
|
|
11
|
+
INBOUND = "inbound",
|
|
12
|
+
/** From us to the contact, through Conduit. */
|
|
13
|
+
OUTBOUND = "outbound",
|
|
14
|
+
/**
|
|
15
|
+
* Never left Unibox. Assignment notes, status changes, private agent comments.
|
|
16
|
+
*
|
|
17
|
+
* Rendered in the thread because context is what makes a handover work, but structurally
|
|
18
|
+
* distinct: an internal message has no delivery status and no provider message id, and a bug
|
|
19
|
+
* that sent one would be a customer reading our internal notes.
|
|
20
|
+
*/
|
|
21
|
+
INTERNAL = "internal"
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=message-direction.enum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-direction.enum.d.ts","sourceRoot":"","sources":["../../../../src/api/unibox/message-direction.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,oBAAY,gBAAgB;IACxB,kDAAkD;IAClD,OAAO,YAAY;IAEnB,+CAA+C;IAC/C,QAAQ,aAAa;IAErB;;;;;;OAMG;IACH,QAAQ,aAAa;CACxB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which way a message travelled.
|
|
3
|
+
*
|
|
4
|
+
* Separate from {@link MessageAuthorType} on purpose, because they answer different questions and
|
|
5
|
+
* the mapping is not one-to-one. A `SYSTEM` note ("conversation assigned to Dana") is outbound in
|
|
6
|
+
* neither sense — it was never sent anywhere — so it is `INTERNAL`, and collapsing the two fields
|
|
7
|
+
* would make every internal note look like something a customer received.
|
|
8
|
+
*/
|
|
9
|
+
export var MessageDirection;
|
|
10
|
+
(function (MessageDirection) {
|
|
11
|
+
/** From the contact to us, through a provider. */
|
|
12
|
+
MessageDirection["INBOUND"] = "inbound";
|
|
13
|
+
/** From us to the contact, through Conduit. */
|
|
14
|
+
MessageDirection["OUTBOUND"] = "outbound";
|
|
15
|
+
/**
|
|
16
|
+
* Never left Unibox. Assignment notes, status changes, private agent comments.
|
|
17
|
+
*
|
|
18
|
+
* Rendered in the thread because context is what makes a handover work, but structurally
|
|
19
|
+
* distinct: an internal message has no delivery status and no provider message id, and a bug
|
|
20
|
+
* that sent one would be a customer reading our internal notes.
|
|
21
|
+
*/
|
|
22
|
+
MessageDirection["INTERNAL"] = "internal";
|
|
23
|
+
})(MessageDirection || (MessageDirection = {}));
|
|
24
|
+
//# sourceMappingURL=message-direction.enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-direction.enum.js","sourceRoot":"","sources":["../../../../src/api/unibox/message-direction.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,gBAeX;AAfD,WAAY,gBAAgB;IACxB,kDAAkD;IAClD,uCAAmB,CAAA;IAEnB,+CAA+C;IAC/C,yCAAqB,CAAA;IAErB;;;;;;OAMG;IACH,yCAAqB,CAAA;AACzB,CAAC,EAfW,gBAAgB,KAAhB,gBAAgB,QAe3B"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How far an **outbound** message got.
|
|
3
|
+
*
|
|
4
|
+
* Inbound and internal messages are always {@link MessageStatus.RECEIVED} and
|
|
5
|
+
* {@link MessageStatus.NONE} respectively — the states below describe our side of a send, and a
|
|
6
|
+
* message that arrived has no send to describe.
|
|
7
|
+
*
|
|
8
|
+
* The three post-send states mirror what the messaging platforms report back through their status
|
|
9
|
+
* webhooks, and they arrive **through the inbound pipeline** (§11): a provider telling us a
|
|
10
|
+
* message was read is just another webhook. Nothing polls for them.
|
|
11
|
+
*/
|
|
12
|
+
export declare enum MessageStatus {
|
|
13
|
+
/** Not applicable — an internal note. */
|
|
14
|
+
NONE = "none",
|
|
15
|
+
/** Inbound. It is here; there was nothing to send. */
|
|
16
|
+
RECEIVED = "received",
|
|
17
|
+
/**
|
|
18
|
+
* Written down and handed to Conduit, which answered `202`.
|
|
19
|
+
*
|
|
20
|
+
* The important state to read correctly: it means Conduit has accepted responsibility, not
|
|
21
|
+
* that the provider has seen it. An inbox that renders this as a delivered tick is lying at
|
|
22
|
+
* exactly the moment a provider outage matters.
|
|
23
|
+
*/
|
|
24
|
+
QUEUED = "queued",
|
|
25
|
+
/** The provider accepted it. */
|
|
26
|
+
SENT = "sent",
|
|
27
|
+
/** The provider says it reached the contact's device. */
|
|
28
|
+
DELIVERED = "delivered",
|
|
29
|
+
/** The contact opened it. Not every platform reports this. */
|
|
30
|
+
READ = "read",
|
|
31
|
+
/**
|
|
32
|
+
* It will not be sent. Terminal.
|
|
33
|
+
*
|
|
34
|
+
* Set when Conduit dead-letters the dispatch, or when the send is refused outright — an
|
|
35
|
+
* inactive channel, a closed messaging window. `failureReason` carries the why, because
|
|
36
|
+
* "failed" alone sends an agent to ask an engineer.
|
|
37
|
+
*/
|
|
38
|
+
FAILED = "failed"
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=message-status.enum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-status.enum.d.ts","sourceRoot":"","sources":["../../../../src/api/unibox/message-status.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,oBAAY,aAAa;IACrB,yCAAyC;IACzC,IAAI,SAAS;IAEb,sDAAsD;IACtD,QAAQ,aAAa;IAErB;;;;;;OAMG;IACH,MAAM,WAAW;IAEjB,gCAAgC;IAChC,IAAI,SAAS;IAEb,yDAAyD;IACzD,SAAS,cAAc;IAEvB,8DAA8D;IAC9D,IAAI,SAAS;IAEb;;;;;;OAMG;IACH,MAAM,WAAW;CACpB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How far an **outbound** message got.
|
|
3
|
+
*
|
|
4
|
+
* Inbound and internal messages are always {@link MessageStatus.RECEIVED} and
|
|
5
|
+
* {@link MessageStatus.NONE} respectively — the states below describe our side of a send, and a
|
|
6
|
+
* message that arrived has no send to describe.
|
|
7
|
+
*
|
|
8
|
+
* The three post-send states mirror what the messaging platforms report back through their status
|
|
9
|
+
* webhooks, and they arrive **through the inbound pipeline** (§11): a provider telling us a
|
|
10
|
+
* message was read is just another webhook. Nothing polls for them.
|
|
11
|
+
*/
|
|
12
|
+
export var MessageStatus;
|
|
13
|
+
(function (MessageStatus) {
|
|
14
|
+
/** Not applicable — an internal note. */
|
|
15
|
+
MessageStatus["NONE"] = "none";
|
|
16
|
+
/** Inbound. It is here; there was nothing to send. */
|
|
17
|
+
MessageStatus["RECEIVED"] = "received";
|
|
18
|
+
/**
|
|
19
|
+
* Written down and handed to Conduit, which answered `202`.
|
|
20
|
+
*
|
|
21
|
+
* The important state to read correctly: it means Conduit has accepted responsibility, not
|
|
22
|
+
* that the provider has seen it. An inbox that renders this as a delivered tick is lying at
|
|
23
|
+
* exactly the moment a provider outage matters.
|
|
24
|
+
*/
|
|
25
|
+
MessageStatus["QUEUED"] = "queued";
|
|
26
|
+
/** The provider accepted it. */
|
|
27
|
+
MessageStatus["SENT"] = "sent";
|
|
28
|
+
/** The provider says it reached the contact's device. */
|
|
29
|
+
MessageStatus["DELIVERED"] = "delivered";
|
|
30
|
+
/** The contact opened it. Not every platform reports this. */
|
|
31
|
+
MessageStatus["READ"] = "read";
|
|
32
|
+
/**
|
|
33
|
+
* It will not be sent. Terminal.
|
|
34
|
+
*
|
|
35
|
+
* Set when Conduit dead-letters the dispatch, or when the send is refused outright — an
|
|
36
|
+
* inactive channel, a closed messaging window. `failureReason` carries the why, because
|
|
37
|
+
* "failed" alone sends an agent to ask an engineer.
|
|
38
|
+
*/
|
|
39
|
+
MessageStatus["FAILED"] = "failed";
|
|
40
|
+
})(MessageStatus || (MessageStatus = {}));
|
|
41
|
+
//# sourceMappingURL=message-status.enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-status.enum.js","sourceRoot":"","sources":["../../../../src/api/unibox/message-status.enum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAN,IAAY,aAiCX;AAjCD,WAAY,aAAa;IACrB,yCAAyC;IACzC,8BAAa,CAAA;IAEb,sDAAsD;IACtD,sCAAqB,CAAA;IAErB;;;;;;OAMG;IACH,kCAAiB,CAAA;IAEjB,gCAAgC;IAChC,8BAAa,CAAA;IAEb,yDAAyD;IACzD,wCAAuB,CAAA;IAEvB,8DAA8D;IAC9D,8BAAa,CAAA;IAEb;;;;;;OAMG;IACH,kCAAiB,CAAA;AACrB,CAAC,EAjCW,aAAa,KAAb,aAAa,QAiCxB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { CursorPage } from '../../type/cursor-page.type.js';
|
|
2
|
+
import type { IsoDateTime } from '../../type/iso-date-time.type.js';
|
|
3
|
+
import type { Nullable } from '../../type/nil.type.js';
|
|
4
|
+
import type { UUID } from '../../type/uuid.type.js';
|
|
5
|
+
import type { MessageAuthorType } from './message-author-type.enum.js';
|
|
6
|
+
import type { MessageContentType } from './message-content-type.enum.js';
|
|
7
|
+
import type { MessageDirection } from './message-direction.enum.js';
|
|
8
|
+
import type { MessageStatus } from './message-status.enum.js';
|
|
9
|
+
/** A file attached to a message. Media is referenced by provider URL until `iveri-files-api` exists. */
|
|
10
|
+
export interface MessageAttachment {
|
|
11
|
+
contentType: MessageContentType;
|
|
12
|
+
/**
|
|
13
|
+
* Where the media lives.
|
|
14
|
+
*
|
|
15
|
+
* Today this is the provider's own URL, which for most platforms is short-lived and requires
|
|
16
|
+
* the channel's credentials to fetch — so it is not something a browser can render directly.
|
|
17
|
+
* Re-hosting is `iveri-files-api`'s job (build-order step 10 territory), and this field is
|
|
18
|
+
* what will point at it instead.
|
|
19
|
+
*/
|
|
20
|
+
url: Nullable<string>;
|
|
21
|
+
/** The provider's media id, which is what a re-host job would need to fetch it. */
|
|
22
|
+
externalMediaId: Nullable<string>;
|
|
23
|
+
fileName: Nullable<string>;
|
|
24
|
+
mimeType: Nullable<string>;
|
|
25
|
+
sizeBytes: Nullable<number>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* One message in a conversation.
|
|
29
|
+
*
|
|
30
|
+
* Immutable once written, apart from `status` and its timestamps. An inbox is a record of what was
|
|
31
|
+
* said, and an editable one is not evidence of anything — which matters the first time a customer
|
|
32
|
+
* disputes what they were told.
|
|
33
|
+
*/
|
|
34
|
+
export interface Message {
|
|
35
|
+
id: UUID;
|
|
36
|
+
conversationId: UUID;
|
|
37
|
+
direction: MessageDirection;
|
|
38
|
+
authorType: MessageAuthorType;
|
|
39
|
+
/** The agent who wrote it. Null for anything not authored by a human. */
|
|
40
|
+
authorUserId: Nullable<UUID>;
|
|
41
|
+
contentType: MessageContentType;
|
|
42
|
+
/** The text, or a caption on a media message. Null when there was none. */
|
|
43
|
+
text: Nullable<string>;
|
|
44
|
+
attachments: MessageAttachment[];
|
|
45
|
+
status: MessageStatus;
|
|
46
|
+
/** Why a `FAILED` message failed, in words an agent can act on. Null otherwise. */
|
|
47
|
+
failureReason: Nullable<string>;
|
|
48
|
+
/**
|
|
49
|
+
* The provider's own message id.
|
|
50
|
+
*
|
|
51
|
+
* Inbound, this is the **idempotency key**: Conduit is at-least-once by design and a
|
|
52
|
+
* redelivered webhook must not produce a second message. Outbound, it arrives with the
|
|
53
|
+
* provider's acceptance and is what a later status webhook is matched against.
|
|
54
|
+
*/
|
|
55
|
+
externalMessageId: Nullable<string>;
|
|
56
|
+
/**
|
|
57
|
+
* The Conduit dispatch this send was submitted as.
|
|
58
|
+
*
|
|
59
|
+
* Kept so a dead letter in Conduit's outbound DLQ can be traced back to the message an agent
|
|
60
|
+
* is looking at. Conduit puts `x-conduit-dispatch-id` on every send for the same reason from
|
|
61
|
+
* the other end.
|
|
62
|
+
*/
|
|
63
|
+
dispatchId: Nullable<UUID>;
|
|
64
|
+
/**
|
|
65
|
+
* When the message was said, according to the provider — not when we stored it.
|
|
66
|
+
*
|
|
67
|
+
* These differ by however long a provider queued a webhook, which after an outage is hours.
|
|
68
|
+
* Ordering the thread by arrival would then shuffle a conversation into nonsense, so this is
|
|
69
|
+
* what the thread sorts on.
|
|
70
|
+
*/
|
|
71
|
+
sentAt: IsoDateTime;
|
|
72
|
+
deliveredAt: Nullable<IsoDateTime>;
|
|
73
|
+
readAt: Nullable<IsoDateTime>;
|
|
74
|
+
createdAt: IsoDateTime;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* `GET /api/v1/conversations/:id/messages`. Cursor-paged, **newest first**.
|
|
78
|
+
*
|
|
79
|
+
* Newest first because that is what a thread opens to, and because paging backwards through
|
|
80
|
+
* history is the direction a scroll actually goes. The client reverses a page to render it.
|
|
81
|
+
*/
|
|
82
|
+
export type MessagesPage = CursorPage<Message>;
|
|
83
|
+
/** Query for `GET /api/v1/conversations/:id/messages`. */
|
|
84
|
+
export interface GetMessagesQuery {
|
|
85
|
+
limit?: number;
|
|
86
|
+
/** Opaque cursor from the previous page's `nextCursor`. Never parse it. */
|
|
87
|
+
before?: Nullable<string>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* `POST /api/v1/conversations/:id/messages` — an agent replying.
|
|
91
|
+
*
|
|
92
|
+
* Note what is absent: no channel, no recipient, no provider fields. The conversation already
|
|
93
|
+
* knows which channel it is on and who the contact is, and letting a caller restate either would
|
|
94
|
+
* be a way to send a message to one person through another person's thread.
|
|
95
|
+
*/
|
|
96
|
+
export interface SendMessageBody {
|
|
97
|
+
/** The reply text. Required for `TEXT`; a caption otherwise. */
|
|
98
|
+
text?: Nullable<string>;
|
|
99
|
+
contentType?: Nullable<MessageContentType>;
|
|
100
|
+
attachments?: Nullable<MessageAttachment[]>;
|
|
101
|
+
/**
|
|
102
|
+
* The caller's idempotency key, scoped to the conversation.
|
|
103
|
+
*
|
|
104
|
+
* **Strongly recommended, and forwarded to Conduit as its dispatch key.** Without one, an
|
|
105
|
+
* agent double-clicking Send messages the customer twice — and unlike an inbound duplicate,
|
|
106
|
+
* which is evidence, an outbound duplicate is a mistake the customer sees.
|
|
107
|
+
*/
|
|
108
|
+
idempotencyKey?: Nullable<string>;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* `POST /api/v1/conversations/:id/notes` — a private note in the thread.
|
|
112
|
+
*
|
|
113
|
+
* A separate endpoint from sending rather than a flag on {@link SendMessageBody}, because the
|
|
114
|
+
* difference between "the customer reads this" and "only we read this" must not be one boolean
|
|
115
|
+
* away from being wrong. It also carries a different permission: writing a note is not sending.
|
|
116
|
+
*/
|
|
117
|
+
export interface AddNoteBody {
|
|
118
|
+
text: string;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=message.type.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message.type.d.ts","sourceRoot":"","sources":["../../../../src/api/unibox/message.type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,wGAAwG;AACxG,MAAM,WAAW,iBAAiB;IAC9B,WAAW,EAAE,kBAAkB,CAAC;IAEhC;;;;;;;OAOG;IACH,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEtB,mFAAmF;IACnF,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAElC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3B,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CAC/B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,IAAI,CAAC;IAET,cAAc,EAAE,IAAI,CAAC;IAErB,SAAS,EAAE,gBAAgB,CAAC;IAE5B,UAAU,EAAE,iBAAiB,CAAC;IAE9B,yEAAyE;IACzE,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE7B,WAAW,EAAE,kBAAkB,CAAC;IAEhC,2EAA2E;IAC3E,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEvB,WAAW,EAAE,iBAAiB,EAAE,CAAC;IAEjC,MAAM,EAAE,aAAa,CAAC;IAEtB,mFAAmF;IACnF,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEhC;;;;;;OAMG;IACH,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAEpC;;;;;;OAMG;IACH,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE3B;;;;;;OAMG;IACH,MAAM,EAAE,WAAW,CAAC;IAEpB,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IACnC,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IAE9B,SAAS,EAAE,WAAW,CAAC;CAC1B;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;AAE/C,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,2EAA2E;IAC3E,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC5B,gEAAgE;IAChE,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAExB,WAAW,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAE3C,WAAW,CAAC,EAAE,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAE5C;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CACrC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;CAChB"}
|