mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
feat: go-cqhttp api send_private_forward_msg & send_group_forward_msg
This commit is contained in:
parent
5ef221608c
commit
e4508ea5c7
@ -91,6 +91,7 @@ export abstract class HttpServerBase {
|
|||||||
if (method == "get"){
|
if (method == "get"){
|
||||||
payload = req.query
|
payload = req.query
|
||||||
}
|
}
|
||||||
|
log("收到http请求", url, payload);
|
||||||
try{
|
try{
|
||||||
res.send(await handler(res, payload))
|
res.send(await handler(res, payload))
|
||||||
}catch (e) {
|
}catch (e) {
|
||||||
|
@ -13,6 +13,23 @@ export function getConfigUtil() {
|
|||||||
return new ConfigUtil(configFilePath)
|
return new ConfigUtil(configFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function truncateString(obj: any, maxLength = 500) {
|
||||||
|
if (obj !== null && typeof obj === 'object') {
|
||||||
|
Object.keys(obj).forEach(key => {
|
||||||
|
if (typeof obj[key] === 'string') {
|
||||||
|
// 如果是字符串且超过指定长度,则截断
|
||||||
|
if (obj[key].length > maxLength) {
|
||||||
|
obj[key] = obj[key].substring(0, maxLength) + '...';
|
||||||
|
}
|
||||||
|
} else if (typeof obj[key] === 'object') {
|
||||||
|
// 如果是对象或数组,则递归调用
|
||||||
|
truncateString(obj[key], maxLength);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
export function log(...msg: any[]) {
|
export function log(...msg: any[]) {
|
||||||
if (!getConfigUtil().getConfig().log) {
|
if (!getConfigUtil().getConfig().log) {
|
||||||
return
|
return
|
||||||
@ -28,7 +45,8 @@ export function log(...msg: any[]) {
|
|||||||
for (let msgItem of msg) {
|
for (let msgItem of msg) {
|
||||||
// 判断是否是对象
|
// 判断是否是对象
|
||||||
if (typeof msgItem === "object") {
|
if (typeof msgItem === "object") {
|
||||||
logMsg += JSON.stringify(msgItem) + " ";
|
let obj = JSON.parse(JSON.stringify(msgItem));
|
||||||
|
logMsg += JSON.stringify(truncateString(obj)) + " ";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
logMsg += msgItem + " ";
|
logMsg += msgItem + " ";
|
||||||
|
@ -226,9 +226,9 @@ export class NTQQApi {
|
|||||||
|
|
||||||
let members = Array.from(values) as GroupMember[]
|
let members = Array.from(values) as GroupMember[]
|
||||||
for(const member of members){
|
for(const member of members){
|
||||||
uidMaps[member.uid] = member.uin;
|
// uidMaps[member.uid] = member.uin;
|
||||||
}
|
}
|
||||||
log(uidMaps);
|
// log(uidMaps);
|
||||||
// log("members info", values);
|
// log("members info", values);
|
||||||
return members
|
return members
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -341,8 +341,8 @@ export class NTQQApi {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = false) {
|
static sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = false, timeout=10000) {
|
||||||
const sendTimeout = 10 * 1000
|
const sendTimeout = timeout
|
||||||
|
|
||||||
return new Promise<RawMessage>((resolve, reject) => {
|
return new Promise<RawMessage>((resolve, reject) => {
|
||||||
const peerUid = peer.peerUid;
|
const peerUid = peer.peerUid;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {ActionName, BaseCheckResult} from "./types"
|
import {ActionName, BaseCheckResult} from "./types"
|
||||||
import {OB11Response, OB11WebsocketResponse} from "./utils"
|
import {OB11Response} from "./utils"
|
||||||
import {OB11Return, OB11WebsocketReturn} from "../types";
|
import {OB11Return} from "../types";
|
||||||
|
|
||||||
class BaseAction<PayloadType, ReturnDataType> {
|
class BaseAction<PayloadType, ReturnDataType> {
|
||||||
actionName: ActionName
|
actionName: ActionName
|
||||||
@ -23,16 +23,16 @@ class BaseAction<PayloadType, ReturnDataType> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async websocketHandle(payload: PayloadType, echo: string): Promise<OB11WebsocketReturn<ReturnDataType | null>> {
|
public async websocketHandle(payload: PayloadType, echo: string): Promise<OB11Return<ReturnDataType | null>> {
|
||||||
const result = await this.check(payload)
|
const result = await this.check(payload)
|
||||||
if (!result.valid) {
|
if (!result.valid) {
|
||||||
return OB11WebsocketResponse.error(result.message, 1400)
|
return OB11Response.error(result.message, 1400)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const resData = await this._handle(payload)
|
const resData = await this._handle(payload)
|
||||||
return OB11WebsocketResponse.ok(resData, echo);
|
return OB11Response.ok(resData, echo);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return OB11WebsocketResponse.error(e.toString(), 1200)
|
return OB11Response.error(e.toString(), 1200, echo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import {ActionName, BaseCheckResult} from "./types";
|
|||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import {log} from "../../common/utils";
|
import {log} from "../../common/utils";
|
||||||
import {v4 as uuidv4} from "uuid"
|
import {v4 as uuidv4} from "uuid"
|
||||||
|
import {parseCQCode} from "../cqcode";
|
||||||
|
|
||||||
function checkSendMessage(sendMsgList: OB11MessageData[]) {
|
function checkSendMessage(sendMsgList: OB11MessageData[]) {
|
||||||
function checkUri(uri: string): boolean {
|
function checkUri(uri: string): boolean {
|
||||||
@ -49,7 +50,7 @@ export interface ReturnDataType {
|
|||||||
message_id: number
|
message_id: number
|
||||||
}
|
}
|
||||||
|
|
||||||
class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||||
actionName = ActionName.SendMsg
|
actionName = ActionName.SendMsg
|
||||||
|
|
||||||
protected async check(payload: OB11PostSendMsg): Promise<BaseCheckResult> {
|
protected async check(payload: OB11PostSendMsg): Promise<BaseCheckResult> {
|
||||||
@ -115,14 +116,15 @@ class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private convertMessage2List(message: OB11MessageMixType) {
|
protected convertMessage2List(message: OB11MessageMixType) {
|
||||||
if (typeof message === "string") {
|
if (typeof message === "string") {
|
||||||
message = [{
|
// message = [{
|
||||||
type: OB11MessageDataType.text,
|
// type: OB11MessageDataType.text,
|
||||||
data: {
|
// data: {
|
||||||
text: message
|
// text: message
|
||||||
}
|
// }
|
||||||
}] as OB11MessageData[]
|
// }] as OB11MessageData[]
|
||||||
|
message = parseCQCode(message.toString())
|
||||||
} else if (!Array.isArray(message)) {
|
} else if (!Array.isArray(message)) {
|
||||||
message = [message]
|
message = [message]
|
||||||
}
|
}
|
||||||
@ -143,9 +145,8 @@ class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
peerUid: selfInfo.uid
|
peerUid: selfInfo.uid
|
||||||
}
|
}
|
||||||
let nodeIds: string[] = []
|
let nodeIds: string[] = []
|
||||||
for (const messageNode of messageNodes) {
|
for (const messageNode of messageNodes){
|
||||||
// 一个node表示一个人的消息
|
// 一个node表示一个人的消息
|
||||||
|
|
||||||
let nodeId = messageNode.data.id;
|
let nodeId = messageNode.data.id;
|
||||||
// 有nodeId表示一个子转发消息卡片
|
// 有nodeId表示一个子转发消息卡片
|
||||||
if (nodeId) {
|
if (nodeId) {
|
||||||
@ -153,14 +154,15 @@ class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
} else {
|
} else {
|
||||||
// 自定义的消息
|
// 自定义的消息
|
||||||
// 提取消息段,发给自己生成消息id
|
// 提取消息段,发给自己生成消息id
|
||||||
const {
|
|
||||||
sendElements,
|
|
||||||
deleteAfterSentFiles
|
|
||||||
} = await this.createSendElements(this.convertMessage2List(messageNode.data.content), group)
|
|
||||||
try {
|
try {
|
||||||
|
const {
|
||||||
|
sendElements,
|
||||||
|
deleteAfterSentFiles
|
||||||
|
} = await this.createSendElements(this.convertMessage2List(messageNode.data.content), group);
|
||||||
log("开始生成转发节点", sendElements);
|
log("开始生成转发节点", sendElements);
|
||||||
const nodeMsg = await this.send(selfPeer, sendElements, deleteAfterSentFiles, true);
|
const nodeMsg = await this.send(selfPeer, sendElements, deleteAfterSentFiles, true);
|
||||||
nodeIds.push(nodeMsg.msgId)
|
nodeIds.push(nodeMsg.msgId)
|
||||||
|
log("转发节点生成成功", nodeMsg.msgId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log("生效转发消息节点失败", e)
|
log("生效转发消息节点失败", e)
|
||||||
}
|
}
|
||||||
@ -240,7 +242,8 @@ class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -255,7 +258,7 @@ class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
|||||||
if (!sendElements.length) {
|
if (!sendElements.length) {
|
||||||
throw ("消息体无法解析")
|
throw ("消息体无法解析")
|
||||||
}
|
}
|
||||||
const returnMsg = await NTQQApi.sendMsg(peer, sendElements, waitComplete)
|
const returnMsg = await NTQQApi.sendMsg(peer, sendElements, waitComplete, 20000);
|
||||||
addHistoryMsg(returnMsg)
|
addHistoryMsg(returnMsg)
|
||||||
deleteAfterSentFiles.map(f => fs.unlink(f, () => {
|
deleteAfterSentFiles.map(f => fs.unlink(f, () => {
|
||||||
}))
|
}))
|
||||||
|
15
src/onebot11/action/go-cqhttp/SendForwardMsg.ts
Normal file
15
src/onebot11/action/go-cqhttp/SendForwardMsg.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import SendMsg, {ReturnDataType} from "../SendMsg";
|
||||||
|
import {OB11MessageMixType, OB11PostSendMsg} from "../../types";
|
||||||
|
import {ActionName, BaseCheckResult} from "../types";
|
||||||
|
|
||||||
|
export class GoCQHTTPSendGroupForwardMsg extends SendMsg{
|
||||||
|
actionName = ActionName.GoCQHTTP_SendGroupForwardMsg;
|
||||||
|
protected async check(payload: OB11PostSendMsg){
|
||||||
|
payload.message = this.convertMessage2List(payload.messages);
|
||||||
|
return super.check(payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GoCQHTTPSendPrivateForwardMsg extends GoCQHTTPSendGroupForwardMsg{
|
||||||
|
actionName = ActionName.GoCQHTTP_SendPrivateForwardMsg;
|
||||||
|
}
|
@ -14,6 +14,7 @@ import GetVersionInfo from "./GetVersionInfo";
|
|||||||
import CanSendRecord from "./CanSendRecord";
|
import CanSendRecord from "./CanSendRecord";
|
||||||
import CanSendImage from "./CanSendImage";
|
import CanSendImage from "./CanSendImage";
|
||||||
import GetStatus from "./GetStatus";
|
import GetStatus from "./GetStatus";
|
||||||
|
import {GoCQHTTPSendGroupForwardMsg, GoCQHTTPSendPrivateForwardMsg} from "./go-cqhttp/SendForwardMsg";
|
||||||
|
|
||||||
export const actionHandlers = [
|
export const actionHandlers = [
|
||||||
new GetMsg(),
|
new GetMsg(),
|
||||||
@ -25,7 +26,12 @@ export const actionHandlers = [
|
|||||||
new GetVersionInfo(),
|
new GetVersionInfo(),
|
||||||
new CanSendRecord(),
|
new CanSendRecord(),
|
||||||
new CanSendImage(),
|
new CanSendImage(),
|
||||||
new GetStatus()
|
new GetStatus(),
|
||||||
|
|
||||||
|
//以下为go-cqhttp api
|
||||||
|
new GoCQHTTPSendGroupForwardMsg(),
|
||||||
|
new GoCQHTTPSendPrivateForwardMsg(),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
function initActionMap() {
|
function initActionMap() {
|
||||||
|
@ -28,4 +28,7 @@ export enum ActionName {
|
|||||||
GetStatus = "get_status",
|
GetStatus = "get_status",
|
||||||
CanSendRecord = "can_send_record",
|
CanSendRecord = "can_send_record",
|
||||||
CanSendImage = "can_send_image",
|
CanSendImage = "can_send_image",
|
||||||
|
// 以下为go-cqhttp api
|
||||||
|
GoCQHTTP_SendGroupForwardMsg = "send_group_forward_msg",
|
||||||
|
GoCQHTTP_SendPrivateForwardMsg = "send_private_forward_msg"
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import {OB11Return, OB11WebsocketReturn} from '../types';
|
import {OB11Return} from '../types';
|
||||||
|
|
||||||
export class OB11Response {
|
export class OB11Response {
|
||||||
static res<T>(data: T, status: string, retcode: number, message: string = ""): OB11Return<T> {
|
static res<T>(data: T, status: string, retcode: number, message: string = ""): OB11Return<T> {
|
||||||
@ -6,31 +6,25 @@ export class OB11Response {
|
|||||||
status: status,
|
status: status,
|
||||||
retcode: retcode,
|
retcode: retcode,
|
||||||
data: data,
|
data: data,
|
||||||
message: message
|
message: message,
|
||||||
|
wording: message,
|
||||||
|
echo: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static ok<T>(data: T) {
|
|
||||||
return OB11Response.res<T>(data, "ok", 0)
|
|
||||||
}
|
|
||||||
static error(err: string, retcode: number) {
|
|
||||||
return OB11Response.res(null, "failed", retcode, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class OB11WebsocketResponse {
|
|
||||||
static res<T>(data: T, status: string, retcode: number, echo: string, message: string = ""): OB11WebsocketReturn<T> {
|
|
||||||
return {
|
|
||||||
status: status,
|
|
||||||
retcode: retcode,
|
|
||||||
data: data,
|
|
||||||
echo: echo,
|
|
||||||
message: message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static ok<T>(data: T, echo: string = "") {
|
static ok<T>(data: T, echo: string = "") {
|
||||||
return OB11WebsocketResponse.res<T>(data, "ok", 0, echo)
|
let res = OB11Response.res<T>(data, "ok", 0)
|
||||||
|
if (echo) {
|
||||||
|
res.echo = echo;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static error(err: string, retcode: number, echo: string = "") {
|
static error(err: string, retcode: number, echo: string = "") {
|
||||||
return OB11WebsocketResponse.res(null, "failed", retcode, echo, err)
|
let res = OB11Response.res(null, "failed", retcode, err)
|
||||||
|
if (echo) {
|
||||||
|
res.echo = echo;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
49
src/onebot11/cqcode.ts
Normal file
49
src/onebot11/cqcode.ts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import {OB11MessageData} from "./types";
|
||||||
|
|
||||||
|
const pattern = /\[CQ:(\w+)((,\w+=[^,\]]*)*)\]/
|
||||||
|
|
||||||
|
function unescape(source: string) {
|
||||||
|
return String(source)
|
||||||
|
.replace(/[/g, '[')
|
||||||
|
.replace(/]/g, ']')
|
||||||
|
.replace(/,/g, ',')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
}
|
||||||
|
|
||||||
|
function from(source: string) {
|
||||||
|
const capture = pattern.exec(source)
|
||||||
|
if (!capture) return null
|
||||||
|
const [, type, attrs] = capture
|
||||||
|
const data: Record<string, any> = {}
|
||||||
|
attrs && attrs.slice(1).split(',').forEach((str) => {
|
||||||
|
const index = str.indexOf('=')
|
||||||
|
data[str.slice(0, index)] = unescape(str.slice(index + 1))
|
||||||
|
})
|
||||||
|
return {type, data, capture}
|
||||||
|
}
|
||||||
|
|
||||||
|
function h(type: string, data: any) {
|
||||||
|
return {
|
||||||
|
type,
|
||||||
|
data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseCQCode(source: string): OB11MessageData[] {
|
||||||
|
const elements: any[] = []
|
||||||
|
let result: ReturnType<typeof from>
|
||||||
|
while ((result = from(source))) {
|
||||||
|
const {type, data, capture} = result
|
||||||
|
if (capture.index) {
|
||||||
|
elements.push(h('text', {text: unescape(source.slice(0, capture.index))}))
|
||||||
|
}
|
||||||
|
elements.push(h(type, data))
|
||||||
|
source = source.slice(capture.index + capture[0].length)
|
||||||
|
}
|
||||||
|
if (source) elements.push(h('text', {text: unescape(source)}))
|
||||||
|
return elements
|
||||||
|
}
|
||||||
|
|
||||||
|
// const result = parseCQCode("[CQ:at,qq=114514]早上好啊[CQ:image,file=http://baidu.com/1.jpg,type=show,id=40004]")
|
||||||
|
// const result = parseCQCode("好好好")
|
||||||
|
// console.log(JSON.stringify(result))
|
@ -4,7 +4,7 @@ import * as WebSocket from "ws";
|
|||||||
import {selfInfo} from "../../../common/data";
|
import {selfInfo} from "../../../common/data";
|
||||||
import {LifeCycleSubType, OB11LifeCycleEvent} from "../../event/meta/OB11LifeCycleEvent";
|
import {LifeCycleSubType, OB11LifeCycleEvent} from "../../event/meta/OB11LifeCycleEvent";
|
||||||
import {ActionName} from "../../action/types";
|
import {ActionName} from "../../action/types";
|
||||||
import {OB11WebsocketResponse} from "../../action/utils";
|
import {OB11Response} from "../../action/utils";
|
||||||
import BaseAction from "../../action/BaseAction";
|
import BaseAction from "../../action/BaseAction";
|
||||||
import {actionMap} from "../../action";
|
import {actionMap} from "../../action";
|
||||||
import {registerWsEventSender, unregisterWsEventSender} from "../postevent";
|
import {registerWsEventSender, unregisterWsEventSender} from "../postevent";
|
||||||
@ -35,22 +35,22 @@ export class ReverseWebsocket {
|
|||||||
public async onmessage(msg: string) {
|
public async onmessage(msg: string) {
|
||||||
let receiveData: { action: ActionName, params: any, echo?: string } = {action: null, params: {}}
|
let receiveData: { action: ActionName, params: any, echo?: string } = {action: null, params: {}}
|
||||||
let echo = ""
|
let echo = ""
|
||||||
log("收到反向Websocket消息", msg.toString())
|
log("收到反向Websocket消息", msg)
|
||||||
try {
|
try {
|
||||||
receiveData = JSON.parse(msg.toString())
|
receiveData = JSON.parse(msg.toString())
|
||||||
echo = receiveData.echo
|
echo = receiveData.echo
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return wsReply(this.websocket, OB11WebsocketResponse.error("json解析失败,请检查数据格式", 1400, echo))
|
return wsReply(this.websocket, OB11Response.error("json解析失败,请检查数据格式", 1400, echo))
|
||||||
}
|
}
|
||||||
const action: BaseAction<any, any> = actionMap.get(receiveData.action);
|
const action: BaseAction<any, any> = actionMap.get(receiveData.action);
|
||||||
if (!action) {
|
if (!action) {
|
||||||
return wsReply(this.websocket, OB11WebsocketResponse.error("不支持的api " + receiveData.action, 1404, echo))
|
return wsReply(this.websocket, OB11Response.error("不支持的api " + receiveData.action, 1404, echo))
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
let handleResult = await action.websocketHandle(receiveData.params, echo);
|
let handleResult = await action.websocketHandle(receiveData.params, echo);
|
||||||
wsReply(this.websocket, handleResult)
|
wsReply(this.websocket, handleResult)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
wsReply(this.websocket, OB11WebsocketResponse.error(`api处理出错:${e}`, 1200, echo))
|
wsReply(this.websocket, OB11Response.error(`api处理出错:${e}`, 1200, echo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {WebSocket} from "ws";
|
import {WebSocket} from "ws";
|
||||||
import {getConfigUtil, log} from "../../../common/utils";
|
import {getConfigUtil, log} from "../../../common/utils";
|
||||||
import {actionMap} from "../../action";
|
import {actionMap} from "../../action";
|
||||||
import {OB11WebsocketResponse} from "../../action/utils";
|
import {OB11Response} from "../../action/utils";
|
||||||
import {postWsEvent, registerWsEventSender, unregisterWsEventSender} from "../postevent";
|
import {postWsEvent, registerWsEventSender, unregisterWsEventSender} from "../postevent";
|
||||||
import {ActionName} from "../../action/types";
|
import {ActionName} from "../../action/types";
|
||||||
import BaseAction from "../../action/BaseAction";
|
import BaseAction from "../../action/BaseAction";
|
||||||
@ -15,19 +15,19 @@ let heartbeatRunning = false;
|
|||||||
|
|
||||||
class OB11WebsocketServer extends WebsocketServerBase {
|
class OB11WebsocketServer extends WebsocketServerBase {
|
||||||
authorizeFailed(wsClient: WebSocket) {
|
authorizeFailed(wsClient: WebSocket) {
|
||||||
wsClient.send(JSON.stringify(OB11WebsocketResponse.res(null, "failed", 1403, "token验证失败")))
|
wsClient.send(JSON.stringify(OB11Response.res(null, "failed", 1403, "token验证失败")))
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleAction(wsClient: WebSocket, actionName: string, params: any, echo?: string) {
|
async handleAction(wsClient: WebSocket, actionName: string, params: any, echo?: string) {
|
||||||
const action: BaseAction<any, any> = actionMap.get(actionName);
|
const action: BaseAction<any, any> = actionMap.get(actionName);
|
||||||
if (!action) {
|
if (!action) {
|
||||||
return wsReply(wsClient, OB11WebsocketResponse.error("不支持的api " + actionName, 1404, echo))
|
return wsReply(wsClient, OB11Response.error("不支持的api " + actionName, 1404, echo))
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
let handleResult = await action.websocketHandle(params, echo);
|
let handleResult = await action.websocketHandle(params, echo);
|
||||||
wsReply(wsClient, handleResult)
|
wsReply(wsClient, handleResult)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
wsReply(wsClient, OB11WebsocketResponse.error(`api处理出错:${e}`, 1200, echo))
|
wsReply(wsClient, OB11Response.error(`api处理出错:${e}`, 1200, echo))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,12 +36,12 @@ class OB11WebsocketServer extends WebsocketServerBase {
|
|||||||
wsClient.on("message", async (msg) => {
|
wsClient.on("message", async (msg) => {
|
||||||
let receiveData: { action: ActionName, params: any, echo?: string } = {action: null, params: {}}
|
let receiveData: { action: ActionName, params: any, echo?: string } = {action: null, params: {}}
|
||||||
let echo = ""
|
let echo = ""
|
||||||
log("收到正向Websocket消息", msg.toString())
|
log("收到正向Websocket消息", msg)
|
||||||
try {
|
try {
|
||||||
receiveData = JSON.parse(msg.toString())
|
receiveData = JSON.parse(msg.toString())
|
||||||
echo = receiveData.echo
|
echo = receiveData.echo
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return wsReply(wsClient, OB11WebsocketResponse.error("json解析失败,请检查数据格式", 1400, echo))
|
return wsReply(wsClient, OB11Response.error("json解析失败,请检查数据格式", 1400, echo))
|
||||||
}
|
}
|
||||||
this.handleAction(wsClient, receiveData.action, receiveData.params, receiveData.echo).then()
|
this.handleAction(wsClient, receiveData.action, receiveData.params, receiveData.echo).then()
|
||||||
})
|
})
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import * as websocket from "ws";
|
import * as websocket from "ws";
|
||||||
import {OB11WebsocketResponse} from "../../action/utils";
|
import {OB11Response} from "../../action/utils";
|
||||||
import {PostEventType} from "../postevent";
|
import {PostEventType} from "../postevent";
|
||||||
import {log} from "../../../common/utils";
|
import {log} from "../../../common/utils";
|
||||||
|
|
||||||
export function wsReply(wsClient: websocket.WebSocket, data: OB11WebsocketResponse | PostEventType) {
|
export function wsReply(wsClient: websocket.WebSocket, data: OB11Response | PostEventType) {
|
||||||
try {
|
try {
|
||||||
let packet = Object.assign({
|
let packet = Object.assign({
|
||||||
}, data);
|
}, data);
|
||||||
|
@ -76,10 +76,8 @@ export interface OB11Return<DataType> {
|
|||||||
retcode: number
|
retcode: number
|
||||||
data: DataType
|
data: DataType
|
||||||
message: string,
|
message: string,
|
||||||
}
|
echo?: string, // ws调用api才有此字段
|
||||||
|
wording?: string, // go-cqhttp字段,错误信息
|
||||||
export interface OB11WebsocketReturn<DataType> extends OB11Return<DataType>{
|
|
||||||
echo: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum OB11MessageDataType {
|
export enum OB11MessageDataType {
|
||||||
@ -160,6 +158,7 @@ export interface OB11PostSendMsg {
|
|||||||
user_id: string,
|
user_id: string,
|
||||||
group_id?: string,
|
group_id?: string,
|
||||||
message: OB11MessageMixType;
|
message: OB11MessageMixType;
|
||||||
|
messages?: OB11MessageMixType; // 兼容 go-cqhttp
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OB11Version {
|
export interface OB11Version {
|
||||||
|
@ -60,40 +60,4 @@ export async function uri2local(fileName: string, uri: string){
|
|||||||
res.success = true
|
res.success = true
|
||||||
res.path = filePath
|
res.path = filePath
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function checkSendMessage(sendMsgList: OB11MessageData[]) {
|
|
||||||
function checkUri(uri: string): boolean {
|
|
||||||
const pattern = /^(file:\/\/|http:\/\/|https:\/\/|base64:\/\/)/;
|
|
||||||
return pattern.test(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let msg of sendMsgList) {
|
|
||||||
if (msg["type"] && msg["data"]) {
|
|
||||||
let type = msg["type"];
|
|
||||||
let data = msg["data"];
|
|
||||||
if (type === "text" && !data["text"]) {
|
|
||||||
return 400;
|
|
||||||
} else if (["image", "voice", "record"].includes(type)) {
|
|
||||||
if (!data["file"]) {
|
|
||||||
return 400;
|
|
||||||
} else {
|
|
||||||
if (checkUri(data["file"])) {
|
|
||||||
return 200;
|
|
||||||
} else {
|
|
||||||
return 400;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (type === "at" && !data["qq"]) {
|
|
||||||
return 400;
|
|
||||||
} else if (type === "reply" && !data["id"]) {
|
|
||||||
return 400;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 400
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 200;
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user