@lansenger-pm/openclaw-lansenger-channel 3.2.2 → 3.2.4

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.
package/README.fr.md CHANGED
@@ -33,41 +33,43 @@ Connecte OpenClaw à Lansenger — une plateforme de messagerie d'entreprise —
33
33
 
34
34
  **Stratégie par défaut** : utiliser `formatText` en priorité pour les réponses Markdown. Revenir à `text` pour les pièces jointes. Les deux types supportent @mention via le paramètre `reminder` — inclure « @姓名 » dans le texte pour les mentions.
35
35
 
36
- ## Outils de l'agent
37
-
38
- | Outil | Description |
39
- |-------|-------------|
40
- | `lansenger_send_text` | Envoyer un message text ou formatText (Markdown par défaut) |
41
- | `lansenger_send_file` | Envoyer fichier/image/vidéo/audio (workspace ou chemin externe) |
42
- | `lansenger_send_image_url` | Envoyer une image par URL |
43
- | `lansenger_send_link_card` | Envoyer une carte de prévisualisation de lien |
44
- | `lansenger_send_app_card` | Envoyer une carte interactive/approbation |
45
- | `lansenger_send_app_articles` | Envoyer une carte multi-articles |
46
- | `lansenger_update_dynamic_card` | Mettre à jour le statut d'une carte dynamique |
47
- | `lansenger_revoke_message` | Révoquer un message précédemment envoyé |
48
- | `lansenger_query_groups` | Interroger les groupes disponibles |
36
+ ## Outils de l'agent & CLI
37
+
38
+ Les messages peuvent être envoyés via les **outils de l'agent**, les **commandes CLI**, ou les deux :
39
+
40
+ | Méthode | Installation | Utilisation |
41
+ |---------|-------------|-------------|
42
+ | Outils agent | `openclaw plugins install @lansenger-pm/openclaw-lansenger-tools` | `lansenger_send_file`, `lansenger_send_text`, etc. |
43
+ | Commandes CLI | `pip install lansenger-cli` | `lansenger message send-file`, `lansenger message send-text`, etc. |
44
+
45
+ > ⚠️ **Les outils agent nécessitent le plugin `lansenger-tools`** installation séparée. Les commandes CLI nécessitent `lansenger-cli` (Python). Sans aucun des deux, seules les réponses Markdown normales fonctionnent.
49
46
 
50
47
  ## Installation et Configuration
51
48
 
52
- ### Flux recommandé en 4 étapes
49
+ ### Installation recommandée
53
50
 
54
51
  ```bash
55
- # 1. Installer le plugin
52
+ # 1. Installer le plugin de canal
56
53
  openclaw plugins install @lansenger-pm/openclaw-lansenger-channel
57
54
 
58
- # 2. Activer le plugin (si non auto-activé)
55
+ # 2. Installer le plugin outils OU le CLI (au moins un est nécessaire pour les messages)
56
+ # Option A : Plugin outils agent OpenClaw
57
+ openclaw plugins install @lansenger-pm/openclaw-lansenger-tools
58
+ # Option B : CLI Python (fonctionne via bash)
59
+ pip install lansenger-cli
60
+
61
+ # 3. Activer les plugins (si non auto-activés)
59
62
  openclaw config set plugins.entries.lansenger.enabled true
63
+ openclaw config set plugins.entries.lansenger-tools.enabled true # si Option A
60
64
 
61
- # 3. Configurer le canal (assistant interactif)
65
+ # 4. Configurer le canal (assistant interactif)
62
66
  openclaw channels add
63
- # OU ajout rapide (crée une config vide, puis lancez l'assistant ci-dessus) :
64
- # openclaw channels add --channel lansenger
65
67
 
66
- # 4. Redémarrer la passerelle
68
+ # 5. Redémarrer la passerelle
67
69
  openclaw gateway restart
68
70
  ```
69
71
 
70
- Les métadonnées `openclaw.install` dans `package.json` (`npmSpec`, `localPath`, `defaultChoice`) permettent l'**installation à la demande** : si un utilisateur sélectionne Lansenger dans l'assistant `openclaw channels add` avant que le plugin soit installé, OpenClaw peut l'installer automatiquement.
72
+ Les `peerDependencies` de `package.json` avertiront lors de npm install si le plugin tools est absent. L'assistant de configuration vous rappelle également de l'installer.
71
73
 
72
74
  > **Passerelle personnalisée** : pour les déploiements entreprise (ex. 奇安信), configurez `apiGatewayUrl` dans `openclaw.json` ou via les variables d'environnement après la configuration — voir [Configuration optionnelle](#configuration-optionnelle).
73
75
 
@@ -303,6 +305,7 @@ Le plugin supporte les cartes d'approbation :
303
305
  - **reminder** — champ optionnel dans formatText ; recommandé dans les chats de groupe. Inclure « @姓名 » dans le texte pour les mentions.
304
306
  - **Média** — les balises `<media>` fonctionnent pour les fichiers du workspace ; pour les chemins externes, utilisez `lansenger_send_file`.
305
307
  - **openclaw skill/message lansenger** — ces commandes CLI n'existent PAS ; utilisez les outils de l'agent.
308
+ - **Plugin outils** — les outils agent (`lansenger_send_*`) nécessitent le plugin `@lansenger-pm/openclaw-lansenger-tools` installé séparément. Les commandes CLI (`lansenger message send-*`) nécessitent `pip install lansenger-cli`. Installez au moins l'un des deux.
306
309
 
307
310
  ## Développement
308
311
 
@@ -336,7 +339,7 @@ openclaw-lansenger-channel/
336
339
  │ └── runtime.ts # Runtime passerelle (méthodes, handler entrant)
337
340
  ├── skills/
338
341
  │ └── lansenger-messaging/
339
- │ └── SKILL.md # Stratégie de messagerie de l'agent
342
+ │ └── SKILL.md # Stratégie de messagerie (outils + CLI)
340
343
  ├── dist/ # JavaScript compilé
341
344
  ├── index.ts # Point d'entrée du plugin
342
345
  ├── setup-entry.ts # Point d'entrée de l'assistant de configuration
package/README.md CHANGED
@@ -31,7 +31,16 @@ Lansenger (蓝信) channel plugin for OpenClaw — WebSocket inbound, HTTP API o
31
31
 
32
32
  **Default strategy**: Use `formatText` first for Markdown replies. Fall back to `text` for attachments. Both `formatText` and `text` support @mention via `reminder` param — include "@姓名" in text content when mentioning.
33
33
 
34
- ## Agent Tools
34
+ ## Agent Tools & CLI
35
+
36
+ Messages can be sent via **agent tools**, **CLI commands**, or both:
37
+
38
+ | Method | How to install | Usage |
39
+ |--------|---------------|-------|
40
+ | Agent tools | `openclaw plugins install @lansenger-pm/openclaw-lansenger-tools` | `lansenger_send_file`, `lansenger_send_text`, etc. |
41
+ | CLI commands | `pip install lansenger-cli` | `lansenger message send-file`, `lansenger message send-text`, etc. |
42
+
43
+ > ⚠️ **Agent tools require the `lansenger-tools` plugin** — install separately. CLI commands require `lansenger-cli` (Python). Without either, only normal Markdown replies work.
35
44
 
36
45
  | Tool | Description |
37
46
  |------|-------------|
@@ -45,27 +54,34 @@ Lansenger (蓝信) channel plugin for OpenClaw — WebSocket inbound, HTTP API o
45
54
  | `lansenger_revoke_message` | Revoke a previously sent message |
46
55
  | `lansenger_query_groups` | Query available groups |
47
56
 
57
+ Tools are also available via CLI: `lansenger message send-text`, `lansenger message send-file`, etc.
58
+
48
59
  ## Installation & Configuration
49
60
 
50
- ### Recommended 4-step flow
61
+ ### Recommended setup
51
62
 
52
63
  ```bash
53
- # 1. Install the plugin
64
+ # 1. Install the channel plugin
54
65
  openclaw plugins install @lansenger-pm/openclaw-lansenger-channel
55
66
 
56
- # 2. Enable the plugin (if not auto-enabled)
67
+ # 2. Install the tools plugin OR the CLI (at least one is needed for messaging)
68
+ # Option A: OpenClaw agent tools plugin
69
+ openclaw plugins install @lansenger-pm/openclaw-lansenger-tools
70
+ # Option B: Python CLI (works via bash)
71
+ pip install lansenger-cli
72
+
73
+ # 3. Enable the plugins (if not auto-enabled)
57
74
  openclaw config set plugins.entries.lansenger.enabled true
75
+ openclaw config set plugins.entries.lansenger-tools.enabled true # if using Option A
58
76
 
59
- # 3. Configure the channel (interactive wizard)
77
+ # 4. Configure the channel (interactive wizard)
60
78
  openclaw channels add
61
- # OR quick add (creates empty config, then run wizard above):
62
- # openclaw channels add --channel lansenger
63
79
 
64
- # 4. Restart the gateway
80
+ # 5. Restart the gateway
65
81
  openclaw gateway restart
66
82
  ```
67
83
 
68
- The `openclaw.install` metadata in `package.json` (`npmSpec`, `localPath`, `defaultChoice`) enables **install-on-demand**: if a user selects Lansenger in the `openclaw channels add` wizard before the plugin is installed, OpenClaw can automatically install it using this metadata.
84
+ The `package.json` `peerDependencies` will warn during npm install if the tools plugin is missing. The setup wizard also reminds you to install it.
69
85
 
70
86
  > **Custom gateway**: For enterprise deployments (e.g. 奇安信), set `apiGatewayUrl` in `openclaw.json` or environment after configuration — see [Optional Configuration](#optional-configuration).
71
87
 
@@ -295,6 +311,7 @@ The plugin supports approval workflow cards:
295
311
  - **reminder** — optional in formatText; recommended in group chat. Include "@姓名" in text when mentioning.
296
312
  - **Media** — `<media>` tags work for workspace files; for external paths use `lansenger_send_file`.
297
313
  - **openclaw skill/message lansenger** — these CLI commands do NOT exist; use agent tools instead.
314
+ - **Tools plugin** — agent tools (`lansenger_send_*`) require `@lansenger-pm/openclaw-lansenger-tools` plugin installed separately. CLI commands (`lansenger message send-*`) require `pip install lansenger-cli`. Install at least one.
298
315
 
299
316
  ## Development
300
317
 
@@ -328,7 +345,7 @@ openclaw-lansenger-channel/
328
345
  │ └── runtime.ts # Gateway runtime (methods, inbound handler)
329
346
  ├── skills/
330
347
  │ └── lansenger-messaging/
331
- │ └── SKILL.md # Agent messaging strategy
348
+ │ └── SKILL.md # Agent messaging strategy (tools + CLI)
332
349
  ├── dist/ # Compiled JavaScript
333
350
  ├── index.ts # Plugin entry point
334
351
  ├── setup-entry.ts # Setup wizard entry
package/README.zhHans.md CHANGED
@@ -33,7 +33,16 @@
33
33
 
34
34
  **默认策略**:优先使用 `formatText` 发送 Markdown 回复。附件使用 `text` 回退。两种类型均支持 @mention(通过 `reminder` 参数)—提及用户时在文本中包含"@姓名"。
35
35
 
36
- ## 代理工具
36
+ ## 代理工具 & CLI
37
+
38
+ 消息可以通过**代理工具**、**CLI 命令**或两者发送:
39
+
40
+ | 方式 | 安装方法 | 使用 |
41
+ |------|----------|------|
42
+ | 代理工具 | `openclaw plugins install @lansenger-pm/openclaw-lansenger-tools` | `lansenger_send_file`、`lansenger_send_text` 等 |
43
+ | CLI 命令 | `pip install lansenger-cli` | `lansenger message send-file`、`lansenger message send-text` 等 |
44
+
45
+ > ⚠️ **代理工具需要 `lansenger-tools` 插件** — 需单独安装。CLI 命令需要 `lansenger-cli`(Python)。两者均未安装时,代理只能通过普通 Markdown 文本回复。
37
46
 
38
47
  | 工具 | 说明 |
39
48
  |------|------|
@@ -47,27 +56,34 @@
47
56
  | `lansenger_revoke_message` | 撤回已发送的消息 |
48
57
  | `lansenger_query_groups` | 查询可用群组 |
49
58
 
59
+ 工具也可通过 CLI 使用:`lansenger message send-text`、`lansenger message send-file` 等。
60
+
50
61
  ## 安装与配置
51
62
 
52
- ### 推荐 4 步流程
63
+ ### 推荐安装流程
53
64
 
54
65
  ```bash
55
- # 1. 安装插件
66
+ # 1. 安装频道插件
56
67
  openclaw plugins install @lansenger-pm/openclaw-lansenger-channel
57
68
 
58
- # 2. 启用插件(如未自动启用)
69
+ # 2. 安装工具插件或 CLI(至少需要一个来发送消息)
70
+ # 方案 A:OpenClaw 代理工具插件
71
+ openclaw plugins install @lansenger-pm/openclaw-lansenger-tools
72
+ # 方案 B:Python CLI(通过 bash 调用)
73
+ pip install lansenger-cli
74
+
75
+ # 3. 启用插件(如未自动启用)
59
76
  openclaw config set plugins.entries.lansenger.enabled true
77
+ openclaw config set plugins.entries.lansenger-tools.enabled true # 使用方案 A 时
60
78
 
61
- # 3. 配置频道(交互式向导)
79
+ # 4. 配置频道(交互式向导)
62
80
  openclaw channels add
63
- # 或者快速添加(创建空配置,再运行上面的向导):
64
- # openclaw channels add --channel lansenger
65
81
 
66
- # 4. 重启网关
82
+ # 5. 重启网关
67
83
  openclaw gateway restart
68
84
  ```
69
85
 
70
- `package.json` 中的 `openclaw.install` 元数据(`npmSpec`、`localPath`、`defaultChoice`)支持**按需安装**:如果用户在 `openclaw channels add` 向导中选择 Lansenger 但插件未安装,OpenClaw 可自动安装该插件。
86
+ `package.json` `peerDependencies` npm install 时会警告缺失 tools 插件。设置向导也会提醒安装。
71
87
 
72
88
  > **自定义网关**:企业私有化部署(如奇安信)需在配置后通过 `openclaw.json` 或环境变量设置 `apiGatewayUrl` — 见[可选配置](#可选配置)。
73
89
 
@@ -303,6 +319,7 @@ openclaw channels status --probe
303
319
  - **reminder** — formatText 中可选字段;群聊中建议使用。提及用户时在文本中包含"@姓名"。
304
320
  - **媒体标签** — `<media>` 标签适用于工作区文件;外部路径请使用 `lansenger_send_file`。
305
321
  - **openclaw skill/message lansenger** — 这些 CLI 命令不存在;请使用代理工具。
322
+ - **工具插件** — 代理工具(`lansenger_send_*`)需要单独安装 `@lansenger-pm/openclaw-lansenger-tools` 插件。CLI 命令(`lansenger message send-*`)需要 `pip install lansenger-cli`。至少安装其中一个。
306
323
 
307
324
  ## 开发
308
325
 
@@ -336,7 +353,7 @@ openclaw-lansenger-channel/
336
353
  │ └── runtime.ts # 网关运行时(方法、入站处理器)
337
354
  ├── skills/
338
355
  │ └── lansenger-messaging/
339
- │ └── SKILL.md # 代理消息策略
356
+ │ └── SKILL.md # 代理消息策略(工具 + CLI)
340
357
  ├── dist/ # 编译后的 JavaScript
341
358
  ├── index.ts # 插件入口
342
359
  ├── setup-entry.ts # 设置向导入口
package/README.zhHant.md CHANGED
@@ -33,41 +33,43 @@
33
33
 
34
34
  **預設策略**:優先使用 `formatText` 傳送 Markdown 回覆。附件使用 `text` 回退。兩種類型均支援 @mention(透過 `reminder` 參數)—提及使用者時在文字中包含「@姓名」。
35
35
 
36
- ## 代理工具
37
-
38
- | 工具 | 說明 |
39
- |------|------|
40
- | `lansenger_send_text` | 傳送文字或 formatText 訊息(預設 Markdown) |
41
- | `lansenger_send_file` | 傳送檔案/圖片/影片/語音(工作區或外部路徑) |
42
- | `lansenger_send_image_url` | 透過 URL 傳送圖片 |
43
- | `lansenger_send_link_card` | 傳送富連結預覽卡片 |
44
- | `lansenger_send_app_card` | 傳送互動/審批卡片 |
45
- | `lansenger_send_app_articles` | 傳送多文章卡片 |
46
- | `lansenger_update_dynamic_card` | 原地更新動態卡片狀態 |
47
- | `lansenger_revoke_message` | 撤回已傳送的訊息 |
48
- | `lansenger_query_groups` | 查詢可用群組 |
36
+ ## 代理工具 & CLI
37
+
38
+ 訊息可以透過**代理工具**、**CLI 命令**或兩者傳送:
39
+
40
+ | 方式 | 安裝方法 | 使用 |
41
+ |------|----------|------|
42
+ | 代理工具 | `openclaw plugins install @lansenger-pm/openclaw-lansenger-tools` | `lansenger_send_file`、`lansenger_send_text` |
43
+ | CLI 命令 | `pip install lansenger-cli` | `lansenger message send-file`、`lansenger message send-text` 等 |
44
+
45
+ > ⚠️ **代理工具需要 `lansenger-tools` 插件** 需單獨安裝。CLI 命令需要 `lansenger-cli`(Python)。兩者均未安裝時,代理只能透過普通 Markdown 文字回覆。
49
46
 
50
47
  ## 安裝與設定
51
48
 
52
- ### 建議 4 步流程
49
+ ### 建議安裝流程
53
50
 
54
51
  ```bash
55
- # 1. 安裝插件
52
+ # 1. 安裝頻道插件
56
53
  openclaw plugins install @lansenger-pm/openclaw-lansenger-channel
57
54
 
58
- # 2. 啟用插件(如未自動啟用)
55
+ # 2. 安裝工具插件或 CLI(至少需要一個來傳送訊息)
56
+ # 方案 A:OpenClaw 代理工具插件
57
+ openclaw plugins install @lansenger-pm/openclaw-lansenger-tools
58
+ # 方案 B:Python CLI(透過 bash 呼叫)
59
+ pip install lansenger-cli
60
+
61
+ # 3. 啟用插件(如未自動啟用)
59
62
  openclaw config set plugins.entries.lansenger.enabled true
63
+ openclaw config set plugins.entries.lansenger-tools.enabled true # 使用方案 A 時
60
64
 
61
- # 3. 配置頻道(互動式精靈)
65
+ # 4. 配置頻道(互動式精靈)
62
66
  openclaw channels add
63
- # 或快速新增(建立空設定,再執行上面的精靈):
64
- # openclaw channels add --channel lansenger
65
67
 
66
- # 4. 重啟閘道
68
+ # 5. 重啟閘道
67
69
  openclaw gateway restart
68
70
  ```
69
71
 
70
- `package.json` 中的 `openclaw.install` 元資料(`npmSpec`、`localPath`、`defaultChoice`)支援**按需安裝**:如果使用者在 `openclaw channels add` 精靈中選擇 Lansenger 但插件未安裝,OpenClaw 可自動安裝該插件。
72
+ `package.json` `peerDependencies` npm install 時會警告缺少 tools 插件。設定精靈也會提醒安裝。
71
73
 
72
74
  > **自訂閘道**:企業私有化部署(如奇安信)需在設定後透過 `openclaw.json` 或環境變數設定 `apiGatewayUrl` — 見[可選設定](#可選設定)。
73
75
 
@@ -303,6 +305,7 @@ openclaw channels status --probe
303
305
  - **reminder**——formatText 中可選欄位;群組聊天中建議使用。提及使用者時在文字中包含「@姓名」。
304
306
  - **媒體標籤**——`<media>` 標籤適用於工作區檔案;外部路徑請使用 `lansenger_send_file`。
305
307
  - **openclaw skill/message lansenger**——這些 CLI 命令不存在;請使用代理工具。
308
+ - **工具插件**——代理工具(`lansenger_send_*`)需要單獨安裝 `@lansenger-pm/openclaw-lansenger-tools` 插件。CLI 命令(`lansenger message send-*`)需要 `pip install lansenger-cli`。至少安裝其中一個。
306
309
 
307
310
  ## 開發
308
311
 
@@ -336,7 +339,7 @@ openclaw-lansenger-channel/
336
339
  │ └── runtime.ts # 閘道運行時(方法、入站處理器)
337
340
  ├── skills/
338
341
  │ └── lansenger-messaging/
339
- │ └── SKILL.md # 代理訊息策略
342
+ │ └── SKILL.md # 代理訊息策略(工具 + CLI)
340
343
  ├── dist/ # 編譯後的 JavaScript
341
344
  ├── index.ts # 插件入口
342
345
  ├── setup-entry.ts # 設定精靈入口
@@ -33,41 +33,43 @@
33
33
 
34
34
  **預設策略**:優先使用 `formatText` 發送 Markdown 回覆。附件使用 `text` 回退。兩種類型均支援 @mention(透過 `reminder` 參數)—提及使用者時在文字中包含「@姓名」。
35
35
 
36
- ## 代理工具
37
-
38
- | 工具 | 說明 |
39
- |------|------|
40
- | `lansenger_send_text` | 發送文字或 formatText 訊息(預設 Markdown) |
41
- | `lansenger_send_file` | 發送檔案/圖片/影片/語音(工作區或外部路徑) |
42
- | `lansenger_send_image_url` | 透過 URL 發送圖片 |
43
- | `lansenger_send_link_card` | 發送富連結預覽卡片 |
44
- | `lansenger_send_app_card` | 發送互動/審批卡片 |
45
- | `lansenger_send_app_articles` | 發送多文章卡片 |
46
- | `lansenger_update_dynamic_card` | 原地更新動態卡片狀態 |
47
- | `lansenger_revoke_message` | 撤回已發送的訊息 |
48
- | `lansenger_query_groups` | 查詢可用群組 |
36
+ ## 代理工具 & CLI
37
+
38
+ 訊息可以透過**代理工具**、**CLI 命令**或兩者發送:
39
+
40
+ | 方式 | 安裝方法 | 使用 |
41
+ |------|----------|------|
42
+ | 代理工具 | `openclaw plugins install @lansenger-pm/openclaw-lansenger-tools` | `lansenger_send_file`、`lansenger_send_text` |
43
+ | CLI 命令 | `pip install lansenger-cli` | `lansenger message send-file`、`lansenger message send-text` 等 |
44
+
45
+ > ⚠️ **代理工具需要 `lansenger-tools` 插件** 需單獨安裝。CLI 命令需要 `lansenger-cli`(Python)。兩者均未安裝時,代理只能透過普通 Markdown 文字回覆。
49
46
 
50
47
  ## 安裝與設定
51
48
 
52
- ### 建議 4 步流程
49
+ ### 建議安裝流程
53
50
 
54
51
  ```bash
55
- # 1. 安裝插件
52
+ # 1. 安裝頻道插件
56
53
  openclaw plugins install @lansenger-pm/openclaw-lansenger-channel
57
54
 
58
- # 2. 啟用插件(如未自動啟用)
55
+ # 2. 安裝工具插件或 CLI(至少需要一個來發送訊息)
56
+ # 方案 A:OpenClaw 代理工具插件
57
+ openclaw plugins install @lansenger-pm/openclaw-lansenger-tools
58
+ # 方案 B:Python CLI(透過 bash 呼叫)
59
+ pip install lansenger-cli
60
+
61
+ # 3. 啟用插件(如未自動啟用)
59
62
  openclaw config set plugins.entries.lansenger.enabled true
63
+ openclaw config set plugins.entries.lansenger-tools.enabled true # 使用方案 A 時
60
64
 
61
- # 3. 配置頻道(互動式精靈)
65
+ # 4. 配置頻道(互動式精靈)
62
66
  openclaw channels add
63
- # 或快速新增(建立空設定,再執行上面的精靈):
64
- # openclaw channels add --channel lansenger
65
67
 
66
- # 4. 重啟網關
68
+ # 5. 重啟網關
67
69
  openclaw gateway restart
68
70
  ```
69
71
 
70
- `package.json` 中的 `openclaw.install` 元資料(`npmSpec`、`localPath`、`defaultChoice`)支援**按需安裝**:如果使用者在 `openclaw channels add` 精靈中選擇 Lansenger 但插件未安裝,OpenClaw 可自動安裝該插件。
72
+ `package.json` `peerDependencies` npm install 時會警告缺少 tools 插件。設定精靈也會提醒安裝。
71
73
 
72
74
  > **自訂閘道**:企業私有化部署(如奇安信)需在設定後透過 `openclaw.json` 或環境變數設定 `apiGatewayUrl` — 見[可選設定](#可選設定)。
73
75
 
@@ -305,6 +307,7 @@ openclaw channels status --probe
305
307
  - **reminder** — formatText 中可選欄位;群組聊天中建議使用。提及使用者時在文字中包含「@姓名」。
306
308
  - **媒體標籤** — `<media>` 標籤適用於工作區檔案;外部路徑請使用 `lansenger_send_file`。
307
309
  - **openclaw skill/message lansenger** — 這些 CLI 命令不存在;請使用代理工具。
310
+ - **工具插件** — 代理工具(`lansenger_send_*`)需要單獨安裝 `@lansenger-pm/openclaw-lansenger-tools` 插件。CLI 命令(`lansenger message send-*`)需要 `pip install lansenger-cli`。至少安裝其中一個。
308
311
 
309
312
  ## 開發
310
313
 
@@ -338,7 +341,7 @@ openclaw-lansenger-channel/
338
341
  │ └── runtime.ts # 網關運行時(方法、入站處理器)
339
342
  ├── skills/
340
343
  │ └── lansenger-messaging/
341
- │ └── SKILL.md # 代理訊息策略
344
+ │ └── SKILL.md # 代理訊息策略(工具 + CLI)
342
345
  ├── dist/ # 編譯後的 JavaScript
343
346
  ├── index.ts # 插件入口
344
347
  ├── setup-entry.ts # 設定精靈入口
@@ -0,0 +1,11 @@
1
+ import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";
2
+ import type { ChannelConfigSchema } from "openclaw/plugin-sdk/channel-core";
3
+ export { resolveAccount, makeClient } from "./src/channel.js";
4
+ export type { ResolvedAccount } from "./src/channel.js";
5
+ export { getRunningClient, getRunningAccount, getLastInboundChatId } from "./src/runtime.js";
6
+ export { LansengerClient } from "./src/client.js";
7
+ export type { ChannelConfigSchema } from "openclaw/plugin-sdk/channel-core";
8
+ declare const entry: ReturnType<typeof defineChannelPluginEntry> & {
9
+ configSchema?: ChannelConfigSchema;
10
+ };
11
+ export default entry;
@@ -0,0 +1,8 @@
1
+ declare const _default: {
2
+ plugin: import("openclaw/plugin-sdk/channel-core").ChannelPlugin<import("./index.js").ResolvedAccount, {
3
+ ok: boolean;
4
+ appId?: string;
5
+ error?: string;
6
+ }>;
7
+ };
8
+ export default _default;
@@ -0,0 +1,23 @@
1
+ import type { OpenClawConfig, ChannelPlugin } from "openclaw/plugin-sdk/channel-core";
2
+ import { LansengerClient } from "./client.js";
3
+ import type { ClientLogger } from "./client.js";
4
+ type LansengerProbeResult = {
5
+ ok: boolean;
6
+ appId?: string;
7
+ error?: string;
8
+ };
9
+ type ResolvedAccount = {
10
+ accountId: string | null;
11
+ appId: string;
12
+ appSecret: string;
13
+ apiGatewayUrl: string;
14
+ allowFrom: string[];
15
+ dmPolicy: string | undefined;
16
+ homeChannel: string | undefined;
17
+ enabled: boolean;
18
+ };
19
+ declare function resolveAccount(cfg: OpenClawConfig, accountId?: string | null): ResolvedAccount;
20
+ declare function makeClient(account: ResolvedAccount, logger?: ClientLogger): LansengerClient;
21
+ export declare const lansengerPlugin: ChannelPlugin<ResolvedAccount, LansengerProbeResult>;
22
+ export { resolveAccount, makeClient };
23
+ export type { ResolvedAccount };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,208 @@
1
+ export type ClientLogger = {
2
+ info: (message: string) => void;
3
+ error: (message: string) => void;
4
+ };
5
+ declare const DEFAULT_API_GATEWAY_URL = "https://open.e.lanxin.cn/open/apigw";
6
+ declare const MAX_MESSAGE_LENGTH = 4000;
7
+ export type ApiResult = {
8
+ success: boolean;
9
+ messageId?: string | undefined;
10
+ error?: string | undefined;
11
+ rawResponse?: unknown;
12
+ };
13
+ export declare function mediaTypeFromPath(filePath: string): number;
14
+ export declare class LansengerClient {
15
+ private appId;
16
+ private appSecret;
17
+ private apiGatewayUrl;
18
+ private appToken;
19
+ private tokenExpiry;
20
+ private ws;
21
+ private wsTask;
22
+ private running;
23
+ private backoffIdx;
24
+ private heartbeatTimer;
25
+ private pongTimeoutTimer;
26
+ private lastPongAt;
27
+ private messageHandler;
28
+ private log;
29
+ private chatTypeMap;
30
+ private userLangMap;
31
+ constructor(config: {
32
+ appId: string;
33
+ appSecret: string;
34
+ apiGatewayUrl?: string;
35
+ logger?: ClientLogger;
36
+ });
37
+ setMessageHandler(handler: (event: InboundEvent) => Promise<void>): void;
38
+ isWsAlive(): boolean;
39
+ getAppToken(): Promise<string | null>;
40
+ sendText(chatId: string, content: string, reminder?: ReminderParams): Promise<ApiResult>;
41
+ sendFormatText(chatId: string, content: string, reminder?: ReminderParams): Promise<ApiResult>;
42
+ sendTextWithMedia(chatId: string, content: string, mediaType: number, mediaIds: string[], reminder?: ReminderParams): Promise<ApiResult>;
43
+ uploadMedia(filePath: string, mediaType?: number): Promise<{
44
+ mediaId: string;
45
+ } | {
46
+ error: string;
47
+ }>;
48
+ sendFile(chatId: string, filePath: string, caption?: string, mediaType?: number): Promise<ApiResult>;
49
+ sendImageUrl(chatId: string, imageUrl: string, caption?: string): Promise<ApiResult>;
50
+ revokeMessage(messageIds: string[], chatType?: string, senderId?: string): Promise<ApiResult>;
51
+ sendLinkCard(chatId: string, title: string, link: string, options?: LinkCardOptions): Promise<ApiResult>;
52
+ sendI18nAppCard(chatId: string, cardData: I18nAppCardData): Promise<ApiResult>;
53
+ sendAppCard(chatId: string, cardData: AppCardData): Promise<ApiResult>;
54
+ sendAppArticles(chatId: string, articles: AppArticle[], options?: ArticleCardOptions): Promise<ApiResult>;
55
+ updateCardStatus(messageId: string, status: "pending" | "approved" | "denied", lang?: "zh" | "en"): Promise<ApiResult>;
56
+ updateDynamicCard(msgId: string, headStatusInfo?: Record<string, string>, links?: Array<{
57
+ title: string;
58
+ url: string;
59
+ }>, isLastUpdate?: boolean): Promise<ApiResult>;
60
+ queryGroups(pageOffset?: number, pageSize?: number): Promise<{
61
+ totalGroupIds: number;
62
+ groupIds: string[];
63
+ } | {
64
+ error: string;
65
+ }>;
66
+ detectLang(text: string): "zh" | "en";
67
+ cacheUserLang(userId: string, text: string): void;
68
+ getUserLang(userId: string): "zh" | "en";
69
+ cacheChatType(chatId: string, chatType: "group" | "dm"): void;
70
+ getChatType(chatId: string): "group" | "dm" | undefined;
71
+ isGroupChat(chatId: string): boolean;
72
+ downloadMedia(mediaId: string): Promise<{
73
+ bytes: Buffer;
74
+ ext?: string;
75
+ } | null>;
76
+ saveMediaToTemp(mediaBytes: Buffer, mediaKind?: string, suggestedExt?: string): Promise<string | null>;
77
+ processRawMessage(raw: string): Promise<InboundEvent[]>;
78
+ connect(): Promise<boolean>;
79
+ disconnect(): Promise<void>;
80
+ private getWsUrl;
81
+ private runWs;
82
+ private startHeartbeat;
83
+ private clearPongTimeout;
84
+ private stopHeartbeat;
85
+ private msgTarget;
86
+ private extractText;
87
+ private downloadAllMedia;
88
+ private postJson;
89
+ }
90
+ export type ReminderParams = {
91
+ all?: boolean;
92
+ userIds?: string[];
93
+ };
94
+ export type LinkCardOptions = {
95
+ description?: string;
96
+ iconLink?: string;
97
+ pcLink?: string;
98
+ fromName?: string;
99
+ fromIconLink?: string;
100
+ };
101
+ export type AppCardField = {
102
+ key: string;
103
+ value: string;
104
+ };
105
+ export type AppCardLink = {
106
+ title: string;
107
+ url: string;
108
+ };
109
+ export type AppCardButton = {
110
+ title: string;
111
+ action: string;
112
+ };
113
+ export type HeadStatusInfo = {
114
+ iconLink?: string;
115
+ description: string;
116
+ colour?: string;
117
+ };
118
+ export type AppCardData = {
119
+ headTitle?: string;
120
+ headIconId?: string;
121
+ headIconUrl?: string;
122
+ isDynamic?: boolean;
123
+ headStatusInfo?: HeadStatusInfo;
124
+ bodyTitle: string;
125
+ bodySubTitle?: string;
126
+ bodyContent?: string;
127
+ signature?: string;
128
+ staffId?: string;
129
+ fields?: AppCardField[];
130
+ links?: AppCardLink[];
131
+ buttons?: AppCardButton[];
132
+ cardLink?: string;
133
+ pcCardLink?: string;
134
+ padCardLink?: string;
135
+ };
136
+ export type AppCardOptions = {
137
+ isDynamic?: boolean;
138
+ cover?: string;
139
+ link?: string;
140
+ pcLink?: string;
141
+ actionLink?: string;
142
+ actionText?: string;
143
+ };
144
+ export type AppArticle = {
145
+ title: string;
146
+ summary?: string;
147
+ imgUrl: string;
148
+ url: string;
149
+ pcUrl?: string;
150
+ padUrl?: string;
151
+ };
152
+ export type ArticleCardOptions = {
153
+ sourceName?: string;
154
+ sourceIcon?: string;
155
+ };
156
+ export type InboundEvent = {
157
+ messageId: string;
158
+ text: string;
159
+ chatId: string;
160
+ chatName?: string;
161
+ isGroup: boolean;
162
+ senderId: string;
163
+ userName: string;
164
+ rawMessage: Record<string, any>;
165
+ msgType: string;
166
+ mediaPaths?: string[];
167
+ };
168
+ export type LansengerApiResponse = {
169
+ errCode: number;
170
+ errMsg?: string;
171
+ data?: {
172
+ appToken?: string;
173
+ expiresIn?: number;
174
+ wsEndpoint?: string;
175
+ msgId?: string;
176
+ mediaId?: string;
177
+ };
178
+ };
179
+ export type LansengerWsMessage = {
180
+ events?: Array<{
181
+ data: Record<string, any>;
182
+ }>;
183
+ };
184
+ export type I18nObj = {
185
+ zhHans: string;
186
+ zhHant: string;
187
+ zhHantHK: string;
188
+ en: string;
189
+ fr: string;
190
+ };
191
+ export type I18nAppCardData = {
192
+ i18nHeadTitle: I18nObj;
193
+ headIconId?: string;
194
+ i18nBodyTitle?: I18nObj;
195
+ i18nBodySubTitle?: I18nObj;
196
+ i18nBodyContent?: I18nObj;
197
+ i18nSignature?: I18nObj;
198
+ i18nFields?: Array<{
199
+ i18nKey: I18nObj;
200
+ i18nValue: I18nObj;
201
+ timestamp: number;
202
+ }>;
203
+ i18nLinks?: Array<unknown>;
204
+ cardLink?: string;
205
+ pcCardLink?: string;
206
+ };
207
+ export declare function buildI18n(zhHans: string, zhHant: string, zhHantHK: string, en: string, fr: string): I18nObj;
208
+ export { DEFAULT_API_GATEWAY_URL, MAX_MESSAGE_LENGTH };
@@ -0,0 +1 @@
1
+ export {};