chatwire 0.2.0__tar.gz

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 (44) hide show
  1. chatwire-0.2.0/LICENSE +21 -0
  2. chatwire-0.2.0/PKG-INFO +228 -0
  3. chatwire-0.2.0/README.md +172 -0
  4. chatwire-0.2.0/_version.py +12 -0
  5. chatwire-0.2.0/bridge.py +487 -0
  6. chatwire-0.2.0/chat_db.py +393 -0
  7. chatwire-0.2.0/chat_send.py +433 -0
  8. chatwire-0.2.0/chatwire.egg-info/PKG-INFO +228 -0
  9. chatwire-0.2.0/chatwire.egg-info/SOURCES.txt +42 -0
  10. chatwire-0.2.0/chatwire.egg-info/dependency_links.txt +1 -0
  11. chatwire-0.2.0/chatwire.egg-info/entry_points.txt +2 -0
  12. chatwire-0.2.0/chatwire.egg-info/requires.txt +8 -0
  13. chatwire-0.2.0/chatwire.egg-info/top_level.txt +14 -0
  14. chatwire-0.2.0/chatwire_cli.py +317 -0
  15. chatwire-0.2.0/config.py +233 -0
  16. chatwire-0.2.0/contacts.py +145 -0
  17. chatwire-0.2.0/echo_log.py +60 -0
  18. chatwire-0.2.0/integrations/__init__.py +26 -0
  19. chatwire-0.2.0/integrations/base.py +158 -0
  20. chatwire-0.2.0/integrations/telegram/__init__.py +957 -0
  21. chatwire-0.2.0/integrations/web/__init__.py +130 -0
  22. chatwire-0.2.0/integrations/webhook/__init__.py +169 -0
  23. chatwire-0.2.0/migrations/0001_initial.py +16 -0
  24. chatwire-0.2.0/migrations/0002_integration_split.py +115 -0
  25. chatwire-0.2.0/migrations/__init__.py +62 -0
  26. chatwire-0.2.0/prefix.py +64 -0
  27. chatwire-0.2.0/pyproject.toml +110 -0
  28. chatwire-0.2.0/setup.cfg +4 -0
  29. chatwire-0.2.0/templates/__init__.py +0 -0
  30. chatwire-0.2.0/templates/launchd/bridge.plist.template +56 -0
  31. chatwire-0.2.0/templates/launchd/keepawake.plist.template +40 -0
  32. chatwire-0.2.0/templates/launchd/web.plist.template +46 -0
  33. chatwire-0.2.0/web/main.py +1280 -0
  34. chatwire-0.2.0/web/setup_wizard.py +337 -0
  35. chatwire-0.2.0/web/static/favicon.svg +4 -0
  36. chatwire-0.2.0/web/static/style.css +676 -0
  37. chatwire-0.2.0/web/static/sw.js +43 -0
  38. chatwire-0.2.0/web/static/update-check.js +159 -0
  39. chatwire-0.2.0/web/templates/_conversation.html +246 -0
  40. chatwire-0.2.0/web/templates/_conversations.html +52 -0
  41. chatwire-0.2.0/web/templates/_settings.html +53 -0
  42. chatwire-0.2.0/web/templates/_whitelist_rows.html +28 -0
  43. chatwire-0.2.0/web/templates/index.html +214 -0
  44. chatwire-0.2.0/whitelist.py +149 -0
chatwire-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Allen Bina
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.
@@ -0,0 +1,228 @@
1
+ Metadata-Version: 2.4
2
+ Name: chatwire
3
+ Version: 0.2.0
4
+ Summary: macOS chat-relay bridge: iMessage <-> Telegram, web UI, and pluggable integrations
5
+ Author: Allen Bina
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 Allen Bina
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/allenbina/chatwire
29
+ Project-URL: Issues, https://github.com/allenbina/chatwire/issues
30
+ Keywords: imessage,telegram,macos,bridge,relay
31
+ Classifier: Development Status :: 3 - Alpha
32
+ Classifier: Environment :: Console
33
+ Classifier: Environment :: Web Environment
34
+ Classifier: Intended Audience :: End Users/Desktop
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Operating System :: MacOS :: MacOS X
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3 :: Only
39
+ Classifier: Programming Language :: Python :: 3.10
40
+ Classifier: Programming Language :: Python :: 3.11
41
+ Classifier: Programming Language :: Python :: 3.12
42
+ Classifier: Programming Language :: Python :: 3.13
43
+ Classifier: Topic :: Communications :: Chat
44
+ Requires-Python: >=3.10
45
+ Description-Content-Type: text/markdown
46
+ License-File: LICENSE
47
+ Requires-Dist: python-telegram-bot<22,>=21.0
48
+ Requires-Dist: fastapi>=0.110
49
+ Requires-Dist: uvicorn[standard]>=0.27
50
+ Requires-Dist: jinja2>=3.1
51
+ Requires-Dist: python-multipart>=0.0.9
52
+ Requires-Dist: pywebpush>=2.0
53
+ Requires-Dist: httpx
54
+ Requires-Dist: jsonschema>=4
55
+ Dynamic: license-file
56
+
57
+ # chatwire
58
+
59
+ Relay iMessages from a macOS host to other places — currently a Telegram bot
60
+ and a web UI, with more integrations planned.
61
+
62
+ > Originally branded `chat-bridge`; renamed to `chatwire` for v0.2.0 because
63
+ > PyPI's similarity check rejected `chat-bridge` (collides with an unrelated
64
+ > `chatbridge` package).
65
+
66
+ > **Status:** alpha. The author runs this daily; nobody else has installed it
67
+ > yet. Things will change. See [`docs/OPEN_SOURCE_PLAN.md`](docs/OPEN_SOURCE_PLAN.md)
68
+ > for the roadmap.
69
+
70
+ ## What it does
71
+
72
+ - **Inbound.** A small Python service polls `~/Library/Messages/chat.db`,
73
+ resolves senders against Contacts.app, and forwards messages (text, photos,
74
+ videos, attachments) to your configured integrations.
75
+ - **Outbound.** Reply from your phone, your laptop, anywhere — the service
76
+ drives Messages.app via AppleScript to send back as you.
77
+ - **Group chats.** First-class. Replies route by chat GUID, not the sender's
78
+ 1:1 handle, so you can keep a group conversation in Telegram or the web UI
79
+ and replies land back in the group.
80
+
81
+ ## Constraints
82
+
83
+ iMessage is Mac-only. The bridge has to live on a Mac with the user's Apple
84
+ ID logged into Messages.app, granted Full Disk Access (to read `chat.db`)
85
+ and Automation→Messages (to send). macOS gates both behind System Settings
86
+ clicks that no installer can bypass — the setup wizard makes them as short
87
+ as possible, but you will click through some prompts the first time.
88
+
89
+ Tested on macOS 12 Monterey. macOS 13–15 should work; not yet smoke-tested.
90
+ See `docs/OPEN_SOURCE_PLAN.md` for the support matrix.
91
+
92
+ ## Install
93
+
94
+ Recommended path: **pipx**, against python.org's Python.
95
+
96
+ ```bash
97
+ # Install python.org Python first if you don't have it:
98
+ # https://www.python.org/downloads/macos/
99
+ # (Homebrew Python works but TCC treats it as a different identity —
100
+ # you'd have to grant Full Disk Access + Automation to that binary
101
+ # specifically. python.org is the well-trodden path.)
102
+
103
+ # Install pipx if you don't have it (once per machine):
104
+ python3 -m pip install --user pipx
105
+ python3 -m pipx ensurepath
106
+
107
+ # Install chatwire (from PyPI, once v0.2.0 ships):
108
+ pipx install --python /Library/Frameworks/Python.framework/Versions/Current/bin/python3 \
109
+ chatwire
110
+
111
+ # Or from the v0.1.0 git tag (still under the old chat-bridge repo URL —
112
+ # the GitHub redirect to chatwire keeps this working):
113
+ pipx install --python /Library/Frameworks/Python.framework/Versions/Current/bin/python3 \
114
+ git+https://github.com/allenbina/chatwire.git@v0.1.0
115
+
116
+ # Wire it up:
117
+ chatwire install-agents
118
+ chatwire setup
119
+ ```
120
+
121
+ The setup wizard walks you through the Telegram bot token, the macOS
122
+ permission grants (Full Disk Access + Automation→Messages), and writes
123
+ `~/.chatwire/config.json`.
124
+
125
+ ### Alternate install methods
126
+
127
+ **Homebrew tap.** Convenient if you already use brew. Note: the formula
128
+ still ships under the old `chat-bridge` name in the tap; renaming the
129
+ formula is tracked separately.
130
+
131
+ ```bash
132
+ brew install allenbina/tap/chat-bridge
133
+ chatwire install-agents
134
+ chatwire setup
135
+ ```
136
+
137
+ Tap source: <https://github.com/allenbina/homebrew-tap>.
138
+
139
+ **curl-pipe-bash.** No PyPI access, no Homebrew, just a shell.
140
+
141
+ ```bash
142
+ curl -fsSL https://raw.githubusercontent.com/allenbina/chatwire/main/scripts/install.sh | bash
143
+ ```
144
+
145
+ Pin to a tag with `CHATWIRE_REF=v0.1.0`. The script refuses Xcode CLT's
146
+ Python stub and warns on Homebrew Python (TCC identity protection). Same
147
+ post-install steps (`chatwire install-agents` etc.).
148
+
149
+ **Developer / git-clone path.** For hacking on the bridge itself:
150
+
151
+ ```bash
152
+ git clone https://github.com/allenbina/chatwire.git ~/projects/chatwire
153
+ cd ~/projects/chatwire
154
+ python3 -m venv .venv
155
+ .venv/bin/pip install -e .
156
+
157
+ # Render and load the launchd agents:
158
+ .venv/bin/chatwire install-agents
159
+
160
+ # (legacy installs only) one-shot migration from ~/.imessage-tg/.env:
161
+ .venv/bin/chatwire migrate
162
+
163
+ # Sanity check:
164
+ .venv/bin/chatwire doctor
165
+ ```
166
+
167
+ Configure `~/.chatwire/config.json` (chmod 600). Schema:
168
+
169
+ ```json
170
+ {
171
+ "version": 1,
172
+ "TELEGRAM_BOT_TOKEN": "...",
173
+ "TELEGRAM_ALLOWED_USER_IDS": "123456789",
174
+ "SELF_HANDLES": "+1XXXXXXXXXX,you@icloud.com",
175
+ "WEB_PORT": "8723"
176
+ }
177
+ ```
178
+
179
+ The setup wizard (Phase 2) will write this for you. Until then it's hand-edited.
180
+
181
+ ## macOS permissions
182
+
183
+ Both the FDA grant and the Automation→Messages grant need to be given to the
184
+ **python.org Python binary** (not Homebrew's), because the python.org
185
+ installer ships two Mach-O binaries with different code-signing identities
186
+ that TCC tracks separately. See
187
+ [`docs/REFERENCE_INSTALL.md`](docs/REFERENCE_INSTALL.md) section 5 for the
188
+ full walkthrough — that section was the reason the bridge worked at all on
189
+ the first install, and it's the same on every Mac.
190
+
191
+ `scripts/check-permissions.sh` (or `chatwire doctor`) will tell you
192
+ which prompts you still need to click.
193
+
194
+ ## Repo layout
195
+
196
+ ```
197
+ bridge.py telegram bot + outbound (TG -> iMessage)
198
+ chat_db.py reads chat.db, HEIC -> JPEG via sips
199
+ chat_send.py osascript wrappers (send_text, send_file)
200
+ prefix.py message prefix formatter + reply parser
201
+ config.py config.json loader (with .env fallback)
202
+ chatwire_cli.py setup / install-agents / logs / doctor / migrate
203
+ contacts.py Contacts.app -> handle/name lookup
204
+ echo_log.py cross-process echo dedup
205
+ whitelist.py runtime-mutable allowlist
206
+ _version.py release-semver source of truth
207
+ web/ FastAPI web UI + first-run setup wizard
208
+ migrations/ config-schema migration runner
209
+ templates/launchd/ plist templates rendered by install-agents
210
+ scripts/install.sh curl-pipe-bash installer (alternative to brew)
211
+ docs/ OPEN_SOURCE_PLAN.md, REFERENCE_INSTALL.md
212
+ ```
213
+
214
+ ## Trademarks
215
+
216
+ iMessage, Messages, macOS, and AppleScript are trademarks of Apple Inc.,
217
+ referenced here in their descriptive sense — this project relays to and
218
+ from Apple's iMessage service. **chatwire is not affiliated with,
219
+ endorsed by, or sponsored by Apple Inc.**
220
+
221
+ ## License
222
+
223
+ MIT — see [`LICENSE`](LICENSE).
224
+
225
+ ## Contributing
226
+
227
+ Not accepting PRs yet — Phase 1 is mid-flight. Open an issue if you have
228
+ questions or hit a wall installing.
@@ -0,0 +1,172 @@
1
+ # chatwire
2
+
3
+ Relay iMessages from a macOS host to other places — currently a Telegram bot
4
+ and a web UI, with more integrations planned.
5
+
6
+ > Originally branded `chat-bridge`; renamed to `chatwire` for v0.2.0 because
7
+ > PyPI's similarity check rejected `chat-bridge` (collides with an unrelated
8
+ > `chatbridge` package).
9
+
10
+ > **Status:** alpha. The author runs this daily; nobody else has installed it
11
+ > yet. Things will change. See [`docs/OPEN_SOURCE_PLAN.md`](docs/OPEN_SOURCE_PLAN.md)
12
+ > for the roadmap.
13
+
14
+ ## What it does
15
+
16
+ - **Inbound.** A small Python service polls `~/Library/Messages/chat.db`,
17
+ resolves senders against Contacts.app, and forwards messages (text, photos,
18
+ videos, attachments) to your configured integrations.
19
+ - **Outbound.** Reply from your phone, your laptop, anywhere — the service
20
+ drives Messages.app via AppleScript to send back as you.
21
+ - **Group chats.** First-class. Replies route by chat GUID, not the sender's
22
+ 1:1 handle, so you can keep a group conversation in Telegram or the web UI
23
+ and replies land back in the group.
24
+
25
+ ## Constraints
26
+
27
+ iMessage is Mac-only. The bridge has to live on a Mac with the user's Apple
28
+ ID logged into Messages.app, granted Full Disk Access (to read `chat.db`)
29
+ and Automation→Messages (to send). macOS gates both behind System Settings
30
+ clicks that no installer can bypass — the setup wizard makes them as short
31
+ as possible, but you will click through some prompts the first time.
32
+
33
+ Tested on macOS 12 Monterey. macOS 13–15 should work; not yet smoke-tested.
34
+ See `docs/OPEN_SOURCE_PLAN.md` for the support matrix.
35
+
36
+ ## Install
37
+
38
+ Recommended path: **pipx**, against python.org's Python.
39
+
40
+ ```bash
41
+ # Install python.org Python first if you don't have it:
42
+ # https://www.python.org/downloads/macos/
43
+ # (Homebrew Python works but TCC treats it as a different identity —
44
+ # you'd have to grant Full Disk Access + Automation to that binary
45
+ # specifically. python.org is the well-trodden path.)
46
+
47
+ # Install pipx if you don't have it (once per machine):
48
+ python3 -m pip install --user pipx
49
+ python3 -m pipx ensurepath
50
+
51
+ # Install chatwire (from PyPI, once v0.2.0 ships):
52
+ pipx install --python /Library/Frameworks/Python.framework/Versions/Current/bin/python3 \
53
+ chatwire
54
+
55
+ # Or from the v0.1.0 git tag (still under the old chat-bridge repo URL —
56
+ # the GitHub redirect to chatwire keeps this working):
57
+ pipx install --python /Library/Frameworks/Python.framework/Versions/Current/bin/python3 \
58
+ git+https://github.com/allenbina/chatwire.git@v0.1.0
59
+
60
+ # Wire it up:
61
+ chatwire install-agents
62
+ chatwire setup
63
+ ```
64
+
65
+ The setup wizard walks you through the Telegram bot token, the macOS
66
+ permission grants (Full Disk Access + Automation→Messages), and writes
67
+ `~/.chatwire/config.json`.
68
+
69
+ ### Alternate install methods
70
+
71
+ **Homebrew tap.** Convenient if you already use brew. Note: the formula
72
+ still ships under the old `chat-bridge` name in the tap; renaming the
73
+ formula is tracked separately.
74
+
75
+ ```bash
76
+ brew install allenbina/tap/chat-bridge
77
+ chatwire install-agents
78
+ chatwire setup
79
+ ```
80
+
81
+ Tap source: <https://github.com/allenbina/homebrew-tap>.
82
+
83
+ **curl-pipe-bash.** No PyPI access, no Homebrew, just a shell.
84
+
85
+ ```bash
86
+ curl -fsSL https://raw.githubusercontent.com/allenbina/chatwire/main/scripts/install.sh | bash
87
+ ```
88
+
89
+ Pin to a tag with `CHATWIRE_REF=v0.1.0`. The script refuses Xcode CLT's
90
+ Python stub and warns on Homebrew Python (TCC identity protection). Same
91
+ post-install steps (`chatwire install-agents` etc.).
92
+
93
+ **Developer / git-clone path.** For hacking on the bridge itself:
94
+
95
+ ```bash
96
+ git clone https://github.com/allenbina/chatwire.git ~/projects/chatwire
97
+ cd ~/projects/chatwire
98
+ python3 -m venv .venv
99
+ .venv/bin/pip install -e .
100
+
101
+ # Render and load the launchd agents:
102
+ .venv/bin/chatwire install-agents
103
+
104
+ # (legacy installs only) one-shot migration from ~/.imessage-tg/.env:
105
+ .venv/bin/chatwire migrate
106
+
107
+ # Sanity check:
108
+ .venv/bin/chatwire doctor
109
+ ```
110
+
111
+ Configure `~/.chatwire/config.json` (chmod 600). Schema:
112
+
113
+ ```json
114
+ {
115
+ "version": 1,
116
+ "TELEGRAM_BOT_TOKEN": "...",
117
+ "TELEGRAM_ALLOWED_USER_IDS": "123456789",
118
+ "SELF_HANDLES": "+1XXXXXXXXXX,you@icloud.com",
119
+ "WEB_PORT": "8723"
120
+ }
121
+ ```
122
+
123
+ The setup wizard (Phase 2) will write this for you. Until then it's hand-edited.
124
+
125
+ ## macOS permissions
126
+
127
+ Both the FDA grant and the Automation→Messages grant need to be given to the
128
+ **python.org Python binary** (not Homebrew's), because the python.org
129
+ installer ships two Mach-O binaries with different code-signing identities
130
+ that TCC tracks separately. See
131
+ [`docs/REFERENCE_INSTALL.md`](docs/REFERENCE_INSTALL.md) section 5 for the
132
+ full walkthrough — that section was the reason the bridge worked at all on
133
+ the first install, and it's the same on every Mac.
134
+
135
+ `scripts/check-permissions.sh` (or `chatwire doctor`) will tell you
136
+ which prompts you still need to click.
137
+
138
+ ## Repo layout
139
+
140
+ ```
141
+ bridge.py telegram bot + outbound (TG -> iMessage)
142
+ chat_db.py reads chat.db, HEIC -> JPEG via sips
143
+ chat_send.py osascript wrappers (send_text, send_file)
144
+ prefix.py message prefix formatter + reply parser
145
+ config.py config.json loader (with .env fallback)
146
+ chatwire_cli.py setup / install-agents / logs / doctor / migrate
147
+ contacts.py Contacts.app -> handle/name lookup
148
+ echo_log.py cross-process echo dedup
149
+ whitelist.py runtime-mutable allowlist
150
+ _version.py release-semver source of truth
151
+ web/ FastAPI web UI + first-run setup wizard
152
+ migrations/ config-schema migration runner
153
+ templates/launchd/ plist templates rendered by install-agents
154
+ scripts/install.sh curl-pipe-bash installer (alternative to brew)
155
+ docs/ OPEN_SOURCE_PLAN.md, REFERENCE_INSTALL.md
156
+ ```
157
+
158
+ ## Trademarks
159
+
160
+ iMessage, Messages, macOS, and AppleScript are trademarks of Apple Inc.,
161
+ referenced here in their descriptive sense — this project relays to and
162
+ from Apple's iMessage service. **chatwire is not affiliated with,
163
+ endorsed by, or sponsored by Apple Inc.**
164
+
165
+ ## License
166
+
167
+ MIT — see [`LICENSE`](LICENSE).
168
+
169
+ ## Contributing
170
+
171
+ Not accepting PRs yet — Phase 1 is mid-flight. Open an issue if you have
172
+ questions or hit a wall installing.
@@ -0,0 +1,12 @@
1
+ """Single source of truth for the bridge release version.
2
+
3
+ Bumped at release time. Used by:
4
+ - web/main.py for /healthz and the update-check banner
5
+ - chatwire_cli.py for `--version`
6
+ - pyproject.toml dynamic version
7
+
8
+ Format: PEP 440-flavored semver. Pre-1.0 dev builds carry a `-dev` suffix
9
+ which the update-check JS treats as "skip the check" (no point pinging
10
+ GitHub when you cloned from main).
11
+ """
12
+ __version__ = "0.2.0"