claude-telegram-mirror 0.1.0

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 (99) hide show
  1. package/README.md +331 -0
  2. package/dist/bot/commands.d.ts +41 -0
  3. package/dist/bot/commands.d.ts.map +1 -0
  4. package/dist/bot/commands.js +231 -0
  5. package/dist/bot/commands.js.map +1 -0
  6. package/dist/bot/formatting.d.ts +62 -0
  7. package/dist/bot/formatting.d.ts.map +1 -0
  8. package/dist/bot/formatting.js +295 -0
  9. package/dist/bot/formatting.js.map +1 -0
  10. package/dist/bot/telegram.d.ts +93 -0
  11. package/dist/bot/telegram.d.ts.map +1 -0
  12. package/dist/bot/telegram.js +378 -0
  13. package/dist/bot/telegram.js.map +1 -0
  14. package/dist/bot/types.d.ts +28 -0
  15. package/dist/bot/types.d.ts.map +1 -0
  16. package/dist/bot/types.js +5 -0
  17. package/dist/bot/types.js.map +1 -0
  18. package/dist/bridge/daemon.d.ts +93 -0
  19. package/dist/bridge/daemon.d.ts.map +1 -0
  20. package/dist/bridge/daemon.js +626 -0
  21. package/dist/bridge/daemon.js.map +1 -0
  22. package/dist/bridge/index.d.ts +10 -0
  23. package/dist/bridge/index.d.ts.map +1 -0
  24. package/dist/bridge/index.js +9 -0
  25. package/dist/bridge/index.js.map +1 -0
  26. package/dist/bridge/injector.d.ts +97 -0
  27. package/dist/bridge/injector.d.ts.map +1 -0
  28. package/dist/bridge/injector.js +289 -0
  29. package/dist/bridge/injector.js.map +1 -0
  30. package/dist/bridge/session.d.ts +108 -0
  31. package/dist/bridge/session.d.ts.map +1 -0
  32. package/dist/bridge/session.js +381 -0
  33. package/dist/bridge/session.js.map +1 -0
  34. package/dist/bridge/socket.d.ts +97 -0
  35. package/dist/bridge/socket.d.ts.map +1 -0
  36. package/dist/bridge/socket.js +436 -0
  37. package/dist/bridge/socket.js.map +1 -0
  38. package/dist/bridge/types.d.ts +38 -0
  39. package/dist/bridge/types.d.ts.map +1 -0
  40. package/dist/bridge/types.js +5 -0
  41. package/dist/bridge/types.js.map +1 -0
  42. package/dist/cli.d.ts +7 -0
  43. package/dist/cli.d.ts.map +1 -0
  44. package/dist/cli.js +332 -0
  45. package/dist/cli.js.map +1 -0
  46. package/dist/hooks/handler.d.ts +94 -0
  47. package/dist/hooks/handler.d.ts.map +1 -0
  48. package/dist/hooks/handler.js +431 -0
  49. package/dist/hooks/handler.js.map +1 -0
  50. package/dist/hooks/index.d.ts +8 -0
  51. package/dist/hooks/index.d.ts.map +1 -0
  52. package/dist/hooks/index.js +7 -0
  53. package/dist/hooks/index.js.map +1 -0
  54. package/dist/hooks/installer.d.ts +46 -0
  55. package/dist/hooks/installer.d.ts.map +1 -0
  56. package/dist/hooks/installer.js +317 -0
  57. package/dist/hooks/installer.js.map +1 -0
  58. package/dist/hooks/types.d.ts +88 -0
  59. package/dist/hooks/types.d.ts.map +1 -0
  60. package/dist/hooks/types.js +6 -0
  61. package/dist/hooks/types.js.map +1 -0
  62. package/dist/index.d.ts +19 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +20 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/service/doctor.d.ts +10 -0
  67. package/dist/service/doctor.d.ts.map +1 -0
  68. package/dist/service/doctor.js +424 -0
  69. package/dist/service/doctor.js.map +1 -0
  70. package/dist/service/manager.d.ts +48 -0
  71. package/dist/service/manager.d.ts.map +1 -0
  72. package/dist/service/manager.js +584 -0
  73. package/dist/service/manager.js.map +1 -0
  74. package/dist/service/setup.d.ts +10 -0
  75. package/dist/service/setup.d.ts.map +1 -0
  76. package/dist/service/setup.js +266 -0
  77. package/dist/service/setup.js.map +1 -0
  78. package/dist/utils/chunker.d.ts +24 -0
  79. package/dist/utils/chunker.d.ts.map +1 -0
  80. package/dist/utils/chunker.js +123 -0
  81. package/dist/utils/chunker.js.map +1 -0
  82. package/dist/utils/config.d.ts +48 -0
  83. package/dist/utils/config.d.ts.map +1 -0
  84. package/dist/utils/config.js +154 -0
  85. package/dist/utils/config.js.map +1 -0
  86. package/dist/utils/logger.d.ts +7 -0
  87. package/dist/utils/logger.d.ts.map +1 -0
  88. package/dist/utils/logger.js +28 -0
  89. package/dist/utils/logger.js.map +1 -0
  90. package/package.json +88 -0
  91. package/postinstall.cjs +76 -0
  92. package/scripts/claude-wrapper.sh +122 -0
  93. package/scripts/doctor.sh +433 -0
  94. package/scripts/get-chat-id.sh +64 -0
  95. package/scripts/global-hooks.sh +39 -0
  96. package/scripts/install.sh +831 -0
  97. package/scripts/start-daemon.sh +49 -0
  98. package/scripts/telegram-hook.sh +449 -0
  99. package/scripts/uninstall.sh +261 -0
@@ -0,0 +1,433 @@
1
+ #!/bin/bash
2
+ #
3
+ # Claude Telegram Mirror - Diagnostic Script
4
+ #
5
+ # Usage:
6
+ # ./scripts/doctor.sh
7
+ # ctm doctor (if installed)
8
+ #
9
+ # Checks system health and helps troubleshoot issues.
10
+ #
11
+
12
+ # Colors (respect NO_COLOR)
13
+ if [[ -z "$NO_COLOR" ]]; then
14
+ GREEN='\033[0;32m'
15
+ RED='\033[0;31m'
16
+ YELLOW='\033[1;33m'
17
+ BLUE='\033[0;34m'
18
+ BOLD='\033[1m'
19
+ NC='\033[0m'
20
+ else
21
+ GREEN=''
22
+ RED=''
23
+ YELLOW=''
24
+ BLUE=''
25
+ BOLD=''
26
+ NC=''
27
+ fi
28
+
29
+ # Output helpers
30
+ ok() { echo -e " ${GREEN}✓${NC} $1"; }
31
+ fail() { echo -e " ${RED}✗${NC} $1"; ERRORS=$((ERRORS + 1)); }
32
+ warn() { echo -e " ${YELLOW}⚠${NC} $1"; WARNINGS=$((WARNINGS + 1)); }
33
+ info() { echo -e " ${BLUE}ℹ${NC} $1"; }
34
+
35
+ # Counters
36
+ ERRORS=0
37
+ WARNINGS=0
38
+
39
+ # Configuration paths
40
+ CONFIG_DIR="$HOME/.config/claude-telegram-mirror"
41
+ ENV_FILE="$HOME/.telegram-env"
42
+ INSTALL_DIR="${TELEGRAM_MIRROR_INSTALL_DIR:-$HOME/.local/share/claude-telegram-mirror}"
43
+ SOCKET_PATH="$CONFIG_DIR/bridge.sock"
44
+ DB_PATH="$CONFIG_DIR/sessions.db"
45
+ LOG_FILE="$CONFIG_DIR/hook-debug.log"
46
+
47
+ # ============================================
48
+ # HEADER
49
+ # ============================================
50
+
51
+ echo ""
52
+ echo -e "${BOLD}Claude Telegram Mirror - Diagnostic Report${NC}"
53
+ echo "==========================================="
54
+ echo "Generated: $(date)"
55
+ echo "Platform: $(uname -s) $(uname -m)"
56
+ echo "User: $USER"
57
+ echo ""
58
+
59
+ # ============================================
60
+ # 1. PREREQUISITES
61
+ # ============================================
62
+
63
+ echo -e "${BOLD}Prerequisites:${NC}"
64
+
65
+ check_cmd() {
66
+ local cmd="$1"
67
+ local min_version="${2:-}"
68
+
69
+ if command -v "$cmd" &>/dev/null; then
70
+ local ver=$("$cmd" --version 2>&1 | head -1 | grep -oE '[0-9]+\.[0-9]+(\.[0-9]+)?' | head -1)
71
+ ok "$cmd ($ver)"
72
+ return 0
73
+ else
74
+ fail "$cmd: NOT FOUND"
75
+ return 1
76
+ fi
77
+ }
78
+
79
+ check_cmd node
80
+ check_cmd npm
81
+ check_cmd git
82
+ check_cmd tmux
83
+ check_cmd jq
84
+ check_cmd nc
85
+ check_cmd curl
86
+
87
+ # Node version check
88
+ NODE_VER=$(node -v 2>/dev/null | cut -d'v' -f2 | cut -d'.' -f1)
89
+ if [[ -n "$NODE_VER" && "$NODE_VER" -lt 18 ]]; then
90
+ warn "Node.js 18+ required (found v$NODE_VER)"
91
+ fi
92
+
93
+ echo ""
94
+
95
+ # ============================================
96
+ # 2. CONFIGURATION
97
+ # ============================================
98
+
99
+ echo -e "${BOLD}Configuration:${NC}"
100
+
101
+ if [[ -f "$ENV_FILE" ]]; then
102
+ ok "~/.telegram-env exists"
103
+ source "$ENV_FILE"
104
+
105
+ if [[ -n "$TELEGRAM_BOT_TOKEN" ]]; then
106
+ # Show first 10 chars only (security)
107
+ ok "TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN:0:10}..."
108
+ else
109
+ fail "TELEGRAM_BOT_TOKEN: NOT SET"
110
+ fi
111
+
112
+ if [[ -n "$TELEGRAM_CHAT_ID" ]]; then
113
+ ok "TELEGRAM_CHAT_ID: $TELEGRAM_CHAT_ID"
114
+ if [[ ! "$TELEGRAM_CHAT_ID" =~ ^-100 ]]; then
115
+ warn "Chat ID should start with -100 for supergroups"
116
+ fi
117
+ else
118
+ fail "TELEGRAM_CHAT_ID: NOT SET"
119
+ fi
120
+
121
+ info "TELEGRAM_MIRROR: ${TELEGRAM_MIRROR:-false}"
122
+ else
123
+ fail "~/.telegram-env: NOT FOUND"
124
+ info "Run installer or create manually"
125
+ fi
126
+
127
+ echo ""
128
+
129
+ # ============================================
130
+ # 3. INSTALLATION
131
+ # ============================================
132
+
133
+ echo -e "${BOLD}Installation:${NC}"
134
+
135
+ # Check common install locations
136
+ FOUND_INSTALL=""
137
+ for check_dir in "$INSTALL_DIR" "/opt/claude-mobile/packages/claude-telegram-mirror" "$HOME/.local/share/claude-telegram-mirror"; do
138
+ if [[ -d "$check_dir" && -f "$check_dir/package.json" ]]; then
139
+ FOUND_INSTALL="$check_dir"
140
+ break
141
+ fi
142
+ done
143
+
144
+ if [[ -n "$FOUND_INSTALL" ]]; then
145
+ ok "Install dir: $FOUND_INSTALL"
146
+ INSTALL_DIR="$FOUND_INSTALL"
147
+
148
+ if [[ -f "$INSTALL_DIR/dist/cli.js" ]]; then
149
+ ok "CLI built (dist/cli.js)"
150
+ else
151
+ fail "CLI not built - run: npm run build"
152
+ fi
153
+
154
+ if [[ -f "$INSTALL_DIR/package.json" ]]; then
155
+ ver=$(jq -r '.version' "$INSTALL_DIR/package.json" 2>/dev/null || echo "unknown")
156
+ info "Version: $ver"
157
+ fi
158
+
159
+ # Check if node_modules exists
160
+ if [[ -d "$INSTALL_DIR/node_modules" ]]; then
161
+ ok "Dependencies installed"
162
+ else
163
+ fail "Dependencies missing - run: npm install"
164
+ fi
165
+ else
166
+ fail "Not installed (checked $INSTALL_DIR)"
167
+ fi
168
+
169
+ # Check ctm symlink
170
+ if command -v ctm &>/dev/null; then
171
+ ok "ctm command available"
172
+ else
173
+ warn "ctm command not in PATH"
174
+ info "Add ~/.local/bin to PATH or use: node $INSTALL_DIR/dist/cli.js"
175
+ fi
176
+
177
+ echo ""
178
+
179
+ # ============================================
180
+ # 4. HOOKS
181
+ # ============================================
182
+
183
+ echo -e "${BOLD}Hooks:${NC}"
184
+
185
+ SETTINGS="$HOME/.claude/settings.json"
186
+
187
+ if [[ -f "$SETTINGS" ]]; then
188
+ ok "~/.claude/settings.json exists"
189
+
190
+ if grep -q "telegram-hook" "$SETTINGS"; then
191
+ ok "Telegram hooks configured"
192
+
193
+ # Extract and check hook script path
194
+ HOOK_PATH=$(grep -o '/[^"]*telegram-hook[^"]*' "$SETTINGS" | head -1)
195
+ if [[ -n "$HOOK_PATH" ]]; then
196
+ if [[ -f "$HOOK_PATH" ]]; then
197
+ ok "Hook script exists: $HOOK_PATH"
198
+ if [[ -x "$HOOK_PATH" ]]; then
199
+ ok "Hook script is executable"
200
+ else
201
+ fail "Hook script not executable"
202
+ info "Fix: chmod +x $HOOK_PATH"
203
+ fi
204
+ else
205
+ fail "Hook script missing: $HOOK_PATH"
206
+ fi
207
+ fi
208
+
209
+ # Check which hooks are registered
210
+ for hook in PreToolUse PostToolUse Notification Stop UserPromptSubmit PreCompact; do
211
+ if grep -q "\"$hook\"" "$SETTINGS"; then
212
+ ok "$hook hook registered"
213
+ fi
214
+ done
215
+ else
216
+ fail "Telegram hooks not configured"
217
+ info "Run: ctm install-hooks"
218
+ fi
219
+ else
220
+ warn "No ~/.claude/settings.json found"
221
+ info "Claude Code creates this on first run"
222
+ fi
223
+
224
+ # Check for project-level hooks that might override
225
+ if [[ -n "$PWD" && -f "$PWD/.claude/settings.json" ]]; then
226
+ warn "Project-level settings found in $PWD/.claude/"
227
+ if grep -q "telegram-hook" "$PWD/.claude/settings.json"; then
228
+ ok "Project hooks include telegram-hook"
229
+ else
230
+ warn "Project hooks do NOT include telegram-hook!"
231
+ info "Run: ctm install-hooks --project (from project directory)"
232
+ fi
233
+ fi
234
+
235
+ echo ""
236
+
237
+ # ============================================
238
+ # 5. SERVICE STATUS
239
+ # ============================================
240
+
241
+ echo -e "${BOLD}Service:${NC}"
242
+
243
+ if [[ "$(uname -s)" == "Linux" ]]; then
244
+ if systemctl --user is-active claude-telegram-mirror &>/dev/null; then
245
+ ok "systemd service: RUNNING"
246
+
247
+ # Get PID
248
+ pid=$(systemctl --user show claude-telegram-mirror --property=MainPID --value 2>/dev/null)
249
+ if [[ -n "$pid" && "$pid" != "0" ]]; then
250
+ info "PID: $pid"
251
+ fi
252
+ elif systemctl --user is-enabled claude-telegram-mirror &>/dev/null; then
253
+ warn "systemd service: ENABLED but NOT RUNNING"
254
+ info "Start with: systemctl --user start claude-telegram-mirror"
255
+ else
256
+ info "systemd service: NOT INSTALLED"
257
+ info "Install with: ctm service install"
258
+ fi
259
+
260
+ # Check linger (required for user services to run after logout)
261
+ if loginctl show-user "$USER" 2>/dev/null | grep -q "Linger=yes"; then
262
+ ok "loginctl linger: ENABLED"
263
+ else
264
+ warn "loginctl linger: DISABLED"
265
+ info "Service won't run when logged out"
266
+ info "Enable with: loginctl enable-linger $USER"
267
+ fi
268
+
269
+ elif [[ "$(uname -s)" == "Darwin" ]]; then
270
+ if launchctl list 2>/dev/null | grep -q "claude-telegram-mirror"; then
271
+ ok "launchd agent: LOADED"
272
+ else
273
+ info "launchd agent: NOT LOADED"
274
+ info "Install with: ctm service install"
275
+ fi
276
+
277
+ # Check for log files
278
+ if ls ~/Library/Logs/claude-telegram-mirror.*.log &>/dev/null; then
279
+ ok "Log files exist in ~/Library/Logs/"
280
+ fi
281
+ fi
282
+
283
+ echo ""
284
+
285
+ # ============================================
286
+ # 6. RUNTIME STATUS
287
+ # ============================================
288
+
289
+ echo -e "${BOLD}Runtime:${NC}"
290
+
291
+ # Check socket
292
+ if [[ -S "$SOCKET_PATH" ]]; then
293
+ ok "Bridge socket: EXISTS"
294
+ info "Daemon is running"
295
+ else
296
+ info "Bridge socket: NOT PRESENT"
297
+ info "Daemon is not running (start with: ctm start)"
298
+ fi
299
+
300
+ # Check PID file
301
+ PID_FILE="$CONFIG_DIR/daemon.pid"
302
+ if [[ -f "$PID_FILE" ]]; then
303
+ daemon_pid=$(cat "$PID_FILE")
304
+ if kill -0 "$daemon_pid" 2>/dev/null; then
305
+ ok "Daemon process: RUNNING (PID $daemon_pid)"
306
+ else
307
+ warn "Stale PID file (process $daemon_pid not running)"
308
+ fi
309
+ fi
310
+
311
+ # Check sessions database
312
+ if [[ -f "$DB_PATH" ]]; then
313
+ if command -v sqlite3 &>/dev/null; then
314
+ active_sessions=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions WHERE status='active'" 2>/dev/null || echo "?")
315
+ total_sessions=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sessions" 2>/dev/null || echo "?")
316
+ ok "Sessions DB: $active_sessions active / $total_sessions total"
317
+ else
318
+ ok "Sessions DB: EXISTS"
319
+ info "(install sqlite3 for details)"
320
+ fi
321
+ else
322
+ info "Sessions DB: NOT CREATED YET"
323
+ fi
324
+
325
+ # Check tmux sessions
326
+ if command -v tmux &>/dev/null; then
327
+ tmux_sessions=$(tmux list-sessions 2>/dev/null | wc -l)
328
+ if [[ $tmux_sessions -gt 0 ]]; then
329
+ ok "tmux sessions: $tmux_sessions active"
330
+ else
331
+ info "tmux sessions: NONE"
332
+ fi
333
+ fi
334
+
335
+ echo ""
336
+
337
+ # ============================================
338
+ # 7. TELEGRAM API CONNECTIVITY
339
+ # ============================================
340
+
341
+ echo -e "${BOLD}Telegram API:${NC}"
342
+
343
+ if [[ -n "$TELEGRAM_BOT_TOKEN" ]]; then
344
+ RESP=$(curl -s --max-time 5 "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe")
345
+
346
+ if echo "$RESP" | jq -e '.ok == true' &>/dev/null; then
347
+ BOT_USER=$(echo "$RESP" | jq -r '.result.username')
348
+ ok "Bot connected: @$BOT_USER"
349
+
350
+ # Test posting permission (if chat ID is set)
351
+ if [[ -n "$TELEGRAM_CHAT_ID" ]]; then
352
+ # Just check if we can get chat info (doesn't spam the chat)
353
+ CHAT_RESP=$(curl -s --max-time 5 "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getChat?chat_id=${TELEGRAM_CHAT_ID}")
354
+
355
+ if echo "$CHAT_RESP" | jq -e '.ok == true' &>/dev/null; then
356
+ CHAT_TITLE=$(echo "$CHAT_RESP" | jq -r '.result.title // "Private chat"')
357
+ ok "Chat accessible: $CHAT_TITLE"
358
+ else
359
+ CHAT_ERR=$(echo "$CHAT_RESP" | jq -r '.description // "Unknown error"')
360
+ fail "Chat error: $CHAT_ERR"
361
+ info "Make sure bot is added to the group"
362
+ fi
363
+ fi
364
+ else
365
+ ERR=$(echo "$RESP" | jq -r '.description // "Connection failed"')
366
+ fail "API Error: $ERR"
367
+
368
+ if [[ "$ERR" == *"Unauthorized"* ]]; then
369
+ info "Token may be invalid - check TELEGRAM_BOT_TOKEN"
370
+ fi
371
+ fi
372
+ else
373
+ warn "Cannot test (no token configured)"
374
+ fi
375
+
376
+ echo ""
377
+
378
+ # ============================================
379
+ # 8. RECENT LOGS
380
+ # ============================================
381
+
382
+ echo -e "${BOLD}Recent Logs:${NC}"
383
+
384
+ if [[ -f "$LOG_FILE" ]]; then
385
+ log_size=$(wc -l < "$LOG_FILE" 2>/dev/null || echo 0)
386
+ info "Hook debug log: $log_size lines"
387
+ echo " (last 5 entries):"
388
+ tail -5 "$LOG_FILE" 2>/dev/null | sed 's/^/ /'
389
+ else
390
+ info "No hook debug log"
391
+ info "Enable with: export TELEGRAM_HOOK_DEBUG=1"
392
+ fi
393
+
394
+ echo ""
395
+
396
+ # Service logs
397
+ if [[ "$(uname -s)" == "Linux" ]]; then
398
+ if systemctl --user is-active claude-telegram-mirror &>/dev/null; then
399
+ echo " (last 5 journal entries):"
400
+ journalctl --user -u claude-telegram-mirror -n 5 --no-pager 2>/dev/null | sed 's/^/ /'
401
+ echo ""
402
+ fi
403
+ elif [[ "$(uname -s)" == "Darwin" ]]; then
404
+ latest_log=$(ls -t ~/Library/Logs/claude-telegram-mirror.*.log 2>/dev/null | head -1)
405
+ if [[ -n "$latest_log" ]]; then
406
+ echo " (last 5 lines from $latest_log):"
407
+ tail -5 "$latest_log" 2>/dev/null | sed 's/^/ /'
408
+ echo ""
409
+ fi
410
+ fi
411
+
412
+ # ============================================
413
+ # 9. SUMMARY
414
+ # ============================================
415
+
416
+ echo "==========================================="
417
+
418
+ if [[ $ERRORS -eq 0 && $WARNINGS -eq 0 ]]; then
419
+ echo -e "${GREEN}All checks passed!${NC}"
420
+ elif [[ $ERRORS -eq 0 ]]; then
421
+ echo -e "${YELLOW}$WARNINGS warning(s), no errors${NC}"
422
+ else
423
+ echo -e "${RED}$ERRORS error(s), $WARNINGS warning(s)${NC}"
424
+ fi
425
+
426
+ echo ""
427
+ echo "Commands:"
428
+ echo " ctm status # Daemon status"
429
+ echo " ctm service status # Service status"
430
+ echo " ctm config --test # Test Telegram connection"
431
+ echo ""
432
+
433
+ exit $ERRORS
@@ -0,0 +1,64 @@
1
+ #!/bin/bash
2
+ # Get Telegram Chat ID helper
3
+ # Usage: ./get-chat-id.sh [BOT_TOKEN]
4
+
5
+ set -e
6
+
7
+ # Get token from argument or environment
8
+ TOKEN="${1:-$TELEGRAM_BOT_TOKEN}"
9
+
10
+ if [[ -z "$TOKEN" ]]; then
11
+ echo "Usage: $0 <BOT_TOKEN>"
12
+ echo " or: export TELEGRAM_BOT_TOKEN=... && $0"
13
+ exit 1
14
+ fi
15
+
16
+ echo "Fetching updates from Telegram API..."
17
+ echo ""
18
+
19
+ # Call getUpdates
20
+ RESPONSE=$(curl -s "https://api.telegram.org/bot${TOKEN}/getUpdates")
21
+
22
+ # Check if valid response
23
+ if echo "$RESPONSE" | grep -q '"ok":false'; then
24
+ ERROR=$(echo "$RESPONSE" | grep -o '"description":"[^"]*"' | cut -d'"' -f4)
25
+ echo "Error: $ERROR"
26
+ echo ""
27
+ echo "Make sure your bot token is correct."
28
+ exit 1
29
+ fi
30
+
31
+ # Extract unique chat IDs
32
+ CHAT_IDS=$(echo "$RESPONSE" | grep -o '"chat":{"id":-\?[0-9]*' | grep -o '\-\?[0-9]*' | sort -u)
33
+
34
+ if [[ -z "$CHAT_IDS" ]]; then
35
+ echo "No messages found yet."
36
+ echo ""
37
+ echo "To get your chat ID:"
38
+ echo " 1. Add your bot to a group (or start a chat with it)"
39
+ echo " 2. Send any message in that chat"
40
+ echo " 3. Run this script again"
41
+ echo ""
42
+ echo "Tip: For supergroups with Topics, the ID starts with -100"
43
+ exit 0
44
+ fi
45
+
46
+ echo "Found chat IDs:"
47
+ echo ""
48
+
49
+ for ID in $CHAT_IDS; do
50
+ # Determine chat type based on ID format
51
+ if [[ "$ID" =~ ^-100 ]]; then
52
+ TYPE="supergroup"
53
+ elif [[ "$ID" =~ ^- ]]; then
54
+ TYPE="group"
55
+ else
56
+ TYPE="private chat"
57
+ fi
58
+
59
+ echo " $ID ($TYPE)"
60
+ done
61
+
62
+ echo ""
63
+ echo "Add to ~/.telegram-env:"
64
+ echo " export TELEGRAM_CHAT_ID=\"$( echo "$CHAT_IDS" | head -1 )\""
@@ -0,0 +1,39 @@
1
+ #!/bin/bash
2
+ #
3
+ # Global Claude Code Hooks Runner
4
+ #
5
+ # This script runs all global hooks and should be called from project-level settings.
6
+ # It reads stdin (hook JSON) and passes it to each global hook.
7
+ #
8
+ # Usage in project .claude/settings.json:
9
+ # "hooks": {
10
+ # "UserPromptSubmit": [
11
+ # { "type": "command", "command": "~/.claude/global-hooks.sh" }
12
+ # ]
13
+ # }
14
+ #
15
+
16
+ set -e
17
+
18
+ # Get script directory
19
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
+
21
+ # Read stdin once and store it
22
+ INPUT=$(cat)
23
+
24
+ # Global hooks to run (add more as needed)
25
+ GLOBAL_HOOKS=(
26
+ "/opt/claude-telegram-mirror/scripts/telegram-hook.sh"
27
+ # Add more global hooks here:
28
+ # "/path/to/another-hook.sh"
29
+ )
30
+
31
+ # Run each global hook, passing the same input
32
+ for hook in "${GLOBAL_HOOKS[@]}"; do
33
+ if [[ -x "$hook" ]]; then
34
+ echo "$INPUT" | "$hook" 2>/dev/null || true
35
+ fi
36
+ done
37
+
38
+ # Pass through the original input for downstream processing
39
+ echo "$INPUT"