wa-audit

wa-audit

Enables comprehensive audit of WhatsApp business conversations, including history export, LLM analysis with verification, and multi-format report generation.

Category
访问服务器

README

wa-audit

A commercial audit of your WhatsApp business number. Point it at a WAHA instance and it exports the full chat history, builds a clean conversation corpus, runs an LLM analysis that is verified against the corpus before it reaches you, and delivers a multi-sheet XLSX report: response times, real FAQs, customer archetypes, objections, what a bot could actually resolve — with a methodology sheet that records what the verification refuted.

Everything runs on your machine. The only outbound traffic in the whole pipeline is the phase-4 analysis call to the LLM provider you configure — and even that goes away with llm.provider: "mock" or a self-hosted OpenAI-compatible endpoint, for a fully offline run.

Leé esto en castellano: README.es.md.


⚠️ Read this first

This project is not affiliated with, associated with, authorized by, endorsed by, or in any way officially connected with WhatsApp, Meta Platforms Inc., or any of their subsidiaries. "WhatsApp" and "Meta", and related names, marks and images, are trademarks of their respective owners. The official WhatsApp website is https://whatsapp.com.

It is also not affiliated with the WAHA project. This tool only consumes the HTTP API of a WAHA instance you operate; it does not redistribute, bundle or modify WAHA (which is Apache-2.0, obtainable from its official repository).

WAHA uses unofficial methods to access WhatsApp. WhatsApp does not allow bots or unofficial clients on its platform, and there is no guarantee your account will not be blocked. The maintainers of this project do not condone any use that violates WhatsApp's Terms of Service and explicitly discourage bulk messaging, spam, stalkerware, or surveillance of people. For business-critical integrations, consider the official WhatsApp Business API. The intended use case is a business analyzing its own conversation history.

Personal data: chat history is personal data of third parties. You are solely responsible for having a valid legal basis to process it and for complying with the law that applies to you (GDPR, LGPD, Ley 25.326, …). Processing happens on your own infrastructure and this project transmits nothing to its authors. The one outbound flow is the analysis phase, which sends a corpus digest to the LLM provider you configure — none at all with a local or mock provider. Choose your provider accordingly.

This software is provided "AS IS", without warranty of any kind.


Why the verifier is the whole point

This pipeline was built for a real business: 11,782 messages, 610 conversations, 8 months of history. The LLM analysis produced 60 findings across 7 dimensions. Then each dimension went through an independent verifier that re-located every quote and re-counted every claim against the corpus.

The verifier refuted 34 of the 60 findings.

Plausible, well-written, confidently-numbered findings — and more than half of them didn't survive contact with the data. An LLM analysis of your business without a verification pass isn't analysis; it's fiction with nice formatting. That's why in this project:

  • every finding must cite verbatim evidence (thread_id + quote), and a deterministic code check refutes any finding whose quote doesn't exist in the corpus — no model gets a vote on that;
  • a second, independent LLM pass re-counts every frequency claim and refutes what doesn't hold as stated;
  • the schema makes the verdict required: an analysis without a recorded verification pass is invalid by construction;
  • the report's methodology sheet prints the refuted findings, so nobody re-cites the bad numbers later.

Two analysis lenses: commercial + FATE behavioral

The analysis ships with two dimension sets, both subject to the same mandatory verification:

  • Commercial (7 dimensions): real FAQs, response times and operations, customer archetypes, products and topics, objections and friction, bot opportunities, tone and style.
  • FATE behavioral (5 dimensions, npm run analyze -- --dimensions fate): how the business captures attention (Focus), projects certainty and keeps its word (Authority), makes clients feel understood (Tribe), reaches the emotional layer instead of dumping specs (Emotion), and reads customer state signals — clusters only, benign explanations first, states, never verdicts about individuals. Inspired by the FATE model in Chase Hughes' The Behavior Ops Manual (original articulation; not affiliated with or endorsed by the author). Interview your operator first and feed business-context.json — see analysis/PLAYBOOK.md.

Try it in two minutes (no WhatsApp needed)

git clone https://github.com/Leandrozz/wa-audit && cd wa-audit
npm install
npm run demo

The demo generates a synthetic corpus, starts a mock WAHA server, runs the entire pipeline against it (probe → export → corpus → verified analysis → report) with a mock LLM, and leaves the report in out/demo/ in all three formats — XLSX (the client spreadsheet), HTML (shareable single file) and DOCX (Word). No keys, no network, no real data.

Run it against your real WhatsApp

You need a running WAHA instance with your business number connected — see docs/waha-setup.md for the traps that cost us days (engine choice, fullSync, device slots, @lid).

cp waha.env.example waha.env        # fill in WAHA_BASE_URL + WAHA_API_KEY
# 0. read-only probe: right engine? how deep does the history go?
node --env-file=waha.env src/probe.mjs
# 2. dump the raw history (resumable)
node --env-file=waha.env src/export.mjs <session-name>
# 3. clean corpus: threads.json + messages.csv + summary.json
node --env-file=waha.env src/threads.mjs --session <session-name>
# 4. LLM analysis with mandatory verification (needs ANTHROPIC_API_KEY,
#    or any OpenAI-compatible endpoint — see Configuration)
node --env-file=waha.env src/analyze.mjs
# 5. the report, in any or all formats
node src/report-xlsx.mjs && node src/report-html.mjs && node src/report-docx.mjs

Prefer to run the analysis with your own agent (Claude Code, Cursor, anything) instead of the built-in engine? That's a first-class path: analysis/PLAYBOOK.md.

The official-API path (Kapso)

If the number runs on the official WhatsApp Business Platform through Kapso, skip WAHA entirely — no unofficial client, no ToS disclaimer for this source, no @lid:

cp kapso.env.example kapso.env      # KAPSO_API_KEY + KAPSO_PHONE_NUMBER_ID
npm run export:kapso
node src/threads.mjs --session kapso --no-net

Same corpus, same verifier, same reports. One honest tradeoff: the official platform has no retroactive backfill, so history covers what flowed through Kapso since the number was connected there. Details and a mock server to try it without an account: docs/kapso-setup.md.

Or let Claude drive the whole thing (MCP)

npm run mcp starts an MCP server that turns Claude Desktop / Claude Code / ChatGPT / Cursor into the audit engine: the agent interviews you, guides the WAHA setup, shows the pairing QR right in the chat, exports the history and runs the analysis itself. The server keeps it honest structurally — submit_dimension rejects any dimension without a recorded verification verdict, every evidence quote is re-checked server-side against the corpus, and chat content is served as untrusted data. It never sends a WhatsApp message. Setup: docs/mcp-setup.md.

The pipeline

 probe ──► export ──► threads ──► analyze ──► report-xlsx
 (0)       (2)        (3)         (4)         (5)
 read-only raw dump   clean       LLM + two-  11-sheet XLSX
 sanity    JSONL,     corpus,     layer       with styles,
 check     resumable  @lid        verifier    frozen panes &
                      resolution              a methodology
                      + metrics               sheet

Each phase reads and writes plain local files (default data/wa-history/), so you can rerun any phase without repeating the previous ones — the dump is never re-scraped because of a parsing bug.

Configuration

Copy wa-audit.config.json and edit, or use env overrides (env wins). The essentials:

Key Default What it does
business.name "My Business" Name printed on the report
business.internalNumbers [] Own lines, excluded from client metrics
business.internalEmailDomains [] CRM emails that mark internal lines
phone.defaultCountry "AR" Country for CRM numbers without prefix
timezone.utcOffset "-03:00" Fixed offset for local timestamps
locale "es-AR" Number formatting in the report
crm.file null Optional CRM CSV (phone,whatsapp,name,contact,email,segment,stage,location)
llm.provider "anthropic" anthropic | openai (any compatible endpoint) | mock
llm.model null anthropic falls back to claude-opus-5; openai requires an explicit model

Secrets are env-only: WAHA_BASE_URL, WAHA_API_KEY (+ ANTHROPIC_API_KEY or LLM_API_KEY for phase 4). WAHA_BASE_URL has no default on purpose — pointing at the wrong instance is the expensive mistake.

The report's prose is currently Spanish (es-AR preset); the data contract underneath is English. Prose i18n is on the roadmap.

Data contract

threads.json, summary.json and analysis.json are versioned (schema_version: 1) and documented in docs/data-contract.md. The analysis contract is formalized in analysis/analysis.schema.json (npm run check:analysis): any engine that emits valid analysis.json — LLM, rules, SQL, a human — plugs into the report without changes.

Honest limitations

  • WAHA's bulk-history endpoint only exists on the NOWEB/GOWS engines; WEBJS would need chat-by-chat export (unsupported here — the probe tells you).
  • History depth beyond ~3 months requires creating the session with noweb.store.fullSync before dumping (docs/waha-setup.md).
  • Response-time medians anchor at the first message of each inbound burst, and outbound messages don't distinguish humans from bots — both stated in the report's methodology sheet.
  • Media has no analyzable text (downloadMedia=false): photos and voice notes appear typed but empty.
  • xlsx@0.18.5 (pinned: the styles post-processing depends on it) has a known upstream advisory (prototype pollution / ReDoS on untrusted spreadsheets). This project only writes XLSX and reads back its own output, so the vector doesn't apply — but npm audit will flag it and we'd rather tell you than hide it.
  • The XLSX styling works by post-processing the file as a ZIP — deliberate, documented black magic: docs/xlsx-postprocess.md.

Development

npm test                 # unit + two end-to-end lanes against goldens
node fixtures/generate.mjs   # regenerate the deterministic synthetic fixture
node test/record-golden.mjs  # re-record goldens (review the diff like a spec)

Everything in fixtures/ is synthetic and invented. No real conversation, phone number or name from any actual business exists in this repository.

License

MIT.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选