@dsbot-channel/onebot 0.0.0-stage → 0.7.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 zerodegress
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,26 @@
1
+ ### onebot transport
2
+
3
+ | Field | Default | Meaning |
4
+ | --- | --- | --- |
5
+ | `protocol` | `http` | `http`, `ws-forward` or `ws-reverse`; a field of another protocol fails the mount |
6
+ | `listen.host` | `127.0.0.1` | concrete address only |
7
+ | `listen.port` | `7331` | |
8
+ | `listen.path` | `/onebot/event` (`http`), `/onebot/ws` (`ws-reverse`) | |
9
+ | `api.url` | required | `http(s)` for `http`, `ws(s)` for `ws-forward` |
10
+ | `event.url` | same as `api.url` | `ws-forward` only; both sockets must be up for `online` |
11
+ | `reconnect` | `{ initialMs: 500, maxMs: 30000, factor: 2 }` | `ws-forward` only; `false` keeps the link offline |
12
+ | `heartbeat` | off | both socket protocols; `intervalMs` 0, `timeoutMs` must exceed it |
13
+ | `accessToken` | | reference name |
14
+ | `selfId` | from the event | a mismatched event is dropped |
15
+ | `bots` | `[]` | ids treated as bots, not as people |
16
+ | `sendTimeoutMs` | `10000` | |
17
+ | `history.group` / `history.private` | `false` | allow `read_history` per address kind |
18
+ | `fileFromUrl` | `false` | allow `send_file` from an http(s) url |
19
+ | `events.turn` | `[]` | non-message classes that may start a turn; an adapter names its own `action.<type>` |
20
+
21
+ One adapter accepts one connection in `ws-reverse`; a new connection for the same account replaces the old one. A named class is `<kind>.<type>`: OneBot's own names, or an adapter's `action.<type>`; it skips the mention requirement, and an unknown name fails the mount.
22
+
23
+ An adapter whose `capabilities.outbound` is `false` is never written back: core does not call its `send` or `refuse`, and the `send_text` tool answers `unsupported` for it. Its turns still run, so a profile that lets such an adapter start turns needs a reply block that always chooses `tool`, or the mount fails.
24
+
25
+ `@dsbot-channel/onebot` supplies this transport: mount it after `@dsbot-channel/core`, then write these fields under `transport` in this plugin's own `config`, beside `channel` and `botName`; `kind` is not written. Each entry is one instance, so the same package mounts twice with two different `channel` values. Without `@dsbot-channel/core` the plugin stays pending on `dsbot-channel.registry`.
26
+
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: dsbot-channel-onebot
3
+ name: '@dsbot-channel/onebot'
@@ -0,0 +1,118 @@
1
+ import type { AdapterStatus, CapabilitySet } from '@dsbot-channel/core/adapter-status.js';
2
+ import type { ChannelSnapshot } from '@dsbot-channel/core/channel-stats.js';
3
+ import type { AdapterHandle, AdapterPorts, ChannelAdapter, HistoryInput, HistoryResult, InboundMessage, SendInput, SendResult } from '@dsbot-channel/core/contract.js';
4
+ import type { Scope } from '@dsbot-channel/core/event-types.js';
5
+ export interface OneBotAdapterConfig {
6
+ channel: string;
7
+ botName: string;
8
+ selfId?: string;
9
+ /** How this link carries OneBot; the other fields below are read per protocol. */
10
+ protocol: 'http' | 'ws-forward' | 'ws-reverse';
11
+ listen?: {
12
+ host: string;
13
+ port: number;
14
+ path: string;
15
+ } | undefined;
16
+ api?: {
17
+ url: string;
18
+ timeoutMs: number;
19
+ } | undefined;
20
+ /** ws-forward only: the event socket; absent means events arrive on the api socket. */
21
+ event?: {
22
+ url: string;
23
+ } | undefined;
24
+ /** ws-forward only: how a dropped link comes back; false turns retrying off. */
25
+ reconnect?: {
26
+ initialMs: number;
27
+ maxMs: number;
28
+ factor: number;
29
+ } | false | undefined;
30
+ /** websocket protocols only: how long silence may last before the link is closed. */
31
+ heartbeat?: {
32
+ intervalMs: number;
33
+ timeoutMs: number;
34
+ } | undefined;
35
+ /** Which addresses a profile lets this link page history for; both off unless written out. */
36
+ history?: {
37
+ group: boolean;
38
+ private: boolean;
39
+ } | undefined;
40
+ /** Whether this implementation takes a file as an http(s) url; most only take a path on its host. */
41
+ fileFromUrl?: boolean | undefined;
42
+ sendTimeoutMs: number;
43
+ accessToken?: string;
44
+ bots: readonly string[];
45
+ /** Whether this adapter answers its own status route. */
46
+ status?: boolean | undefined;
47
+ }
48
+ export interface OneBotEvent {
49
+ post_type?: unknown;
50
+ message_type?: unknown;
51
+ sub_type?: unknown;
52
+ self_id?: unknown;
53
+ message_id?: unknown;
54
+ user_id?: unknown;
55
+ group_id?: unknown;
56
+ time?: unknown;
57
+ raw_message?: unknown;
58
+ message?: unknown;
59
+ sender?: {
60
+ nickname?: unknown;
61
+ card?: unknown;
62
+ };
63
+ notice_type?: unknown;
64
+ request_type?: unknown;
65
+ meta_event_type?: unknown;
66
+ operator_id?: unknown;
67
+ target_id?: unknown;
68
+ flag?: unknown;
69
+ comment?: unknown;
70
+ interval?: unknown;
71
+ status?: unknown;
72
+ file?: {
73
+ name?: unknown;
74
+ size?: unknown;
75
+ };
76
+ }
77
+ export declare const ONEBOT_PEER_GUIDANCE = "This is a private OneBot message. Answer it with your reply as usual. If it needs no answer, call no_reply instead of staying silent. If you refuse it, call decline with a short reason.";
78
+ export declare const ONEBOT_GROUP_GUIDANCE = "This is a group message from OneBot. Your reply is posted back to that group. If it needs no answer, call no_reply; if you refuse it, call decline with a short reason.";
79
+ export declare const ONEBOT_STATUS_ROUTE = "/onebot/status";
80
+ export declare const ONEBOT_DEDUPE_TTL_MS: number;
81
+ export declare const ONEBOT_DEDUPE_LIMIT = 100000;
82
+ export declare const ONEBOT_CHAIN_TTL_MS: number;
83
+ export declare const ONEBOT_CHAIN_LIMIT = 10000;
84
+ export declare const ONEBOT_MAX_BODY_BYTES: number;
85
+ export declare const ONEBOT_NOTICE_TYPES: readonly ["group_recall", "friend_recall", "group_ban", "group_lift_ban", "group_increase", "group_decrease", "group_admin", "group_upload", "group_card", "notify"];
86
+ export declare const ONEBOT_REQUEST_TYPES: readonly ["friend", "group"];
87
+ export declare const ONEBOT_META_TYPES: readonly ["lifecycle", "heartbeat"];
88
+ /** The class a status counts an event under; undefined for a message, 'unknown' for a post_type we do not read. */
89
+ export declare function oneBotEventClass(event: OneBotEvent): string | undefined;
90
+ /** Maps one OneBot event onto the inbound message core takes; returns undefined for an event we do not read. */
91
+ export declare function mapOneBotEvent(event: OneBotEvent, config: OneBotAdapterConfig, chainOf: (messageId: string) => string | undefined, warn?: (message: string) => void, now?: () => number): InboundMessage | undefined;
92
+ /** The OneBot 11 transport: events arrive over reverse HTTP, replies call the implementation's HTTP API. */
93
+ export declare class OneBotAdapter implements ChannelAdapter {
94
+ #private;
95
+ readonly kind = "onebot";
96
+ readonly guidance: {
97
+ peer: string;
98
+ group: string;
99
+ };
100
+ readonly capabilities: CapabilitySet;
101
+ constructor(config: OneBotAdapterConfig, options?: {
102
+ warn?: (message: string) => void;
103
+ now?: () => number;
104
+ });
105
+ get snapshot(): ChannelSnapshot;
106
+ checkConfig(): void;
107
+ sessionScope(key: string): Scope | undefined;
108
+ checkSessionKey(key: string): string | undefined;
109
+ checkTarget(target: string): string | undefined;
110
+ describeTargets(): string;
111
+ status(): AdapterStatus;
112
+ send(input: SendInput): Promise<SendResult>;
113
+ /** Pages earlier messages through the implementation's history API. */
114
+ history(input: HistoryInput): Promise<HistoryResult>;
115
+ start(ports: AdapterPorts): Promise<AdapterHandle>;
116
+ /** Stops the listener without going through the handle, for tests and for a failed mount. */
117
+ stop(): Promise<void>;
118
+ }