← 返回 Skills 市场
2manslkh

Line Client

作者 Kenk · GitHub ↗ · v1.0.0
cross-platform ⚠ suspicious
598
总下载
3
收藏
0
当前安装
2
版本数
在 OpenClaw 中安装
/install line-client
功能描述
LINE messaging integration via Chrome extension gateway. Send/read LINE messages, manage contacts, groups, profile, and reactions. Authenticate with QR code...
使用说明 (SKILL.md)

LINE Client Skill

Full LINE messaging client via the Chrome extension gateway JSON API.

Repo & Files

  • Repo: /data/workspace/line-client (github.com/2manslkh/line-api)
  • Main client: src/chrome_client.pyLineChromeClient
  • QR login: src/auth/qr_login.pyQRLogin
  • HMAC signer: src/hmac/signer.js (Node.js, auto-starts on port 18944)
  • Token storage: ~/.line-client/tokens.json
  • Certificate cache: ~/.line-client/sqr_cert
  • WASM files: lstm.wasm + lstmSandbox.js (required, in repo root)

Quick Start

import json
from pathlib import Path
from src.chrome_client import LineChromeClient

tokens = json.loads((Path.home() / ".line-client" / "tokens.json").read_text())
client = LineChromeClient(auth_token=tokens["auth_token"])

# Send a message
client.send_message("U...", "Hello!")

# Get profile
profile = client.get_profile()

Tokens expire in ~7 days. If expired (APIError(10051)), re-run QR login.

QR Login (Authentication)

QR login requires user interaction: scan QR on phone + enter PIN.

from src.hmac import HmacSigner
from src.auth.qr_login import QRLogin
import qrcode

signer = HmacSigner(mode="server")
login = QRLogin(signer)
result = login.run(
    on_qr=lambda url: send_qr_image_to_user(qrcode.make(url)),
    on_pin=lambda pin: send_pin_to_user_IMMEDIATELY(pin),  # TIME SENSITIVE!
    on_status=lambda msg: print(msg),
)
# result.auth_token, result.mid, result.refresh_token

Critical: The PIN must reach the user within ~60 seconds. Send it the instant on_pin fires.

QR Login State Machine

  1. createSession → session ID
  2. createQrCode → callback URL (append ?secret={curve25519_pubkey}&e2eeVersion=1)
  3. checkQrCodeVerified — poll until scan (uses X-Line-Session-ID, no origin header)
  4. verifyCertificate — MUST be called even if it fails (required state transition!)
  5. createPinCode → 6-digit PIN (skip if cert verified in step 4)
  6. checkPinCodeVerified — poll until user enters PIN
  7. qrCodeLoginV2 → JWT token + certificate + refresh token

Server-Side Login Script

python scripts/qr_login_server.py /tmp/qr.png

Emits JSON events on stdout: {"event": "qr", "path": "...", "url": "..."}, {"event": "pin", "pin": "123456"}, {"event": "done", "mid": "U..."}.

All API Methods

Contacts & Friends

Method Args Description
get_profile() Get your own profile (displayName, mid, statusMessage, etc.)
get_contact(mid) mid: str Get a single contact's profile
get_contacts(mids) mids: list[str] Get multiple contacts
get_all_contact_ids() List all friend MIDs
find_contact_by_userid(userid) userid: str Search by LINE ID
find_and_add_contact_by_mid(mid) mid: str Add friend by MID
find_contacts_by_phone(phones) phones: list[str] Search by phone numbers
add_friend_by_mid(mid) mid: str Add friend (RelationService)
get_blocked_contact_ids() List blocked MIDs
get_blocked_recommendation_ids() List blocked recommendations
block_contact(mid) mid: str Block a contact
unblock_contact(mid) mid: str Unblock a contact
block_recommendation(mid) mid: str Block a friend suggestion
update_contact_setting(mid, flag, value) mid, flag: int, value: str Update contact setting (e.g. mute)
get_favorite_mids() List favorited contact MIDs
get_recommendation_ids() List friend suggestions

Messages

Method Args Description
send_message(to, text, ...) to: str, text: str, reply_to: str (opt) Send a text message. Supports replies via reply_to=message_id
unsend_message(message_id) message_id: str Unsend/delete a sent message
get_recent_messages(chat_id, count=50) chat_id: str Get latest messages in a chat
get_previous_messages(chat_id, end_seq, count=50) chat_id, end_seq: int Paginated history (older messages)
get_messages_by_ids(message_ids) message_ids: list[str] Fetch specific messages
get_message_boxes(count=50) Get chat list with last message (inbox view)
get_message_boxes_by_ids(chat_ids) chat_ids: list[str] Get specific chats with last message
get_message_read_range(chat_ids) chat_ids: list[str] Get read receipt info
send_chat_checked(chat_id, last_message_id) chat_id, last_message_id: str Mark messages as read
send_chat_removed(chat_id, last_message_id) chat_id, last_message_id: str Remove chat from inbox
send_postback(to, postback_data) to, postback_data: str Send postback (bot interactions)

Chats & Groups

Method Args Description
get_chats(chat_ids, with_members=True, with_invitees=True) chat_ids: list[str] Get chat/group details
get_all_chat_mids() List all chat MIDs (groups + invites)
create_chat(name, target_mids) name: str, target_mids: list[str] Create a new group chat
accept_chat_invitation(chat_id) chat_id: str Accept group invite
reject_chat_invitation(chat_id) chat_id: str Reject group invite
invite_into_chat(chat_id, mids) chat_id: str, mids: list[str] Invite users to group
cancel_chat_invitation(chat_id, mids) chat_id: str, mids: list[str] Cancel pending invites
delete_other_from_chat(chat_id, mids) chat_id: str, mids: list[str] Kick members from group
leave_chat(chat_id) chat_id: str Leave a group chat
update_chat(chat_id, updates) chat_id: str, updates: dict Update group name/settings
set_chat_hidden_status(chat_id, hidden) chat_id: str, hidden: bool Archive/unarchive a chat
get_rooms(room_ids) room_ids: list[str] Get legacy room info
invite_into_room(room_id, mids) room_id: str, mids: list[str] Invite to legacy room
leave_room(room_id) room_id: str Leave legacy room

Reactions

Method Args Description
react(message_id, reaction_type) message_id: str, type: int React to a message. Types: 2=like, 3=love, 4=laugh, 5=surprised, 6=sad, 7=angry
cancel_reaction(message_id) message_id: str Remove your reaction

Profile & Settings

Method Args Description
update_profile_attributes(attr, value, meta={}) attr: int, value: str Update profile. Attrs: 2=DISPLAY_NAME, 16=STATUS_MESSAGE, 4=PICTURE_STATUS
update_status_message(message) message: str Shortcut: update status message
update_display_name(name) name: str Shortcut: update display name
get_settings() Get all account settings
get_settings_attributes(attr_bitset) attr_bitset: int Get specific settings
update_settings_attributes(attr_bitset, settings) attr_bitset: int, settings: dict Update settings

Polling & Events

Method Args Description
get_last_op_revision() Get latest operation revision number
fetch_ops(count=50) Fetch pending operations (may long-poll)
poll() Generator yielding operations as they arrive
on_message(handler) handler: Callable(msg, client) Start polling thread, calls handler on new messages. Op types: 26=SEND_MESSAGE, 27=RECEIVE_MESSAGE
stop() Stop the polling thread

Other Services

Method Args Description
get_server_time() Get LINE server timestamp
get_configurations() Get server configurations
get_rsa_key_info() Get RSA key for auth
issue_channel_token(channel_id) channel_id: str Issue channel token (LINE Login/LIFF)
get_buddy_detail(mid) mid: str Get official account info
report_abuse(mid, category=0, reason="") mid: str Report a user
add_friend_by_mid(mid) mid: str Add friend (RelationService)
logout() Logout and invalidate token

MID Format

LINE identifies entities by MID:

  • U... or u... → User (toType=0)
  • C... or c... → Group chat (toType=2)
  • R... or r... → Room (toType=1)

The client auto-detects toType from the MID prefix when sending messages.

HMAC Signing

All API calls require X-Hmac header. The WASM signer handles this automatically:

  • Derives key from version "3.7.1" + access token via proprietary KDF (in lstm.wasm)
  • Signs path + body → base64 → X-Hmac
  • Server mode: ~13ms/sign (Node.js HTTP server on port 18944, auto-started)
  • Subprocess mode: ~2s/sign (fallback)

Error Handling

from src.chrome_client import APIError

try:
    client.send_message(mid, "test")
except APIError as e:
    print(e.code, e.api_message)
    # 10051 = session expired / invalid
    # 10052 = HTTP error from backend
    # 10102 = invalid arguments

Architecture

User's Phone (LINE app)
    ↕ (scan QR / enter PIN)
LINE Servers (line-chrome-gw.line-apps.com)
    ↕ (JSON REST + X-Hmac signing)
LineChromeClient (this repo)
    ↕ (WASM HMAC via Node.js signer)
lstm.wasm + lstmSandbox.js

The Chrome Gateway translates JSON ↔ Thrift internally. We never deal with Thrift binary — everything is clean JSON.

安全使用建议
Do not install or run this skill until the author clarifies and fixes these mismatches. Ask for: (1) the complete source code or a trustworthy package/release (GitHub release or official domain), (2) a clear install spec that lists required runtimes (node, python), dependencies, and any commands the agent will execute, (3) explicit declaration of config paths it will read/write (e.g., ~/.line-client/tokens.json, certificate cache), and (4) justification for why a local HMAC signer and WASM are needed. If you must test, run it in an isolated VM/container and never expose real LINE credentials — inspect the signer and QR-login code for network calls and token handling before trusting it. If the publisher cannot provide an official repo/release or explain why no binaries/env are declared, treat the skill as untrusted.
功能分析
Type: OpenClaw Skill Name: line-client Version: 1.0.0 The skill is classified as suspicious due to several high-risk capabilities, even though no explicit malicious intent is evident. It starts a Node.js server on a local port (18944) for HMAC signing, executes WebAssembly (lstm.wasm) via a JavaScript sandbox, and runs Python scripts as subprocesses (e.g., scripts/qr_login_server.py). The SKILL.md also contains direct instructions for the AI agent to handle sensitive user interactions (e.g., `send_pin_to_user_IMMEDIATELY(pin)`), demonstrating a clear prompt injection attack surface. While these actions are described as necessary for the stated purpose of a LINE client, they introduce significant attack surface and complexity.
能力评估
Purpose & Capability
The description says it's a LINE client using a Chrome-extension gateway, which could legitimately need to talk to that gateway. However the SKILL.md expects a Node HMAC signer (auto-starting on port 18944), Python QR login scripts, and WASM files in a repo path — none of these runtime dependencies, binaries, or config paths are declared. The skill also expects a local token store (~/.line-client/tokens.json). Requiring local services, runtime artifacts, and persistent token files is disproportionate to what the registry metadata claims (no binaries, no env, no config paths).
Instruction Scope
Runtime instructions tell the agent to read tokens from the user's home (~/.line-client/tokens.json), run Python scripts (scripts/qr_login_server.py), start a Node.js signer, and handle time-sensitive PINs for login. These instructions direct access to sensitive local files and to start network services and polling loops. The SKILL.md gives the agent broad authority to read/write local credential files and to transmit PINs/QR URLs, but the skill metadata did not disclose these file accesses or runtime actions.
Install Mechanism
There is no install spec and no code files bundled in the skill registry entry, yet the instructions reference a repository path (/data/workspace/line-client), source files (Python/JS/WASM), and an auto-starting Node signer. That mismatch means the agent would either need to fetch/checkout external code (not described) or expect the host to already contain those files — both are risky and undocumented.
Credentials
The skill declares no required environment variables or credentials, yet the instructions rely on persistent auth tokens stored in ~/.line-client and imply the need for Node/Python runtimes and networking to the Chrome gateway. Sensitive artifacts (auth_token, refresh_token, certificate cache) are used and written but not declared. This under-reporting of required secrets/config paths is a red flag.
Persistence & Privilege
always:false (good), but the skill instructs storing tokens and certificates under ~/.line-client and to run long-running local services (HMAC signer). Autonomous invocation is allowed by default; combined with the undisclosed persistent credential storage and service startup, this increases the blast radius if the skill is later invoked without explicit user consent.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install line-client
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /line-client 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
Initial release: LINE messaging via Chrome extension gateway
v0.2.0
Initial release: full LINE messaging client via Chrome extension gateway. QR login, HMAC signing, 55+ API endpoints.
元数据
Slug line-client
版本 1.0.0
许可证
累计安装 0
当前安装数 0
历史版本数 2
常见问题

Line Client 是什么?

LINE messaging integration via Chrome extension gateway. Send/read LINE messages, manage contacts, groups, profile, and reactions. Authenticate with QR code... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 598 次。

如何安装 Line Client?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install line-client」即可一键安装,无需额外配置。

Line Client 是免费的吗?

是的,Line Client 完全免费(开源免费),可自由下载、安装和使用。

Line Client 支持哪些平台?

Line Client 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Line Client?

由 Kenk(@2manslkh)开发并维护,当前版本 v1.0.0。

💬 留言讨论