Mirai Administrator 机器人管理插件,好友/群管理,黑名单,宵禁
-
Mirai Administrator
基于 Mirai Console 的 管理员 Bot 及其标准
使用前应该查阅的相关文档或项目
本插件实现的功能有:
- 联系人相关 自动审批,指令查看
- 消息相关 发送消息,撤回消息
- 群管理相关 群消息审核,自动宵禁,自动清理不发言
本插件提供服务接口以供其他插件拓展功能
例如使用 Mirai Content Censor 依靠百度API审查群消息MCL 指令安装
./mcl --update-package xyz.cssxsh.mirai:mirai-administrator --channel stable --type plugin
指令
注意: 使用前请确保可以 在聊天环境执行指令
<...>
中的是指令名
[...]
表示参数,当[...]
后面带?
时表示参数可选本插件指令权限ID 格式为
xyz.cssxsh.mirai.plugin.mirai-administrator:command.*
,*
是指令的第一指令名
例如/send to 12345
的权限ID为xyz.cssxsh.mirai.plugin.mirai-administrator:command.send
对 机器人发送的联系人请求通知消息 回复同意
或不同意
或拉黑
即可处理
插件提供黑名单功能,使用指令/contact black u12345
, 即可拉黑用户,Bot将不响应用户动作(包括其他插件的功能)AdminContactCommand
Command Description /<contact> <delete> [contact]
删除联系人 /<contact> <handle> [id] [accept]? [black]?
处理联系人申请 /<contact> <request>
查看申请列表 /<contact> <black> {ids}
拉黑 /<contact> <white> {ids}
取消拉黑 id
是 事件id 或 好友id 或 群idaccept
和black
参数为true
,yes
,enabled
,on
,1
时表示true
(不区分大小写)- 对 机器人发送的新联系人通知消息 回复
同意
或不同意
或拉黑
即可处理,详见 联系人审批配置 ids
是 权限系统的用户标识符,例如m12345.6789
, 可以提供多个id
一次性拉黑- 黑名单通过
@EventHandler(priority = EventPriority.HIGH, concurrency = ConcurrencyKind.LOCKED)
拦截消息
AdminFriendCommand
Command Description /<friend> <list>
好友列表 /<friend> <delete> [friend]
删除好友 AdminGroupCommand
Command Description /<group> <list>
群列表 /<group> <member> [group]
群成员 /<group> <quit> [group]
退出群聊 /<group> <kick> [member] [reason]? [black]?
踢出群员 /<group> <nick> [member] [nick]
群昵称 /<group> <title> [member] [title]
群头衔 /<group> <mute> [member] [second]
禁言 /<group> <admin> [member] [operation]?
设置管理员 /<group> <announce> [group]
设置公告 AdminRecallCommand
Command Description /<recall> [contact]?
撤回消息 - 不指定
contact
时,可以通过回复消息指定要撤销的消息,如果没有指定,将尝试撤销最后一条不是由指令发送者发送的消息 contact
是群员时,将尝试撤销这个群员的最后一条消息contact
是群或好友时,将尝试撤销bot的最后一条消息
AdminRegisteredCommand
Command Description /<registered>
查看已注册指令 /<reg>
查看已注册指令 AdminSendCommand
Command Description /<send> <groups> [bot]? [at]?
发送给所有群 /<send> <friends> [bot]?
发送给所有好友 /<send> <to> [contact] [at]?
发送给指定联系人 /<send> <nudge> [user]
戳一戳指定联系人 bot
参数在命令行模式下需要指定at
参数为true
,yes
,enabled
,on
,1
时表示true
, 将附加一个At
AdminTimerCommand
Command Description /<timer> <mute> [moment] [cron] [group]?
宵禁 /<timer> <cleaner> [day] [group]?
清理不发言 /<timer> <status> [cron] [bot]?
定时发送机器人状态 group
为 要操作的群,在群聊中可以不指定cron
, 为 CRON 表达式, 由秒 分钟 小时 日 月 周
组成
例如0 0 1 * * ?
表示每天 01:00 执行一次,0 30 2 ? * 2-6
表示星期一至星期五 每天 02:30 执行一次
可以使用在线编辑器生成 https://www.bejson.com/othertools/cron/
为防止被 空格 分成多个参数,请使用"
包裹参数moment
为 DURATION 表达式, 由PnDTnHnMn.nS
组成
例如P1DT2H3M4.5S
表示 一天二小时三分钟四点五秒,PT5H
表示 五小时- mute 指令,moment 小于
0
宵禁就会关闭
例如/timer mute PT5H "0 0 1 ? * 2-6"
, 将会在 星期一到星期五的凌晨01:00 禁言 5 小时
例如/timer mute PT0S "0 0 0 1 * ?"
, 将会 取消 禁言定时器 - day 单位为天数的发言期限,小于
0
就会关闭
例如/timer cleaner 365 123456
配置
联系人审批配置
AdminAutoApproverConfig.yml
机器人上线消息配置
AdminOnlineMessageConfig.yml
xyz.cssxsh.mirai.plugin.mirai-administrator:online.include
作用: 拥有此权限的群,会发送上线通知
消息审查及机器人所有者
AdminSetting.yml
服务接口
SPI接口 ComparableService
Wiki Service Provider Interface
举例 JvmPlugin内容审核
接口 ContentCensor
实例 MiraiContentCensor联系人审批
接口 FriendApprover
接口 MemberApprover
接口 GroupApprover
实例 MiraiAutoApprover定时消息
接口 BotTimingMessage
实例 MiraiOnlineMessage
实例 MiraiStatusMessage宵禁(群定时禁言)
接口 GroupCurfewTimer
实例 MiraiCurfewTimer放风(限时权限)
群成员清理
接口 MemberCleaner
实例 MiraiMemberCleaner群昵称检查
群头衔检查
黑名单
-
太6了66666666666666
-
@cssxsh
有个小BUG 对所有人群发消息后 还会跟着提示信息
-
@kissqianfu321
1.0.1 修复,重复读取消息了 -
@cssxsh 好 不过 gitee上的包 最好能及时更新 因为主仓在Gitee啊 ○| ̄|_
-
和AutoGroup 折磨群友插件一起用的时候,AutoGroup 折磨群友插件的戳一戳会导致插件报错
AutoGroup 折磨群友插件2022-02-07 11:06:15 V/Bot.3517372535: Event: NudgeEvent(from=Bot(3517372535), target=NormalMember(3565601730), subject=Group(1039019092), action=戳了戳, suffix=的0x0000006E) 2022-02-07 11:06:15 W/mirai-administrator: MiraiAdministrator with NudgeEvent(from=Bot(3517372535), target=NormalMember(3565601730), subject=Group(1039019092), action=戳了戳, suffix=的0x0000006E) java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.base/java.lang.reflect.Method.invoke(Unknown Source) at kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:97) at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Instance.call(CallerImpl.kt:113) at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:108) at kotlin.reflect.full.KCallables.callSuspend(KCallables.kt:56) at net.mamoe.mirai.internal.event.JvmMethodListenersInternalKt.registerEventHandler$callFunction(JvmMethodListenersInternal.kt:80) at net.mamoe.mirai.internal.event.JvmMethodListenersInternalKt.access$registerEventHandler$callFunction(JvmMethodListenersInternal.kt:1) at net.mamoe.mirai.internal.event.JvmMethodListenersInternalKt$registerEventHandler$8.invokeSuspend(JvmMethodListenersInternal.kt:110) at net.mamoe.mirai.internal.event.JvmMethodListenersInternalKt$registerEventHandler$8.invoke(JvmMethodListenersInternal.kt) at net.mamoe.mirai.internal.event.JvmMethodListenersInternalKt$registerEventHandler$8.invoke(JvmMethodListenersInternal.kt) at net.mamoe.mirai.event.EventChannel$subscribeAlways$1.invokeSuspend(EventChannel.kt:455) at net.mamoe.mirai.event.EventChannel$subscribeAlways$1.invoke(EventChannel.kt) at net.mamoe.mirai.event.EventChannel$subscribeAlways$1.invoke(EventChannel.kt) at net.mamoe.mirai.internal.event.Handler$onEvent$2.invokeSuspend(InternalEventListeners.kt:50) at net.mamoe.mirai.internal.event.Handler$onEvent$2.invoke(InternalEventListeners.kt) at net.mamoe.mirai.internal.event.Handler$onEvent$2.invoke(InternalEventListeners.kt) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:89) at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:165) at kotlinx.coroutines.BuildersKt.withContext(Unknown Source) at net.mamoe.mirai.internal.event.Handler.onEvent(InternalEventListeners.kt:50) at net.mamoe.mirai.internal.event.InternalEventListenersKt.process(InternalEventListeners.kt:166) at net.mamoe.mirai.internal.event.InternalEventListenersKt.callAndRemoveIfRequired(InternalEventListeners.kt:115) at net.mamoe.mirai.event._EventBroadcast.broadcastImpl(Event.kt:174) at net.mamoe.mirai.IMirai.broadcastEvent(IMirai.kt:318) at net.mamoe.mirai.internal.MiraiImpl.broadcastEvent$suspendImpl(MiraiImpl.kt:308) at net.mamoe.mirai.internal.MiraiImpl.broadcastEvent(MiraiImpl.kt) at net.mamoe.mirai.event._EventBroadcast.broadcastPublic$suspendImpl(Event.kt:161) at net.mamoe.mirai.event._EventBroadcast.broadcastPublic(Event.kt) at net.mamoe.mirai.event.EventKt.broadcast(Event.kt:146) at net.mamoe.mirai.internal.network.components.EventDispatcherImpl$broadcast$2.invokeSuspend(EventDispatcher.kt:90) at net.mamoe.mirai.internal.network.components.EventDispatcherImpl$broadcast$2.invoke(EventDispatcher.kt) at net.mamoe.mirai.internal.network.components.EventDispatcherImpl$broadcast$2.invoke(EventDispatcher.kt) at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:89) at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:165) at kotlinx.coroutines.BuildersKt.withContext(Unknown Source) at net.mamoe.mirai.internal.network.components.EventDispatcherImpl.broadcast$suspendImpl(EventDispatcher.kt:89) at net.mamoe.mirai.internal.network.components.EventDispatcherImpl.broadcast(EventDispatcher.kt) at net.mamoe.mirai.internal.network.components.EventDispatcherImpl$broadcastAsync$job$1.invokeSuspend(EventDispatcher.kt:105) at net.mamoe.mirai.internal.network.components.EventDispatcherImpl$broadcastAsync$job$1.invoke(EventDispatcher.kt) at net.mamoe.mirai.internal.network.components.EventDispatcherImpl$broadcastAsync$job$1.invoke(EventDispatcher.kt) at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:55) at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:112) at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126) at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56) at kotlinx.coroutines.BuildersKt.launch(Unknown Source) at net.mamoe.mirai.internal.network.components.EventDispatcherImpl.broadcastAsync-kKe4JaQ(EventDispatcher.kt:102) at net.mamoe.mirai.internal.network.components.EventDispatcher.broadcastAsync-kKe4JaQ$default(EventDispatcher.kt:35) at net.mamoe.mirai.internal.network.components.EventBroadcasterPacketHandler.impl(PacketHandler.kt:87) at net.mamoe.mirai.internal.network.components.EventBroadcasterPacketHandler.impl(PacketHandler.kt:80) at net.mamoe.mirai.internal.network.components.EventBroadcasterPacketHandler.handlePacket(PacketHandler.kt:73) at net.mamoe.mirai.internal.network.components.PacketHandlerChain.handlePacket(PacketHandler.kt:42) at net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport$collectReceived$3.invokeSuspend(NetworkHandlerSupport.kt:84) at net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport$collectReceived$3.invoke(NetworkHandlerSupport.kt) at net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport$collectReceived$3.invoke(NetworkHandlerSupport.kt) at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:55) at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:112) at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126) at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56) at kotlinx.coroutines.BuildersKt.launch(Unknown Source) at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47) at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source) at net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport.collectReceived$mirai_core(NetworkHandlerSupport.kt:82) at net.mamoe.mirai.internal.network.impl.netty.NettyNetworkHandler$PacketDecodePipeline$send$1.invokeSuspend(NettyNetworkHandler.kt:178) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Unknown Source) Caused by: java.lang.ClassCastException: class net.mamoe.mirai.internal.QQAndroidBot cannot be cast to class net.mamoe.mirai.contact.Member (net.mamoe.mirai.internal.QQAndroidBot and net.mamoe.mirai.contact.Member are in unnamed module of loader 'app') at xyz.cssxsh.mirai.plugin.MiraiAdministrator.mark$mirai_administrator(MiraiAdministrator.kt:298) ... 75 more
-
@clanmao
1.0.2 修复 -
每次启动机器人后都会推送一次状态 启动之后每间隔1小时推送一次 如果是专门加的 当我没说orz
-
@kissqianfu321
专门加的功能,用于定期查阅机器人的状态 -
@cssxsh 好的
-
MA 似乎连AdminSetting.yml生成不了,而且lp也查不到该插件的权限
-
加载这个插件的时候报的错,好像AdminSetting.yml也没生成
2022-02-08 15:00:51 E/mirai-administrator: java.lang.NoSuchMethodError: 'kotlin.reflect.KType kotlin.jvm.internal.Reflection.mutableCollectionType(kotlin.reflect.KType)' java.lang.NoSuchMethodError: 'kotlin.reflect.KType kotlin.jvm.internal.Reflection.mutableCollectionType(kotlin.reflect.KType)' at xyz.cssxsh.mirai.plugin.data.AdminRequestEventData.<clinit>(AdminRequestEventData.kt:107) at xyz.cssxsh.mirai.plugin.MiraiAdminPlugin.onEnable(MiraiAdminPlugin.kt:25) at net.mamoe.mirai.console.internal.plugin.JvmPluginInternal.internalOnEnable$mirai_console(JvmPluginInternal.kt:113) at net.mamoe.mirai.console.internal.plugin.BuiltInJvmPluginLoaderImpl.enable(BuiltInJvmPluginLoaderImpl.kt:158) at net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader$BuiltIn.enable(JvmPluginLoader.kt) at net.mamoe.mirai.console.plugin.jvm.JvmPluginLoader$BuiltIn.enable(JvmPluginLoader.kt:36) at net.mamoe.mirai.console.plugin.PluginManager.enablePlugin(PluginManager.kt:129) at net.mamoe.mirai.console.internal.plugin.PluginManagerImpl.enableAllLoadedPlugins$mirai_console(PluginManagerImpl.kt:172) at net.mamoe.mirai.console.internal.MiraiConsoleImplementationBridge.doStart$mirai_console(MiraiConsoleImplementationBridge.kt:214)
-
@atonioy
mirai 版本是多少?检查一下是不是版本太旧了 -
@cssxsh 好了,蟹蟹大佬
-
@greenhandzdl
版本? -
@cssxsh 是mirai版本问题,沃更了最新就可以,顺便问下,那个关闭自动宵禁的指令是啥,那个重复设置的宵禁时间是覆盖的吗
-
@atonioy
会覆盖, 把开始时间和结束时间设置成一样就会关闭 -
@cssxsh 大佬那个自动宵禁怎么总是多次执行,沃设置的是00:30到06:00,它每六分钟就给我执行一次宵禁
-
@atonioy
写代码的时候草率了,下个版本修复 -
@cssxsh
MiraiCore v2.9.0
MiraiConsole v2.9.0