finish onebot interface

This commit is contained in:
锦恢 2024-05-30 22:48:38 +08:00
parent b75341ae6c
commit ab7a18282f
5 changed files with 94 additions and 170 deletions

View File

@ -1,7 +1,85 @@
class LagrangeMapper {
constructor() {
import assert from 'assert';
import type * as Lagrange from './type';
type PrivateUserInvoker = (message: Lagrange.PrivateMessage) => void;
type GroupUserInvoker = (message: Lagrange.GroupMessage) => void;
type MessageInvoker = PrivateUserInvoker | GroupUserInvoker;
interface CustomDescriptor<T extends MessageInvoker> {
value?: T;
configurable?: boolean;
enumerable?: boolean;
writable?: boolean;
get?(): any;
set?(v: any): void;
}
interface MessageInvokerStorage<T extends MessageInvoker> {
invoker: T;
config: Partial<Lagrange.CommonMessage>
}
class LagrangeMapper {
private _privateUserStorage: Map<number, MessageInvokerStorage<PrivateUserInvoker>>;
private _groupStorage: Map<number, MessageInvokerStorage<GroupUserInvoker>>;
constructor() {
this._privateUserStorage = new Map<number, MessageInvokerStorage<PrivateUserInvoker>>();
this._groupStorage = new Map<number, MessageInvokerStorage<GroupUserInvoker>>();
}
get privateUserStorage() {
return this._privateUserStorage;
}
get groupStorage() {
return this._groupStorage;
}
public matchPrivateUser(message: Lagrange.PrivateMessage) {
const user_id = message.user_id;
const userStorage = this._privateUserStorage.get(user_id);
if (userStorage) {
userStorage.invoker(message);
}
}
public onPrivateUser(config: Partial<Lagrange.CommonMessage>) {
assert(config.user_id, 'onPrivateUser 中 user_id 不能为空');
const _this = this;
return function(target: any, propertyKey: string, descriptor: CustomDescriptor<PrivateUserInvoker>) {
const user_id = config.user_id;
if (_this.privateUserStorage.has(user_id)) {
console.warn(`${propertyKey} -> 用户 ${user_id} 已经被注册过了,该操作将覆盖原本的!`);
}
const invoker = descriptor.value;
_this.privateUserStorage.set(user_id, { invoker, config });
}
}
public onGroupUser(config: Partial<Lagrange.CommonMessage>) {
assert(config.user_id, 'onGroupUser 中 user_id 不能为空');
assert(config.group_id, 'onGroupUser 中 group_id 不能为空');
const _this = this;
return function(target: any, propertyKey: string, descriptor: CustomDescriptor<GroupUserInvoker>) {
}
}
public onGroup(config: Partial<Lagrange.CommonMessage>) {
assert(config.group_id, 'onGroup 中 group_id 不能为空');
const _this = this;
return function(target: any, propertyKey: string, descriptor: CustomDescriptor<GroupUserInvoker>) {
const group_id = config.group_id;
if (_this.groupStorage.has(group_id)) {
console.warn(`${propertyKey} -> 群 ${group_id} 已经被注册过了,该操作将覆盖原本的!`);
}
const invoker = descriptor.value;
_this.groupStorage.set(group_id, { invoker, config });
}
}
}
const lagMapper = new LagrangeMapper();
export default lagMapper;

View File

@ -2,6 +2,7 @@ import * as fs from 'fs';
import WebSocket from 'ws';
import { onMessage, onClose } from './event';
import { apiQueryVecdb } from './api/vecdb';
const lagrangeBuffer = fs.readFileSync('./app/publish/appsettings.json', 'utf-8');
@ -19,22 +20,16 @@ socket.on('connection', (ws: WebSocket) => {
console.log('完成 ws 连接,启动参数如下');
console.table(connectionParam);
ws.on('message', (event: Buffer) => {
const messageBuffer = event.toString('utf-8');
const messageJson = JSON.parse(messageBuffer);
if (messageJson.post_type === 'meta_event') {
return;
}
console.info(messageJson);
ws.on('message', onMessage);
ws.on('close', onClose);
for (const item of messageJson.message) {
console.log(item.type);
console.log(item.data);
const testMsg = {
action: 'send_private_msg',
params: {
user_id: 1193466151,
message: '你好'
}
});
}
ws.on('close', () => {
console.log('服务器连接关闭');
});
ws.send(JSON.stringify(testMsg));
});

148
bot/type.d.ts vendored
View File

@ -1,148 +0,0 @@
declare module Lagrange {
export interface HeartBeatStatus {
app_initialized: boolean,
app_enabled: boolean,
app_good: boolean,
online: boolean,
good: boolean
}
export type MetaEventType = 'heartbeat' | 'lifecycle';
export interface HeartBeatMessage {
interval: number,
status: HeartBeatStatus,
meta_event_type: 'heartbeat',
time: number,
self_id: number,
post_type: 'meta_event'
}
export interface Sender {
user_id: number,
nickname: string,
sex: 'unknown' | 'male' | 'female',
card?: string,
age?: number,
area?: string,
level?: string, // 群聊等级,但是是 string
role?: string,
title?: string
}
export interface MsgText {
type: 'text',
data: {
text: string
}
}
export interface MsgImage {
type: 'image',
data: {
file: string,
url: string,
// 在简略窗口可以看到的信息,对于图片来说,这就是 [图片]
summary: string
}
}
export interface MsgFace {
type: 'face',
data: {
id: string
}
}
export interface MsgAt {
type: 'at',
data: {
qq: string
}
}
export interface MsgFile {
// 一般是 ''
id: string,
// 文件名
name: string,
// 文件大小,单位:字节
size: number,
// id
busid: number,
// 链接 IPv4
url: string
}
export interface MetaMessage {
post_type: 'meta_event',
[msg: string]: any
}
export interface CommonMessage {
// 事件类型
post_type: 'message',
// 信息来自私聊还是群聊
message_type?: 'private' | 'group',
// 发送信息的是朋友还是群友/陌生人
sub_type?: 'friend' | 'normal',
// 消息的编号
message_id?: number,
// 群号
group_id?: number,
// 发消息的人的 QQ 号
user_id: number,
// 是否为匿名发言,一般都是 null
anonymous?: null | boolean,
// 消息内容(结构化)
message?: MsgText | MsgImage | MsgFace | MsgAt,
// 消息内容(纯文本)
raw_message?: string,
// 发送的时间戳
time: number,
// 自己的 id
self_id: number,
// 发送的文件
// 默认字体大小,一般都是 0
font?: number
}
export interface FileMessage {
post_type: 'notice',
user_id: number,
file: MsgFile,
notice_type?: 'offline_file',
time: number,
self_id: number
}
// 加群或者加好友
export interface AddMessage {
post_type: 'request',
sub_type: 'add',
user_id: number,
group_id: number,
// 默认为 0 代表没有邀请者
invitor_id: number,
request_type: 'private' | 'group',
// 群问题和申请者的回答
comment: string,
flag: string,
time: number,
self_id: number,
}
// 同意
export interface ApproveMessage {
post_type: 'notice',
sub_type: 'approve',
group_id: number,
operator_id: number,
user_id: number,
notice_type: 'group_increase',
time: number,
self_id: number,
}
export type Message = MetaMessage | CommonMessage | FileMessage | AddMessage | ApproveMessage
}

View File

@ -21,7 +21,6 @@ class UrlMappingRegister:
except Exception as e:
return ''
urlmapping = UrlMappingRegister()
# 样例: docs/kirigaya.cn/129.md
@ -33,7 +32,6 @@ def kirigaya_cn(source: str) -> str:
template = f'https://kirigaya.cn/blog/article?seq={article_id}'
return template
# 样例: docs/digital-document/guide/quick-start.md
# 目标: https://sterben.nitcloud.cn/zh/guide/quick-start.html
@urlmapping.startsWith('docs/digital-document')

View File

@ -3,7 +3,8 @@
"module": "CommonJS",
"target": "ES2020",
"outDir": "dist",
"esModuleInterop": true
"esModuleInterop": true,
"experimentalDecorators": true
},
"include": [
"bot/**/*"