mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
feat: 支持回复消息
This commit is contained in:
8
src/global.d.ts
vendored
8
src/global.d.ts
vendored
@@ -11,21 +11,21 @@ declare var LLAPI: {
|
|||||||
|
|
||||||
// uid是一串加密的字符串, 收到群消息的时候,可以用此函数获取群成员的qq号
|
// uid是一串加密的字符串, 收到群消息的时候,可以用此函数获取群成员的qq号
|
||||||
getUserInfo(uid: string): Promise<User>;
|
getUserInfo(uid: string): Promise<User>;
|
||||||
sendMessage(peer: Peer, message: SendMessage[]): Promise<void>;
|
sendMessage(peer: Peer, message: SendMessage[]): Promise<any>;
|
||||||
|
recallMessage(peer: Peer, msgIds: string[]): Promise<void>;
|
||||||
getGroupsList(forced: boolean): Promise<Group[]>
|
getGroupsList(forced: boolean): Promise<Group[]>
|
||||||
getFriendsList(forced: boolean): Promise<User[]>
|
getFriendsList(forced: boolean): Promise<User[]>
|
||||||
getGroupMemberList(group_id: string, num: number): Promise<{result: { infos: Map<string, GroupMemberInfo> }}>
|
getGroupMemberList(group_id: string, num: number): Promise<{result: { infos: Map<string, GroupMemberInfo> }}>
|
||||||
getPeer(): Promise<Peer>
|
getPeer(): Promise<Peer>
|
||||||
add_qmenu(func: (qContextMenu: Node)=>void): void
|
add_qmenu(func: (qContextMenu: Node)=>void): void
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
declare var llonebot: {
|
declare var llonebot: {
|
||||||
postData: (data: any) => void
|
postData: (data: any) => void
|
||||||
listenSendMessage: (handle: (msg: PostDataSendMsg) => void) => void
|
listenSendMessage: (handle: (msg: PostDataSendMsg) => void) => void
|
||||||
|
listenRecallMessage: (handle: (msg: {message_id: string}) => void) => void
|
||||||
updateGroups: (groups: Group[]) => void
|
updateGroups: (groups: Group[]) => void
|
||||||
updateFriends: (friends: User[]) => void
|
updateFriends: (friends: User[]) => void
|
||||||
updateGroupMembers: (data: { groupMembers: User[], group_id: string }) => void
|
updateGroupMembers: (data: { groupMembers: User[], group_id: string }) => void
|
||||||
|
@@ -337,13 +337,14 @@ class Api extends EventEmitter {
|
|||||||
}]
|
}]
|
||||||
*/
|
*/
|
||||||
async sendMessage(peer, elements) {
|
async sendMessage(peer, elements) {
|
||||||
ntCall("ns-ntApi", "nodeIKernelMsgService/sendMsg", [
|
return ntCall("ns-ntApi", "nodeIKernelMsgService/sendMsg", [
|
||||||
{
|
{
|
||||||
msgId: "0",
|
msgId: "0",
|
||||||
peer: destructor.destructPeer(peer),
|
peer: destructor.destructPeer(peer),
|
||||||
msgElements: await Promise.all(
|
msgElements: await Promise.all(
|
||||||
elements.map(async (element) => {
|
elements.map(async (element) => {
|
||||||
if (element.type == "text") return destructor.destructTextElement(element);
|
if (element.type == "text") return destructor.destructTextElement(element);
|
||||||
|
else if (element.type == "reply") return destructor.destructReplyElement(element);
|
||||||
else if (element.type == "image") return destructor.destructImageElement(element, await media.prepareImageElement(element.file));
|
else if (element.type == "image") return destructor.destructImageElement(element, await media.prepareImageElement(element.file));
|
||||||
else if (element.type == "voice") return destructor.destructPttElement(element, await media.prepareVoiceElement(element.file));
|
else if (element.type == "voice") return destructor.destructPttElement(element, await media.prepareVoiceElement(element.file));
|
||||||
else if (element.type == "face") return destructor.destructFaceElement(element);
|
else if (element.type == "face") return destructor.destructFaceElement(element);
|
||||||
@@ -355,6 +356,15 @@ class Api extends EventEmitter {
|
|||||||
null,
|
null,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
async recallMessage(peer, msgIds) {
|
||||||
|
ntCall("ns-ntApi", "nodeIKernelMsgService/recallMsg", [
|
||||||
|
{
|
||||||
|
msgIds,
|
||||||
|
peer: destructor.destructPeer(peer),
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
]);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @description 转发消息
|
* @description 转发消息
|
||||||
* @param {Peer} peer 对方的ID
|
* @param {Peer} peer 对方的ID
|
||||||
@@ -654,6 +664,18 @@ class Destructor {
|
|||||||
pttElement
|
pttElement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
destructReplyElement(element) {
|
||||||
|
return {
|
||||||
|
elementType: 7,
|
||||||
|
elementId: "",
|
||||||
|
replyElement: {
|
||||||
|
replayMsgSeq: element.msgSeq, // raw.msgSeq
|
||||||
|
replayMsgId: element.msgId, // raw.msgId
|
||||||
|
senderUin: element.senderUin,
|
||||||
|
senderUinStr: element.senderUinStr,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
destructFaceElement(element) {
|
destructFaceElement(element) {
|
||||||
return {
|
return {
|
||||||
|
10
src/main.ts
10
src/main.ts
@@ -6,6 +6,7 @@ const express = require("express");
|
|||||||
import {Group, PostDataSendMsg, User} from "./types";
|
import {Group, PostDataSendMsg, User} from "./types";
|
||||||
|
|
||||||
const CHANNEL_SEND_MSG = "llonebot_sendMsg"
|
const CHANNEL_SEND_MSG = "llonebot_sendMsg"
|
||||||
|
const CHANNEL_RECALL_MSG = "llonebot_recallMsg"
|
||||||
|
|
||||||
let groups: Group[] = []
|
let groups: Group[] = []
|
||||||
let friends: User[] = []
|
let friends: User[] = []
|
||||||
@@ -114,6 +115,9 @@ function startExpress(event: any) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
else if (jsonData.action == "delete_msg"){
|
||||||
|
sendIPCMsg(CHANNEL_RECALL_MSG, jsonData as {message_id: string})
|
||||||
|
}
|
||||||
return resData
|
return resData
|
||||||
}
|
}
|
||||||
// 处理POST请求的路由
|
// 处理POST请求的路由
|
||||||
@@ -153,6 +157,12 @@ function startExpress(event: any) {
|
|||||||
let resData = handlePost(jsonData)
|
let resData = handlePost(jsonData)
|
||||||
res.send(resData)
|
res.send(resData)
|
||||||
})
|
})
|
||||||
|
app.post('/delete_msg', (req: any, res: any) => {
|
||||||
|
let jsonData: PostDataSendMsg = req.body;
|
||||||
|
jsonData.action = "delete_msg"
|
||||||
|
let resData = handlePost(jsonData)
|
||||||
|
res.send(resData)
|
||||||
|
})
|
||||||
app.listen(port,"0.0.0.0", () => {
|
app.listen(port,"0.0.0.0", () => {
|
||||||
console.log(`服务器已启动,监听端口 ${port}`);
|
console.log(`服务器已启动,监听端口 ${port}`);
|
||||||
});
|
});
|
||||||
|
@@ -10,6 +10,7 @@ const {ipcRenderer} = require('electron');
|
|||||||
|
|
||||||
// 在window对象下导出只读对象
|
// 在window对象下导出只读对象
|
||||||
contextBridge.exposeInMainWorld("llonebot", {
|
contextBridge.exposeInMainWorld("llonebot", {
|
||||||
|
|
||||||
postData: (data: any) => {
|
postData: (data: any) => {
|
||||||
ipcRenderer.send("postOnebotData", data);
|
ipcRenderer.send("postOnebotData", data);
|
||||||
},
|
},
|
||||||
@@ -24,6 +25,11 @@ contextBridge.exposeInMainWorld("llonebot", {
|
|||||||
handle(args)
|
handle(args)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
listenRecallMessage: (handle: (jsonData: {message_id: string}) => void) => {
|
||||||
|
ipcRenderer.on("llonebot_recallMsg", (event: any, args: {message_id: string}) => {
|
||||||
|
handle(args)
|
||||||
|
})
|
||||||
|
},
|
||||||
startExpress: () => {
|
startExpress: () => {
|
||||||
ipcRenderer.send("startExpress");
|
ipcRenderer.send("startExpress");
|
||||||
},
|
},
|
||||||
|
@@ -10,6 +10,7 @@ const host = "http://localhost:5000"
|
|||||||
let self_qq: string = ""
|
let self_qq: string = ""
|
||||||
let groups: Group[] = []
|
let groups: Group[] = []
|
||||||
let friends: User[] = []
|
let friends: User[] = []
|
||||||
|
let msgHistory: MessageElement[] = []
|
||||||
let uid_maps: Record<string, User> = {} // 一串加密的字符串 -> qq号
|
let uid_maps: Record<string, User> = {} // 一串加密的字符串 -> qq号
|
||||||
async function getUserInfo(uid: string): Promise<User> {
|
async function getUserInfo(uid: string): Promise<User> {
|
||||||
let user = uid_maps[uid]
|
let user = uid_maps[uid]
|
||||||
@@ -97,6 +98,7 @@ async function forwardMessage(message: MessageElement) {
|
|||||||
post_type: "message",
|
post_type: "message",
|
||||||
message_type: message.peer.chatType,
|
message_type: message.peer.chatType,
|
||||||
detail_type: message.peer.chatType,
|
detail_type: message.peer.chatType,
|
||||||
|
message_id: message.raw.msgId,
|
||||||
sub_type: "",
|
sub_type: "",
|
||||||
message: []
|
message: []
|
||||||
}
|
}
|
||||||
@@ -140,7 +142,7 @@ async function forwardMessage(message: MessageElement) {
|
|||||||
}
|
}
|
||||||
onebot_message_data.message.push(message_data)
|
onebot_message_data.message.push(message_data)
|
||||||
}
|
}
|
||||||
|
msgHistory.push(message)
|
||||||
console.log("发送上传消息给ipc main", onebot_message_data)
|
console.log("发送上传消息给ipc main", onebot_message_data)
|
||||||
window.llonebot.postData(onebot_message_data);
|
window.llonebot.postData(onebot_message_data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -206,6 +208,12 @@ async function listenSendMessage(postData: PostDataSendMsg) {
|
|||||||
else if (message.type == "image" || message.type == "voice"){
|
else if (message.type == "image" || message.type == "voice"){
|
||||||
message.file = message.data?.file || message.file
|
message.file = message.data?.file || message.file
|
||||||
}
|
}
|
||||||
|
else if (message.type == "reply"){
|
||||||
|
let msgId = message.data?.id || message.msgId
|
||||||
|
let replyMessage = msgHistory.find(msg => msg.raw.msgId == msgId)
|
||||||
|
message.msgId = msgId
|
||||||
|
message.msgSeq = replyMessage?.raw.msgSeq || ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
console.log("发送消息", postData)
|
console.log("发送消息", postData)
|
||||||
window.LLAPI.sendMessage(peer, postData.params.message).then(res => console.log("消息发送成功:", res),
|
window.LLAPI.sendMessage(peer, postData.params.message).then(res => console.log("消息发送成功:", res),
|
||||||
@@ -214,6 +222,11 @@ async function listenSendMessage(postData: PostDataSendMsg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function recallMessage(msgId: string) {
|
||||||
|
let msg = msgHistory.find(msg => msg.raw.msgId == msgId)
|
||||||
|
window.LLAPI.recallMessage(msg.peer, [msgId]).then()
|
||||||
|
}
|
||||||
|
|
||||||
let chatListEle: HTMLCollectionOf<Element>
|
let chatListEle: HTMLCollectionOf<Element>
|
||||||
|
|
||||||
function onLoad() {
|
function onLoad() {
|
||||||
@@ -221,6 +234,9 @@ function onLoad() {
|
|||||||
window.llonebot.listenSendMessage((postData: PostDataSendMsg) => {
|
window.llonebot.listenSendMessage((postData: PostDataSendMsg) => {
|
||||||
listenSendMessage(postData).then()
|
listenSendMessage(postData).then()
|
||||||
});
|
});
|
||||||
|
window.llonebot.listenRecallMessage((arg: { message_id: string }) => {
|
||||||
|
recallMessage(arg.message_id)
|
||||||
|
})
|
||||||
|
|
||||||
async function getGroupsMembers(groupsArg: Group[]) {
|
async function getGroupsMembers(groupsArg: Group[]) {
|
||||||
// 批量获取群成员列表
|
// 批量获取群成员列表
|
||||||
|
14
src/types.ts
14
src/types.ts
@@ -2,6 +2,7 @@ export enum AtType {
|
|||||||
notAt = 0,
|
notAt = 0,
|
||||||
atUser = 2
|
atUser = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GroupMemberInfo = {
|
export type GroupMemberInfo = {
|
||||||
avatarPath: string;
|
avatarPath: string;
|
||||||
cardName: string;
|
cardName: string;
|
||||||
@@ -38,8 +39,9 @@ export type Peer = {
|
|||||||
|
|
||||||
export type MessageElement = {
|
export type MessageElement = {
|
||||||
raw: {
|
raw: {
|
||||||
|
msgId: string,
|
||||||
|
msgSeq: string,
|
||||||
elements: {
|
elements: {
|
||||||
|
|
||||||
replyElement: {
|
replyElement: {
|
||||||
senderUid: string, // 原消息发送者QQ号
|
senderUid: string, // 原消息发送者QQ号
|
||||||
sourceMsgIsIncPic: boolean; // 原消息是否有图片
|
sourceMsgIsIncPic: boolean; // 原消息是否有图片
|
||||||
@@ -114,10 +116,18 @@ export type SendMessage = {
|
|||||||
data?: {
|
data?: {
|
||||||
qq: string // at的qq号
|
qq: string // at的qq号
|
||||||
}
|
}
|
||||||
|
} | {
|
||||||
|
type: "reply",
|
||||||
|
msgId: string,
|
||||||
|
msgSeq: string,
|
||||||
|
senderUin: string,
|
||||||
|
data: {
|
||||||
|
id: string,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostDataSendMsg = {
|
export type PostDataSendMsg = {
|
||||||
action: "send_private_msg" | "send_group_msg" | "get_group_list",
|
action: "send_private_msg" | "send_group_msg" | "get_group_list" | "get_friend_list" | "delete_msg",
|
||||||
message_type?: "private" | "group"
|
message_type?: "private" | "group"
|
||||||
params?: {
|
params?: {
|
||||||
user_id: string,
|
user_id: string,
|
||||||
|
Reference in New Issue
Block a user