From ea154ac87bb0b4025f495bdc0bdcfaf0c7f73a24 Mon Sep 17 00:00:00 2001 From: Shigma <1700011071@pku.edu.cn> Date: Fri, 11 Feb 2022 02:48:16 +0800 Subject: [PATCH] feat(core): add guildId to channel table --- packages/core/src/app.ts | 3 +- packages/core/src/bot.ts | 7 ++-- packages/core/src/context.ts | 20 +++-------- packages/core/src/database.ts | 1 + packages/core/src/orm.ts | 1 + plugins/common/echo/src/index.ts | 3 +- plugins/common/forward/src/index.ts | 51 ++++++++++++++++------------- 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/packages/core/src/app.ts b/packages/core/src/app.ts index 1530005879..a31e9249b0 100644 --- a/packages/core/src/app.ts +++ b/packages/core/src/app.ts @@ -138,9 +138,10 @@ export class App extends Context { if (this.database) { if (session.subtype === 'group') { // attach group data - const channelFields = new Set(['flag', 'assignee']) + const channelFields = new Set(['flag', 'assignee', 'guildId']) this.emit('before-attach-channel', session, channelFields) const channel = await session.observeChannel(channelFields) + channel.guildId = session.guildId // emit attach event if (await this.serial(session, 'attach-channel', session)) return diff --git a/packages/core/src/bot.ts b/packages/core/src/bot.ts index d28eca368f..0647f06382 100644 --- a/packages/core/src/bot.ts +++ b/packages/core/src/bot.ts @@ -1,4 +1,4 @@ -import { Dict, Logger, Random, sleep } from '@koishijs/utils' +import { Dict, Logger, makeArray, Random, sleep } from '@koishijs/utils' import { Adapter } from './adapter' import { App } from './app' import { Session } from './session' @@ -112,12 +112,13 @@ export abstract class Bot { return Object.fromEntries(list.map(info => [info.userId, info.nickname || info.username])) } - async broadcast(channels: string[], content: string, delay = this.app.options.delay.broadcast) { + async broadcast(channels: (string | [string, string])[], content: string, delay = this.app.options.delay.broadcast) { const messageIds: string[] = [] for (let index = 0; index < channels.length; index++) { if (index && delay) await sleep(delay) try { - messageIds.push(...await this.sendMessage(channels[index], content, 'unknown')) + const [channelId, guildId] = makeArray(channels[index]) + messageIds.push(...await this.sendMessage(channelId, content, guildId)) } catch (error) { this.app.logger('bot').warn(error) } diff --git a/packages/core/src/context.ts b/packages/core/src/context.ts index 3718942016..554083ad3d 100644 --- a/packages/core/src/context.ts +++ b/packages/core/src/context.ts @@ -566,24 +566,12 @@ export class Context { const [content, forced] = args as [string, boolean] if (!content) return [] - const data = this.database - ? await this.database.getAssignedChannels(['id', 'assignee', 'flag', 'platform']) - : channels.map((id) => { - const [platform] = id.split(':') - const bot = this.bots.find(bot => bot.platform === platform) - return bot && { id, assignee: bot.selfId, flag: 0, platform } - }).filter(Boolean) - - const assignMap: Dict> = {} - for (const { id, assignee, flag, platform } of data) { + const data = await this.database.getAssignedChannels(['id', 'assignee', 'flag', 'platform', 'guildId']) + const assignMap: Dict> = {} + for (const { id, assignee, flag, platform, guildId } of data) { if (channels && !channels.includes(`${platform}:${id}`)) continue if (!forced && (flag & Channel.Flag.silent)) continue - const map = assignMap[platform] ||= {} - if (map[assignee]) { - map[assignee].push(id) - } else { - map[assignee] = [id] - } + ((assignMap[platform] ||= {})[assignee] ||= []).push([id, guildId]) } return (await Promise.all(Object.entries(assignMap).flatMap(([platform, map]) => { diff --git a/packages/core/src/database.ts b/packages/core/src/database.ts index d924924a71..975accc6cb 100644 --- a/packages/core/src/database.ts +++ b/packages/core/src/database.ts @@ -25,6 +25,7 @@ export interface Channel { platform: string flag: number assignee: string + guildId: string } export namespace Channel { diff --git a/packages/core/src/orm.ts b/packages/core/src/orm.ts index 52cb7bd03a..275dcf5406 100644 --- a/packages/core/src/orm.ts +++ b/packages/core/src/orm.ts @@ -35,6 +35,7 @@ export class Model { platform: 'string(63)', flag: 'unsigned(20)', assignee: 'string(63)', + guildId: 'string(63)', }, { primary: ['id', 'platform'], }) diff --git a/plugins/common/echo/src/index.ts b/plugins/common/echo/src/index.ts index 8baee46cea..da2888189f 100644 --- a/plugins/common/echo/src/index.ts +++ b/plugins/common/echo/src/index.ts @@ -15,6 +15,7 @@ export function apply(ctx: Context) { .option('escape', '-e 发送转义消息', { authority: 3 }) .option('user', '-u [user:user] 发送到用户', { authority: 3 }) .option('channel', '-c [channel:channel] 发送到频道', { authority: 3 }) + .option('guild', '-g [guild:string] 指定群组编号', { authority: 3 }) .action(async ({ options }, message) => { if (!message) return template('echo.expect-text') @@ -37,7 +38,7 @@ export function apply(ctx: Context) { } else if (options.user) { await bot.sendPrivateMessage(id, message) } else { - await bot.sendMessage(id, message, 'unknown') + await bot.sendMessage(id, message, options.guild) } return } diff --git a/plugins/common/forward/src/index.ts b/plugins/common/forward/src/index.ts index adf6c474b3..39431db70f 100644 --- a/plugins/common/forward/src/index.ts +++ b/plugins/common/forward/src/index.ts @@ -13,6 +13,7 @@ export interface Rule { source: string target: string selfId: string + guildId?: string } export const Rule = Schema.object({ @@ -39,30 +40,36 @@ export const schema = Schema.union([ export function apply(ctx: Context, { rules, interval }: Config) { const relayMap: Dict = {} - async function sendRelay(session: Session, target: string, selfId?: string) { + async function sendRelay(session: Session, rule: Partial) { const { author, parsed } = session if (!parsed.content) return - // get selfId - const [platform, channelId] = parsePlatform(target) - if (!selfId) { - const channel = await ctx.database.getChannel(platform, channelId, ['assignee']) - if (!channel || !channel.assignee) return - selfId = channel.assignee - } - - const bot = ctx.bots.get(`${platform}:${selfId}`) - const content = template('forward', author.nickname || author.username, parsed.content) - await bot.sendMessage(channelId, content).then((ids) => { - for (const id of ids) { - relayMap[id] = { source: target, target: session.cid, selfId: session.selfId } - ctx.setTimeout(() => delete relayMap[id], interval) + try { + // get selfId + const [platform, channelId] = parsePlatform(rule.target) + if (!rule.selfId) { + const channel = await ctx.database.getChannel(platform, channelId, ['assignee', 'guildId']) + if (!channel || !channel.assignee) return + rule.selfId = channel.assignee + rule.guildId = channel.guildId } - }) - } - function handleError(error: any) { - ctx.logger('forward').warn(error) + const bot = ctx.bots.get(`${platform}:${rule.selfId}`) + const content = template('forward', author.nickname || author.username, parsed.content) + await bot.sendMessage(channelId, content, rule.guildId).then((ids) => { + for (const id of ids) { + relayMap[id] = { + source: rule.target, + target: session.cid, + selfId: session.selfId, + guildId: session.guildId, + } + ctx.setTimeout(() => delete relayMap[id], interval) + } + }) + } catch (error) { + ctx.logger('forward').warn(error) + } } ctx.before('attach-channel', (session, fields) => { @@ -73,17 +80,17 @@ export function apply(ctx: Context, { rules, interval }: Config) { const { quote = {}, subtype } = session if (subtype !== 'group') return const data = relayMap[quote.messageId] - if (data) return sendRelay(session, data.target, data.selfId) + if (data) return sendRelay(session, data) const tasks: Promise[] = [] if (ctx.database) { for (const target of session.channel.forward) { - tasks.push(sendRelay(session, target).catch(handleError)) + tasks.push(sendRelay(session, { target })) } } else { for (const rule of rules) { if (session.cid !== rule.source) continue - tasks.push(sendRelay(session, rule.target, rule.selfId).catch(handleError)) + tasks.push(sendRelay(session, rule)) } } const [result] = await Promise.all([next(), ...tasks])