Skip to content

fix: Unicode-safe chat search + auto-detect business bridge DB#181

Open
EtanHey wants to merge 5 commits intolharries:mainfrom
EtanHey:fix/hebrew-search-and-messages
Open

fix: Unicode-safe chat search + auto-detect business bridge DB#181
EtanHey wants to merge 5 commits intolharries:mainfrom
EtanHey:fix/hebrew-search-and-messages

Conversation

@EtanHey
Copy link
Copy Markdown

@EtanHey EtanHey commented Mar 15, 2026

Summary

  • Unicode-safe search: Replaces LOWER()+LIKE with instr() in all three text-search paths (list_messages content, list_chats name, search_contacts name). SQLite's built-in LOWER() only handles ASCII — for Hebrew, Arabic, CJK, and emoji it is a no-op, causing silent failures on non-Latin queries. instr() does byte-level substring matching and is reliable for all Unicode.
  • Personal bridge is the default: WHATSAPP_DB_PATH defaults to whatsapp-bridge/store/messages.db (the personal bridge). Business users must set WHATSAPP_DB_PATH explicitly — there is no auto-detection that could silently redirect both instances to the same database.
  • Dual-bridge docs: README section explains how to run personal and business bridges side by side with per-instance env vars (WHATSAPP_DB_PATH, WHATSAPP_API_URL, WHATSAPP_BRIDGE_PORT). Clarifies that WHATSAPP_API_URL must include the /api suffix.
  • CONTRIBUTING.md: New file covering dev setup, project structure, the instr() convention, PR guidelines, and issue reporting.
  • Repo topics: whatsapp, mcp, model-context-protocol, whatsapp-api, claude, sqlite, go, python

What changed in whatsapp.py

Location Before After
list_messages content search LOWER(content) LIKE LOWER(?) instr(LOWER(content), LOWER(?)) > 0 OR instr(content, ?) > 0
list_chats name search LOWER(name) LIKE LOWER(?) instr(LOWER(name), LOWER(?)) > 0 OR instr(name, ?) > 0
search_contacts name search LOWER(name) LIKE LOWER(?) instr(LOWER(name), LOWER(?)) > 0 OR instr(name, ?) > 0
Default DB path whatsapp-bridge/store/messages.db (hardcoded) Same, via os.path.normpath (no auto-detection)

Test plan

  • list_messages(query="תודה") returns Hebrew-content messages
  • list_chats(query="מהיום") finds groups with Hebrew names
  • search_contacts(query="smith") still works for ASCII names
  • Personal MCP instance reads whatsapp-bridge/store/messages.db by default
  • Business MCP instance reads correct DB when WHATSAPP_DB_PATH is set explicitly

🤖 Generated with Claude Code

EtanHey and others added 5 commits March 15, 2026 11:29
- MESSAGES_DB_PATH now prefers whatsapp-bridge-business/store/messages.db
  when it exists, falling back to whatsapp-bridge/store/messages.db.
  This fixes list_messages returning 'No messages to display' for groups
  that only exist in the business bridge (e.g. מהיום פיתוח 🔥).

- Replace LOWER()+LIKE with instr() for chat name search so Hebrew and
  other non-ASCII names match correctly (SQLite LOWER() is ASCII-only;
  instr() does byte-level substring search which is Unicode-safe).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SQLite's LOWER() only handles ASCII (A-Z); Hebrew, Arabic, emoji and
other non-ASCII text is passed through unchanged, meaning LOWER()+LIKE
silently falls back to case-sensitive byte matching. instr() does
explicit byte-level substring search and is reliable for all Unicode.

- list_messages content query: LOWER(content) LIKE → instr()
- search_contacts name query:  LOWER(name) LIKE  → instr()
  (JID search kept as LIKE — JIDs are ASCII phone numbers)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Explains why instr() is used instead of LOWER()+LIKE for non-ASCII
  search (SQLite LOWER() is ASCII-only)
- Documents how to run personal and business bridges side by side with
  per-instance env vars (WHATSAPP_DB_PATH, WHATSAPP_API_URL,
  WHATSAPP_BRIDGE_PORT)
- Notes the auto-detection behaviour when business bridge DB is present

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers dev setup (uv + Go), project structure, the instr() SQLite
search convention, PR guidelines, and issue reporting template.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous _default_db_path() preferred whatsapp-bridge-business when
it existed, causing both personal and business MCP instances to silently
read the same (business) database. The correct behaviour is: default to
the personal bridge (whatsapp-bridge/store/messages.db) and require
business users to set WHATSAPP_DB_PATH explicitly.

Also updates README to clarify that WHATSAPP_API_URL must include the
/api suffix (it is used as-is with no suffix appended by the code).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant