简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

SnowLuma Platform Feature Document

SnowLumaAdapter is an adapter built on the SnowLuma backend (NTQQ hook), communicating via the OneBot v11 protocol.


Document Information

Basic Information

Relationship with OneBot11 Adapter

SnowLuma uses the OB11 protocol, with standard actions and events converted in the same structure as the OneBot11 adapter (OB12 standard action names are automatically mapped). Main differences:

  1. Default client mode: Actively connects to SnowLuma WS (ws://127.0.0.1:3001), no need for public network listening
  2. Automatic bot_id recognition: No need to fill in the QQ number in account configuration; the adapter automatically detects and maintains the self_id → account_name mapping after startup
  3. 109 extension actions: Poke, QQ Space, group files/photos, message history, highlights, read status, etc., SnowLuma/NapCat compatible extensions
  4. Merged forward extension chain: Dedicated endpoint + upload_forward_msg (upload node takes resid) + get_forward_msg (parse forwarded content) three-level fallback

Standard API Actions (API DSL)

The adapter automatically maps OneBot12 standard action names to OB11 action names, allowing modules to invoke cross-platform uniformly:

OB12 Standard Action OB11 Action Description
get_self_info get_login_info Standardized fields user_id/user_name/user_displayname
get_user_info get_stranger_info Standardized fields
delete_message delete_msg Recall message
leave_group set_group_leave Leave group
upload_file upload_group_file / upload_private_file Extended group_id/user_id optional parameters

Basic Usage

from ErisPulse import sdk
snowluma = sdk.adapter.get("snowluma")

# Get bot information
result = await snowluma.Api.get_self_info()
print(result["data"]["user_id"], result["data"]["user_name"])

# Recall message
await snowluma.Api.delete_message(message_id=123456)

# Specify account (multi-account)
result = await snowluma.Api.Using("main").get_self_info()

# Call extension actions through call() escape hatch (SnowLuma/NapCat universal)
result = await snowluma.Api.call("send_poke", group_id=123, user_id=456)

Supported Message Sending Types

All sending methods are implemented using chained syntax, for example:

from ErisPulse import sdk
snowluma = sdk.adapter.get("snowluma")

# Send using default account
await snowluma.Send.To("group", group_id).Text("Hello World!")

# Send using specific account
await snowluma.Send.Using("main").To("group", group_id).Text("Message from main account")

# Chained modifiers: @user + reply
await snowluma.Send.To("group", group_id).At(123456).Reply(msg_id).Text("Reply message")

Basic Sending Methods

Merged Forward

nodes = [
    {
        "type": "node",
        "data": {
            "user_id": "10000",
            "nickname": "MyBot",
            "content": [{"type": "text", "data": {"text": "【1/3】Title\nBody…"}}],
        },
    },
]

# Send merged forward (three-level fallback, suitable for SnowLuma / NapCat backends):
# ① send_group/private_forward_msg dedicated endpoint (native to NapCat, SnowLuma compatible)
# ② upload_forward_msg takes resid → send_msg sends forward segment (SnowLuma extension chain)
# ③ send_msg directly sends node segment
await snowluma.Send.To("group", group_id).MergeForward(nodes)

# Parse received merged forward message (inbound forward segments are transmitted as onebot11_forward, data.id is resid)
result = await snowluma.Api.get_forward_msg(id="resid_xxx")

Group Operation Methods

The following methods require specifying the target group via To("group", group_id):

Poke / Social

QQ Space

Group Files / Message History / Read Status

Chained Modifier Methods (can be combined)


OB11 Extension Actions (API DSL)

In addition to standard actions, OB11ExtensionApi mixin provides over 60 type-safe extension methods. All 109 extension actions can be directly called via Api.call("action_name", ...) (SnowLuma/NapCat universal). Group overview:

Group Representative Action
Poke / Social send_poke / group_poke / friend_poke / send_like
Message Reaction / Highlights set_msg_emoji_like / get_emoji_likes / set_essence_msg / get_essence_msg_list
Read / Status mark_msg_as_read / mark_group_msg_as_read / mark_all_as_read / set_online_status / set_input_status
Message History get_group_msg_history / get_friend_msg_history
Group Management Extensions set_group_reaction / set_group_remark / set_group_sign / set_group_todo / get_group_info_ex / get_group_shut_list / get_group_at_all_remain
Friends / Contacts set_friend_remark / get_unidirectional_friend_list / get_friends_with_category / get_recent_contact
Group Files get_group_file_url / get_private_file_url / get_group_root_files / get_group_files_by_folder / create_group_file_folder / delete_group_file
Group Album get_group_album_list / get_group_album_media_list
QQ Space send_qzone_msg / get_qzone_msg_list / get_qzone_feeds
Merged Forward get_forward_msg / upload_forward_msg
Media / OCR ocr_image / get_image

Event Type Mapping

Standard OB12 Mapping

OB11 Original Type Converted detail_type Description
message_type: private private Private chat message
message_type: group group Group chat message
notice_type: group_upload group_file_upload Group file upload
notice_type: group_admin group_admin_change Group admin change
notice_type: group_increase group_member_increase Group member increase
notice_type: group_decrease group_member_decrease Group member decrease
notice_type: group_ban group_ban Group mute
notice_type: friend_add friend_increase Friend added
notice_type: friend_delete friend_decrease Friend removed
notice_type: group_recall / friend_recall message_recall Message recall

Platform-Specific Events and Extension Segments

Extension Field Description


Event Extension Methods

from ErisPulse.Core.Event import message

@message.on_message()
async def handle_message(event):
    raw_self_id = event.get_raw_self_id()
    sender_info = event.get_sender_info()
    sender_role = event.get_sender_role()
Method Return Type Description
get_raw_event() dict Get complete SnowLuma raw event data
get_raw_self_id() str Get raw self_id (Bot's QQ number)
get_sender_info() dict Get complete sender information (includes nickname, role, level, etc.)
get_sender_role() str Get sender's role in group (owner/admin/member)
get_sender_level() int Get sender's level
get_sender_title() str Get sender's group title
is_system_message() bool Determine if it is a system message

Configuration Options

SnowLuma adapter adopts a multi-account architecture, with each account independently configured. The configuration key name is SnowLuma_Adapter.

Account Configuration Fields

Field Type Required Default Description
mode str No "client" Running mode: "client" (active connection, recommended) or "server" (passive listening)
url str No "ws://127.0.0.1:3001" WebSocket address for client mode (SnowLuma default WS port 3001)
token str No "" Access token (Bearer authentication)
server_path str No "/" WebSocket path for server mode
enabled bool No true Whether to enable this account
name str No "" Account comment name

bot_id (QQ number) does not need to be configured: the adapter automatically recognizes it after connection and maintains the self_id → account_name mapping. event.reply() automatically routes to the originating account.

Configuration Example

[SnowLuma_Adapter.accounts.main]
mode = "client"
url = "ws://127.0.0.1:3001"
token = ""
enabled = true

[SnowLuma_Adapter.accounts.second]
mode = "client"
url = "ws://192.168.1.100:3001"
token = "second_token"
enabled = true

Send Method Return Values

All send methods return a Task object, which can be directly awaited to obtain the send result. The return result follows the ErisPulse adapter standardized return specification:

{
    "status": "ok",
    "retcode": 0,
    "data": {...},
    "message_id": "123456",
    "message": "",
    "snowluma_raw": {...}
}

Multi-account Send Syntax

# Account selection method
await snowluma.Send.Using("main").To("group", 123456).Text("Message from main account")

# API call method
await snowluma.call_api("send_msg", account_id="main", group_id=123456, message="Hello")

self_id Automatic Mapping

The adapter automatically establishes a mapping relationship from OneBot self_id (QQ number) to account_name, used for event routing:

@message.on_message()
async def handler(event):
    # Automatically routes to the correct account
    await event.reply("Automatically routes to the originating account")