fauna-api 1.0.781 → 1.0.785
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/dist/src/chats.d.ts +11 -17
- package/dist/src/chats.js +10 -3
- package/dist/src/cicada/chats.d.ts +98 -0
- package/dist/src/cicada/chats.js +92 -0
- package/dist/src/cicada/inboxes.d.ts +5 -0
- package/dist/src/cicada/inboxes.js +6 -0
- package/dist/src/cicada/index.d.ts +2 -2
- package/dist/src/cicada/index.js +2 -2
- package/dist/src/friends.js +2 -5
- package/dist/src/groups.js +2 -2
- package/dist/src/parrot/chat.d.ts +10 -13
- package/dist/src/parrot/chat.js +32 -43
- package/dist/src/parrot/generative.d.ts +25 -6
- package/dist/src/parrot/generative.js +27 -0
- package/dist/src/parrot/room.d.ts +11 -9
- package/dist/src/parrot/room.js +32 -14
- package/dist/src/parrot/share.d.ts +3 -20
- package/dist/src/parrot/share.js +2 -30
- package/dist/src/tickets.d.ts +2 -3
- package/dist/src/tickets.js +2 -2
- package/dist/src/ui/chat.d.ts +21 -0
- package/dist/src/ui/chat.js +157 -19
- package/dist/src/ui/chatSequence.d.ts +3 -0
- package/dist/src/ui/chatSequence.js +3 -0
- package/dist/src/ui/tokenized.d.ts +5 -0
- package/dist/src/ui/tokenized.js +73 -0
- package/dist/src/ui/ui.css +36 -0
- package/package.json +1 -1
- package/dist/src/cicada/conversations.d.ts +0 -73
- package/dist/src/cicada/conversations.js +0 -236
package/dist/src/ui/tokenized.js
CHANGED
|
@@ -49,6 +49,8 @@ export function createTokenizedInput(container, options = {}) {
|
|
|
49
49
|
}
|
|
50
50
|
else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
51
51
|
const el = node;
|
|
52
|
+
if (el.classList.contains('tokenized-ghost'))
|
|
53
|
+
return;
|
|
52
54
|
if (el.classList.contains('tokenized-token')) {
|
|
53
55
|
parts.push({
|
|
54
56
|
kind: 'token',
|
|
@@ -328,8 +330,49 @@ export function createTokenizedInput(container, options = {}) {
|
|
|
328
330
|
clearTimeout(suggestTimer);
|
|
329
331
|
suggestTimer = setTimeout(() => runSuggest(query), 120);
|
|
330
332
|
}
|
|
333
|
+
// ── Suggested ending ──
|
|
334
|
+
let ghostEl = null;
|
|
335
|
+
function clearGhost() {
|
|
336
|
+
ghostEl?.remove();
|
|
337
|
+
ghostEl = null;
|
|
338
|
+
}
|
|
339
|
+
function caretAtEnd() {
|
|
340
|
+
const sel = window.getSelection();
|
|
341
|
+
if (!sel || sel.rangeCount === 0 || !editor.contains(sel.anchorNode))
|
|
342
|
+
return false;
|
|
343
|
+
const after = document.createRange();
|
|
344
|
+
after.selectNodeContents(editor);
|
|
345
|
+
after.setStart(sel.getRangeAt(0).endContainer, sel.getRangeAt(0).endOffset);
|
|
346
|
+
const rest = after.cloneContents();
|
|
347
|
+
rest.querySelectorAll('.tokenized-ghost').forEach((g) => g.remove());
|
|
348
|
+
return (rest.textContent ?? '').replace(/\u200B/g, '') === '';
|
|
349
|
+
}
|
|
350
|
+
function placeCaretAtEnd() {
|
|
351
|
+
const range = document.createRange();
|
|
352
|
+
range.selectNodeContents(editor);
|
|
353
|
+
range.collapse(false);
|
|
354
|
+
const sel = window.getSelection();
|
|
355
|
+
sel?.removeAllRanges();
|
|
356
|
+
sel?.addRange(range);
|
|
357
|
+
}
|
|
358
|
+
function acceptGhost() {
|
|
359
|
+
const text = ghostEl?.textContent ?? '';
|
|
360
|
+
clearGhost();
|
|
361
|
+
if (!text)
|
|
362
|
+
return;
|
|
363
|
+
const lines = text.split('\n');
|
|
364
|
+
for (let i = 0; i < lines.length; i++) {
|
|
365
|
+
if (lines[i])
|
|
366
|
+
editor.appendChild(document.createTextNode(lines[i]));
|
|
367
|
+
if (i < lines.length - 1)
|
|
368
|
+
editor.appendChild(document.createElement('br'));
|
|
369
|
+
}
|
|
370
|
+
placeCaretAtEnd();
|
|
371
|
+
fireInput();
|
|
372
|
+
}
|
|
331
373
|
// ── Input events ──
|
|
332
374
|
editor.addEventListener('input', () => {
|
|
375
|
+
clearGhost();
|
|
333
376
|
fireInput();
|
|
334
377
|
if (activeTrigger) {
|
|
335
378
|
const query = getTriggerQuery();
|
|
@@ -342,6 +385,19 @@ export function createTokenizedInput(container, options = {}) {
|
|
|
342
385
|
}
|
|
343
386
|
});
|
|
344
387
|
editor.addEventListener('keydown', (e) => {
|
|
388
|
+
// A suggested ending: Tab takes it, Shift+Tab or Escape drops it
|
|
389
|
+
if (ghostEl) {
|
|
390
|
+
if (e.key === 'Tab' && !e.shiftKey) {
|
|
391
|
+
e.preventDefault();
|
|
392
|
+
acceptGhost();
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
if (e.key === 'Escape' || e.key === 'Tab') {
|
|
396
|
+
e.preventDefault();
|
|
397
|
+
clearGhost();
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
345
401
|
// Suggestion navigation
|
|
346
402
|
if (suggestionsEl.style.display !== 'none' && suggestionItems.length > 0) {
|
|
347
403
|
if (e.key === 'ArrowDown') {
|
|
@@ -435,6 +491,7 @@ export function createTokenizedInput(container, options = {}) {
|
|
|
435
491
|
}
|
|
436
492
|
});
|
|
437
493
|
editor.addEventListener('blur', () => {
|
|
494
|
+
clearGhost();
|
|
438
495
|
// Delay to allow mousedown on suggestions
|
|
439
496
|
setTimeout(() => {
|
|
440
497
|
if (!suggestionsEl.matches(':hover')) {
|
|
@@ -457,6 +514,20 @@ export function createTokenizedInput(container, options = {}) {
|
|
|
457
514
|
});
|
|
458
515
|
// ── Public API ──
|
|
459
516
|
return {
|
|
517
|
+
setGhost(text) {
|
|
518
|
+
clearGhost();
|
|
519
|
+
if (!text || !caretAtEnd())
|
|
520
|
+
return;
|
|
521
|
+
ghostEl = document.createElement('span');
|
|
522
|
+
ghostEl.className = 'tokenized-ghost';
|
|
523
|
+
ghostEl.contentEditable = 'false';
|
|
524
|
+
ghostEl.textContent = text;
|
|
525
|
+
ghostEl.dataset.hint = 'Tab';
|
|
526
|
+
editor.appendChild(ghostEl);
|
|
527
|
+
},
|
|
528
|
+
atEnd() {
|
|
529
|
+
return caretAtEnd();
|
|
530
|
+
},
|
|
460
531
|
getParts() {
|
|
461
532
|
return parseParts();
|
|
462
533
|
},
|
|
@@ -464,6 +535,7 @@ export function createTokenizedInput(container, options = {}) {
|
|
|
464
535
|
return serializeText(parseParts());
|
|
465
536
|
},
|
|
466
537
|
setParts(parts) {
|
|
538
|
+
clearGhost();
|
|
467
539
|
editor.innerHTML = '';
|
|
468
540
|
for (const part of parts) {
|
|
469
541
|
if (part.kind === 'text') {
|
|
@@ -487,6 +559,7 @@ export function createTokenizedInput(container, options = {}) {
|
|
|
487
559
|
insertTokenAtCaret(token);
|
|
488
560
|
},
|
|
489
561
|
clear() {
|
|
562
|
+
clearGhost();
|
|
490
563
|
editor.innerHTML = '';
|
|
491
564
|
hideSuggestions();
|
|
492
565
|
fireInput();
|
package/dist/src/ui/ui.css
CHANGED
|
@@ -435,6 +435,25 @@
|
|
|
435
435
|
color: var(--chat-text, inherit);
|
|
436
436
|
}
|
|
437
437
|
.chat-message-text > :first-child { margin-top: 0; }
|
|
438
|
+
|
|
439
|
+
/* An HTML body (an email's), drawn as it is in a frame that runs no scripts. */
|
|
440
|
+
.chat-message-html {
|
|
441
|
+
display: block;
|
|
442
|
+
width: 100%;
|
|
443
|
+
min-width: 280px;
|
|
444
|
+
min-height: 48px;
|
|
445
|
+
max-height: 640px;
|
|
446
|
+
border: 0;
|
|
447
|
+
border-radius: 10px;
|
|
448
|
+
background: #fff;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/* A line under a message, such as why it wasn't delivered. */
|
|
452
|
+
.chat-message-note {
|
|
453
|
+
margin-top: 4px;
|
|
454
|
+
font-size: 12px;
|
|
455
|
+
color: var(--chat-note, #c0392b);
|
|
456
|
+
}
|
|
438
457
|
.chat-message-text > :last-child { margin-bottom: 0; }
|
|
439
458
|
|
|
440
459
|
.chat-message-text table {
|
|
@@ -4992,3 +5011,20 @@ button.chat-message-file {
|
|
|
4992
5011
|
padding: 6px 12px;
|
|
4993
5012
|
cursor: pointer;
|
|
4994
5013
|
}
|
|
5014
|
+
|
|
5015
|
+
/* A suggested ending after the caret: Tab takes it. */
|
|
5016
|
+
.tokenized-ghost {
|
|
5017
|
+
color: var(--chat-ghost, rgba(0, 0, 0, 0.35));
|
|
5018
|
+
white-space: pre-wrap;
|
|
5019
|
+
pointer-events: none;
|
|
5020
|
+
user-select: none;
|
|
5021
|
+
}
|
|
5022
|
+
.tokenized-ghost::after {
|
|
5023
|
+
content: attr(data-hint);
|
|
5024
|
+
margin-left: 6px;
|
|
5025
|
+
padding: 0 4px;
|
|
5026
|
+
border: 1px solid currentColor;
|
|
5027
|
+
border-radius: 4px;
|
|
5028
|
+
font-size: 10px;
|
|
5029
|
+
vertical-align: middle;
|
|
5030
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fauna-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.785",
|
|
4
4
|
"description": "The Fauna SDK: accounts, Drive, groups, calendar, chats, payments and every Fauna app (Parrot, Marmot, Magpie, Cicada, Ant, Termite), plus React UI.",
|
|
5
5
|
"homepage": "https://docs.faunakit.com",
|
|
6
6
|
"repository": {
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { Contact, Owner } from "./contacts.js";
|
|
2
|
-
import { Platform } from "../integrations.js";
|
|
3
|
-
import { Credentials, ApiKey } from "../authentification.js";
|
|
4
|
-
import { File as FaunaFile } from "../drive.js";
|
|
5
|
-
export type Conversation = {
|
|
6
|
-
id: string;
|
|
7
|
-
inboxId?: string;
|
|
8
|
-
participants: (Contact | Owner | string)[];
|
|
9
|
-
activeAt: Date;
|
|
10
|
-
unread: number;
|
|
11
|
-
};
|
|
12
|
-
export type Reminder = {
|
|
13
|
-
conversation: Conversation;
|
|
14
|
-
remindAt: Date;
|
|
15
|
-
};
|
|
16
|
-
export type ScheduledSend = {
|
|
17
|
-
id: string;
|
|
18
|
-
sendAt: Date;
|
|
19
|
-
createdAt: Date;
|
|
20
|
-
message: string;
|
|
21
|
-
context: {
|
|
22
|
-
conversation: string;
|
|
23
|
-
platform?: Platform;
|
|
24
|
-
} | {
|
|
25
|
-
recipients: (Contact | Owner | string)[];
|
|
26
|
-
mode: 'broadcast' | 'group';
|
|
27
|
-
platform: Platform;
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
export type Message = {
|
|
31
|
-
id: string;
|
|
32
|
-
author: Contact | Owner | string;
|
|
33
|
-
platform: Platform;
|
|
34
|
-
createdAt: Date;
|
|
35
|
-
message: string;
|
|
36
|
-
raw?: string;
|
|
37
|
-
attachments: FaunaFile[];
|
|
38
|
-
/** Sent by the inbox agent. */
|
|
39
|
-
agent: boolean;
|
|
40
|
-
};
|
|
41
|
-
export declare function listInbox(authorization: Credentials | ApiKey, inboxId?: string): Promise<Conversation[]>;
|
|
42
|
-
export declare function listArchived(authorization: Credentials | ApiKey, inboxId?: string): Promise<Conversation[]>;
|
|
43
|
-
export declare function listReminders(authorization: Credentials | ApiKey, inboxId?: string): Promise<Reminder[]>;
|
|
44
|
-
export declare function get(authorization: Credentials | ApiKey, conversation: string): Promise<Conversation | null>;
|
|
45
|
-
export declare function read(authorization: Credentials | ApiKey, conversation: string): Promise<Message[]>;
|
|
46
|
-
export declare function autocomplete(authorization: Credentials | ApiKey, conversation: string, text: string): Promise<string>;
|
|
47
|
-
export declare function markRead(authorization: Credentials | ApiKey, conversation: string): Promise<void>;
|
|
48
|
-
export declare function remove(authorization: Credentials | ApiKey, conversation: string): Promise<void>;
|
|
49
|
-
export declare function compose(authorization: Credentials | ApiKey, options: {
|
|
50
|
-
recipients: string[];
|
|
51
|
-
platform: Platform;
|
|
52
|
-
text: string;
|
|
53
|
-
mode: 'broadcast' | 'group';
|
|
54
|
-
inboxId?: string;
|
|
55
|
-
accountId?: string;
|
|
56
|
-
}): Promise<string[]>;
|
|
57
|
-
export declare function send(authorization: Credentials | ApiKey, conversation: string, text: string, platform?: Platform): Promise<string>;
|
|
58
|
-
export declare function archive(authorization: Credentials | ApiKey, conversation: string, archived: boolean): Promise<void>;
|
|
59
|
-
export declare function remind(authorization: Credentials | ApiKey, conversation: string, at: Date | null): Promise<void>;
|
|
60
|
-
export declare function schedule(authorization: Credentials | ApiKey, options: {
|
|
61
|
-
sendAt: Date;
|
|
62
|
-
text: string;
|
|
63
|
-
platform?: Platform;
|
|
64
|
-
conversationId?: string;
|
|
65
|
-
compose?: {
|
|
66
|
-
recipients: string[];
|
|
67
|
-
mode: 'broadcast' | 'group';
|
|
68
|
-
};
|
|
69
|
-
inboxId?: string;
|
|
70
|
-
accountId?: string;
|
|
71
|
-
}): Promise<string>;
|
|
72
|
-
export declare function listScheduled(authorization: Credentials | ApiKey, inboxId?: string): Promise<ScheduledSend[]>;
|
|
73
|
-
export declare function cancelScheduled(authorization: Credentials | ApiKey, scheduled: string): Promise<void>;
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import { Cicada } from "./index.js";
|
|
2
|
-
function wrapConversation(raw) {
|
|
3
|
-
return {
|
|
4
|
-
...raw,
|
|
5
|
-
inboxId: raw.inboxId !== undefined ? String(raw.inboxId) : undefined,
|
|
6
|
-
activeAt: new Date(raw.activeAt)
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
function wrapMessage(raw) {
|
|
10
|
-
return {
|
|
11
|
-
...raw,
|
|
12
|
-
createdAt: new Date(raw.createdAt),
|
|
13
|
-
attachments: raw.attachments ?? [],
|
|
14
|
-
agent: raw.agent === true,
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
async function listView(authorization, path, inboxId) {
|
|
18
|
-
const response = await fetch(`${Cicada.getURL()}${path}`, {
|
|
19
|
-
method: "POST",
|
|
20
|
-
headers: {
|
|
21
|
-
"Content-Type": "application/json",
|
|
22
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
23
|
-
},
|
|
24
|
-
body: JSON.stringify(inboxId ? { inboxId } : {})
|
|
25
|
-
});
|
|
26
|
-
if (!response.ok)
|
|
27
|
-
throw new Error(await response.text());
|
|
28
|
-
const json = await response.json();
|
|
29
|
-
return json.map(wrapConversation);
|
|
30
|
-
}
|
|
31
|
-
// The inbox working set: everything except archived threads and conversations
|
|
32
|
-
// parked for a future reminder.
|
|
33
|
-
export async function listInbox(authorization, inboxId) {
|
|
34
|
-
return listView(authorization, '/cicada/inbox', inboxId);
|
|
35
|
-
}
|
|
36
|
-
// The archive.
|
|
37
|
-
export async function listArchived(authorization, inboxId) {
|
|
38
|
-
return listView(authorization, '/cicada/archived', inboxId);
|
|
39
|
-
}
|
|
40
|
-
// Threads with a pending (future) remindAt, each paired with its due time.
|
|
41
|
-
export async function listReminders(authorization, inboxId) {
|
|
42
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/reminders`, {
|
|
43
|
-
method: "POST",
|
|
44
|
-
headers: {
|
|
45
|
-
"Content-Type": "application/json",
|
|
46
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
47
|
-
},
|
|
48
|
-
body: JSON.stringify(inboxId ? { inboxId } : {})
|
|
49
|
-
});
|
|
50
|
-
if (!response.ok)
|
|
51
|
-
throw new Error(await response.text());
|
|
52
|
-
const json = await response.json();
|
|
53
|
-
return json.map((raw) => ({
|
|
54
|
-
conversation: wrapConversation(raw.conversation),
|
|
55
|
-
remindAt: new Date(raw.remindAt)
|
|
56
|
-
}));
|
|
57
|
-
}
|
|
58
|
-
// Fetch a single conversation's metadata by id (hydrated participants), or null
|
|
59
|
-
// if it no longer exists.
|
|
60
|
-
export async function get(authorization, conversation) {
|
|
61
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/conversation/get`, {
|
|
62
|
-
method: "POST",
|
|
63
|
-
headers: {
|
|
64
|
-
"Content-Type": "application/json",
|
|
65
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
66
|
-
},
|
|
67
|
-
body: JSON.stringify({ conversation })
|
|
68
|
-
});
|
|
69
|
-
if (!response.ok)
|
|
70
|
-
throw new Error(await response.text());
|
|
71
|
-
const json = await response.json();
|
|
72
|
-
return json ? wrapConversation(json) : null;
|
|
73
|
-
}
|
|
74
|
-
export async function read(authorization, conversation) {
|
|
75
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/conversation`, {
|
|
76
|
-
method: "POST",
|
|
77
|
-
headers: {
|
|
78
|
-
"Content-Type": "application/json",
|
|
79
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
80
|
-
},
|
|
81
|
-
body: JSON.stringify({ conversation })
|
|
82
|
-
});
|
|
83
|
-
if (!response.ok)
|
|
84
|
-
throw new Error(await response.text());
|
|
85
|
-
const json = await response.json();
|
|
86
|
-
return json.map(wrapMessage);
|
|
87
|
-
}
|
|
88
|
-
// Suggest a continuation of an in-progress reply for a conversation. Returns
|
|
89
|
-
// the raw completion text (the part that should follow the current draft); an
|
|
90
|
-
// empty string means no suggestion.
|
|
91
|
-
export async function autocomplete(authorization, conversation, text) {
|
|
92
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/autocomplete`, {
|
|
93
|
-
method: "POST",
|
|
94
|
-
headers: {
|
|
95
|
-
"Content-Type": "application/json",
|
|
96
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
97
|
-
},
|
|
98
|
-
body: JSON.stringify({ conversation, text })
|
|
99
|
-
});
|
|
100
|
-
if (!response.ok)
|
|
101
|
-
throw new Error(await response.text());
|
|
102
|
-
return await response.text();
|
|
103
|
-
}
|
|
104
|
-
export async function markRead(authorization, conversation) {
|
|
105
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/conversation/mark-read`, {
|
|
106
|
-
method: "POST",
|
|
107
|
-
headers: {
|
|
108
|
-
"Content-Type": "application/json",
|
|
109
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
110
|
-
},
|
|
111
|
-
body: JSON.stringify({ conversation })
|
|
112
|
-
});
|
|
113
|
-
if (!response.ok)
|
|
114
|
-
throw new Error(await response.text());
|
|
115
|
-
}
|
|
116
|
-
// Permanently delete a conversation (index entry + stored messages). Backfill
|
|
117
|
-
// won't repopulate it — it only runs on account link, and polling fetches
|
|
118
|
-
// deltas, so old messages never re-arrive.
|
|
119
|
-
export async function remove(authorization, conversation) {
|
|
120
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/conversation/delete`, {
|
|
121
|
-
method: "POST",
|
|
122
|
-
headers: {
|
|
123
|
-
"Content-Type": "application/json",
|
|
124
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
125
|
-
},
|
|
126
|
-
body: JSON.stringify({ conversation })
|
|
127
|
-
});
|
|
128
|
-
if (!response.ok)
|
|
129
|
-
throw new Error(await response.text());
|
|
130
|
-
}
|
|
131
|
-
// Start (or append to) conversations with picked contacts on a platform.
|
|
132
|
-
// `recipients` are contact keys (email/handle/phone). `broadcast` sends a
|
|
133
|
-
// separate 1:1 to each; `group` sends one shared thread (collapsing to
|
|
134
|
-
// broadcast on platforms without a real group path). Returns the affected
|
|
135
|
-
// conversation ids — open the first to show the resulting thread.
|
|
136
|
-
export async function compose(authorization, options) {
|
|
137
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/compose`, {
|
|
138
|
-
method: "POST",
|
|
139
|
-
headers: {
|
|
140
|
-
"Content-Type": "application/json",
|
|
141
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
142
|
-
},
|
|
143
|
-
body: JSON.stringify(options)
|
|
144
|
-
});
|
|
145
|
-
if (!response.ok)
|
|
146
|
-
throw new Error(await response.text());
|
|
147
|
-
const json = await response.json();
|
|
148
|
-
return json.conversationIds;
|
|
149
|
-
}
|
|
150
|
-
export async function send(authorization, conversation, text, platform) {
|
|
151
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/send`, {
|
|
152
|
-
method: "POST",
|
|
153
|
-
headers: {
|
|
154
|
-
"Content-Type": "application/json",
|
|
155
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
156
|
-
},
|
|
157
|
-
body: JSON.stringify({ conversation, text, platform })
|
|
158
|
-
});
|
|
159
|
-
if (!response.ok)
|
|
160
|
-
throw new Error(await response.text());
|
|
161
|
-
const json = await response.json();
|
|
162
|
-
return json.id;
|
|
163
|
-
}
|
|
164
|
-
// Move a conversation in/out of the archive.
|
|
165
|
-
export async function archive(authorization, conversation, archived) {
|
|
166
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/conversation/archive`, {
|
|
167
|
-
method: "POST",
|
|
168
|
-
headers: {
|
|
169
|
-
"Content-Type": "application/json",
|
|
170
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
171
|
-
},
|
|
172
|
-
body: JSON.stringify({ conversation, archived })
|
|
173
|
-
});
|
|
174
|
-
if (!response.ok)
|
|
175
|
-
throw new Error(await response.text());
|
|
176
|
-
}
|
|
177
|
-
// Set (or clear, with `at = null`) a reminder on a conversation. When the time
|
|
178
|
-
// arrives the server re-surfaces the thread at the top of the inbox.
|
|
179
|
-
export async function remind(authorization, conversation, at) {
|
|
180
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/conversation/remind`, {
|
|
181
|
-
method: "POST",
|
|
182
|
-
headers: {
|
|
183
|
-
"Content-Type": "application/json",
|
|
184
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
185
|
-
},
|
|
186
|
-
body: JSON.stringify({ conversation, at: at ? at.toISOString() : null })
|
|
187
|
-
});
|
|
188
|
-
if (!response.ok)
|
|
189
|
-
throw new Error(await response.text());
|
|
190
|
-
}
|
|
191
|
-
// Queue an outbound message for later. Provide `conversationId` to reply into an
|
|
192
|
-
// existing thread, or `compose` to start a fresh one. Returns the queue id.
|
|
193
|
-
export async function schedule(authorization, options) {
|
|
194
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/schedule`, {
|
|
195
|
-
method: "POST",
|
|
196
|
-
headers: {
|
|
197
|
-
"Content-Type": "application/json",
|
|
198
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
199
|
-
},
|
|
200
|
-
body: JSON.stringify({ ...options, sendAt: options.sendAt.toISOString() })
|
|
201
|
-
});
|
|
202
|
-
if (!response.ok)
|
|
203
|
-
throw new Error(await response.text());
|
|
204
|
-
const json = await response.json();
|
|
205
|
-
return json.id;
|
|
206
|
-
}
|
|
207
|
-
export async function listScheduled(authorization, inboxId) {
|
|
208
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/scheduled/list`, {
|
|
209
|
-
method: "POST",
|
|
210
|
-
headers: {
|
|
211
|
-
"Content-Type": "application/json",
|
|
212
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
213
|
-
},
|
|
214
|
-
body: JSON.stringify(inboxId ? { inboxId } : {})
|
|
215
|
-
});
|
|
216
|
-
if (!response.ok)
|
|
217
|
-
throw new Error(await response.text());
|
|
218
|
-
const json = await response.json();
|
|
219
|
-
return json.map((raw) => ({
|
|
220
|
-
...raw,
|
|
221
|
-
sendAt: new Date(raw.sendAt),
|
|
222
|
-
createdAt: new Date(raw.createdAt)
|
|
223
|
-
}));
|
|
224
|
-
}
|
|
225
|
-
export async function cancelScheduled(authorization, scheduled) {
|
|
226
|
-
const response = await fetch(`${Cicada.getURL()}/cicada/scheduled/cancel`, {
|
|
227
|
-
method: "POST",
|
|
228
|
-
headers: {
|
|
229
|
-
"Content-Type": "application/json",
|
|
230
|
-
"Authorization": 'email' in authorization ? `Token ${authorization.token}` : `ApiKey ${authorization.id}`
|
|
231
|
-
},
|
|
232
|
-
body: JSON.stringify({ scheduled })
|
|
233
|
-
});
|
|
234
|
-
if (!response.ok)
|
|
235
|
-
throw new Error(await response.text());
|
|
236
|
-
}
|