macOS chat-relay bridge: iMessage <-> Telegram, web UI, and pluggable integrations
Project description
chatwire
Relay iMessages from a macOS host to other places — currently a Telegram bot and a web UI, with more integrations planned.
Originally branded
chat-bridge; renamed tochatwirefor v0.2.0 because PyPI's similarity check rejectedchat-bridge(collides with an unrelatedchatbridgepackage).
Status: alpha. The author runs this daily; nobody else has installed it yet. Things will change. See
docs/OPEN_SOURCE_PLAN.mdfor the roadmap.
What it does
- Inbound. A small Python service polls
~/Library/Messages/chat.db, resolves senders against Contacts.app, and forwards messages (text, photos, videos, attachments) to your configured integrations. - Outbound. Reply from your phone, your laptop, anywhere — the service drives Messages.app via AppleScript to send back as you.
- Group chats. First-class. Replies route by chat GUID, not the sender's 1:1 handle, so you can keep a group conversation in Telegram or the web UI and replies land back in the group.
Constraints
iMessage is Mac-only. The bridge has to live on a Mac with the user's Apple
ID logged into Messages.app, granted Full Disk Access (to read chat.db)
and Automation→Messages (to send). macOS gates both behind System Settings
clicks that no installer can bypass — the setup wizard makes them as short
as possible, but you will click through some prompts the first time.
Tested on macOS 12 Monterey. macOS 13–15 should work; not yet smoke-tested.
See docs/OPEN_SOURCE_PLAN.md for the support matrix.
Install
Recommended path: pipx, against python.org's Python.
# Install python.org Python first if you don't have it:
# https://www.python.org/downloads/macos/
# (Homebrew Python works but TCC treats it as a different identity —
# you'd have to grant Full Disk Access + Automation to that binary
# specifically. python.org is the well-trodden path.)
# Install pipx if you don't have it (once per machine):
python3 -m pip install --user pipx
python3 -m pipx ensurepath
# Install chatwire from PyPI:
pipx install --python /Library/Frameworks/Python.framework/Versions/Current/bin/python3 \
chatwire
# Wire it up:
chatwire install-agents
chatwire setup
The setup wizard walks you through the Telegram bot token, the macOS
permission grants (Full Disk Access + Automation→Messages), and writes
~/.chatwire/config.json.
Alternate install methods
Homebrew tap. Convenient if you already use brew.
brew install allenbina/tap/chatwire
chatwire install-agents
chatwire setup
Tap source: https://github.com/allenbina/homebrew-tap.
curl-pipe-bash. No PyPI access, no Homebrew, just a shell.
curl -fsSL https://raw.githubusercontent.com/allenbina/chatwire/main/scripts/install.sh | bash
Pin to a tag with CHATWIRE_REF=v0.2.0. The script refuses Xcode CLT's
Python stub and warns on Homebrew Python (TCC identity protection). Same
post-install steps (chatwire install-agents etc.).
Developer / git-clone path. For hacking on the bridge itself:
git clone https://github.com/allenbina/chatwire.git ~/projects/chatwire
cd ~/projects/chatwire
python3 -m venv .venv
.venv/bin/pip install -e .
# Render and load the launchd agents:
.venv/bin/chatwire install-agents
# (legacy installs only) one-shot migration from ~/.imessage-tg/.env:
.venv/bin/chatwire migrate
# Sanity check:
.venv/bin/chatwire doctor
Configure ~/.chatwire/config.json (chmod 600). Schema:
{
"version": 1,
"TELEGRAM_BOT_TOKEN": "...",
"TELEGRAM_ALLOWED_USER_IDS": "123456789",
"SELF_HANDLES": "+1XXXXXXXXXX,you@icloud.com",
"WEB_PORT": "8723"
}
The setup wizard (Phase 2) will write this for you. Until then it's hand-edited.
macOS permissions
Both the FDA grant and the Automation→Messages grant need to be given to the
python.org Python binary (not Homebrew's), because the python.org
installer ships two Mach-O binaries with different code-signing identities
that TCC tracks separately. See
docs/REFERENCE_INSTALL.md section 5 for the
full walkthrough — that section was the reason the bridge worked at all on
the first install, and it's the same on every Mac.
scripts/check-permissions.sh (or chatwire doctor) will tell you
which prompts you still need to click.
Privacy
No telemetry. chatwire collects no analytics, sends no usage data, and
includes no third-party SDKs that report back. Your messages, contacts,
and chat.db stay on your Mac; outbound traffic only goes to integrations
you configure (e.g. Telegram via your own bot token).
Two narrow third-party requests the web UI does make, neither carrying any of your data:
- The update-check banner fetches
api.github.com/repos/<repo>/releases/latestonce a day to surface new-version notices. Disable by settingUPDATE_CHECK_REPO=""in the launchd agent's environment. - Static assets (htmx, emoji-picker-element) load from
unpkg.comandcdn.jsdelivr.net.
Repo layout
bridge.py telegram bot + outbound (TG -> iMessage)
chat_db.py reads chat.db, HEIC -> JPEG via sips
chat_send.py osascript wrappers (send_text, send_file)
prefix.py message prefix formatter + reply parser
config.py config.json loader (with .env fallback)
chatwire_cli.py setup / install-agents / logs / doctor / migrate
contacts.py Contacts.app -> handle/name lookup
echo_log.py cross-process echo dedup
whitelist.py runtime-mutable allowlist
_version.py release-semver source of truth
web/ FastAPI web UI + first-run setup wizard
migrations/ config-schema migration runner
templates/launchd/ plist templates rendered by install-agents
scripts/install.sh curl-pipe-bash installer (alternative to brew)
docs/ OPEN_SOURCE_PLAN.md, REFERENCE_INSTALL.md
Trademarks
iMessage, Messages, macOS, and AppleScript are trademarks of Apple Inc., referenced here in their descriptive sense — this project relays to and from Apple's iMessage service. chatwire is not affiliated with, endorsed by, or sponsored by Apple Inc.
License
MIT — see LICENSE.
Contributing
Not accepting PRs yet — Phase 1 is mid-flight. Open an issue if you have questions or hit a wall installing.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file chatwire-0.4.2.tar.gz.
File metadata
- Download URL: chatwire-0.4.2.tar.gz
- Upload date:
- Size: 103.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
671736ec3314e06aa7ab0d04f45b6ffa07a744d52eb6199a4b5c6eb464f354e7
|
|
| MD5 |
0994c3c5b5d0db50570e6a81ebed9823
|
|
| BLAKE2b-256 |
1434b73b6d831780300c84b51ab165d71c3736f594b7a1fc80a5bcd70cf33bcb
|
Provenance
The following attestation bundles were made for chatwire-0.4.2.tar.gz:
Publisher:
publish.yml on allenbina/chatwire
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chatwire-0.4.2.tar.gz -
Subject digest:
671736ec3314e06aa7ab0d04f45b6ffa07a744d52eb6199a4b5c6eb464f354e7 - Sigstore transparency entry: 1455387222
- Sigstore integration time:
-
Permalink:
allenbina/chatwire@9e556df51207203a7d48173db6af522c490e7d87 -
Branch / Tag:
refs/tags/v0.4.2 - Owner: https://github.com/allenbina
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9e556df51207203a7d48173db6af522c490e7d87 -
Trigger Event:
push
-
Statement type:
File details
Details for the file chatwire-0.4.2-py3-none-any.whl.
File metadata
- Download URL: chatwire-0.4.2-py3-none-any.whl
- Upload date:
- Size: 117.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5928ec06b230cfe274de6648fabd66e5cd45a36543b1aabd25a6bf445c847a40
|
|
| MD5 |
a4d85fd65d7a48693c7df0702ad4d65d
|
|
| BLAKE2b-256 |
1863570b2bbe60942e32a22f3065c81a2a8c155571e4413549e2b07892bc425d
|
Provenance
The following attestation bundles were made for chatwire-0.4.2-py3-none-any.whl:
Publisher:
publish.yml on allenbina/chatwire
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
chatwire-0.4.2-py3-none-any.whl -
Subject digest:
5928ec06b230cfe274de6648fabd66e5cd45a36543b1aabd25a6bf445c847a40 - Sigstore transparency entry: 1455387324
- Sigstore integration time:
-
Permalink:
allenbina/chatwire@9e556df51207203a7d48173db6af522c490e7d87 -
Branch / Tag:
refs/tags/v0.4.2 - Owner: https://github.com/allenbina
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9e556df51207203a7d48173db6af522c490e7d87 -
Trigger Event:
push
-
Statement type: