Tools
Lansenger Tools
Lansenger (蓝信) messaging tools plugin for OpenClaw — send text, Markdown, files, cards, manage groups
Install
npm install
openclaw
Configuration Example
{ "filePath": "/absolute/path/to/file.pdf", "caption": "Report Q1", "to": "chat-id" }
README
[English](README.md) | [简体中文](README.zhHans.md) | [繁体中文](README.zhHant.md) | [繁体中文香港](README.zhHantHK.md) | [Français](README.fr.md)
# @lansenger-pm/openclaw-lansenger-tools
Lansenger (蓝信) messaging **tools plugin** for OpenClaw — provides 10 agent tools for sending text, Markdown, files, cards, and managing groups.
[](https://opensource.org/licenses/MIT)

## Why a separate tools plugin?
The [`@lansenger-pm/openclaw-lansenger-channel`](https://github.com/lansenger-pm/openclaw-lansenger-channel) plugin handles WebSocket inbound, HTTP outbound, and channel lifecycle. Tools registration was originally embedded in the channel plugin, but OpenClaw's plugin system requires **tools contracts** to be declared in a dedicated plugin's `openclaw.plugin.json`. This standalone tools plugin:
- Declares all 10 tool contracts and `configSignals` in its own `openclaw.plugin.json`
- Imports runtime state (`getRunningClient`, `getRunningAccount`, `getLastInboundChatId`) from the channel package at runtime — tools share the same LansengerClient instance
- Registers tools only in `full` registration mode (when the channel gateway is running)
## Tools
| Tool | msgType | Description | Key params |
|------|---------|-------------|------------|
| `lansenger_send_file` | file | Send local file attachment (any path) | `filePath`, `caption?`, `to?` |
| `lansenger_send_text` | text | Plain text with optional file + @mention | `content`, `filePath?`, `reminderAll?`, `reminderUserIds?`, `to?` |
| `lansenger_send_format_text` | formatText | Markdown text with optional @mention | `content`, `reminderAll?`, `reminderUserIds?`, `to?` |
| `lansenger_send_image_url` | image | Send image from URL | `imageUrl`, `caption?`, `to?` |
| `lansenger_send_link_card` | linkCard | Rich link preview card | `title`, `link`, `description?`, `to?` |
| `lansenger_send_app_articles` | appArticles | Multi-article card | `articles[]`, `to?` |
| `lansenger_send_app_card` | appCard | Rich/approval card (supports div-style) | `bodyTitle`, `isDynamic?`, `fields?`, `links?`, `to?` |
| `lansenger_update_dynamic_card` | dynamic | Update dynamic card status in-place | `msgId`, `headStatusInfo?`, `isLastUpdate?` |
| `lansenger_revoke_message` | — | Revoke previously sent messages | `messageIds[]`, `chatType?`, `senderId?` |
| `lansenger_query_groups` | — | Query bot's group list | `pageOffset?`, `pageSize?` |
## Message Type Capability Matrix
| msgType | Markdown | @mention | Attachments |
|---------|----------|----------|-------------|
| `text` | ✗ | ✓ | ✓ |
| `formatText` | ✓ | ✓ (reminder) | ✗ |
**Default strategy**: Write Markdown replies normally (auto-rendered). Use `lansenger_send_text` for file attachments. Use `lansenger_send_format_text` for explicit Markdown + @mention. For Markdown AND a file, send two separate messages.
## Installation
```bash
# Install both plugins (tools depends on channel for runtime state)
openclaw plugins install @lansenger-pm/openclaw-lansenger-channel
openclaw plugins install @lansenger-pm/openclaw-lansenger-tools
# Configure the channel (interactive wizard)
openclaw channels add
# Restart the gateway
openclaw gateway restart
```
The tools plugin auto-registers all 10 tools when the Lansenger channel is running. No separate configuration needed — tools read from the same channel config (`channels.lansenger`).
### Development install (linked)
```bash
cd /path/to/openclaw-lansenger-tools
npm install
openclaw plugins install --link
openclaw gateway restart
```
## Tool Details
### lansenger_send_file
Send a local file as an attachment. Any local path works — workspace, Documents, Desktop, `/tmp`, etc.
```json
{ "filePath": "/absolute/path/to/file.pdf", "caption": "Report Q1", "to": "chat-id" }
```
> ⚠️ Do NOT use `<media>` tags for files outside the workspace; they silently fail. Always use this tool.
### lansenger_send_text
Plain text (no Markdown). Supports optional file attachment and @mentions.
```json
{ "content": "Please review the attached file.", "filePath": "/path/to/file.pdf", "reminderAll": true, "to": "group-chat-id" }
```
> For Markdown replies, just write normally — it renders automatically. Use this tool only for text + file or text + @mention combos.
### lansenger_send_format_text
Markdown-formatted text with optional @mentions. No file attachments.
```json
{ "content": "## Summary\n- Item 1\n- Item 2", "reminderUserIds": ["user-id-1"], "to": "chat-id" }
```
### lansenger_send_image_url
Send an image from a URL. The gateway downloads and re-uploads it.
```json
{ "imageUrl": "https://example.com/image.png", "caption": "Screenshot", "to": "chat-id" }
```
### lansenger_send_link_card
Rich link preview card.
```json
{ "title": "OpenClaw Docs", "link": "https://opencode.ai", "description": "Documentation", "to": "chat-id" }
```
### lansenger_send_app_articles
Multi-article card (图文卡片). Each article requires `imgUrl`, `title`, `url`.
```json
{ "articles": [{ "imgUrl": "https://example.com/img.jpg", "title": "Article 1", "url": "https://example.com/1", "summary": "摘要" }], "to": "chat-id" }
```
> ⚠️ Use `summary` field (NOT `description` — that field is silently ignored by the API).
### lansenger_send_app_card
Rich formatted card (应用卡片). Supports div-style formatting for color, font-size, text-align.
```json
{
"bodyTitle": "Approval Request",
"isDynamic": true,
"fields": [{ "key": "Amount", "value": "¥5,000" }],
"links": [{ "title": "Approve", "url": "https://example.com/approve" }],
"to": "chat-id"
}
```
> ⚠️ **font-size** MUST use `pt` units (12pt–36pt) — `px` causes "invalid bodyContent".
> ⚠️ **text-indent** MUST have units — bare `0` causes silent failure; use `0em`.
> ⚠️ **headStatusInfo**: `description` is status text (supports div-style, max 30 bytes), `colour` is the status dot color (hex). These are TWO different things — text color vs dot color.
> ⚠️ Group chat does NOT support appCard — falls back to plain text.
### lansenger_update_dynamic_card
Update a dynamic card's status in-place. The card must have been sent with `isDynamic=true`.
```json
{ "msgId": "msg-id-from-send-app-card", "headStatusInfo": { "description": "Approved", "colour": "#198754" }, "isLastUpdate": true }
```
### lansenger_revoke_message
Revoke previously sent messages. For group chat, `senderId` is required.
```json
{ "messageIds": ["msg-id-1", "msg-id-2"], "chatType": "group", "senderId": "sender-openid" }
```
### lansenger_query_groups
Query the bot's group list. Returns total count and group IDs.
```json
{ "pageOffset": 1, "pageSize": 100 }
```
> ⚠️ May return `errCode=10005` "API服务无权限" on enterprise deployments where `/v2/groups/fetch` is not authorized. Ask the user for group chatIds manually.
## Auto-target resolution
All tools with a `to` parameter auto-resolve the target:
- If `to` is provided → use it directly
- If `to` is omitted → use `getLastInboundChatId()` (the chat that triggered the current conversation)
This means in normal conversation flow, agents don't need to specify `to` — the tool automatically sends back to the current chat.
## configSignals
Each tool declares `configSignals` pointing to `channels.lansenger` with `required: ["appId", "appSecret"]`. OpenClaw uses this to show "configured" / "not running" status per tool in the GUI.
## Important Notes
- **Requires channel plugin** — tools import `getRunningClient`, `getRunningAccount`, `getLastInboundChatId` from the channel package at runtime
- **No separate config** — tools read the same Lansenger credentials as the channel plugin
- **appArticles** — uses `summary` (NOT `description`)
- **linkCard** — `description`, `iconLink`, `fromName`, `fromIconLink` are required (empty string defaults)
- **appCard div-style** — font-size in `pt` only; text-indent with units; headStatusInfo description vs colour
- **Revoke chatType** — only `bot` or `group`; no `staff` type
- **Group chat** — appCard falls back to plain text in group chats
## Development
### Build
```bash
npm install
npx tsc
```
### Typecheck
```bash
npx tsc --noEmit
```
### Project Structure
```
openclaw-lansenger-tools/
├── src/
│ └── tools.ts # All 10 tool definitions + registerLansengerTools()
├── tools-entry.ts # Plugin entry point (definePluginEntry)
├── dist/ # Compiled JavaScript
├── openclaw.plugin.json # Plugin metadata, contracts, configSignals
├── package.json
├── VERSION
└── tsconfig.json
```
## Changelog
- **v1.0.0** — Initial release: 10 tools (send_file, send_text, send_format_text, send_image_url, send_link_card, send_app_articles, send_app_card, update_dynamic_card, revoke_message, query_groups)
## License
MIT — see [LICENSE](LICENSE).
tools
Comments
Sign in to leave a comment