Skip to content

Commit

Permalink
feat(plugin-common): support broadcast -f option
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Mar 7, 2020
1 parent f0a236f commit 24ee7f2
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 12 deletions.
19 changes: 12 additions & 7 deletions packages/plugin-common/src/broadcast.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Context, appMap } from 'koishi-core'
import { Context, appMap, GroupFlag } from 'koishi-core'
import { sleep } from 'koishi-utils'

export interface BroadcastOptions {
Expand All @@ -12,27 +12,32 @@ const defaultOptions: BroadcastOptions = {
export default function apply (ctx: Context, config: BroadcastOptions = {}) {
config = { ...defaultOptions, ...config }

async function broadcast (selfId: string | number, groups: number[], message: string) {
async function broadcast (selfId: string | number, groupIds: number[], message: string) {
const { sender } = appMap[selfId]
for (let index = 0; index < groups.length; index++) {
for (let index = 0; index < groupIds.length; index++) {
if (index) await sleep(config.broadcastInterval)
sender.sendGroupMsgAsync(groups[index], message)
sender.sendGroupMsgAsync(groupIds[index], message)
}
}

ctx.command('broadcast <message...>', '全服广播', { authority: 4 })
.option('-f, --forced', '无视 noEmit 标签进行广播')
.option('-o, --only', '仅向当前 Bot 负责的群进行广播')
.action(async ({ options, meta }, message) => {
if (!message) return meta.$send('请输入要发送的文本。')

if (options.only) {
const groups = await ctx.database.getAllGroups(['id'], [ctx.app.selfId])
let groups = await ctx.database.getAllGroups(['id', 'flag'], [ctx.app.selfId])
if (!options.forced) {
groups = groups.filter(g => !(g.flag & GroupFlag.noEmit))
}
return broadcast(ctx.app.selfId, groups.map(g => g.id), message)
}

const groups = await ctx.database.getAllGroups(['id', 'assignee'])
const groups = await ctx.database.getAllGroups(['id', 'assignee', 'flag'])
const assignMap: Record<number, number[]> = {}
for (const { id, assignee } of groups) {
for (const { id, assignee, flag } of groups) {
if (!options.forced && (flag & GroupFlag.noEmit)) continue
if (!assignMap[assignee]) {
assignMap[assignee] = [id]
} else {
Expand Down
20 changes: 15 additions & 5 deletions packages/plugin-common/tests/broadcast.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MockedApp, BASE_SELF_ID } from 'koishi-test-utils'
import { startAll, stopAll } from 'koishi-core'
import { MockedApp, BASE_SELF_ID, utils } from 'koishi-test-utils'
import { startAll, stopAll, GroupFlag } from 'koishi-core'
import { broadcast } from '../src'
import 'koishi-database-memory'

Expand All @@ -13,24 +13,34 @@ beforeAll(async () => {
await app1.database.getUser(123, 4)
await app1.database.getGroup(321, app1.selfId)
await app1.database.getGroup(654, app1.selfId)
await app1.database.setGroup(654, { flag: GroupFlag.noEmit })
await app2.database.getGroup(987, app2.selfId)
})

afterAll(() => stopAll())

utils.sleep.mockResolvedValue()

test('check message', async () => {
await app1.receiveMessage('user', 'broadcast', 123)
app1.shouldHaveLastRequests([
['send_private_msg', { message: '请输入要发送的文本。', userId: 123 }],
])
})

test('basic support', async () => {
await app1.receiveMessage('user', 'broadcast foo bar', 123)
app1.shouldHaveLastRequests([
['send_group_msg', { message: 'foo bar', groupId: 321 }],
['send_group_msg', { message: 'foo bar', groupId: 654 }],
])
app2.shouldHaveLastRequests([
['send_group_msg', { message: 'foo bar', groupId: 987 }],
])
})

test('self only', async () => {
await app1.receiveMessage('user', 'broadcast -o foo bar', 123)
test('self only & force emit', async () => {
await app1.receiveMessage('user', 'broadcast -of foo bar', 123)
expect(utils.sleep).toBeCalledTimes(1)
app1.shouldHaveLastRequests([
['send_group_msg', { message: 'foo bar', groupId: 321 }],
['send_group_msg', { message: 'foo bar', groupId: 654 }],
Expand Down

0 comments on commit 24ee7f2

Please sign in to comment.