# Telegram 抓消息说明

> **用途**：在 notiMessage 中抓取 Telegram 消息（前台 + 后台），转发到 App 本地日志与 PC 调试台。  
> **关联**：[`Hook指南.md`](Hook指南.md)（通用架构、Xposed/LSPosed）· [`手机操作手册.md`](手机操作手册.md) · [`更新说明.md`](更新说明.md)

---

## 1. 能力概览

| 场景 | 通道 | 是否需要 Root / LSPosed | 日志标识 |
|------|------|-------------------------|----------|
| TG **后台** / 锁屏，系统弹出通知 | 通知监听 `NotificationService` | ❌ 不需要（仅需通知使用权） | 无前缀 |
| TG **前台** 打开聊天（通常无系统通知） | Xposed `TelegramMessageHook` | ✅ 需要 Magisk + LSPosed + 模块 | `[Hook/xposed_telegram]` |

**重要**：只开通知监听、不装 Xposed 时，**TG 在前台收消息抓不到**。要完整覆盖，必须启用 Hook 模块。

---

## 2. 必须安装什么

### 2.1 完整能力（前台 + 后台）

| 序号 | 组件 | 说明 |
|------|------|------|
| 1 | **Telegram** | 包名见 §3 |
| 2 | **notiMessage 主 App** | `com.miraclegarden.smsmessage` |
| 3 | **Xposed 模块 APK** | `com.miraclegarden.smsmessage.xposed`（与主 App 同仓库 `:xposed-module`） |
| 4 | **Magisk + Zygisk** | Root 环境 |
| 5 | **LSPosed** | 加载 Xposed 模块 |

抓 TG **不需要** Shamiko（那是 MariBank 等银行 App 用的）。

### 2.2 仅后台通知（不抓前台）

| 必须 | 不需要 |
|------|--------|
| notiMessage 主 App | Xposed 模块 |
| Telegram | LSPosed / Root |
| 通知监听权限 | |

### 2.3 PC 端（调试台，可选）

| 组件 | 用途 |
|------|------|
| 本仓库源码 + JDK + Android SDK | 编译安装 |
| **adb** | USB 安装、`adb reverse` |
| **Python 3** | `configure-lsposed.py`（`install-full.ps1` 用） |
| `debug-server/server.py` | PC 浏览器查看消息（端口 **8765**） |

---

## 3. 包名与 LSPosed 作用域

Pixel 6 等设备常见包名：

| 安装来源 | 包名 |
|----------|------|
| Play / 官网 APK | `org.telegram.messenger` |
| 部分渠道 / Web 版 | `org.telegram.messenger.web` |

**必须勾选与实际安装一致的包名**（两个都装则两个都勾）。

LSPosed 作用域需勾选：

1. **目标 Telegram 包名**（上表）
2. **notiMessage 主 App** `com.miraclegarden.smsmessage`（接收 Hook 广播、写日志）
3. 模块本身已在 LSPosed 里 **启用**

默认作用域见 `xposed-module/src/main/res/values/arrays.xml`。  
一键安装时 `scripts/configure-lsposed.py` 会写入上述包名。

**每次更新 Xposed 模块 APK 后**：LSPosed 里对 Telegram **软重启**（或整机重启），否则 Hook 不注入。

---

## 4. 安装与配置（推荐流程）

### 4.1 PC 一键安装

```powershell
cd C:\Users\Administrator\Desktop\notiMessage
.\scripts\install-full.ps1
```

自动完成：编译 → 安装双 APK → 写入 LSPosed 作用域 → `adb reverse` → 电池白名单 → 通知监听授权。

仅编译安装、不写作用域：

```powershell
.\scripts\build-debug.ps1
.\scripts\install-debug.ps1
```

> **注意**：Android Studio 直接 Run 只装主 App，**不会**装 Xposed 模块。完整 TG 抓取必须用 `install-full.ps1` 或手动装两个 APK。

### 4.2 手机上

1. **LSPosed** → 启用模块 **notiMessage Xposed** → 作用域勾选 Telegram + 主 App → **软重启 Telegram**
2. 打开 **notiMessage** → **监听设置** → 添加 **Telegram**（包名须与 LSPosed 一致）
3. 回到 **监听控制台** → **开始监听** → 授予通知使用权
4. （可选）设置 → 给 Telegram / notiMessage **电池不受限制**

### 4.3 PC 调试台

```powershell
.\scripts\start-debug-server.ps1
```

浏览器打开 **http://127.0.0.1:8765**，按群/会话分组展示。  
脚本会自动执行 `adb reverse tcp:8765 tcp:8765`。

### 4.4 验证

1. 启动调试台（可选）
2. notiMessage 开始监听后 **切到桌面**
3. 打开 Telegram，在任意群/私聊 **收一条别人发的消息**（前台场景）
4. 期望：
   - App 监听页出现 `[Hook/xposed_telegram] 群名 发送者: 内容`
   - PC 调试台同内容
5. 再把 TG 切后台，收一条 **会弹系统通知** 的消息 → 走通知通道（无前缀）

---

## 5. 双通道架构

```
                    Telegram
                        │
         ┌──────────────┴──────────────┐
         │                             │
   后台弹系统通知                  前台收到新消息
         │                             │
         ▼                             ▼
 NotificationService          TelegramMessageHook
 (NotificationListener)       (xposed-module 进程内)
         │                             │
         │                             │ 广播 HOOK_MESSAGE
         │                             ▼
         │                    HookMessageReceiver
         │                      ├─ MessageLogStore
         │                      ├─ DebugForwarder → PC :8765
         │                      └─ （可选）正式后端上传
         └──────────────┬──────────────┘
                        ▼
                 监听页 / PC 调试台
```

| 配置项 | 文件 | 默认值 |
|--------|------|--------|
| PC 转发开关 | `AppConfig.ENABLE_DEBUG_FORWARD` | `true` |
| 调试台地址 | `AppConfig.DEBUG_SERVER_URL` | `http://127.0.0.1:8765` |
| 正式后端上传 | `AppConfig.ENABLE_SERVER_UPLOAD` | `false` |

Hook 广播格式：

```text
Action: com.miraclegarden.smsmessage.action.HOOK_MESSAGE
Package: com.miraclegarden.smsmessage
Extras: packageName, title, content, timestamp, source=xposed_telegram
```

`HookMessageReceiver` 会检查 Telegram 是否在 **监听列表**；未添加则日志 `[Hook] 未配置监听: org.telegram...` 并丢弃。

---

## 6. 实现原理（TelegramMessageHook）

源码：`xposed-module/src/main/java/.../hook/TelegramMessageHook.java`

### 6.1 为何不 Hook SQLite？

Telegram 消息存在 SQLite 的 **`data` 字段（TL 二进制序列化）**，不是明文 `content`/`text`。  
通用 `SqliteMessageHook` **对 Telegram 无效**，因此单独实现本 Hook。

### 6.2 Hook 路径（三条，互为补充）

| 优先级 | Hook 点 | 触发时机 |
|--------|---------|----------|
| **主路径** | `NotificationCenter.postNotificationName(int, Object[])`，当 `id == didReceiveNewMessages` | 前台收到新消息、消息已解密为 `MessageObject` |
| **通知路径** | `NotificationsController.appendMessage(MessageObject)` | 后台准备弹系统通知时 |
| **兜底** | `MessageObject` 全部构造函数 | 主路径安装失败时 |

### 6.3 过滤与去重

- 只处理 **非 outgoing**（`messageOwner.out == false`），忽略自己发出的消息
- 去重键：`dialogId:messageId`，内存保留最近 512 条

### 6.4 字段提取

| 字段 | 提取方式 | 展示 |
|------|----------|------|
| **群名/会话名** | `MessagesController.getPeerTitle(dialogId)` → `getName()` → `getChat().title` | 广播 `title` |
| **发送者** | `MessageObject.getFromName()` | 群内：`发送者: 正文` |
| **正文** | `messageText` → `messageOwner.message` → `caption` | 广播 `content` |
| **媒体** | `isPhoto` / `isVideo` 等 → `[图片]`、`[视频]`… | 与 caption 合并 |

支持的媒体标签：`[图片]`、`[视频]`、`[GIF]`、`[贴纸]`、`[语音]`、`[音频]`、`[文件]`、`[位置]`、`[联系人]`、`[媒体消息]`。

**注意**：不要把 `TLRPC$...` 对象直接 `toString()` 当标题；代码里 `safeText()` 会过滤这类字符串。

---

## 7. 常见问题

| 现象 | 原因 | 处理 |
|------|------|------|
| 前台有消息，无 `[Hook/...]` | Hook 未注入 | LSPosed 启用模块；作用域勾 **实际 TG 包名**；**软重启 TG** |
| 日志 `[Hook] 未配置监听` | 监听列表未加 Telegram | 监听设置里添加对应包名 |
| 只有后台有、前台没有 | 未装 Xposed / 作用域错误 | 安装 xposed 模块 + `install-full.ps1` |
| PC 无数据 | `adb reverse` 未设或调试台未开 | 跑 `start-debug-server.ps1` |
| notiMessage 切后台后 PC 断 | 旧版依赖 startService | 更新到 v2.2.1+，`HookMessageReceiver` 内直接转发 |
| 标题显示 `TLRPC$...` | 旧版或异常路径 | 更新模块；见 `TelegramMessageHook.extractTitle` |
| 图片只有「图片」无说明 | 说明在 caption | 已合并 caption；仍空则 TG 未带说明 |
| 群静音 / 无通知 | 后台通道无触发 | 前台靠 Hook；后台需 TG 允许通知且未静音 |
| TG 被系统冻结 | 省电策略 | TG、notiMessage 设「不受限制」 |
| logcat 无 `notiMessageHook/Telegram` | Hook 未加载 | 查 LSPosed 日志；确认包名是否为 `.web` 版 |

---

## 8. 诊断 logcat

```powershell
$adb = "$env:LOCALAPPDATA\Android\Sdk\platform-tools\adb.exe"

# Hook 是否安装
& $adb logcat -d | Select-String "notiMessageHook/Telegram"

# 主 App 是否收到广播
& $adb logcat -d | Select-String "HookMessageReceiver|DebugForwarder"

# 通知通道
& $adb logcat -d | Select-String "NotificationService"
```

期望看到：

```text
notiMessageHook/Telegram: installed for org.telegram.messenger.web, didReceiveNewMessages=...
notiMessageHook/Telegram: appendMessage hook installed for ...
HookMessageReceiver: hook received: pkg=org.telegram.messenger.web source=xposed_telegram title=...
```

---

## 9. 与 MariBank 模块的关系

本仓库 **同一个 Xposed APK** 里还包含 MariBank bypass、澳银 Hook 等；**Telegram 抓消息与银行 bypass 互不依赖**：

| 能力 | 是否需要 Telegram Hook | 是否需要 MariBank Hook |
|------|------------------------|------------------------|
| 抓 TG 消息 | ✅ | ❌ |
| MariBank 注册 bypass | ❌ | ✅ |

LSPosed 作用域可以 **只勾 Telegram + 主 App**，不勾银行包名。

详见 [`Hook指南.md`](Hook指南.md) 中「模块与通知管理的关系」说明。

---

## 10. 相关文件

```text
xposed-module/
├── src/main/assets/xposed_init
├── src/main/java/.../MainHook.java              # 路由到 TelegramMessageHook
├── src/main/java/.../HookForwarder.java
├── src/main/java/.../hook/TelegramMessageHook.java
└── src/main/res/values/arrays.xml               # 默认 xposed_scope

app/
├── src/main/java/.../service/HookMessageReceiver.java
├── src/main/java/.../service/NotificationService.java
├── src/main/java/.../MessageLogStore.java
├── src/main/java/.../network/DebugForwarder.java
└── src/main/java/.../AppConfig.java

debug-server/server.py
scripts/install-full.ps1
scripts/start-debug-server.ps1
```

---

## 11. 最短路径速查

```text
PC:   install-full.ps1 → start-debug-server.ps1
手机: LSPosed 启用模块 → 勾 Telegram + 主 App → 软重启 TG
App:  监听设置添加 Telegram → 开始监听
验证: TG 前台收消息 → 出现 [Hook/xposed_telegram]
```

---

*最后更新：2026-07-06*
