Skip to content

Commit

Permalink
feat: support listening group
Browse files Browse the repository at this point in the history
  • Loading branch information
RTAkland committed Aug 30, 2024
1 parent 312dc91 commit 2ff3a8e
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 73 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

# 概述

这是一个类似于NoneBot的异步(协程)框架主要接入OneBot11协议,
这是一个类似于NoneBot的异步(协程)框架主要接入OneBot11协议,
现在可以处理绝大部分的输入输出, 你可以点击[这里](./src/main/kotlin/cn/rtast/rob/util/ob/OBMessage.kt)
来查看支持哪些输入. 点击[这里](./src/main/kotlin/cn/rtast/rob/util/ob/OBAction.kt)查看支持哪些输出

Expand All @@ -38,7 +38,8 @@ fun main() {

# 内置指令管理器

> 内置的指令管理器可以处理 `指令别名` 即多个指令名指向一个指令, 你可以在[这里](src/main/kotlin/cn/rtast/rob/util/MessageCommand.kt)
> 内置的指令管理器可以处理 `指令别名` 即多个指令名指向一个指令,
> 你可以在[这里](src/main/kotlin/cn/rtast/rob/util/MessageCommand.kt)
> 查看指令别名是如何实现的
```kotlin
Expand Down Expand Up @@ -83,6 +84,10 @@ dependencies {
}
```

# 注意事项

你只能使用本框架创建一种服务方式, 要么使用`createServer` 要么使用 `createClient` 如果创建了两种会导致无法正常收发消息

# 开源

- 本项目以[Apache-2.0](./LICENSE)许可开源, 即:
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
kotlin.code.style=official

libVersion=1.2.6
libVersion=1.2.7
10 changes: 10 additions & 0 deletions src/main/kotlin/cn/rtast/rob/ROneBotFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ object ROneBotFactory {
internal var websocketServer: WebSocketServer? = null
internal lateinit var action: OBAction
internal var isServer = false
private val listenedGroups = mutableListOf<Long>()
val commandManager = MessageCommand()

fun createClient(address: String, accessToken: String, listener: OBMessage): ROneBotFactory {
Expand All @@ -36,4 +37,13 @@ object ROneBotFactory {
websocketServer = WsServer(port, accessToken, listener).also { it.start() }
return this
}

/**
* set group ids to listen and reply, if is empty then listen all groups
*/
fun addListeningGroups(vararg groups: Long) {
groups.forEach { listenedGroups.add(it) }
}

fun getListeningGroups() = listenedGroups
}
4 changes: 4 additions & 0 deletions src/main/kotlin/cn/rtast/rob/util/ob/MessageHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

package cn.rtast.rob.util.ob

import cn.rtast.rob.ROneBotFactory
import cn.rtast.rob.ROneBotFactory.commandManager
import cn.rtast.rob.entity.BaseMessage
import cn.rtast.rob.entity.CanSend
Expand Down Expand Up @@ -35,6 +36,8 @@ import org.java_websocket.WebSocket

object MessageHandler {

private val listeningGroups = ROneBotFactory.getListeningGroups()

suspend fun onMessage(listener: OBMessage, websocket: WebSocket, message: String) {
try {
listener.onMessage(websocket, message)
Expand All @@ -55,6 +58,7 @@ object MessageHandler {
when (serializedMessage.messageType) {
MessageType.group -> {
val msg = message.fromJson<GroupMessage>()
if (msg.groupId !in listeningGroups && listeningGroups.isNotEmpty()) return
msg.message.distinctBy { it.type }.forEach {
if (it.type == ArrayMessageType.reply) {
listener.onBeRepliedInGroup(websocket, msg)
Expand Down
102 changes: 43 additions & 59 deletions src/main/kotlin/cn/rtast/rob/util/ob/OBAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,153 +42,137 @@ import cn.rtast.rob.util.toJson

interface OBAction {

private fun sendToWs(message: String) {
private fun sendToWs(message: Any) {
if (isServer) {
websocketServer?.connections?.forEach { it.send(message) }
websocketServer?.connections?.forEach { it.send(message.toJson()) }
return
}
websocket?.send(message)
websocket?.send(message.toJson())
}

// do not override all suspend function, or you know what you are doing!
suspend fun sendGroupMessage(groupId: Long, content: String) {
val msg = GroupMessageOut(params = GroupMessageOut.Params(groupId, content)).toJson()
this.sendToWs(msg)
this.sendToWs(GroupMessageOut(params = GroupMessageOut.Params(groupId, content)))
}

/**
* if appendNewLine is true, the content will be @{user}\n{content}
* if it is false, content will be @{user}{content}
*/
suspend fun sendGroupMessageWithAt(groupId: Long, userId: Long, content: String, appendNewLine: Boolean = true) {
val content = StringBuilder("[CQ:at,qq=$userId]").also {
if (appendNewLine) it.append("\n")
it.append(content)
}
this.sendGroupMessage(groupId, content.toString())
}

suspend fun sendPrivateMessage(userId: Long, content: String) {
val msg = PrivateMessageOut(params = PrivateMessageOut.Params(userId, content)).toJson()
this.sendToWs(msg)
this.sendToWs(PrivateMessageOut(params = PrivateMessageOut.Params(userId, content)))
}

suspend fun revokeMessage(messageId: Long) {
val msg = RevokeMessageOut(params = RevokeMessageOut.Params(messageId)).toJson()
this.sendToWs(msg)
this.sendToWs(RevokeMessageOut(params = RevokeMessageOut.Params(messageId)))
}

suspend fun getMessage(messageId: Long) {
val msg = GetMessageOut(params = GetMessageOut.Params(messageId)).toJson()
this.sendToWs(msg)
this.sendToWs(GetMessageOut(params = GetMessageOut.Params(messageId)))
}

suspend fun getForwardMessage(messageId: String) {
val msg = GetForwardMessageOut(params = GetForwardMessageOut.Params(messageId)).toJson()
this.sendToWs(msg)
this.sendToWs(GetForwardMessageOut(params = GetForwardMessageOut.Params(messageId)))
}

suspend fun sendLike(userId: Long, times: Int = 1) {
val msg = SendLikeOut(params = SendLikeOut.Params(userId, times)).toJson()
this.sendToWs(msg)
this.sendToWs(SendLikeOut(params = SendLikeOut.Params(userId, times)))
}

suspend fun kickGroupMember(groupId: Long, userId: Long, rejectJoinRequest: Boolean = false) {
val msg = KickGroupMemberOut(params = KickGroupMemberOut.Params(groupId, userId, rejectJoinRequest)).toJson()
this.sendToWs(msg)
this.sendToWs(KickGroupMemberOut(params = KickGroupMemberOut.Params(groupId, userId, rejectJoinRequest)))
}

suspend fun setGroupBan(groupId: Long, userId: Long, duration: Int = 1800) {
val msg = SetGroupBanOut(params = SetGroupBanOut.Params(groupId, userId, duration)).toJson()
this.sendToWs(msg)
this.sendToWs(SetGroupBanOut(params = SetGroupBanOut.Params(groupId, userId, duration)))
}

suspend fun setGroupWholeBan(groupId: Long, enable: Boolean = true) {
val msg = SetGroupWholeBanOut(params = SetGroupWholeBanOut.Params(groupId, enable)).toJson()
this.sendToWs(msg)
this.sendToWs(SetGroupWholeBanOut(params = SetGroupWholeBanOut.Params(groupId, enable)))
}

suspend fun setGroupAdmin(groupId: Long, userId: Long, enable: Boolean = true) {
val msg = SetGroupAdminOut(params = SetGroupAdminOut.Params(groupId, userId, enable)).toJson()
this.sendToWs(msg)
this.sendToWs(SetGroupAdminOut(params = SetGroupAdminOut.Params(groupId, userId, enable)))
}

suspend fun setGroupAnonymous(groupId: Long, enable: Boolean = true) {
val msg = SetGroupAnonymousOut(params = SetGroupAnonymousOut.Params(groupId, enable)).toJson()
this.sendToWs(msg)
this.sendToWs(SetGroupAnonymousOut(params = SetGroupAnonymousOut.Params(groupId, enable)))
}

suspend fun setGroupMemberCard(groupId: Long, userId: Long, card: String = "") {
val msg = SetGroupMemberCardOut(params = SetGroupMemberCardOut.Params(groupId, userId, card)).toJson()
this.sendToWs(msg)
this.sendToWs(SetGroupMemberCardOut(params = SetGroupMemberCardOut.Params(groupId, userId, card)))
}

suspend fun setGroupName(groupId: Long, groupName: String) {
val msg = SetGroupNameOut(params = Params(groupId, groupName)).toJson()
this.sendToWs(msg)
this.sendToWs(SetGroupNameOut(params = Params(groupId, groupName)))
}

suspend fun setGroupLeaveOrDismiss(groupId: Long, dismiss: Boolean = false) {
val msg = SetGroupLeaveOut(params = SetGroupLeaveOut.Params(groupId, dismiss)).toJson()
this.sendToWs(msg)
this.sendToWs(SetGroupLeaveOut(params = SetGroupLeaveOut.Params(groupId, dismiss)))
}

suspend fun setGroupMemberTitle(groupId: Long, userId: Long, title: String = "", duration: Int = -1) {
val msg =
SetGroupMemberTitleOut(params = SetGroupMemberTitleOut.Params(groupId, userId, title, duration)).toJson()
this.sendToWs(msg)
this.sendToWs(SetGroupMemberTitleOut(params = SetGroupMemberTitleOut.Params(groupId, userId, title, duration)))
}

suspend fun setFriendRequest(flag: String, approve: Boolean = true, remark: String = "") {
val msg = SetFriendRequestOut(params = SetFriendRequestOut.Params(flag, approve, remark)).toJson()
this.sendToWs(msg)
this.sendToWs(SetFriendRequestOut(params = SetFriendRequestOut.Params(flag, approve, remark)))
}

suspend fun setGroupRequest(
flag: String,
type: String,
approve: Boolean = true,
reason: String = ""
reason: String = "" // only reject user to join group need to provide this param
) {
val msg = SetGroupRequestOut(params = SetGroupRequestOut.Params(flag, type, type, approve, reason)).toJson()
this.sendToWs(msg)
this.sendToWs(SetGroupRequestOut(params = SetGroupRequestOut.Params(flag, type, type, approve, reason)))
}

suspend fun getLoginInfo() {
val msg = GetLoginInfoOut().toJson()
this.sendToWs(msg)
this.sendToWs(GetLoginInfoOut())
}

suspend fun getStrangerInfo(userId: Long, noCache: Boolean = false) {
val msg = GetStrangerInfoOut(params = GetStrangerInfoOut.Params(userId, noCache)).toJson()
this.sendToWs(msg)
this.sendToWs(GetStrangerInfoOut(params = GetStrangerInfoOut.Params(userId, noCache)))
}

suspend fun getFriendList() {
val msg = GetFriendListOut().toJson()
this.sendToWs(msg)
this.sendToWs(GetFriendListOut())
}

suspend fun getGroupInfo(groupId: Long, noCache: Boolean = false) {
val msg = GetGroupInfoOut(params = GetGroupInfoOut.Params(groupId, noCache)).toJson()
this.sendToWs(msg)
this.sendToWs(GetGroupInfoOut(params = GetGroupInfoOut.Params(groupId, noCache)))
}

suspend fun getGroupList() {
val msg = GetGroupListOut().toJson()
this.sendToWs(msg)
this.sendToWs(GetGroupListOut())
}

suspend fun getGroupMemberInfo(groupId: Long, userId: Long, noCache: Boolean = false) {
val msg = GetGroupMemberInfoOut(params = GetGroupMemberInfoOut.Params(groupId, userId, noCache)).toJson()
this.sendToWs(msg)
this.sendToWs(GetGroupMemberInfoOut(params = GetGroupMemberInfoOut.Params(groupId, userId, noCache)))
}

suspend fun getGroupMemberList(groupId: Long) {
val msg = GetGroupMemberListOut(params = GetGroupMemberListOut.Params(groupId)).toJson()
this.sendToWs(msg)
this.sendToWs(GetGroupMemberListOut(params = GetGroupMemberListOut.Params(groupId)))
}

suspend fun getVersionInfo() {
val msg = GetVersionInfo().toJson()
this.sendToWs(msg)
this.sendToWs(GetVersionInfo())
}

suspend fun canSendImage() {
val msg = CanSendImageOut().toJson()
this.sendToWs(msg)
this.sendToWs(CanSendImageOut())
}

suspend fun canSendRecord() {
val msg = CanSendRecordOut().toJson()
this.sendToWs(msg)
this.sendToWs(CanSendRecordOut())
}
}
8 changes: 4 additions & 4 deletions src/test/kotlin/Common.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OBMessage

/*
* Copyright © 2024 RTAkland
* Author: RTAkland
* Date: 2024/8/29
*/


import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.util.BaseCommand
import cn.rtast.rob.util.ob.OBMessage

class EchoCommand : BaseCommand() {
// A simple echo message command
override val commandNames = listOf("/echo", "/eee")
Expand Down
10 changes: 3 additions & 7 deletions src/test/kotlin/TestClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import cn.rtast.rob.ROneBotFactory
import cn.rtast.rob.entity.GroupMessage
import cn.rtast.rob.entity.PrivateMessage
import cn.rtast.rob.util.ob.OBMessage
import org.java_websocket.WebSocket

Expand All @@ -15,14 +14,11 @@ fun main() {
val wsAddress = System.getenv("WS_ADDRESS")
val wsAccessToken = System.getenv("WS_ACCESS_TOKEN")
val rob = ROneBotFactory.createClient(wsAddress, wsAccessToken, object : OBMessage {
override suspend fun onBeRepliedInGroup(webSocket: WebSocket, message: GroupMessage) {
println(message)
}

override suspend fun onBeRepliedInPrivate(webSocket: WebSocket, message: PrivateMessage) {
println(message)
override suspend fun onGroupMessage(websocket: WebSocket, message: GroupMessage, json: String) {
println(message.rawMessage)
}
})
rob.commandManager.register(EchoCommand()) // not a suspend function
// rob.action.sendGroupMessage(114514, "1919810") // send a message in global scope
rob.addListeningGroups(985927054, 114514) // set listening groups, set empty to listen all groups' event
}

0 comments on commit 2ff3a8e

Please sign in to comment.