crewly 1.20.122 → 1.20.124
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/config/skills/agent/core/whatsapp-draft/SKILL.md +80 -0
- package/config/skills/agent/core/whatsapp-draft/execute.sh +84 -0
- package/config/skills/agent/core/whatsapp-draft/execute.test.sh +70 -0
- package/config/skills/agent/core/whatsapp-inbox/SKILL.md +75 -0
- package/config/skills/agent/core/whatsapp-inbox/execute.sh +87 -0
- package/config/skills/agent/core/whatsapp-inbox/execute.test.sh +68 -0
- package/config/skills/agent/core/whatsapp-read/SKILL.md +80 -0
- package/config/skills/agent/core/whatsapp-read/execute.sh +116 -0
- package/config/skills/agent/core/whatsapp-read/execute.test.sh +84 -0
- package/config/skills/agent/core/whatsapp-send/SKILL.md +70 -0
- package/config/skills/agent/core/whatsapp-send/execute.sh +84 -0
- package/config/skills/agent/core/whatsapp-send/execute.test.sh +79 -0
- package/dist/backend/backend/src/constants.d.ts +225 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +223 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/harness/harness.controller.d.ts +54 -0
- package/dist/backend/backend/src/controllers/harness/harness.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/harness/harness.controller.js +204 -0
- package/dist/backend/backend/src/controllers/harness/harness.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/harness/harness.routes.d.ts +27 -0
- package/dist/backend/backend/src/controllers/harness/harness.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/harness/harness.routes.js +43 -0
- package/dist/backend/backend/src/controllers/harness/harness.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.d.ts +73 -0
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.js +310 -0
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp-inbox.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.js +53 -4
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +4 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +5 -0
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js +7 -0
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +5 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts +2 -1
- package/dist/backend/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-client.service.js +4 -3
- package/dist/backend/backend/src/services/cloud/cloud-client.service.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +43 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
- package/dist/backend/backend/src/services/harness/claude-config.utils.d.ts +67 -0
- package/dist/backend/backend/src/services/harness/claude-config.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/claude-config.utils.js +118 -0
- package/dist/backend/backend/src/services/harness/claude-config.utils.js.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-api-key.service.d.ts +99 -0
- package/dist/backend/backend/src/services/harness/harness-api-key.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-api-key.service.js +157 -0
- package/dist/backend/backend/src/services/harness/harness-api-key.service.js.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-credentials.store.d.ts +135 -0
- package/dist/backend/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-credentials.store.js +208 -0
- package/dist/backend/backend/src/services/harness/harness-credentials.store.js.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-exec.utils.d.ts +85 -0
- package/dist/backend/backend/src/services/harness/harness-exec.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-exec.utils.js +183 -0
- package/dist/backend/backend/src/services/harness/harness-exec.utils.js.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-install.service.d.ts +106 -0
- package/dist/backend/backend/src/services/harness/harness-install.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-install.service.js +205 -0
- package/dist/backend/backend/src/services/harness/harness-install.service.js.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-registry.d.ts +86 -0
- package/dist/backend/backend/src/services/harness/harness-registry.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-registry.js +121 -0
- package/dist/backend/backend/src/services/harness/harness-registry.js.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-status.service.d.ts +173 -0
- package/dist/backend/backend/src/services/harness/harness-status.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/harness-status.service.js +324 -0
- package/dist/backend/backend/src/services/harness/harness-status.service.js.map +1 -0
- package/dist/backend/backend/src/services/harness/harness.service.d.ts +146 -0
- package/dist/backend/backend/src/services/harness/harness.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/harness.service.js +193 -0
- package/dist/backend/backend/src/services/harness/harness.service.js.map +1 -0
- package/dist/backend/backend/src/services/harness/harness.types.d.ts +138 -0
- package/dist/backend/backend/src/services/harness/harness.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/harness.types.js +51 -0
- package/dist/backend/backend/src/services/harness/harness.types.js.map +1 -0
- package/dist/backend/backend/src/services/harness/login-broker.service.d.ts +238 -0
- package/dist/backend/backend/src/services/harness/login-broker.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/login-broker.service.js +495 -0
- package/dist/backend/backend/src/services/harness/login-broker.service.js.map +1 -0
- package/dist/backend/backend/src/services/harness/login-rules.d.ts +162 -0
- package/dist/backend/backend/src/services/harness/login-rules.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/login-rules.js +344 -0
- package/dist/backend/backend/src/services/harness/login-rules.js.map +1 -0
- package/dist/backend/backend/src/services/harness/orc-harness.store.d.ts +59 -0
- package/dist/backend/backend/src/services/harness/orc-harness.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/harness/orc-harness.store.js +108 -0
- package/dist/backend/backend/src/services/harness/orc-harness.store.js.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/index.d.ts +5 -1
- package/dist/backend/backend/src/services/whatsapp/index.d.ts.map +1 -1
- package/dist/backend/backend/src/services/whatsapp/index.js +5 -1
- package/dist/backend/backend/src/services/whatsapp/index.js.map +1 -1
- package/dist/backend/backend/src/services/whatsapp/whatsapp-connection-config.d.ts +59 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-connection-config.d.ts.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-connection-config.js +108 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-connection-config.js.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.d.ts +74 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.d.ts.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.js +82 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-draft-gate.js.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox-capture.d.ts +184 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox-capture.d.ts.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox-capture.js +420 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox-capture.js.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox.store.d.ts +243 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox.store.d.ts.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox.store.js +538 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-inbox.store.js.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.d.ts +32 -2
- package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.js +65 -9
- package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.js.map +1 -1
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts.map +1 -1
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js +11 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/whatsapp/whatsapp.service.d.ts +59 -1
- package/dist/backend/backend/src/services/whatsapp/whatsapp.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/whatsapp/whatsapp.service.js +159 -9
- package/dist/backend/backend/src/services/whatsapp/whatsapp.service.js.map +1 -1
- package/dist/backend/backend/src/types/whatsapp.types.d.ts +108 -0
- package/dist/backend/backend/src/types/whatsapp.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/whatsapp.types.js +9 -0
- package/dist/backend/backend/src/types/whatsapp.types.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +225 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +223 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts +5 -0
- package/dist/cli/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/agent/agent-registration.service.js +7 -0
- package/dist/cli/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js +5 -0
- package/dist/cli/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts +2 -1
- package/dist/cli/backend/src/services/cloud/cloud-client.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-client.service.js +4 -3
- package/dist/cli/backend/src/services/cloud/cloud-client.service.js.map +1 -1
- package/dist/cli/backend/src/services/harness/claude-config.utils.d.ts +67 -0
- package/dist/cli/backend/src/services/harness/claude-config.utils.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/claude-config.utils.js +118 -0
- package/dist/cli/backend/src/services/harness/claude-config.utils.js.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-api-key.service.d.ts +99 -0
- package/dist/cli/backend/src/services/harness/harness-api-key.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-api-key.service.js +157 -0
- package/dist/cli/backend/src/services/harness/harness-api-key.service.js.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts +135 -0
- package/dist/cli/backend/src/services/harness/harness-credentials.store.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-credentials.store.js +208 -0
- package/dist/cli/backend/src/services/harness/harness-credentials.store.js.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-exec.utils.d.ts +85 -0
- package/dist/cli/backend/src/services/harness/harness-exec.utils.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-exec.utils.js +183 -0
- package/dist/cli/backend/src/services/harness/harness-exec.utils.js.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-install.service.d.ts +106 -0
- package/dist/cli/backend/src/services/harness/harness-install.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-install.service.js +205 -0
- package/dist/cli/backend/src/services/harness/harness-install.service.js.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-registry.d.ts +86 -0
- package/dist/cli/backend/src/services/harness/harness-registry.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-registry.js +121 -0
- package/dist/cli/backend/src/services/harness/harness-registry.js.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-status.service.d.ts +173 -0
- package/dist/cli/backend/src/services/harness/harness-status.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/harness-status.service.js +324 -0
- package/dist/cli/backend/src/services/harness/harness-status.service.js.map +1 -0
- package/dist/cli/backend/src/services/harness/harness.service.d.ts +146 -0
- package/dist/cli/backend/src/services/harness/harness.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/harness.service.js +193 -0
- package/dist/cli/backend/src/services/harness/harness.service.js.map +1 -0
- package/dist/cli/backend/src/services/harness/harness.types.d.ts +138 -0
- package/dist/cli/backend/src/services/harness/harness.types.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/harness.types.js +51 -0
- package/dist/cli/backend/src/services/harness/harness.types.js.map +1 -0
- package/dist/cli/backend/src/services/harness/login-broker.service.d.ts +238 -0
- package/dist/cli/backend/src/services/harness/login-broker.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/login-broker.service.js +495 -0
- package/dist/cli/backend/src/services/harness/login-broker.service.js.map +1 -0
- package/dist/cli/backend/src/services/harness/login-rules.d.ts +162 -0
- package/dist/cli/backend/src/services/harness/login-rules.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/login-rules.js +344 -0
- package/dist/cli/backend/src/services/harness/login-rules.js.map +1 -0
- package/dist/cli/backend/src/services/harness/orc-harness.store.d.ts +59 -0
- package/dist/cli/backend/src/services/harness/orc-harness.store.d.ts.map +1 -0
- package/dist/cli/backend/src/services/harness/orc-harness.store.js +108 -0
- package/dist/cli/backend/src/services/harness/orc-harness.store.js.map +1 -0
- package/dist/cli/cli/src/commands/harness-setup.d.ts +159 -0
- package/dist/cli/cli/src/commands/harness-setup.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/harness-setup.js +377 -0
- package/dist/cli/cli/src/commands/harness-setup.js.map +1 -0
- package/dist/cli/cli/src/commands/harness.d.ts +56 -0
- package/dist/cli/cli/src/commands/harness.d.ts.map +1 -0
- package/dist/cli/cli/src/commands/harness.js +97 -0
- package/dist/cli/cli/src/commands/harness.js.map +1 -0
- package/dist/cli/cli/src/commands/onboard.d.ts +108 -50
- package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/onboard.js +200 -191
- package/dist/cli/cli/src/commands/onboard.js.map +1 -1
- package/dist/cli/cli/src/constants.d.ts +18 -0
- package/dist/cli/cli/src/constants.d.ts.map +1 -1
- package/dist/cli/cli/src/constants.js +18 -0
- package/dist/cli/cli/src/constants.js.map +1 -1
- package/dist/cli/cli/src/index.js +22 -3
- package/dist/cli/cli/src/index.js.map +1 -1
- package/dist/cli/cli/src/utils/harness-engine.d.ts +99 -0
- package/dist/cli/cli/src/utils/harness-engine.d.ts.map +1 -0
- package/dist/cli/cli/src/utils/harness-engine.js +143 -0
- package/dist/cli/cli/src/utils/harness-engine.js.map +1 -0
- package/dist/cli/cli/src/utils/prompt-io.d.ts +25 -0
- package/dist/cli/cli/src/utils/prompt-io.d.ts.map +1 -0
- package/dist/cli/cli/src/utils/prompt-io.js +47 -0
- package/dist/cli/cli/src/utils/prompt-io.js.map +1 -0
- package/frontend/dist/assets/{index-8327e63e.css → index-0a2f783c.css} +1 -1
- package/frontend/dist/assets/{index-07e338a9.js → index-aaf65055.js} +309 -309
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WhatsApp Inbox Capture
|
|
3
|
+
*
|
|
4
|
+
* Turns Baileys events into inbox-store rows. Used only in `inbox` mode.
|
|
5
|
+
* Unlike the assistant path (`WhatsAppService.handleIncomingMessage`) nothing
|
|
6
|
+
* is dropped for being the owner's own message, a group message, media, or
|
|
7
|
+
* from a contact outside `allowedContacts` — the inbox has to know whether
|
|
8
|
+
* the owner already replied, and it is the owner's own account.
|
|
9
|
+
*
|
|
10
|
+
* Media are never downloaded: a message is recorded as its kind plus caption
|
|
11
|
+
* (or file name for documents).
|
|
12
|
+
*
|
|
13
|
+
* Baileys shapes relied on (v7, `@whiskeysockets/baileys` typings):
|
|
14
|
+
* - `messages.upsert`: `{ messages: WAMessage[], type: 'notify' | 'append' }`
|
|
15
|
+
* - `messaging-history.set`: `{ chats: Chat[], contacts: Contact[], messages: WAMessage[], syncType? }`
|
|
16
|
+
* - `contacts.upsert` / `contacts.update`: `Contact[]` (`id`, `name` = address book, `notify` = their pushName)
|
|
17
|
+
* - `chats.upsert` / `chats.update`: `Chat[]` (`id`, `name`, `conversationTimestamp`)
|
|
18
|
+
* - `groups.upsert` / `groups.update`: `GroupMetadata[]` (`id`, `subject`)
|
|
19
|
+
* - `WAMessage.key.remoteJidAlt` / `participantAlt` (v7 LID↔PN alternates)
|
|
20
|
+
* - `messageTimestamp`: seconds, as number, numeric string or protobuf Long
|
|
21
|
+
*
|
|
22
|
+
* @module services/whatsapp/whatsapp-inbox-capture
|
|
23
|
+
*/
|
|
24
|
+
import { WHATSAPP_CONSTANTS } from '../../constants.js';
|
|
25
|
+
/** Milliseconds per second (Baileys timestamps are seconds). */
|
|
26
|
+
const MS_PER_SECOND = 1000;
|
|
27
|
+
/** Max wrapper depth unwrapped (ephemeral → viewOnce → ...), as Baileys does. */
|
|
28
|
+
const MAX_UNWRAP_DEPTH = 5;
|
|
29
|
+
/** Wrapper message keys whose `.message` holds the real content. */
|
|
30
|
+
const WRAPPER_KEYS = [
|
|
31
|
+
'ephemeralMessage',
|
|
32
|
+
'viewOnceMessage',
|
|
33
|
+
'viewOnceMessageV2',
|
|
34
|
+
'viewOnceMessageV2Extension',
|
|
35
|
+
'documentWithCaptionMessage',
|
|
36
|
+
'editedMessage',
|
|
37
|
+
];
|
|
38
|
+
/**
|
|
39
|
+
* Content keys that are not user-visible messages (receipts of protocol
|
|
40
|
+
* work, reactions, key distribution). A message carrying only these is not
|
|
41
|
+
* stored.
|
|
42
|
+
*/
|
|
43
|
+
const NON_MESSAGE_KEYS = new Set([
|
|
44
|
+
'protocolMessage',
|
|
45
|
+
'reactionMessage',
|
|
46
|
+
'senderKeyDistributionMessage',
|
|
47
|
+
'messageContextInfo',
|
|
48
|
+
'pollUpdateMessage',
|
|
49
|
+
'keepInChatMessage',
|
|
50
|
+
'encReactionMessage',
|
|
51
|
+
]);
|
|
52
|
+
/**
|
|
53
|
+
* Narrow an unknown to a plain object.
|
|
54
|
+
*
|
|
55
|
+
* @param v - Anything
|
|
56
|
+
* @returns The object, or undefined
|
|
57
|
+
*/
|
|
58
|
+
function asRec(v) {
|
|
59
|
+
return v && typeof v === 'object' ? v : undefined;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Read a non-empty string field.
|
|
63
|
+
*
|
|
64
|
+
* @param v - Anything
|
|
65
|
+
* @returns The string, or undefined when absent/blank
|
|
66
|
+
*/
|
|
67
|
+
function str(v) {
|
|
68
|
+
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Convert a Baileys timestamp (seconds as number, numeric string, or
|
|
72
|
+
* protobuf Long with `toNumber()` / `low`+`high`) to epoch ms.
|
|
73
|
+
*
|
|
74
|
+
* @param ts - Raw timestamp
|
|
75
|
+
* @returns Epoch ms, or null when unparseable / non-positive
|
|
76
|
+
*/
|
|
77
|
+
export function toEpochMs(ts) {
|
|
78
|
+
let seconds = null;
|
|
79
|
+
if (typeof ts === 'number')
|
|
80
|
+
seconds = ts;
|
|
81
|
+
else if (typeof ts === 'bigint')
|
|
82
|
+
seconds = Number(ts);
|
|
83
|
+
else if (typeof ts === 'string' && /^\d+$/.test(ts))
|
|
84
|
+
seconds = Number(ts);
|
|
85
|
+
else {
|
|
86
|
+
const r = asRec(ts);
|
|
87
|
+
if (r && typeof r.toNumber === 'function')
|
|
88
|
+
seconds = r.toNumber();
|
|
89
|
+
else if (r && typeof r.low === 'number') {
|
|
90
|
+
const high = typeof r.high === 'number' ? r.high : 0;
|
|
91
|
+
seconds = high * 2 ** 32 + (r.low >>> 0);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (seconds === null || !Number.isFinite(seconds) || seconds <= 0)
|
|
95
|
+
return null;
|
|
96
|
+
return Math.round(seconds * MS_PER_SECOND);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Whether a JID is a group chat.
|
|
100
|
+
*
|
|
101
|
+
* @param jid - JID
|
|
102
|
+
* @returns True for `...@g.us`
|
|
103
|
+
*/
|
|
104
|
+
export function isGroupJid(jid) {
|
|
105
|
+
return jid.endsWith(WHATSAPP_CONSTANTS.GROUP_JID_SUFFIX);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Pick the canonical JID for a person: prefer the phone-number form when
|
|
109
|
+
* Baileys supplies it as the alternate of a LID, so the same person's
|
|
110
|
+
* messages (some keyed by LID, some by phone number) land in one chat.
|
|
111
|
+
*
|
|
112
|
+
* @param jid - Primary JID (`remoteJid` / `participant`)
|
|
113
|
+
* @param alt - Alternate JID (`remoteJidAlt` / `participantAlt`)
|
|
114
|
+
* @returns The canonical JID
|
|
115
|
+
*/
|
|
116
|
+
export function canonicalJid(jid, alt) {
|
|
117
|
+
if (jid.endsWith(WHATSAPP_CONSTANTS.LID_JID_SUFFIX) && alt && alt.endsWith(WHATSAPP_CONSTANTS.USER_JID_SUFFIX)) {
|
|
118
|
+
return alt;
|
|
119
|
+
}
|
|
120
|
+
return jid;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Strip wrapper messages (disappearing, view-once, edited, doc-with-caption).
|
|
124
|
+
*
|
|
125
|
+
* @param content - `WAMessage.message`
|
|
126
|
+
* @returns The innermost content object, or undefined
|
|
127
|
+
*/
|
|
128
|
+
export function unwrapMessageContent(content) {
|
|
129
|
+
let cur = asRec(content);
|
|
130
|
+
for (let i = 0; i < MAX_UNWRAP_DEPTH && cur; i++) {
|
|
131
|
+
let inner;
|
|
132
|
+
for (const k of WRAPPER_KEYS) {
|
|
133
|
+
inner = asRec(asRec(cur[k])?.message);
|
|
134
|
+
if (inner)
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
if (!inner)
|
|
138
|
+
break;
|
|
139
|
+
cur = inner;
|
|
140
|
+
}
|
|
141
|
+
return cur;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Classify message content into a stored kind and its text/caption.
|
|
145
|
+
*
|
|
146
|
+
* @param content - `WAMessage.message` (wrappers allowed)
|
|
147
|
+
* @returns `{ kind, text }`, or null when this is not a user-visible message
|
|
148
|
+
* (protocol message, reaction, empty envelope)
|
|
149
|
+
*/
|
|
150
|
+
export function classifyMessageContent(content) {
|
|
151
|
+
const c = unwrapMessageContent(content);
|
|
152
|
+
if (!c)
|
|
153
|
+
return null;
|
|
154
|
+
const K = WHATSAPP_CONSTANTS.MESSAGE_KINDS;
|
|
155
|
+
const conversation = str(c.conversation);
|
|
156
|
+
if (conversation)
|
|
157
|
+
return { kind: K.TEXT, text: conversation };
|
|
158
|
+
const ext = asRec(c.extendedTextMessage);
|
|
159
|
+
if (ext)
|
|
160
|
+
return { kind: K.TEXT, text: str(ext.text) ?? '' };
|
|
161
|
+
const image = asRec(c.imageMessage);
|
|
162
|
+
if (image)
|
|
163
|
+
return { kind: K.IMAGE, text: str(image.caption) ?? '' };
|
|
164
|
+
const video = asRec(c.videoMessage) ?? asRec(c.ptvMessage);
|
|
165
|
+
if (video)
|
|
166
|
+
return { kind: K.VIDEO, text: str(video.caption) ?? '' };
|
|
167
|
+
const doc = asRec(c.documentMessage);
|
|
168
|
+
if (doc)
|
|
169
|
+
return { kind: K.DOCUMENT, text: str(doc.caption) ?? str(doc.fileName) ?? str(doc.title) ?? '' };
|
|
170
|
+
if (asRec(c.audioMessage))
|
|
171
|
+
return { kind: K.AUDIO, text: '' };
|
|
172
|
+
if (asRec(c.stickerMessage))
|
|
173
|
+
return { kind: K.STICKER, text: '' };
|
|
174
|
+
const visibleKeys = Object.keys(c).filter((k) => c[k] !== null && c[k] !== undefined && !NON_MESSAGE_KEYS.has(k));
|
|
175
|
+
if (visibleKeys.length === 0)
|
|
176
|
+
return null;
|
|
177
|
+
return { kind: K.OTHER, text: '' };
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Parse a Baileys `WAMessage` into an inbox row.
|
|
181
|
+
*
|
|
182
|
+
* @param raw - The WAMessage
|
|
183
|
+
* @param ownJid - The connected account's JID (sender of `fromMe` messages), if known
|
|
184
|
+
* @returns The parsed message, or null when it is not storable (no id/chat,
|
|
185
|
+
* status broadcast, protocol-only content, no timestamp)
|
|
186
|
+
*/
|
|
187
|
+
export function parseBaileysMessage(raw, ownJid) {
|
|
188
|
+
const r = asRec(raw);
|
|
189
|
+
const key = asRec(r?.key);
|
|
190
|
+
const remoteJid = str(key?.remoteJid);
|
|
191
|
+
const id = str(key?.id);
|
|
192
|
+
if (!r || !key || !remoteJid || !id)
|
|
193
|
+
return null;
|
|
194
|
+
if (remoteJid === WHATSAPP_CONSTANTS.STATUS_BROADCAST_JID)
|
|
195
|
+
return null;
|
|
196
|
+
const classified = classifyMessageContent(r.message);
|
|
197
|
+
if (!classified)
|
|
198
|
+
return null;
|
|
199
|
+
const ts = toEpochMs(r.messageTimestamp);
|
|
200
|
+
if (ts === null)
|
|
201
|
+
return null;
|
|
202
|
+
const fromMe = key.fromMe === true;
|
|
203
|
+
const chatId = canonicalJid(remoteJid, str(key.remoteJidAlt));
|
|
204
|
+
const isGroup = isGroupJid(chatId);
|
|
205
|
+
const participant = str(key.participant);
|
|
206
|
+
const pushName = fromMe ? null : (str(r.pushName) ?? null);
|
|
207
|
+
let senderJid;
|
|
208
|
+
if (fromMe)
|
|
209
|
+
senderJid = ownJid ?? null;
|
|
210
|
+
else if (isGroup)
|
|
211
|
+
senderJid = participant ? canonicalJid(participant, str(key.participantAlt)) : null;
|
|
212
|
+
else
|
|
213
|
+
senderJid = chatId;
|
|
214
|
+
return {
|
|
215
|
+
message: {
|
|
216
|
+
id,
|
|
217
|
+
chatId,
|
|
218
|
+
fromMe,
|
|
219
|
+
senderJid,
|
|
220
|
+
senderName: pushName,
|
|
221
|
+
text: classified.text,
|
|
222
|
+
ts,
|
|
223
|
+
kind: classified.kind,
|
|
224
|
+
},
|
|
225
|
+
isGroup,
|
|
226
|
+
pushName,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Chat row from a Baileys `Contact`: the address-book name outranks the
|
|
231
|
+
* contact's own pushName (`notify`) and business `verifiedName`.
|
|
232
|
+
*
|
|
233
|
+
* @param contact - Contact (full or partial update)
|
|
234
|
+
* @returns Upsert input, or null when the contact names nothing useful
|
|
235
|
+
*/
|
|
236
|
+
export function chatFromContact(contact) {
|
|
237
|
+
const c = asRec(contact);
|
|
238
|
+
const rawId = str(c?.id);
|
|
239
|
+
if (!c || !rawId)
|
|
240
|
+
return null;
|
|
241
|
+
const id = canonicalJid(rawId, str(c.phoneNumber));
|
|
242
|
+
const R = WHATSAPP_CONSTANTS.NAME_RANKS;
|
|
243
|
+
const saved = str(c.name);
|
|
244
|
+
if (saved)
|
|
245
|
+
return { id, name: saved, nameRank: R.CONTACT };
|
|
246
|
+
const other = str(c.notify) ?? str(c.verifiedName);
|
|
247
|
+
if (other)
|
|
248
|
+
return { id, name: other, nameRank: R.PUSH_NAME };
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Chat row from a Baileys `Chat` (history sync, `chats.upsert/update`).
|
|
253
|
+
*
|
|
254
|
+
* @param chat - Chat
|
|
255
|
+
* @returns Upsert input, or null without an id / for the status pseudo-chat
|
|
256
|
+
*/
|
|
257
|
+
export function chatFromChat(chat) {
|
|
258
|
+
const c = asRec(chat);
|
|
259
|
+
const id = str(c?.id);
|
|
260
|
+
if (!c || !id || id === WHATSAPP_CONSTANTS.STATUS_BROADCAST_JID)
|
|
261
|
+
return null;
|
|
262
|
+
return {
|
|
263
|
+
id,
|
|
264
|
+
name: str(c.name) ?? null,
|
|
265
|
+
nameRank: WHATSAPP_CONSTANTS.NAME_RANKS.CHAT,
|
|
266
|
+
isGroup: isGroupJid(id),
|
|
267
|
+
lastMessageAt: toEpochMs(c.conversationTimestamp),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Chat row from Baileys `GroupMetadata` (subject = group name).
|
|
272
|
+
*
|
|
273
|
+
* @param group - Group metadata (full or partial)
|
|
274
|
+
* @returns Upsert input, or null without an id
|
|
275
|
+
*/
|
|
276
|
+
export function chatFromGroup(group) {
|
|
277
|
+
const g = asRec(group);
|
|
278
|
+
const id = str(g?.id);
|
|
279
|
+
if (!g || !id)
|
|
280
|
+
return null;
|
|
281
|
+
return { id, name: str(g.subject) ?? null, nameRank: WHATSAPP_CONSTANTS.NAME_RANKS.CHAT, isGroup: true };
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Writes Baileys events into a {@link WhatsAppInboxStore}.
|
|
285
|
+
*
|
|
286
|
+
* Every handler is defensive: a malformed payload is skipped, never thrown,
|
|
287
|
+
* because it runs inside the socket's event loop.
|
|
288
|
+
*/
|
|
289
|
+
export class WhatsAppInboxCapture {
|
|
290
|
+
store;
|
|
291
|
+
opts;
|
|
292
|
+
groupLookups = new Set();
|
|
293
|
+
/**
|
|
294
|
+
* @param store - Destination store
|
|
295
|
+
* @param opts - Own-JID accessor, group-subject fetcher, clock
|
|
296
|
+
*/
|
|
297
|
+
constructor(store, opts = {}) {
|
|
298
|
+
this.store = store;
|
|
299
|
+
this.opts = opts;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Store one message and name its chat.
|
|
303
|
+
*
|
|
304
|
+
* @param raw - A WAMessage
|
|
305
|
+
* @returns True when stored
|
|
306
|
+
*/
|
|
307
|
+
captureMessage(raw) {
|
|
308
|
+
const parsed = parseBaileysMessage(raw, this.opts.getOwnJid?.() ?? null);
|
|
309
|
+
if (!parsed)
|
|
310
|
+
return false;
|
|
311
|
+
const { message, isGroup, pushName } = parsed;
|
|
312
|
+
// In a 1:1 chat the sender's pushName is a (weak) name for the chat.
|
|
313
|
+
this.store.upsertChat({
|
|
314
|
+
id: message.chatId,
|
|
315
|
+
isGroup,
|
|
316
|
+
name: !isGroup ? pushName : null,
|
|
317
|
+
nameRank: WHATSAPP_CONSTANTS.NAME_RANKS.PUSH_NAME,
|
|
318
|
+
lastMessageAt: message.ts,
|
|
319
|
+
});
|
|
320
|
+
this.store.upsertMessage(message);
|
|
321
|
+
if (isGroup)
|
|
322
|
+
this.maybeFetchGroupName(message.chatId);
|
|
323
|
+
return true;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Handle `messages.upsert` (both `notify` and `append`: own messages sent
|
|
327
|
+
* from the phone and backfills arrive as `append`).
|
|
328
|
+
*
|
|
329
|
+
* @param upsert - `{ messages, type }`
|
|
330
|
+
* @returns Number of messages stored
|
|
331
|
+
*/
|
|
332
|
+
onMessagesUpsert(upsert) {
|
|
333
|
+
const messages = asRec(upsert)?.messages;
|
|
334
|
+
if (!Array.isArray(messages))
|
|
335
|
+
return 0;
|
|
336
|
+
let n = 0;
|
|
337
|
+
for (const m of messages)
|
|
338
|
+
if (this.captureMessage(m))
|
|
339
|
+
n++;
|
|
340
|
+
return n;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Handle `messaging-history.set`: seed chats, contact names and recent
|
|
344
|
+
* messages. Messages older than `HISTORY_SYNC_MAX_AGE_MS` are skipped.
|
|
345
|
+
*
|
|
346
|
+
* @param payload - `{ chats, contacts, messages }`
|
|
347
|
+
* @returns Number of messages stored
|
|
348
|
+
*/
|
|
349
|
+
onHistorySet(payload) {
|
|
350
|
+
const p = asRec(payload);
|
|
351
|
+
if (!p)
|
|
352
|
+
return 0;
|
|
353
|
+
const chats = (Array.isArray(p.chats) ? p.chats : []).map(chatFromChat).filter((c) => c !== null);
|
|
354
|
+
const contacts = (Array.isArray(p.contacts) ? p.contacts : [])
|
|
355
|
+
.map(chatFromContact)
|
|
356
|
+
.filter((c) => c !== null);
|
|
357
|
+
this.store.upsertChats([...chats, ...contacts]);
|
|
358
|
+
const cutoff = (this.opts.now?.() ?? Date.now()) - WHATSAPP_CONSTANTS.HISTORY_SYNC_MAX_AGE_MS;
|
|
359
|
+
const ownJid = this.opts.getOwnJid?.() ?? null;
|
|
360
|
+
const parsed = (Array.isArray(p.messages) ? p.messages : [])
|
|
361
|
+
.map((m) => parseBaileysMessage(m, ownJid))
|
|
362
|
+
.filter((m) => m !== null && m.message.ts >= cutoff);
|
|
363
|
+
this.store.upsertChats(parsed
|
|
364
|
+
.filter((m) => !m.isGroup && m.pushName)
|
|
365
|
+
.map((m) => ({ id: m.message.chatId, name: m.pushName, nameRank: WHATSAPP_CONSTANTS.NAME_RANKS.PUSH_NAME })));
|
|
366
|
+
return this.store.upsertMessages(parsed.map((m) => m.message));
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Handle `contacts.upsert` / `contacts.update`.
|
|
370
|
+
*
|
|
371
|
+
* @param contacts - Contact list
|
|
372
|
+
*/
|
|
373
|
+
onContacts(contacts) {
|
|
374
|
+
if (!Array.isArray(contacts))
|
|
375
|
+
return;
|
|
376
|
+
this.store.upsertChats(contacts.map(chatFromContact).filter((c) => c !== null));
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Handle `chats.upsert` / `chats.update`.
|
|
380
|
+
*
|
|
381
|
+
* @param chats - Chat list
|
|
382
|
+
*/
|
|
383
|
+
onChats(chats) {
|
|
384
|
+
if (!Array.isArray(chats))
|
|
385
|
+
return;
|
|
386
|
+
this.store.upsertChats(chats.map(chatFromChat).filter((c) => c !== null));
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Handle `groups.upsert` / `groups.update`.
|
|
390
|
+
*
|
|
391
|
+
* @param groups - Group metadata list
|
|
392
|
+
*/
|
|
393
|
+
onGroups(groups) {
|
|
394
|
+
if (!Array.isArray(groups))
|
|
395
|
+
return;
|
|
396
|
+
this.store.upsertChats(groups.map(chatFromGroup).filter((c) => c !== null));
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Look a group's subject up once per process when we have no name for it.
|
|
400
|
+
*
|
|
401
|
+
* @param jid - Group JID
|
|
402
|
+
*/
|
|
403
|
+
maybeFetchGroupName(jid) {
|
|
404
|
+
const fetcher = this.opts.fetchGroupSubject;
|
|
405
|
+
if (!fetcher || this.groupLookups.has(jid))
|
|
406
|
+
return;
|
|
407
|
+
if (this.store.getChat(jid)?.name)
|
|
408
|
+
return;
|
|
409
|
+
this.groupLookups.add(jid);
|
|
410
|
+
fetcher(jid)
|
|
411
|
+
.then((subject) => {
|
|
412
|
+
if (subject)
|
|
413
|
+
this.store.upsertChat({ id: jid, name: subject, nameRank: WHATSAPP_CONSTANTS.NAME_RANKS.CHAT, isGroup: true });
|
|
414
|
+
})
|
|
415
|
+
.catch(() => {
|
|
416
|
+
// Best effort — the chat keeps its JID as the label.
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
//# sourceMappingURL=whatsapp-inbox-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp-inbox-capture.js","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp-inbox-capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WhatsApp Inbox Store
|
|
3
|
+
*
|
|
4
|
+
* Local SQLite store behind the WhatsApp inbox connector: the chats and
|
|
5
|
+
* messages captured from the owner's personal account (read-only), and the
|
|
6
|
+
* reply drafts agents propose. Lives at `~/.crewly/whatsapp/inbox.db`
|
|
7
|
+
* (resolved through `getCrewlyHomePath()`, so `CREWLY_HOME` isolates it).
|
|
8
|
+
*
|
|
9
|
+
* Nothing in here talks to WhatsApp. Sending a draft is the controller's
|
|
10
|
+
* job, gated on the owner's confirmation; this store only records the
|
|
11
|
+
* draft's lifecycle (`pending` → `sending` → `sent` / back to `pending`,
|
|
12
|
+
* or `discarded`) with an atomic claim so a draft can never be sent twice.
|
|
13
|
+
*
|
|
14
|
+
* @module services/whatsapp/whatsapp-inbox.store
|
|
15
|
+
*/
|
|
16
|
+
import type { WhatsAppDraft, WhatsAppDraftStatus, WhatsAppInboxChat, WhatsAppInboxEntry, WhatsAppInboxMessage, WhatsAppSearchHit } from '../../types/whatsapp.types.js';
|
|
17
|
+
/** In-memory database name accepted by better-sqlite3 (tests). */
|
|
18
|
+
export declare const IN_MEMORY_DB = ":memory:";
|
|
19
|
+
/** Input for {@link WhatsAppInboxStore.upsertChat}. */
|
|
20
|
+
export interface UpsertChatInput {
|
|
21
|
+
/** Chat JID */
|
|
22
|
+
id: string;
|
|
23
|
+
/** Display name, if this source knows one */
|
|
24
|
+
name?: string | null;
|
|
25
|
+
/** Provenance of `name` (see `WHATSAPP_CONSTANTS.NAME_RANKS`); a lower rank never overwrites a higher one */
|
|
26
|
+
nameRank?: number;
|
|
27
|
+
/** Whether the chat is a group (defaults from the JID suffix) */
|
|
28
|
+
isGroup?: boolean;
|
|
29
|
+
/** Epoch ms of the newest message this source knows of (only ever moves forward) */
|
|
30
|
+
lastMessageAt?: number | null;
|
|
31
|
+
}
|
|
32
|
+
/** Options for {@link WhatsAppInboxStore.listInbox}. */
|
|
33
|
+
export interface ListInboxOptions {
|
|
34
|
+
/** Row cap */
|
|
35
|
+
limit: number;
|
|
36
|
+
/** Include group chats (default false — groups are noisy) */
|
|
37
|
+
includeGroups?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the default inbox database path under the Crewly home.
|
|
41
|
+
*
|
|
42
|
+
* @returns Absolute path to `<crewly home>/whatsapp/inbox.db`
|
|
43
|
+
*/
|
|
44
|
+
export declare function getDefaultInboxDbPath(): string;
|
|
45
|
+
/**
|
|
46
|
+
* Format a draft sequence number as its human code.
|
|
47
|
+
*
|
|
48
|
+
* @param seq - Monotonic sequence number
|
|
49
|
+
* @returns Code such as `W12`
|
|
50
|
+
*/
|
|
51
|
+
export declare function formatDraftCode(seq: number): string;
|
|
52
|
+
/**
|
|
53
|
+
* Parse a user-typed draft code (`W12`, `w12`, `#W12`, `12`) into its sequence number.
|
|
54
|
+
*
|
|
55
|
+
* @param raw - The code as typed
|
|
56
|
+
* @returns The sequence number, or null when the text is not a draft code
|
|
57
|
+
*/
|
|
58
|
+
export declare function parseDraftCode(raw: string): number | null;
|
|
59
|
+
/**
|
|
60
|
+
* SQLite-backed store for the WhatsApp inbox and reply drafts.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const store = new WhatsAppInboxStore(':memory:');
|
|
65
|
+
* store.upsertMessage({ id: 'm1', chatId: '1@s.whatsapp.net', fromMe: false, senderJid: null,
|
|
66
|
+
* senderName: 'Ann', text: 'hi', ts: Date.now(), kind: 'text' });
|
|
67
|
+
* store.listInbox({ limit: 20 }); // → [{ chat, unansweredCount: 1, ... }]
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare class WhatsAppInboxStore {
|
|
71
|
+
private readonly db;
|
|
72
|
+
/**
|
|
73
|
+
* Open (and migrate) the inbox database.
|
|
74
|
+
*
|
|
75
|
+
* @param dbPath - File path, or `:memory:` for tests. The parent directory
|
|
76
|
+
* is created owner-only (0700) and the file is chmod 0600.
|
|
77
|
+
* @throws NativeBindingFatalError when better-sqlite3 cannot load
|
|
78
|
+
*/
|
|
79
|
+
constructor(dbPath?: string);
|
|
80
|
+
/**
|
|
81
|
+
* Close the database handle.
|
|
82
|
+
*/
|
|
83
|
+
close(): void;
|
|
84
|
+
/**
|
|
85
|
+
* Insert or update a chat.
|
|
86
|
+
*
|
|
87
|
+
* The name only changes when the new source ranks at least as high as the
|
|
88
|
+
* one that set the current name (an address-book name is never replaced by
|
|
89
|
+
* a pushName). `lastMessageAt` only moves forward.
|
|
90
|
+
*
|
|
91
|
+
* @param input - Chat fields known by this source
|
|
92
|
+
*/
|
|
93
|
+
upsertChat(input: UpsertChatInput): void;
|
|
94
|
+
/**
|
|
95
|
+
* Insert or update one message (idempotent on the message id) and advance
|
|
96
|
+
* its chat's `lastMessageAt`, creating the chat row if needed.
|
|
97
|
+
*
|
|
98
|
+
* A re-delivered message keeps its original `fromMe`, chat and timestamp;
|
|
99
|
+
* text, kind and a newly learned sender name are refreshed (edits, late
|
|
100
|
+
* pushNames).
|
|
101
|
+
*
|
|
102
|
+
* @param msg - The message
|
|
103
|
+
*/
|
|
104
|
+
upsertMessage(msg: WhatsAppInboxMessage): void;
|
|
105
|
+
/**
|
|
106
|
+
* Upsert many messages in one transaction (history sync).
|
|
107
|
+
*
|
|
108
|
+
* @param msgs - Messages
|
|
109
|
+
* @returns How many were written
|
|
110
|
+
*/
|
|
111
|
+
upsertMessages(msgs: WhatsAppInboxMessage[]): number;
|
|
112
|
+
/**
|
|
113
|
+
* Upsert many chats in one transaction.
|
|
114
|
+
*
|
|
115
|
+
* @param chats - Chats
|
|
116
|
+
*/
|
|
117
|
+
upsertChats(chats: UpsertChatInput[]): void;
|
|
118
|
+
/**
|
|
119
|
+
* Look up one chat.
|
|
120
|
+
*
|
|
121
|
+
* @param id - Chat JID
|
|
122
|
+
* @returns The chat, or null
|
|
123
|
+
*/
|
|
124
|
+
getChat(id: string): WhatsAppInboxChat | null;
|
|
125
|
+
/**
|
|
126
|
+
* Chats that need a reply: the newest message is not the owner's.
|
|
127
|
+
*
|
|
128
|
+
* `unansweredCount` counts inbound messages after the owner's last message
|
|
129
|
+
* in that chat (all of them when the owner never wrote there).
|
|
130
|
+
*
|
|
131
|
+
* @param opts - Limit and whether to include groups
|
|
132
|
+
* @returns Entries, newest first
|
|
133
|
+
*/
|
|
134
|
+
listInbox(opts: ListInboxOptions): WhatsAppInboxEntry[];
|
|
135
|
+
/**
|
|
136
|
+
* Recent chats, optionally filtered by name or JID substring.
|
|
137
|
+
*
|
|
138
|
+
* @param opts - Limit and optional query
|
|
139
|
+
* @returns Chats, most recently active first (chats with no messages last)
|
|
140
|
+
*/
|
|
141
|
+
listChats(opts: {
|
|
142
|
+
limit: number;
|
|
143
|
+
q?: string;
|
|
144
|
+
}): WhatsAppInboxChat[];
|
|
145
|
+
/**
|
|
146
|
+
* One page of a chat's messages, in chronological order.
|
|
147
|
+
*
|
|
148
|
+
* @param chatId - Chat JID
|
|
149
|
+
* @param opts - Page size and an exclusive upper bound (epoch ms) for paging back
|
|
150
|
+
* @returns The newest `limit` messages older than `before`, oldest first
|
|
151
|
+
*/
|
|
152
|
+
listMessages(chatId: string, opts: {
|
|
153
|
+
limit: number;
|
|
154
|
+
before?: number;
|
|
155
|
+
}): WhatsAppInboxMessage[];
|
|
156
|
+
/**
|
|
157
|
+
* Substring search over message text (case-insensitive for ASCII).
|
|
158
|
+
*
|
|
159
|
+
* @param q - Search text (must be non-empty)
|
|
160
|
+
* @param limit - Row cap
|
|
161
|
+
* @returns Hits, newest first
|
|
162
|
+
*/
|
|
163
|
+
search(q: string, limit: number): WhatsAppSearchHit[];
|
|
164
|
+
/**
|
|
165
|
+
* Record a reply draft with the next monotonic code.
|
|
166
|
+
*
|
|
167
|
+
* @param input - Recipient, text, author session (null = owner) and clock
|
|
168
|
+
* @returns The stored draft (status `pending`)
|
|
169
|
+
*/
|
|
170
|
+
createDraft(input: {
|
|
171
|
+
chatId: string;
|
|
172
|
+
text: string;
|
|
173
|
+
createdBy: string | null;
|
|
174
|
+
now: number;
|
|
175
|
+
}): WhatsAppDraft;
|
|
176
|
+
/**
|
|
177
|
+
* Look up a draft by its opaque id.
|
|
178
|
+
*
|
|
179
|
+
* @param id - Draft id
|
|
180
|
+
* @returns The draft, or null
|
|
181
|
+
*/
|
|
182
|
+
getDraftById(id: string): WhatsAppDraft | null;
|
|
183
|
+
/**
|
|
184
|
+
* Look up a draft by id or by human code (`W12`, `12`, `#W12`).
|
|
185
|
+
*
|
|
186
|
+
* @param ref - Id or code
|
|
187
|
+
* @returns The draft, or null
|
|
188
|
+
*/
|
|
189
|
+
findDraft(ref: string): WhatsAppDraft | null;
|
|
190
|
+
/**
|
|
191
|
+
* List drafts, newest first.
|
|
192
|
+
*
|
|
193
|
+
* @param opts - Optional status filter and row cap
|
|
194
|
+
* @returns Drafts
|
|
195
|
+
*/
|
|
196
|
+
listDrafts(opts: {
|
|
197
|
+
status?: WhatsAppDraftStatus;
|
|
198
|
+
limit: number;
|
|
199
|
+
}): WhatsAppDraft[];
|
|
200
|
+
/**
|
|
201
|
+
* Atomically move a draft from `pending` to `sending`.
|
|
202
|
+
*
|
|
203
|
+
* Only one caller can win: this is what makes "a draft can't be sent twice"
|
|
204
|
+
* hold under concurrent requests.
|
|
205
|
+
*
|
|
206
|
+
* @param id - Draft id
|
|
207
|
+
* @returns True when this caller now holds the send claim
|
|
208
|
+
*/
|
|
209
|
+
claimDraftForSend(id: string): boolean;
|
|
210
|
+
/**
|
|
211
|
+
* Mark a claimed draft as sent.
|
|
212
|
+
*
|
|
213
|
+
* @param id - Draft id
|
|
214
|
+
* @param now - Epoch ms of the send
|
|
215
|
+
*/
|
|
216
|
+
markDraftSent(id: string, now: number): void;
|
|
217
|
+
/**
|
|
218
|
+
* Return a claimed draft to `pending` after a failed send, keeping the error.
|
|
219
|
+
*
|
|
220
|
+
* @param id - Draft id
|
|
221
|
+
* @param error - Why the send failed
|
|
222
|
+
*/
|
|
223
|
+
releaseDraftClaim(id: string, error: string): void;
|
|
224
|
+
/**
|
|
225
|
+
* Discard a pending draft.
|
|
226
|
+
*
|
|
227
|
+
* @param id - Draft id
|
|
228
|
+
* @param now - Epoch ms
|
|
229
|
+
* @returns True when the draft was pending and is now discarded
|
|
230
|
+
*/
|
|
231
|
+
discardDraft(id: string, now: number): boolean;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Get the process-wide inbox store, opening it on first use.
|
|
235
|
+
*
|
|
236
|
+
* @returns The store at {@link getDefaultInboxDbPath}
|
|
237
|
+
*/
|
|
238
|
+
export declare function getWhatsAppInboxStore(): WhatsAppInboxStore;
|
|
239
|
+
/**
|
|
240
|
+
* Close and forget the process-wide store (tests, shutdown).
|
|
241
|
+
*/
|
|
242
|
+
export declare function resetWhatsAppInboxStore(): void;
|
|
243
|
+
//# sourceMappingURL=whatsapp-inbox.store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp-inbox.store.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp-inbox.store.ts"],"names":[],"mappings":"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"}
|