Skip to content
This repository has been archived by the owner on Oct 4, 2023. It is now read-only.

Commit

Permalink
feat(renderer/api): add revoke message api (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
FlysoftBeta committed Jun 17, 2023
1 parent b9599ac commit 83f5a86
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 52 deletions.
26 changes: 18 additions & 8 deletions examples/自动回复/renderer.js
Expand Up @@ -2,15 +2,25 @@ module.exports = (qqntim) => {
qqntim.nt.on("new-messages", (messages) => {
console.log("[Example-AutoReply] 收到新消息", messages);
messages.forEach((message) => {
if (message.chatType != "friend") return;
if (message.peer.chatType != "friend") return;
message.allDownloadedPromise.then(() => {
qqntim.nt.sendMessage("friend", message.peer.uid, [
{
type: "text",
content: "收到一条来自好友的消息:",
},
...message.elements,
]);
qqntim.nt
.sendMessage(message.peer, [
{
type: "text",
content: "收到一条来自好友的消息:",
},
...message.elements,
{
type: "text",
content: "(此消息两秒后自动撤回)",
},
])
.then((id) => {
setTimeout(() => {
qqntim.nt.revokeMessage(message.peer, id);
}, 2000);
});
});
});
});
Expand Down
5 changes: 4 additions & 1 deletion src/ipc.ts
Expand Up @@ -18,6 +18,8 @@ export type InterruptWindowCreation = (
const interruptIpcs: [InterruptIPC, InterruptIPCOptions | undefined][] = [];

export function handleIpc(args: IPCArgs<any>, ipcIn: boolean) {
if (args[0].eventName == "ns-LoggerApi-1" || args[0].eventName == "ns-LoggerApi-2")
return false;
for (const [func, options] of interruptIpcs) {
if (
(options?.cmdName && (!args[1] || args[1][0]?.cmdName != options?.cmdName)) ||
Expand All @@ -30,8 +32,9 @@ export function handleIpc(args: IPCArgs<any>, ipcIn: boolean) {
continue;

const ret = func(args);
if (ret == false) return;
if (ret == false) return false;
}
return true;
}

export function addInterruptIpc(func: InterruptIPC, options?: InterruptIPCOptions) {
Expand Down
8 changes: 1 addition & 7 deletions src/main/patch.ts
Expand Up @@ -48,13 +48,7 @@ function patchIpcMain(ipcMain: typeof Electron.ipcMain) {
...ipcMain,
on(channel: string, listener: (event: any, ...args: any[]) => void) {
ipcMain.on(channel, (event: any, ...args: IPCArgs<any>) => {
if (
args[0].eventName == "ns-LoggerApi-1" ||
args[0].eventName == "ns-LoggerApi-2"
)
return;
handleIpc(args, true);
listener(event, ...args);
if (handleIpc(args, true)) listener(event, ...args);
});
},
};
Expand Down
25 changes: 13 additions & 12 deletions src/nt.d.ts
Expand Up @@ -13,7 +13,7 @@ export interface MessageElementImage extends MessageElementBase {
export interface MessageElementFace extends MessageElementBase {
type: "face";
faceIndex: number;
faceType: "normal" | "super" | "unknown";
faceType: "normal" | "normal-extended" | "super" | number;
faceSuperIndex?: number;
}
export interface MessageElementRaw extends MessageElementBase {
Expand All @@ -29,18 +29,19 @@ export type MessageElementSend =
| Omit<MessageElementImage, "raw">
| Omit<Omit<MessageElementFace, "raw">, "downloadPromise">
| MessageElementRaw;
export type MessageChatType = "friend" | "group" | "others";
export interface Message {
peer: {
uid: string;
name: string;
};
sender: {
uid: string;
memberName: string;
nickName: string;
};
chatType: MessageChatType;
peer: Peer;
sender: Sender;
elements: MessageElement[];
allDownloadedPromise: Promise<void[]>;
}
export interface Sender {
uid: string;
memberName?: string;
nickName?: string;
}
export interface Peer {
chatType: "friend" | "group" | "others";
uid: string;
name?: string;
}
83 changes: 61 additions & 22 deletions src/renderer/api.ts
Expand Up @@ -5,12 +5,12 @@ import { ipcRenderer } from "electron";
import { randomUUID } from "crypto";
import {
Message,
MessageChatType,
MessageElement,
MessageElementFace,
MessageElementImage,
MessageElementRaw,
MessageElementText,
Peer,
} from "../nt";
import {
IPCArgs,
Expand All @@ -37,10 +37,12 @@ type NTEvents = {
class NT extends (EventEmitter as new () => TypedEmitter<NTEvents>) {
private pendingCallbacks: Record<string, Function> = {};
private pendingMediaDownloads: Record<string, Function> = {};
private pendingSentMessages: Record<string, Function> = {};
constructor() {
super();
this.listenCallResponse();
this.listenMediaDownload();
this.listenSentMessages();
this.listenNewMessages();
}

Expand All @@ -49,6 +51,7 @@ class NT extends (EventEmitter as new () => TypedEmitter<NTEvents>) {
const id = args[0].callbackId;
if (this.pendingCallbacks[id]) {
this.pendingCallbacks[id](args);
delete this.pendingCallbacks[id];
return false;
}
});
Expand Down Expand Up @@ -99,9 +102,11 @@ class NT extends (EventEmitter as new () => TypedEmitter<NTEvents>) {
faceType:
ele.faceElement.faceType == 1
? "normal"
: ele.faceElement.faceType == 2
? "normal-extended"
: ele.faceElement.faceType == 3
? "super"
: "unknown",
: ele.faceElement.faceType,
faceSuperIndex:
ele.faceElement.stickerId && parseInt(ele.faceElement.stickerId),
raw: ele,
Expand Down Expand Up @@ -137,19 +142,19 @@ class NT extends (EventEmitter as new () => TypedEmitter<NTEvents>) {
peer: {
uid: msg.peerUid,
name: msg.peerName,
chatType:
msg.chatType == 1
? "friend"
: msg.chatType == 2
? "group"
: "others",
},
sender: {
uid: msg.senderUid,
memberName: msg.sendMemberName || msg.sendNickName,
nickName: msg.sendNickName,
},
elements: elements,
chatType:
msg.chatType == 1
? "friend"
: msg.chatType == 2
? "group"
: "others",
};
}
);
Expand All @@ -166,7 +171,10 @@ class NT extends (EventEmitter as new () => TypedEmitter<NTEvents>) {
addInterruptIpc(
(args) => {
const id = args[1][0].payload?.notifyInfo?.msgElementId;
if (this.pendingMediaDownloads[id]) this.pendingMediaDownloads[id](args);
if (this.pendingMediaDownloads[id]) {
this.pendingMediaDownloads[id](args);
delete this.pendingMediaDownloads[id];
}
},
{
type: "request",
Expand Down Expand Up @@ -243,10 +251,12 @@ class NT extends (EventEmitter as new () => TypedEmitter<NTEvents>) {
faceType:
element.faceType == "normal"
? 1
: element.faceType == "normal-extended"
? 2
: element.faceType == "super"
? 3
: 1,
...(element.faceType == "super" && {
: element.faceType,
...((element.faceType == "super" || element.faceType == 3) && {
packId: "1",
stickerId: (element.faceSuperIndex || "0").toString(),
stickerType: 1,
Expand All @@ -261,19 +271,43 @@ class NT extends (EventEmitter as new () => TypedEmitter<NTEvents>) {
private async destructRawElement(element: MessageElementRaw) {
return element.raw;
}
async sendMessage(
chatType: MessageChatType,
peerUid: string,
elements: MessageElement[]
) {
await this.call("ns-ntApi-2", "nodeIKernelMsgService/sendMsg", [
private destructPeer(peer: Peer) {
return {
chatType: peer.chatType == "friend" ? 1 : peer.chatType == "group" ? 2 : 1,
peerUid: peer.uid,
guildId: "",
};
}
async revokeMessage(peer: Peer, message: string) {
await this.call("ns-ntApi-2", "nodeIKernelMsgService/recallMsg", [
{
peer: this.destructPeer(peer),
msgIds: [message],
},
]);
}
private listenSentMessages() {
addInterruptIpc(
(args) => {
const id = args[1][0].payload.msgRecord.peerUid;
if (this.pendingSentMessages[id]) {
this.pendingSentMessages[id](args);
delete this.pendingSentMessages[id];
return false;
}
},
{
type: "request",
eventName: "ns-ntApi-2",
cmdName: "nodeIKernelMsgListener/onAddSendMsg",
}
);
}
async sendMessage(peer: Peer, elements: MessageElement[]) {
this.call("ns-ntApi-2", "nodeIKernelMsgService/sendMsg", [
{
msgId: "0",
peer: {
chatType: chatType == "friend" ? 1 : chatType == "group" ? 2 : 1,
peerUid: peerUid,
guildId: "",
},
peer: this.destructPeer(peer),
msgElements: await Promise.all(
elements.map(async (element) => {
if (element.type == "text")
Expand All @@ -290,6 +324,11 @@ class NT extends (EventEmitter as new () => TypedEmitter<NTEvents>) {
},
null,
]);
return await new Promise<string>((resolve) => {
this.pendingSentMessages[peer.uid] = (args: IPCArgs<any>) => {
resolve(args[1][0].payload.msgRecord.msgId);
};
});
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/renderer/patch.ts
Expand Up @@ -25,8 +25,7 @@ function patchIpcRenderer(ipcRenderer: typeof Electron.ipcRenderer) {
}
}
}
handleIpc(args, true);
listener(event, ...args);
if (handleIpc(args, true)) listener(event, ...args);
});
},
send(channel: string, ...args: IPCArgs<any>) {
Expand Down

0 comments on commit 83f5a86

Please sign in to comment.