mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
Merge pull request #37 from PurpleNoon/action-layering
This commit is contained in:
commit
1c92f37188
26
src/onebot11/actions/ActionTemplate.ts
Normal file
26
src/onebot11/actions/ActionTemplate.ts
Normal file
@ -0,0 +1,26 @@
|
||||
// import { OB11Return } from '../types';
|
||||
// import BaseAction from "./BaseAction";
|
||||
|
||||
// export type ActionType = ''
|
||||
|
||||
// export interface PayloadType {
|
||||
// action: ActionType
|
||||
// // 参数定义待完善
|
||||
// [k: string | number]: any
|
||||
// }
|
||||
|
||||
// export interface ReturnDataType {
|
||||
// // 参数定义待完善
|
||||
// [k: string | number]: any
|
||||
// }
|
||||
|
||||
|
||||
// class ActionTemplate extends BaseAction {
|
||||
// static ACTION_TYPE: ActionType = ''
|
||||
|
||||
// async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
|
||||
// export default ActionTemplate
|
25
src/onebot11/actions/BaseAction.ts
Normal file
25
src/onebot11/actions/BaseAction.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { BaseCheckResult } from "./types"
|
||||
import { OB11Response } from "./utils"
|
||||
|
||||
class BaseAction {
|
||||
async check(jsonData: any): Promise<BaseCheckResult> {
|
||||
return {
|
||||
valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
async handle(jsonData: any) {
|
||||
const result = await this.check(jsonData)
|
||||
if (!result.valid) {
|
||||
return OB11Response.error(result.message)
|
||||
}
|
||||
const resData = await this._handle(jsonData)
|
||||
return resData
|
||||
}
|
||||
|
||||
async _handle(payload: unknown): Promise<unknown> {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseAction
|
23
src/onebot11/actions/GetFriendList.ts
Normal file
23
src/onebot11/actions/GetFriendList.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { OB11Response } from "./utils";
|
||||
import { OB11Return, OB11User } from '../types';
|
||||
import { OB11Constructor } from "../constructor";
|
||||
import { friends } from "../../common/data";
|
||||
import BaseAction from "./BaseAction";
|
||||
|
||||
export type ActionType = 'get_friend_list'
|
||||
|
||||
export interface PayloadType {
|
||||
action: ActionType
|
||||
}
|
||||
|
||||
export type ReturnDataType = OB11User[]
|
||||
|
||||
class GetFriendList extends BaseAction {
|
||||
static ACTION_TYPE: ActionType = 'get_friend_list'
|
||||
|
||||
async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
return OB11Response.ok(OB11Constructor.friends(friends));
|
||||
}
|
||||
}
|
||||
|
||||
export default GetFriendList
|
30
src/onebot11/actions/GetGroupInfo.ts
Normal file
30
src/onebot11/actions/GetGroupInfo.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { OB11Response } from "./utils";
|
||||
import { OB11Group, OB11Return } from '../types';
|
||||
import { getGroup, groups } from "../../common/data";
|
||||
import { OB11Constructor } from "../constructor";
|
||||
import BaseAction from "./BaseAction";
|
||||
|
||||
export type ActionType = 'get_group_info'
|
||||
|
||||
export interface PayloadType {
|
||||
action: ActionType
|
||||
group_id: number
|
||||
}
|
||||
|
||||
export type ReturnDataType = OB11Group[]
|
||||
|
||||
class GetGroupInfo extends BaseAction {
|
||||
static ACTION_TYPE: ActionType = 'get_group_info'
|
||||
|
||||
async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
const group = await getGroup(payload.group_id.toString())
|
||||
if (group) {
|
||||
return OB11Response.ok(OB11Constructor.groups(groups));
|
||||
}
|
||||
else {
|
||||
return OB11Response.error(`群${payload.group_id}不存在`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default GetGroupInfo
|
23
src/onebot11/actions/GetGroupList.ts
Normal file
23
src/onebot11/actions/GetGroupList.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { OB11Response } from "./utils";
|
||||
import { OB11Group, OB11Return } from '../types';
|
||||
import { OB11Constructor } from "../constructor";
|
||||
import { groups } from "../../common/data";
|
||||
import BaseAction from "./BaseAction";
|
||||
|
||||
export type ActionType = 'get_group_list'
|
||||
|
||||
export interface PayloadType {
|
||||
action: ActionType
|
||||
}
|
||||
|
||||
export type ReturnDataType = OB11Group[]
|
||||
|
||||
class GetGroupList extends BaseAction {
|
||||
static ACTION_TYPE: ActionType = 'get_group_list'
|
||||
|
||||
async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
return OB11Response.ok(OB11Constructor.groups(groups));
|
||||
}
|
||||
}
|
||||
|
||||
export default GetGroupList
|
31
src/onebot11/actions/GetGroupMemberInfo.ts
Normal file
31
src/onebot11/actions/GetGroupMemberInfo.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { OB11Response } from "./utils";
|
||||
import { OB11GroupMember, OB11Return } from '../types';
|
||||
import { getGroupMember } from "../../common/data";
|
||||
import { OB11Constructor } from "../constructor";
|
||||
import BaseAction from "./BaseAction";
|
||||
|
||||
export type ActionType = 'get_group_member_info'
|
||||
|
||||
export interface PayloadType {
|
||||
action: ActionType
|
||||
group_id: number
|
||||
user_id: number
|
||||
}
|
||||
|
||||
export type ReturnDataType = OB11GroupMember
|
||||
|
||||
class GetGroupMemberInfo extends BaseAction {
|
||||
static ACTION_TYPE: ActionType = 'get_group_member_info'
|
||||
|
||||
async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
const member = await getGroupMember(payload.group_id.toString(), payload.user_id.toString())
|
||||
if (member) {
|
||||
return OB11Response.ok(OB11Constructor.groupMember(payload.group_id.toString(), member))
|
||||
}
|
||||
else {
|
||||
return OB11Response.error(`群成员${payload.user_id}不存在`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default GetGroupMemberInfo
|
34
src/onebot11/actions/GetGroupMemberList.ts
Normal file
34
src/onebot11/actions/GetGroupMemberList.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { OB11Response } from "./utils";
|
||||
import { OB11GroupMember, OB11Return } from '../types';
|
||||
import { getGroup } from "../../common/data";
|
||||
import { NTQQApi } from "../../ntqqapi/ntcall";
|
||||
import { OB11Constructor } from "../constructor";
|
||||
import BaseAction from "./BaseAction";
|
||||
|
||||
export type ActionType = 'get_group_member_list'
|
||||
|
||||
export interface PayloadType {
|
||||
action: ActionType
|
||||
group_id: number
|
||||
}
|
||||
|
||||
export type ReturnDataType = OB11GroupMember[]
|
||||
|
||||
class GetGroupMemberList extends BaseAction {
|
||||
static ACTION_TYPE: ActionType = 'get_group_member_list'
|
||||
|
||||
async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
const group = await getGroup(payload.group_id.toString());
|
||||
if (group) {
|
||||
if (!group.members?.length) {
|
||||
group.members = await NTQQApi.getGroupMembers(payload.group_id.toString())
|
||||
}
|
||||
return OB11Response.ok(OB11Constructor.groupMembers(group));
|
||||
}
|
||||
else {
|
||||
return OB11Response.error(`群${payload.group_id}不存在`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default GetGroupMemberList
|
23
src/onebot11/actions/GetLoginInfo.ts
Normal file
23
src/onebot11/actions/GetLoginInfo.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { OB11Response } from "./utils";
|
||||
import { OB11Return, OB11User } from '../types';
|
||||
import { OB11Constructor } from "../constructor";
|
||||
import { selfInfo } from "../../common/data";
|
||||
import BaseAction from "./BaseAction";
|
||||
|
||||
export type ActionType = 'get_login_info'
|
||||
|
||||
export interface PayloadType {
|
||||
action: ActionType
|
||||
}
|
||||
|
||||
export type ReturnDataType = OB11User
|
||||
|
||||
class GetLoginInfo extends BaseAction {
|
||||
static ACTION_TYPE: ActionType = 'get_login_info'
|
||||
|
||||
async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
return OB11Response.ok(OB11Constructor.selfInfo(selfInfo));
|
||||
}
|
||||
}
|
||||
|
||||
export default GetLoginInfo
|
32
src/onebot11/actions/GetMsg.ts
Normal file
32
src/onebot11/actions/GetMsg.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { OB11Response } from "./utils";
|
||||
import { msgHistory } from "../../common/data";
|
||||
import { OB11Message, OB11Return } from '../types';
|
||||
import { OB11Constructor } from "../constructor";
|
||||
import { log } from "../../common/utils";
|
||||
import BaseAction from "./BaseAction";
|
||||
|
||||
export type ActionType = 'get_msg'
|
||||
|
||||
export interface PayloadType {
|
||||
action: ActionType
|
||||
message_id: string
|
||||
}
|
||||
|
||||
export type ReturnDataType = OB11Message
|
||||
|
||||
class GetMsg extends BaseAction {
|
||||
static ACTION_TYPE: ActionType = 'get_msg'
|
||||
|
||||
async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
log("history msg ids", Object.keys(msgHistory));
|
||||
const msg = msgHistory[payload.message_id.toString()]
|
||||
if (msg) {
|
||||
const msgData = await OB11Constructor.message(msg);
|
||||
return OB11Response.ok(msgData)
|
||||
} else {
|
||||
return OB11Response.error("消息不存在")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default GetMsg
|
24
src/onebot11/actions/SendGroupMsg.ts
Normal file
24
src/onebot11/actions/SendGroupMsg.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { OB11PostSendMsg, OB11Return } from '../types';
|
||||
import SendMsg from "./SendMsg";
|
||||
import BaseAction from './BaseAction';
|
||||
|
||||
export type ActionType = 'send_group_msg'
|
||||
|
||||
export interface PayloadType extends OB11PostSendMsg {
|
||||
action: ActionType
|
||||
}
|
||||
|
||||
export interface ReturnDataType {
|
||||
message_id: string
|
||||
}
|
||||
|
||||
class SendGroupMsg extends BaseAction {
|
||||
static ACTION_TYPE: ActionType = 'send_group_msg'
|
||||
|
||||
async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
// 偷懒借用现有逻辑
|
||||
return new SendMsg()._handle(payload as any)
|
||||
}
|
||||
}
|
||||
|
||||
export default SendGroupMsg
|
133
src/onebot11/actions/SendMsg.ts
Normal file
133
src/onebot11/actions/SendMsg.ts
Normal file
@ -0,0 +1,133 @@
|
||||
import { AtType, ChatType, Group } from "../../ntqqapi/types";
|
||||
import { friends, getGroup, getStrangerByUin, msgHistory } from "../../common/data";
|
||||
import { OB11Return, OB11MessageData, OB11MessageDataType, OB11PostSendMsg } from '../types';
|
||||
import { NTQQApi } from "../../ntqqapi/ntcall";
|
||||
import { Peer } from "../../ntqqapi/ntcall";
|
||||
import { SendMessageElement } from "../../ntqqapi/types";
|
||||
import { SendMsgElementConstructor } from "../../ntqqapi/constructor";
|
||||
import { uri2local } from "../utils";
|
||||
import { OB11Response } from "./utils";
|
||||
import { v4 as uuid4 } from 'uuid';
|
||||
import { log } from "../../common/utils";
|
||||
import BaseAction from "./BaseAction";
|
||||
|
||||
export type ActionType = 'send_msg'
|
||||
|
||||
export interface PayloadType extends OB11PostSendMsg {
|
||||
action: ActionType
|
||||
}
|
||||
|
||||
export interface ReturnDataType {
|
||||
message_id: string
|
||||
}
|
||||
|
||||
class SendMsg extends BaseAction {
|
||||
static ACTION_TYPE: ActionType = 'send_msg'
|
||||
|
||||
async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
const peer: Peer = {
|
||||
chatType: ChatType.friend,
|
||||
peerUid: ""
|
||||
}
|
||||
let group: Group | undefined = undefined;
|
||||
if (payload?.group_id) {
|
||||
group = await getGroup(payload.group_id.toString())
|
||||
if (!group) {
|
||||
return OB11Response.error(`群${payload.group_id}不存在`)
|
||||
}
|
||||
peer.chatType = ChatType.group
|
||||
// peer.name = group.name
|
||||
peer.peerUid = group.groupCode
|
||||
}
|
||||
else if (payload?.user_id) {
|
||||
const friend = friends.find(f => f.uin == payload.user_id.toString())
|
||||
if (friend) {
|
||||
// peer.name = friend.nickName
|
||||
peer.peerUid = friend.uid
|
||||
}
|
||||
else {
|
||||
peer.chatType = ChatType.temp
|
||||
const tempUser = getStrangerByUin(payload.user_id.toString())
|
||||
if (!tempUser) {
|
||||
return OB11Response.error(`找不到私聊对象${payload.user_id}`)
|
||||
}
|
||||
// peer.name = tempUser.nickName
|
||||
peer.peerUid = tempUser.uid
|
||||
}
|
||||
}
|
||||
if (typeof payload.message === "string") {
|
||||
payload.message = [{
|
||||
type: OB11MessageDataType.text,
|
||||
data: {
|
||||
text: payload.message
|
||||
}
|
||||
}] as OB11MessageData[]
|
||||
}
|
||||
else if (!Array.isArray(payload.message)) {
|
||||
payload.message = [payload.message]
|
||||
}
|
||||
const sendElements: SendMessageElement[] = []
|
||||
for (let sendMsg of payload.message) {
|
||||
switch (sendMsg.type) {
|
||||
case OB11MessageDataType.text: {
|
||||
const text = sendMsg.data?.text;
|
||||
if (text) {
|
||||
sendElements.push(SendMsgElementConstructor.text(sendMsg.data!.text))
|
||||
}
|
||||
} break;
|
||||
case OB11MessageDataType.at: {
|
||||
let atQQ = sendMsg.data?.qq;
|
||||
if (atQQ) {
|
||||
atQQ = atQQ.toString()
|
||||
if (atQQ === "all") {
|
||||
sendElements.push(SendMsgElementConstructor.at(atQQ, atQQ, AtType.atAll, "全体成员"))
|
||||
}
|
||||
else {
|
||||
const atMember = group?.members.find(m => m.uin == atQQ)
|
||||
if (atMember) {
|
||||
sendElements.push(SendMsgElementConstructor.at(atQQ, atMember.uid, AtType.atUser, atMember.cardName || atMember.nick))
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case OB11MessageDataType.reply: {
|
||||
let replyMsgId = sendMsg.data.id;
|
||||
if (replyMsgId) {
|
||||
replyMsgId = replyMsgId.toString()
|
||||
const replyMsg = msgHistory[replyMsgId]
|
||||
if (replyMsg) {
|
||||
sendElements.push(SendMsgElementConstructor.reply(replyMsg.msgSeq, replyMsgId, replyMsg.senderUin, replyMsg.senderUin))
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case OB11MessageDataType.image: {
|
||||
const file = sendMsg.data?.file
|
||||
if (file) {
|
||||
const picPath = await (await uri2local(uuid4(), file)).path
|
||||
if (picPath) {
|
||||
sendElements.push(await SendMsgElementConstructor.pic(picPath))
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case OB11MessageDataType.voice: {
|
||||
const file = sendMsg.data?.file
|
||||
if (file) {
|
||||
const voicePath = await (await uri2local(uuid4(), file)).path
|
||||
if (voicePath) {
|
||||
sendElements.push(await SendMsgElementConstructor.ptt(voicePath))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log("send msg:", peer, sendElements)
|
||||
try {
|
||||
const returnMsg = await NTQQApi.sendMsg(peer, sendElements)
|
||||
return OB11Response.ok({ message_id: returnMsg.msgId })
|
||||
} catch (e) {
|
||||
return OB11Response.error(e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default SendMsg
|
24
src/onebot11/actions/SendPrivateMsg.ts
Normal file
24
src/onebot11/actions/SendPrivateMsg.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { OB11PostSendMsg, OB11Return } from '../types';
|
||||
import SendMsg from "./SendMsg";
|
||||
import BaseAction from './BaseAction';
|
||||
|
||||
export type ActionType = 'send_private_msg'
|
||||
|
||||
export interface PayloadType extends OB11PostSendMsg {
|
||||
action: ActionType
|
||||
}
|
||||
|
||||
export interface ReturnDataType {
|
||||
message_id: string
|
||||
}
|
||||
|
||||
class SendPrivateMsg extends BaseAction {
|
||||
static ACTION_TYPE: ActionType = 'send_private_msg'
|
||||
|
||||
async _handle(payload: PayloadType): Promise<OB11Return<ReturnDataType | null>> {
|
||||
// 偷懒借用现有逻辑
|
||||
return new SendMsg()._handle(payload as any)
|
||||
}
|
||||
}
|
||||
|
||||
export default SendPrivateMsg
|
37
src/onebot11/actions/index.ts
Normal file
37
src/onebot11/actions/index.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { OB11Return } from '../types';
|
||||
import { OB11Response } from './utils'
|
||||
|
||||
import GetMsg from './GetMsg'
|
||||
import GetLoginInfo from './GetLoginInfo'
|
||||
import GetFriendList from './GetFriendList'
|
||||
import GetGroupList from './GetGroupList'
|
||||
import GetGroupInfo from './GetGroupInfo'
|
||||
import GetGroupMemberList from './GetGroupMemberList'
|
||||
import GetGroupMemberInfo from './GetGroupMemberInfo'
|
||||
import SendGroupMsg from './SendGroupMsg'
|
||||
import SendPrivateMsg from './SendPrivateMsg'
|
||||
import SendMsg from './SendMsg'
|
||||
|
||||
export const actionHandles = {
|
||||
[GetMsg.ACTION_TYPE]: new GetMsg(),
|
||||
[GetLoginInfo.ACTION_TYPE]: new GetLoginInfo(),
|
||||
[GetFriendList.ACTION_TYPE]: new GetFriendList(),
|
||||
[GetGroupList.ACTION_TYPE]: new GetGroupList(),
|
||||
[GetGroupInfo.ACTION_TYPE]: new GetGroupInfo(),
|
||||
[GetGroupMemberList.ACTION_TYPE]: new GetGroupMemberList(),
|
||||
[GetGroupMemberInfo.ACTION_TYPE]: new GetGroupMemberInfo(),
|
||||
[SendGroupMsg.ACTION_TYPE]: new SendGroupMsg(),
|
||||
[SendPrivateMsg.ACTION_TYPE]: new SendPrivateMsg(),
|
||||
[SendMsg.ACTION_TYPE]: new SendMsg(),
|
||||
}
|
||||
|
||||
export async function handleAction(
|
||||
jsonData: any,
|
||||
): Promise<OB11Return<any>> {
|
||||
const handler = actionHandles[jsonData.action]
|
||||
if (handler) {
|
||||
return await handler.handle(jsonData)
|
||||
} else {
|
||||
return OB11Response.error(`未知的 action: ${jsonData.action}`)
|
||||
}
|
||||
}
|
12
src/onebot11/actions/types.ts
Normal file
12
src/onebot11/actions/types.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export type BaseCheckResult = ValidCheckResult | InvalidCheckResult
|
||||
|
||||
export interface ValidCheckResult {
|
||||
valid: true
|
||||
[k: string | number]: any
|
||||
}
|
||||
|
||||
export interface InvalidCheckResult {
|
||||
valid: false
|
||||
message: string
|
||||
[k: string | number]: any
|
||||
}
|
61
src/onebot11/actions/utils.ts
Normal file
61
src/onebot11/actions/utils.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { OB11Return } from '../types';
|
||||
|
||||
// export function createSuccessActionResponse<T>({
|
||||
// status = 0,
|
||||
// retcode = 0,
|
||||
// data = {} as T,
|
||||
// ...others
|
||||
// }: Partial<OB11Return<any>> = {} = {}): OB11Return<any> {
|
||||
// return {
|
||||
// status,
|
||||
// retcode,
|
||||
// data,
|
||||
// message: '',
|
||||
// ...others
|
||||
// }
|
||||
// }
|
||||
|
||||
// export function createFailedActionResponse({
|
||||
// status = -1,
|
||||
// retcode = -1,
|
||||
// message = '',
|
||||
// ...others
|
||||
// }: Partial<OB11Return<any>> = {}): OB11Return<any> {
|
||||
// return {
|
||||
// status,
|
||||
// retcode,
|
||||
// data: {},
|
||||
// message,
|
||||
// ...others,
|
||||
// }
|
||||
// }
|
||||
|
||||
// export function createActionParamsErrorResponse(type, others = {}) {
|
||||
// return createFailedActionResponse({
|
||||
// message: `${type} 接收到了不正确的参数`,
|
||||
// ...others,
|
||||
// })
|
||||
// }
|
||||
|
||||
// export function createErrorResponseWithParams(params = {}) {
|
||||
// return createFailedActionResponse({
|
||||
// ...params,
|
||||
// })
|
||||
// }
|
||||
|
||||
export class OB11Response {
|
||||
static res<T>(data: T, status: number = 0, message: string = ""): OB11Return<T> {
|
||||
return {
|
||||
status: status,
|
||||
retcode: status,
|
||||
data: data,
|
||||
message: message
|
||||
}
|
||||
}
|
||||
static ok<T>(data: T) {
|
||||
return OB11Response.res<T>(data)
|
||||
}
|
||||
static error(err: string) {
|
||||
return OB11Response.res(null, -1, err)
|
||||
}
|
||||
}
|
@ -5,16 +5,9 @@ import { Request } from 'express';
|
||||
import { Response } from 'express';
|
||||
|
||||
const JSONbig = require('json-bigint')({ storeAsString: true });
|
||||
import { AtType, ChatType, Group, SelfInfo } from "../ntqqapi/types";
|
||||
import { friends, getGroup, getGroupMember, getStrangerByUin, groups, msgHistory, selfInfo } from "../common/data";
|
||||
import { OB11ApiName, OB11Message, OB11Return, OB11MessageData, OB11Group, OB11GroupMember, OB11PostSendMsg, OB11MessageDataType, OB11User } from './types';
|
||||
import { OB11Constructor } from "./constructor";
|
||||
import { NTQQApi } from "../ntqqapi/ntcall";
|
||||
import { Peer } from "../ntqqapi/ntcall";
|
||||
import { SendMessageElement } from "../ntqqapi/types";
|
||||
import { SendMsgElementConstructor } from "../ntqqapi/constructor";
|
||||
import { uri2local } from "./utils";
|
||||
import { v4 as uuid4 } from 'uuid';
|
||||
import { selfInfo } from "../common/data";
|
||||
import { OB11Message, OB11Return, OB11MessageData } from './types';
|
||||
import { actionHandles } from "./actions";
|
||||
|
||||
|
||||
// @SiberianHusky 2021-08-15
|
||||
@ -137,12 +130,12 @@ export function postMsg(msg: OB11Message) {
|
||||
|
||||
let routers: Record<string, (payload: any) => Promise<OB11Return<any>>> = {};
|
||||
|
||||
function registerRouter<PayloadType, ReturnDataType>(action: OB11ApiName, handle: (payload: PayloadType) => Promise<OB11Return<ReturnDataType | null>>) {
|
||||
function registerRouter(action: string, handle: (payload: any) => Promise<any>) {
|
||||
let url = action.toString()
|
||||
if (!action.startsWith("/")) {
|
||||
url = "/" + action
|
||||
}
|
||||
async function _handle(res: Response, payload: PayloadType) {
|
||||
async function _handle(res: Response, payload: any) {
|
||||
log("receive post data", url, payload)
|
||||
try {
|
||||
const result = await handle(payload)
|
||||
@ -163,169 +156,6 @@ function registerRouter<PayloadType, ReturnDataType>(action: OB11ApiName, handle
|
||||
routers[url] = handle
|
||||
}
|
||||
|
||||
registerRouter<{ message_id: string }, OB11Message>("get_msg", async (payload) => {
|
||||
log("history msg ids", Object.keys(msgHistory));
|
||||
const msg = msgHistory[payload.message_id.toString()]
|
||||
if (msg) {
|
||||
const msgData = await OB11Constructor.message(msg);
|
||||
return OB11Response.ok(msgData)
|
||||
} else {
|
||||
return OB11Response.error("消息不存在")
|
||||
}
|
||||
})
|
||||
|
||||
registerRouter<{}, OB11User>("get_login_info", async (payload) => {
|
||||
return OB11Response.ok(OB11Constructor.selfInfo(selfInfo));
|
||||
})
|
||||
|
||||
registerRouter<{}, OB11User[]>("get_friend_list", async (payload) => {
|
||||
return OB11Response.ok(OB11Constructor.friends(friends));
|
||||
})
|
||||
|
||||
registerRouter<{}, OB11Group[]>("get_group_list", async (payload) => {
|
||||
return OB11Response.ok(OB11Constructor.groups(groups));
|
||||
})
|
||||
|
||||
|
||||
registerRouter<{ group_id: number }, OB11Group[]>("get_group_info", async (payload) => {
|
||||
const group = await getGroup(payload.group_id.toString())
|
||||
if (group) {
|
||||
return OB11Response.ok(OB11Constructor.groups(groups));
|
||||
}
|
||||
else {
|
||||
return OB11Response.error(`群${payload.group_id}不存在`)
|
||||
}
|
||||
})
|
||||
|
||||
registerRouter<{ group_id: number }, OB11GroupMember[]>("get_group_member_list", async (payload) => {
|
||||
|
||||
const group = await getGroup(payload.group_id.toString());
|
||||
if (group) {
|
||||
if (!group.members?.length){
|
||||
group.members = await NTQQApi.getGroupMembers(payload.group_id.toString())
|
||||
}
|
||||
return OB11Response.ok(OB11Constructor.groupMembers(group));
|
||||
}
|
||||
else {
|
||||
return OB11Response.error(`群${payload.group_id}不存在`)
|
||||
}
|
||||
})
|
||||
|
||||
registerRouter<{ group_id: number, user_id: number }, OB11GroupMember>("get_group_member_info", async (payload) => {
|
||||
const member = await getGroupMember(payload.group_id.toString(), payload.user_id.toString())
|
||||
if (member) {
|
||||
return OB11Response.ok(OB11Constructor.groupMember(payload.group_id.toString(), member))
|
||||
}
|
||||
else {
|
||||
return OB11Response.error(`群成员${payload.user_id}不存在`)
|
||||
}
|
||||
})
|
||||
|
||||
const handleSendMsg = async (payload) => {
|
||||
const peer: Peer = {
|
||||
chatType: ChatType.friend,
|
||||
peerUid: ""
|
||||
}
|
||||
let group: Group | undefined = undefined;
|
||||
if (payload?.group_id) {
|
||||
group = await getGroup(payload.group_id.toString())
|
||||
if (!group) {
|
||||
return OB11Response.error(`群${payload.group_id}不存在`)
|
||||
}
|
||||
peer.chatType = ChatType.group
|
||||
// peer.name = group.name
|
||||
peer.peerUid = group.groupCode
|
||||
}
|
||||
else if (payload?.user_id) {
|
||||
const friend = friends.find(f => f.uin == payload.user_id.toString())
|
||||
if (friend) {
|
||||
// peer.name = friend.nickName
|
||||
peer.peerUid = friend.uid
|
||||
}
|
||||
else {
|
||||
peer.chatType = ChatType.temp
|
||||
const tempUser = getStrangerByUin(payload.user_id.toString())
|
||||
if (!tempUser) {
|
||||
return OB11Response.error(`找不到私聊对象${payload.user_id}`)
|
||||
}
|
||||
// peer.name = tempUser.nickName
|
||||
peer.peerUid = tempUser.uid
|
||||
}
|
||||
}
|
||||
if (typeof payload.message === "string") {
|
||||
payload.message = [{
|
||||
type: OB11MessageDataType.text,
|
||||
data: {
|
||||
text: payload.message
|
||||
}
|
||||
}] as OB11MessageData[]
|
||||
}
|
||||
else if (!Array.isArray(payload.message)) {
|
||||
payload.message = [payload.message]
|
||||
}
|
||||
const sendElements: SendMessageElement[] = []
|
||||
for (let sendMsg of payload.message) {
|
||||
switch (sendMsg.type) {
|
||||
case OB11MessageDataType.text: {
|
||||
const text = sendMsg.data?.text;
|
||||
if (text) {
|
||||
sendElements.push(SendMsgElementConstructor.text(sendMsg.data!.text))
|
||||
}
|
||||
} break;
|
||||
case OB11MessageDataType.at: {
|
||||
let atQQ = sendMsg.data?.qq;
|
||||
if (atQQ) {
|
||||
atQQ = atQQ.toString()
|
||||
if (atQQ === "all") {
|
||||
sendElements.push(SendMsgElementConstructor.at(atQQ, atQQ, AtType.atAll, "全体成员"))
|
||||
}
|
||||
else {
|
||||
const atMember = group?.members.find(m => m.uin == atQQ)
|
||||
if (atMember) {
|
||||
sendElements.push(SendMsgElementConstructor.at(atQQ, atMember.uid, AtType.atUser, atMember.cardName || atMember.nick))
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case OB11MessageDataType.reply: {
|
||||
let replyMsgId = sendMsg.data.id;
|
||||
if (replyMsgId) {
|
||||
replyMsgId = replyMsgId.toString()
|
||||
const replyMsg = msgHistory[replyMsgId]
|
||||
if (replyMsg) {
|
||||
sendElements.push(SendMsgElementConstructor.reply(replyMsg.msgSeq, replyMsgId, replyMsg.senderUin, replyMsg.senderUin))
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case OB11MessageDataType.image: {
|
||||
const file = sendMsg.data?.file
|
||||
if (file) {
|
||||
const picPath = await (await uri2local(uuid4(), file)).path
|
||||
if (picPath) {
|
||||
sendElements.push(await SendMsgElementConstructor.pic(picPath))
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case OB11MessageDataType.voice: {
|
||||
const file = sendMsg.data?.file
|
||||
if (file) {
|
||||
const voicePath = await (await uri2local(uuid4(), file)).path
|
||||
if (voicePath) {
|
||||
sendElements.push(await SendMsgElementConstructor.ptt(voicePath))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
log("send msg:", peer, sendElements)
|
||||
try {
|
||||
const returnMsg = await NTQQApi.sendMsg(peer, sendElements)
|
||||
return OB11Response.ok({ message_id: returnMsg.msgId })
|
||||
} catch (e) {
|
||||
return OB11Response.error(e.toString())
|
||||
}
|
||||
for (const [action, handler] of Object.entries(actionHandles)) {
|
||||
registerRouter(action, (payload) => handler.handle(payload))
|
||||
}
|
||||
|
||||
registerRouter<OB11PostSendMsg, { message_id: string }>("send_msg", handleSendMsg)
|
||||
registerRouter<OB11PostSendMsg, { message_id: string }>("send_private_msg", handleSendMsg)
|
||||
registerRouter<OB11PostSendMsg, { message_id: string }>("send_group_msg", handleSendMsg)
|
Loading…
x
Reference in New Issue
Block a user