|
@@ -1,11 +1,15 @@
|
|
|
import { App, Bot, segment, Session, sleep } from 'koishi';
|
|
|
import 'koishi-adapter-onebot';
|
|
|
+import { Message as CQMessage, SenderInfo } from 'koishi-adapter-onebot';
|
|
|
|
|
|
import { parseCmd, query, view } from './command';
|
|
|
import { getLogger } from './loggers';
|
|
|
+import { chainPromises } from './utils';
|
|
|
|
|
|
const logger = getLogger('qqbot');
|
|
|
|
|
|
+type CQSession = Session & CQMessage & {sender: SenderInfo & {groupId?: number}};
|
|
|
+
|
|
|
interface IQQProps {
|
|
|
access_token: string;
|
|
|
host: string;
|
|
@@ -42,6 +46,7 @@ export default class {
|
|
|
public bot: Bot;
|
|
|
|
|
|
private messageQueues: {[key: string]: (() => Promise<void>)[]} = {};
|
|
|
+ private tempSenders: {[key: number]: number} = {};
|
|
|
|
|
|
private next = (type: 'private' | 'group', id: string) => {
|
|
|
const queue = this.messageQueues[`${type}:${id}`];
|
|
@@ -62,16 +67,17 @@ export default class {
|
|
|
if (wasEmpty) this.next(type, id);
|
|
|
};
|
|
|
|
|
|
- private getChat = async (session: Session): Promise<IChat> => {
|
|
|
+ private getChat = async (session: CQSession): Promise<IChat> => {
|
|
|
switch (session.subtype) {
|
|
|
case 'private':
|
|
|
- if (session.groupId) { // temp message
|
|
|
+ if (session.sender.groupId) { // temp message
|
|
|
const friendList = await session.bot.getFriendList();
|
|
|
if (!friendList.some(friendItem => friendItem.userId === session.userId)) {
|
|
|
+ this.tempSenders[session.userId] = session.sender.groupId;
|
|
|
return {
|
|
|
chatID: {
|
|
|
qq: Number(session.userId),
|
|
|
- group: Number(session.groupId),
|
|
|
+ group: Number(session.sender.groupId),
|
|
|
},
|
|
|
chatType: ChatType.Temp,
|
|
|
};
|
|
@@ -89,12 +95,12 @@ export default class {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- private sendToGroup = (groupID: string, message: string) => new Promise<string>(resolve => {
|
|
|
- this.enqueue('group', groupID, () => this.bot.sendMessage(groupID, message).then(resolve));
|
|
|
+ private sendToGroup = (groupID: string, message: string) => new Promise<string>((resolve, reject) => {
|
|
|
+ this.enqueue('group', groupID, () => this.bot.sendMessage(groupID, message).then(resolve).catch(reject));
|
|
|
});
|
|
|
|
|
|
- private sendToUser = (userID: string, message: string) => new Promise<string>(resolve => {
|
|
|
- this.enqueue('private', userID, () => this.bot.sendPrivateMessage(userID, message).then(resolve));
|
|
|
+ private sendToUser = (userID: string, message: string) => new Promise<string>((resolve, reject) => {
|
|
|
+ this.enqueue('private', userID, () => this.bot.sendPrivateMessage(userID, message).then(resolve).catch(reject));
|
|
|
});
|
|
|
|
|
|
public sendTo = (subscriber: IChat, messageChain: string) => Promise.all(
|
|
@@ -134,15 +140,33 @@ export default class {
|
|
|
|
|
|
this.app.on('friend-request', async session => {
|
|
|
const userString = `${session.username}(${session.userId})`;
|
|
|
- const groupString = `${session.groupName}(${session.groupId})`;
|
|
|
+ let groupId: string;
|
|
|
+ let groupString: string;
|
|
|
+ if (session.username in this.tempSenders) groupId = this.tempSenders[session.userId as unknown as number].toString();
|
|
|
logger.debug(`detected new friend request event: ${userString}`);
|
|
|
return session.bot.getGroupList().then(groupList => {
|
|
|
- if (groupList.some(groupItem => groupItem.groupId === session.groupId)) {
|
|
|
+ if (groupList.some(groupItem => {
|
|
|
+ const test = groupItem.groupId === groupId;
|
|
|
+ if (test) groupString = `${groupItem.groupName}(${groupId})`;
|
|
|
+ return test;
|
|
|
+ })) {
|
|
|
session.bot.handleFriendRequest(session.messageId, true);
|
|
|
return logger.info(`accepted friend request from ${userString} (from group ${groupString})`);
|
|
|
}
|
|
|
- logger.warn(`received friend request from ${userString} (from group ${groupString})`);
|
|
|
- logger.warn('please manually accept this friend request');
|
|
|
+ chainPromises(groupList.map(groupItem =>
|
|
|
+ (done: boolean) => Promise.resolve(done ||
|
|
|
+ this.bot.getGroupMember(groupItem.groupId, session.userId).then(() => {
|
|
|
+ groupString = `${groupItem.groupName}(${groupItem.groupId})`;
|
|
|
+ session.bot.handleFriendRequest(session.messageId, true);
|
|
|
+ logger.info(`accepted friend request from ${userString} (found in group ${groupString})`);
|
|
|
+ return true;
|
|
|
+ }).catch(() => false)
|
|
|
+ )
|
|
|
+ )).then(done => {
|
|
|
+ if (done) return;
|
|
|
+ logger.warn(`received friend request from ${userString} (stranger)`);
|
|
|
+ logger.warn('please manually accept this friend request');
|
|
|
+ });
|
|
|
});
|
|
|
});
|
|
|
|
|
@@ -160,7 +184,7 @@ export default class {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- this.app.middleware(async session => {
|
|
|
+ this.app.middleware(async (session: CQSession) => {
|
|
|
const chat = await this.getChat(session);
|
|
|
const cmdObj = parseCmd(session.content);
|
|
|
const reply = async msg => session.sendQueued(msg);
|