@lizzythelizard/whatsapp-mcp 0.1.3

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.
Files changed (47) hide show
  1. package/.github/dependabot.yml +20 -0
  2. package/.github/workflows/auto-merge.yml +19 -0
  3. package/.github/workflows/ci.yml +75 -0
  4. package/.vscode/extensions.json +7 -0
  5. package/.vscode/settings.json +12 -0
  6. package/AGENTS.md +42 -0
  7. package/Dockerfile +25 -0
  8. package/LICENSE +21 -0
  9. package/README.md +62 -0
  10. package/dist/auth.d.ts +6 -0
  11. package/dist/auth.d.ts.map +1 -0
  12. package/dist/auth.js +49 -0
  13. package/dist/auth.js.map +1 -0
  14. package/dist/index.d.ts +3 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +18 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/store.d.ts +20 -0
  19. package/dist/store.d.ts.map +1 -0
  20. package/dist/store.js +138 -0
  21. package/dist/store.js.map +1 -0
  22. package/dist/sync.d.ts +18 -0
  23. package/dist/sync.d.ts.map +1 -0
  24. package/dist/sync.js +115 -0
  25. package/dist/sync.js.map +1 -0
  26. package/dist/syncManager.d.ts +29 -0
  27. package/dist/syncManager.d.ts.map +1 -0
  28. package/dist/syncManager.js +79 -0
  29. package/dist/syncManager.js.map +1 -0
  30. package/dist/tools.d.ts +2 -0
  31. package/dist/tools.d.ts.map +1 -0
  32. package/dist/tools.js +65 -0
  33. package/dist/tools.js.map +1 -0
  34. package/eslint.config.mjs +32 -0
  35. package/package.json +45 -0
  36. package/src/auth.test.ts +138 -0
  37. package/src/auth.ts +58 -0
  38. package/src/index.ts +45 -0
  39. package/src/store.test.ts +353 -0
  40. package/src/store.ts +182 -0
  41. package/src/sync.test.ts +304 -0
  42. package/src/sync.ts +170 -0
  43. package/src/tools.test.ts +254 -0
  44. package/src/tools.ts +132 -0
  45. package/tsconfig.json +19 -0
  46. package/tsconfig.test.json +7 -0
  47. package/vitest.config.ts +7 -0
@@ -0,0 +1,20 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "npm"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ day: "monday"
8
+ open-pull-requests-limit: 10
9
+
10
+ - package-ecosystem: "docker"
11
+ directory: "/"
12
+ schedule:
13
+ interval: "weekly"
14
+ day: "monday"
15
+
16
+ - package-ecosystem: "github-actions"
17
+ directory: "/"
18
+ schedule:
19
+ interval: "weekly"
20
+ day: "monday"
@@ -0,0 +1,19 @@
1
+ name: Dependabot Auto-Merge
2
+
3
+ on:
4
+ pull_request_target:
5
+
6
+ permissions:
7
+ contents: write
8
+ pull-requests: write
9
+
10
+ jobs:
11
+ auto-merge:
12
+ if: github.actor == 'dependabot[bot]'
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Auto-merge Dependabot PRs
16
+ run: gh pr merge --auto --merge "$PR_URL"
17
+ env:
18
+ PR_URL: ${{ github.event.pull_request.html_url }}
19
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,75 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+
9
+ env:
10
+ DOCKER_IMAGE: ${{ secrets.DOCKER_USERNAME }}/whatsapp-mcp
11
+
12
+ jobs:
13
+ checks:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v7
17
+ - uses: actions/setup-node@v6
18
+ with:
19
+ node-version: 24
20
+ cache: npm
21
+ - run: npm ci
22
+ - run: npm run build
23
+ - run: npm run lint
24
+ - run: npm run typecheck
25
+ - run: npm test
26
+ - name: Check version can be published
27
+ run: npm publish --dry-run
28
+
29
+ docker:
30
+ runs-on: ubuntu-latest
31
+ needs: [checks]
32
+ permissions:
33
+ contents: read
34
+ packages: write
35
+ steps:
36
+ - uses: actions/checkout@v7
37
+ - uses: docker/setup-buildx-action@v4
38
+ - name: Log in to Docker Hub
39
+ if: github.ref == 'refs/heads/main'
40
+ uses: docker/login-action@v4
41
+ with:
42
+ username: ${{ secrets.DOCKER_USERNAME }}
43
+ password: ${{ secrets.DOCKER_PASSWORD }}
44
+ - name: Extract metadata
45
+ id: meta
46
+ uses: docker/metadata-action@v6
47
+ with:
48
+ images: ${{ env.DOCKER_IMAGE }}
49
+ tags: |
50
+ type=sha,prefix=
51
+ type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
52
+ - name: Build and push
53
+ uses: docker/build-push-action@v7
54
+ with:
55
+ context: .
56
+ push: ${{ github.ref == 'refs/heads/main' }}
57
+ tags: ${{ steps.meta.outputs.tags }}
58
+ labels: ${{ steps.meta.outputs.labels }}
59
+ cache-from: type=gha
60
+ cache-to: type=gha,mode=max
61
+
62
+ npm-publish:
63
+ runs-on: ubuntu-latest
64
+ needs: [checks]
65
+ if: github.ref == 'refs/heads/main'
66
+ steps:
67
+ - uses: actions/checkout@v7
68
+ - uses: actions/setup-node@v6
69
+ with:
70
+ node-version: 24
71
+ cache: npm
72
+ registry-url: "https://registry.npmjs.org"
73
+ - run: npm ci
74
+ - run: npm run build
75
+ - run: npm publish
@@ -0,0 +1,7 @@
1
+ {
2
+ "recommendations": [
3
+ "dbaeumer.vscode-eslint",
4
+ "github.vscode-github-actions",
5
+ "vitest.explorer"
6
+ ]
7
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "editor.codeActionsOnSave": {
3
+ "source.fixAll.eslint": "always"
4
+ },
5
+ "eslint.validate": [
6
+ "javascript",
7
+ "typescript",
8
+ "javascriptreact",
9
+ "typescriptreact"
10
+ ],
11
+ "eslint.format.enable": true
12
+ }
package/AGENTS.md ADDED
@@ -0,0 +1,42 @@
1
+ # AGENTS.md
2
+
3
+ This file helps AI agents understand how to work with this project.
4
+
5
+ ## Project Overview
6
+
7
+ A WhatsApp MCP (Model Context Protocol) server that exposes WhatsApp functionality as tools for AI assistants.
8
+
9
+ ## Key Conventions
10
+
11
+ - TypeScript with ESM (`"type": "module"`)
12
+ - Source code lives in `src/`, tests in `tests/`
13
+ - Use `zod` for input validation
14
+ - Follow existing tool patterns when adding new tools
15
+
16
+ ## Common Commands
17
+
18
+ - `npm run dev` — start dev server with auto-reload
19
+ - `npm test` — run test suite
20
+ - `npm run build` — compile to JavaScript
21
+ - `npm run lint` — check code quality
22
+ - `npm run typecheck` — run TypeScript type checking
23
+
24
+ ## Architecture
25
+
26
+ The MCP server uses `@modelcontextprotocol/sdk` with stdio transport. Tools are registered in `src/index.ts` via `server.setRequestHandler`. Each tool has:
27
+
28
+ 1. A `zod` schema for input validation
29
+ 2. A definition in `ListToolsRequestSchema`
30
+ 3. A handler in `CallToolRequestSchema`
31
+
32
+ ## Adding a New Tool
33
+
34
+ 1. Define a Zod schema for the tool's input
35
+ 2. Add the tool definition to `ListToolsRequestSchema`
36
+ 3. Add a case to the switch in `CallToolRequestSchema`
37
+
38
+ ## Testing
39
+
40
+ - Write tests in `tests/` matching the source structure
41
+ - Use `vitest` with `describe`/`it`/`expect`
42
+ - Test input schemas and handler logic separately
package/Dockerfile ADDED
@@ -0,0 +1,25 @@
1
+ FROM node:26-alpine AS build
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package*.json ./
6
+ RUN npm ci
7
+
8
+ COPY tsconfig.json ./
9
+ COPY src/ ./src/
10
+ RUN npm run build
11
+
12
+ FROM node:26-alpine AS production
13
+
14
+ WORKDIR /app
15
+
16
+ RUN addgroup -S appgroup && adduser -S appuser -G appgroup
17
+
18
+ COPY package*.json ./
19
+ RUN npm ci --omit=dev
20
+
21
+ COPY --from=build /app/dist ./dist
22
+
23
+ USER appuser
24
+
25
+ CMD ["node", "dist/index.js"]
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 whatsapp-mcp
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # WhatsApp MCP Server
2
+
3
+ MCP (Model Context Protocol) server for WhatsApp integration, enabling AI assistants to interact with WhatsApp.
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js >= 20
8
+ - npm
9
+
10
+ ## Setup
11
+
12
+ ```bash
13
+ npm install
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ### Start (production)
19
+
20
+ ```bash
21
+ npm run build
22
+ npm start
23
+ ```
24
+
25
+ ### Development (auto-reload)
26
+
27
+ ```bash
28
+ npm run dev
29
+ ```
30
+
31
+ The server runs on **stdio** transport and communicates via the MCP protocol.
32
+
33
+ ## Scripts
34
+
35
+ | Command | Description |
36
+ | -------------------- | ------------------------------------------ |
37
+ | `npm run build` | Compile TypeScript to `dist/` |
38
+ | `npm start` | Run compiled server |
39
+ | `npm run dev` | Run with auto-reload on file changes |
40
+ | `npm test` | Run tests |
41
+ | `npm run test:watch` | Run tests in watch mode |
42
+ | `npm run lint` | Lint source code |
43
+ | `npm run typecheck` | Type-check without emitting files |
44
+
45
+ ## Docker
46
+
47
+ ```bash
48
+ docker build -t whatsapp-mcp .
49
+ docker run --rm -i whatsapp-mcp
50
+ ```
51
+
52
+ ## Tools
53
+
54
+ | Tool | Description |
55
+ | ----------------- | ------------------------------------ |
56
+ | `send_message` | Send a WhatsApp message |
57
+ | `list_chats` | List recent WhatsApp chats |
58
+ | `read_messages` | Read messages from a WhatsApp chat |
59
+
60
+ ## License
61
+
62
+ MIT
package/dist/auth.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { AuthenticationState } from '@whiskeysockets/baileys';
2
+ export interface ExportableAuthState extends AuthenticationState {
3
+ toAuthState: () => string;
4
+ }
5
+ export declare function createExportableAuth(input?: string): ExportableAuthState;
6
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2F,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAGtJ,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC9D,WAAW,EAAE,MAAM,MAAM,CAAA;CAC1B;AAID,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAOxE"}
package/dist/auth.js ADDED
@@ -0,0 +1,49 @@
1
+ import { BufferJSON, initAuthCreds, proto } from '@whiskeysockets/baileys';
2
+ export function createExportableAuth(input) {
3
+ const { creds, keys } = fromString(input) ?? { creds: initAuthCreds(), keys: {} };
4
+ return {
5
+ creds,
6
+ keys: { get: (t, ids) => getKey(t, ids, keys), set: (data) => { setKey(data, keys); } },
7
+ toAuthState: () => toString({ creds, keys }),
8
+ };
9
+ }
10
+ function fromString(str) {
11
+ if (!str)
12
+ return undefined;
13
+ return JSON.parse(str, BufferJSON.reviver);
14
+ }
15
+ function toString(data) {
16
+ return JSON.stringify(data, BufferJSON.replacer);
17
+ }
18
+ function getKey(type, ids, keys) {
19
+ return ids.reduce((acc, id) => {
20
+ const value = fromString(keys[`${type}-${id}`]);
21
+ if (!value)
22
+ return acc;
23
+ if (type === 'app-state-sync-key') {
24
+ const typedValue = value;
25
+ const converted = proto.Message.AppStateSyncKeyData.fromObject(typedValue);
26
+ const typeResult = converted;
27
+ acc[id] = typeResult;
28
+ }
29
+ else {
30
+ acc[id] = value;
31
+ }
32
+ return acc;
33
+ }, {});
34
+ }
35
+ function setKey(data, keys) {
36
+ for (const category in data) {
37
+ const dataCategory = data[category];
38
+ for (const id in dataCategory) {
39
+ const value = dataCategory[id];
40
+ if (!value)
41
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
42
+ delete keys[`${category}-${id}`];
43
+ else {
44
+ keys[`${category}-${id}`] = JSON.stringify(value, BufferJSON.replacer);
45
+ }
46
+ }
47
+ }
48
+ }
49
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,UAAU,EAAE,aAAa,EAAqB,KAAK,EAAsC,MAAM,yBAAyB,CAAA;AAStJ,MAAM,UAAU,oBAAoB,CAAC,KAAc;IACjD,MAAM,EAAC,KAAK,EAAE,IAAI,EAAC,GAAG,UAAU,CAAiB,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;IAC/F,OAAO;QACL,KAAK;QACL,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA,CAAC,CAAC,EAAE;QACtF,WAAW,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;KAC7C,CAAA;AACH,CAAC;AAED,SAAS,UAAU,CAAI,GAAuB;IAC5C,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAA;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,OAAO,CAAM,CAAA;AACjD,CAAC;AAED,SAAS,QAAQ,CAAC,IAAa;IAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;AAClD,CAAC;AAED,SAAS,MAAM,CAAoC,IAAO,EAAE,GAAa,EAAE,IAA4B;IACrG,OAAO,GAAG,CAAC,MAAM,CAAuC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE;QAClE,MAAM,KAAK,GAAG,UAAU,CAAuB,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;QACrE,IAAI,CAAC,KAAK;YAAE,OAAO,GAAG,CAAA;QACtB,IAAI,IAAI,KAAK,oBAAoB,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,KAAgD,CAAA;YACnE,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAA;YAC1E,MAAM,UAAU,GAAG,SAA4C,CAAA;YAC/D,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAA;QACtB,CAAC;aACI,CAAC;YACJ,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAA;QACjB,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC,EAAE,EAAE,CAAC,CAAA;AACR,CAAC;AAED,SAAS,MAAM,CAAC,IAAmB,EAAE,IAA4B;IAC/D,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,QAAmC,CAAC,CAAA;QAC9D,KAAK,MAAM,EAAE,IAAI,YAAY,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,CAAC,CAAA;YAC9B,IAAI,CAAC,KAAK;gBACV,gEAAgE;gBAC9D,OAAO,IAAI,CAAC,GAAG,QAAQ,IAAI,EAAE,EAAE,CAAC,CAAA;iBAC7B,CAAC;gBACJ,IAAI,CAAC,GAAG,QAAQ,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;YACxE,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { createStore } from "./store.js";
5
+ import { createSyncHandler } from "./sync.js";
6
+ async function main() {
7
+ const server = new McpServer({ name: "whatsapp-mcp", version: "0.1.0" });
8
+ const transport = new StdioServerTransport();
9
+ const whatsappStore = createStore();
10
+ const whatsappSync = createSyncHandler(whatsappStore);
11
+ await server.connect(transport);
12
+ console.info("whatsapp-mcp server running on stdio");
13
+ }
14
+ main().catch((error) => {
15
+ console.error("Server error:", error);
16
+ process.exit(1);
17
+ });
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAG9C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACzE,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,aAAa,GAAG,WAAW,EAAE,CAAC;IACpC,MAAM,YAAY,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;IACtD,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;AACvD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import makeWASocket, { AuthenticationState, Chat, Contact, WAMessage } from '@whiskeysockets/baileys';
2
+ export interface WhatsAppStore {
3
+ bind: (ev: ReturnType<typeof makeWASocket>['ev']) => void;
4
+ getChats: () => Chat[];
5
+ getChat: (id: string) => Chat | undefined;
6
+ getContacts: () => Contact[];
7
+ getContact: (id: string) => Contact | undefined;
8
+ getMessages: () => WAMessage[];
9
+ getMessage: (id: string) => WAMessage | undefined;
10
+ reset: () => void;
11
+ getAuth: () => AuthenticationState;
12
+ }
13
+ export interface DataStore {
14
+ chats: string;
15
+ contacts: string;
16
+ messages: string;
17
+ auth: string;
18
+ }
19
+ export declare function createStore(saveCb?: (data: DataStore) => void, initialData?: DataStore): WhatsAppStore;
20
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,EAAE,EAAE,mBAAmB,EAA+B,IAAI,EAAE,OAAO,EAAE,SAAS,EAAgB,MAAM,yBAAyB,CAAA;AAGhJ,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,CAAC,EAAE,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAA;IACzD,QAAQ,EAAE,MAAM,IAAI,EAAE,CAAA;IACtB,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,SAAS,CAAA;IACzC,WAAW,EAAE,MAAM,OAAO,EAAE,CAAA;IAC5B,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,GAAG,SAAS,CAAA;IAC/C,WAAW,EAAE,MAAM,SAAS,EAAE,CAAA;IAC9B,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,CAAA;IACjD,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,OAAO,EAAE,MAAM,mBAAmB,CAAA;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAG,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb;AAaD,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,EAAE,WAAW,CAAC,EAAE,SAAS,GAAG,aAAa,CA8HtG"}
package/dist/store.js ADDED
@@ -0,0 +1,138 @@
1
+ import { BufferJSON } from '@whiskeysockets/baileys';
2
+ import { createExportableAuth } from './auth.js';
3
+ function fromString(data) {
4
+ if (!data)
5
+ return new Map();
6
+ const parsed = JSON.parse(data);
7
+ return new Map(parsed);
8
+ }
9
+ function toString(map) {
10
+ return JSON.stringify(map, BufferJSON.replacer);
11
+ }
12
+ export function createStore(saveCb, initialData) {
13
+ //TODO: Load initial states from somewhere
14
+ const chats = fromString(initialData?.chats);
15
+ const contacts = fromString(initialData?.contacts);
16
+ const messages = fromString(initialData?.messages);
17
+ let auth = createExportableAuth(initialData?.auth);
18
+ let saveTimeout = undefined;
19
+ function mergeChats(newChats) {
20
+ for (const c of newChats) {
21
+ if (!c.id)
22
+ continue;
23
+ const existing = chats.get(c.id) ?? {};
24
+ const merged = { ...existing, ...c };
25
+ chats.set(c.id, merged);
26
+ }
27
+ }
28
+ function deleteChats(ids) {
29
+ for (const id of ids) {
30
+ chats.delete(id);
31
+ }
32
+ }
33
+ function mergeContacts(newContacts) {
34
+ for (const c of newContacts) {
35
+ if (!c.id)
36
+ continue;
37
+ const existing = contacts.get(c.id) ?? {};
38
+ const merged = { ...existing, ...c };
39
+ contacts.set(c.id, merged);
40
+ }
41
+ }
42
+ function mergeMessages(newMessages) {
43
+ for (const m of newMessages) {
44
+ if (!m.key?.id)
45
+ continue;
46
+ const existing = messages.get(m.key.id) ?? {};
47
+ const merged = { ...existing, ...m };
48
+ messages.set(m.key.id, merged);
49
+ }
50
+ }
51
+ function deleteMessages(keys) {
52
+ for (const key of keys) {
53
+ if (!key.id)
54
+ continue;
55
+ messages.delete(key.id);
56
+ }
57
+ }
58
+ function deleteMessage(jid) {
59
+ for (const [id, m] of messages.entries()) {
60
+ if (m.key?.remoteJid === jid) {
61
+ messages.delete(id);
62
+ }
63
+ }
64
+ }
65
+ function save() {
66
+ if (!saveCb)
67
+ return;
68
+ saveCb({
69
+ chats: toString(chats), contacts: toString(contacts), messages: toString(messages), auth: auth.toAuthState()
70
+ });
71
+ }
72
+ function process(e) {
73
+ //Store data if no new events come in for 1 second
74
+ if (saveTimeout)
75
+ clearTimeout(saveTimeout);
76
+ if (saveCb)
77
+ saveTimeout = setTimeout(save, 1000);
78
+ for (const key of Object.keys(e)) {
79
+ try {
80
+ switch (key) {
81
+ case 'messaging-history.set':
82
+ mergeChats(e[key]?.chats ?? []);
83
+ mergeContacts(e[key]?.contacts ?? []);
84
+ mergeMessages(e[key]?.messages ?? []);
85
+ break;
86
+ case 'chats.delete':
87
+ deleteChats(e[key] ?? []);
88
+ break;
89
+ case 'chats.update':
90
+ case 'chats.upsert':
91
+ mergeChats(e[key] ?? []);
92
+ break;
93
+ case 'contacts.update':
94
+ case 'contacts.upsert':
95
+ mergeContacts(e[key] ?? []);
96
+ break;
97
+ case 'messages.delete':
98
+ if (!e[key])
99
+ break;
100
+ if ('keys' in e[key])
101
+ deleteMessages(e[key].keys);
102
+ else
103
+ deleteMessage(e[key].jid);
104
+ break;
105
+ case 'messages.update':
106
+ mergeMessages(e[key] ?? []);
107
+ break;
108
+ case 'messages.upsert':
109
+ mergeMessages(e[key]?.messages ?? []);
110
+ break;
111
+ }
112
+ }
113
+ catch (error) {
114
+ handleError(error);
115
+ }
116
+ }
117
+ }
118
+ function handleError(error) {
119
+ console.error(`Error processing WhatsApp store event: ${error instanceof Error ? error.message : String(error)}`);
120
+ }
121
+ return {
122
+ bind: (ev) => ev.process(process),
123
+ getChats: () => Array.from(chats.values()),
124
+ getChat: (id) => chats.get(id),
125
+ getContacts: () => Array.from(contacts.values()),
126
+ getContact: (id) => contacts.get(id),
127
+ getMessages: () => Array.from(messages.values()),
128
+ getMessage: (id) => messages.get(id),
129
+ reset: () => {
130
+ chats.clear();
131
+ contacts.clear();
132
+ messages.clear();
133
+ auth = createExportableAuth(undefined);
134
+ },
135
+ getAuth: () => auth
136
+ };
137
+ }
138
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/dist/sync.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import { createStore } from './store.js';
2
+ export type SyncStatus = {
3
+ type: 'connecting';
4
+ } | {
5
+ type: 'needAuth';
6
+ qr: string;
7
+ } | {
8
+ type: 'ready';
9
+ } | {
10
+ type: 'closed';
11
+ error?: Error;
12
+ };
13
+ export interface SyncHandler {
14
+ close: () => void;
15
+ getStatus: () => SyncStatus;
16
+ }
17
+ export declare function createSyncHandler(store: ReturnType<typeof createStore>): SyncHandler;
18
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAExC,MAAM,MAAM,UAAU,GAAG;IAAC,IAAI,EAAE,YAAY,CAAA;CAAC,GAAG;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAC,GAAG;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,GAAG;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAC,CAAA;AAElI,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,SAAS,EAAE,MAAM,UAAU,CAAA;CAC5B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,GAAG,WAAW,CAoEpF"}