Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package love.forte.simbot.component.onebot.v11.core.utils

import love.forte.simbot.common.id.ID
import love.forte.simbot.component.onebot.common.annotations.InternalOneBotAPI
import love.forte.simbot.component.onebot.v11.core.api.OneBotMessageOutgoing
import love.forte.simbot.component.onebot.v11.core.api.SendMsgApi
import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment
Expand All @@ -29,7 +30,8 @@ import love.forte.simbot.component.onebot.v11.message.segment.OneBotText
*
* @param messageType see [SendMsgApi]`.MESSAGE_TYPE_*`
*/
internal fun sendTextMsgApi(
@InternalOneBotAPI
public fun sendTextMsgApi(
messageType: String,
target: ID,
text: String,
Expand Down Expand Up @@ -58,7 +60,8 @@ internal fun sendTextMsgApi(
}
}

internal fun sendPrivateTextMsgApi(
@InternalOneBotAPI
public fun sendPrivateTextMsgApi(
target: ID,
text: String,
reply: ID? = null,
Expand All @@ -69,7 +72,8 @@ internal fun sendPrivateTextMsgApi(
reply = reply,
)

internal fun sendGroupTextMsgApi(
@InternalOneBotAPI
public fun sendGroupTextMsgApi(
target: ID,
text: String,
reply: ID? = null,
Expand All @@ -86,7 +90,8 @@ internal fun sendGroupTextMsgApi(
*
* @param messageType see [SendMsgApi]`.MESSAGE_TYPE_*`
*/
internal fun sendMsgApi(
@InternalOneBotAPI
public fun sendMsgApi(
messageType: String,
target: ID,
message: List<OneBotMessageSegment>,
Expand All @@ -112,7 +117,8 @@ internal fun sendMsgApi(
}
}

internal fun resolveReplyMessageSegmentList(
@InternalOneBotAPI
public fun resolveReplyMessageSegmentList(
message: List<OneBotMessageSegment>,
reply: ID,
): List<OneBotMessageSegment> {
Expand All @@ -132,7 +138,8 @@ internal fun resolveReplyMessageSegmentList(
return newMessage
}

internal fun sendPrivateMsgApi(
@InternalOneBotAPI
public fun sendPrivateMsgApi(
target: ID,
message: List<OneBotMessageSegment>,
reply: ID? = null,
Expand All @@ -143,7 +150,8 @@ internal fun sendPrivateMsgApi(
reply = reply,
)

internal fun sendGroupMsgApi(
@InternalOneBotAPI
public fun sendGroupMsgApi(
target: ID,
message: List<OneBotMessageSegment>,
reply: ID? = null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package love.forte.simbot.component.onebot.v11.core

import kotlinx.coroutines.test.runTest
import love.forte.simbot.common.id.IntID.Companion.ID
import love.forte.simbot.component.onebot.v11.core.api.OneBotMessageOutgoing
import love.forte.simbot.component.onebot.v11.core.api.SendMsgApi
import love.forte.simbot.component.onebot.v11.core.utils.sendMsgApi
import love.forte.simbot.component.onebot.v11.core.utils.sendTextMsgApi
import love.forte.simbot.component.onebot.v11.message.resolveToOneBotSegmentList
import love.forte.simbot.component.onebot.v11.message.segment.OneBotFace
import love.forte.simbot.component.onebot.v11.message.segment.OneBotReply
import love.forte.simbot.component.onebot.v11.message.segment.OneBotText
import love.forte.simbot.message.Face
import love.forte.simbot.message.MessageIdReference
import love.forte.simbot.message.buildMessages
import kotlin.collections.first
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
import kotlin.test.assertNotNull

/**
* Tests for `OneBotReply` and `MessageReference` for send.
*
* @author ForteScarlet
*/
class ReplyAndMessageReferenceTests {
@Test
fun sendReplyWithSingleSegmentTest() {
val api = sendMsgApi(
SendMsgApi.MESSAGE_TYPE_GROUP,
target = 123.ID,
message = listOf(OneBotText.create("Hello")),
reply = 456.ID,
)

val body = assertIs<SendMsgApi.Body>(api.body)
val content = assertIs<OneBotMessageOutgoing.SegmentsValue>(body.message)
val firstReply = assertIs<OneBotReply>(content.segments.first())

assertEquals(456.ID, firstReply.id)
}

@Test
fun sendReplyWithSegmentsTest() {
val api = sendMsgApi(
SendMsgApi.MESSAGE_TYPE_GROUP,
target = 123.ID,
message = listOf(OneBotText.create("Hello"), OneBotText.create("Hello"), OneBotFace.create(999.ID)),
reply = 456.ID,
)

val body = assertIs<SendMsgApi.Body>(api.body)
val content = assertIs<OneBotMessageOutgoing.SegmentsValue>(body.message)
val firstReply = assertIs<OneBotReply>(content.segments.first())

assertEquals(456.ID, firstReply.id)
}

@Test
fun sendReplyWithTextTest() {
val api = sendTextMsgApi(
SendMsgApi.MESSAGE_TYPE_GROUP,
target = 123.ID,
text = "666",
reply = 456.ID,
)

val body = assertIs<SendMsgApi.Body>(api.body)
val content = assertIs<OneBotMessageOutgoing.SegmentsValue>(body.message)
val firstReply = assertIs<OneBotReply>(content.segments.first())

assertEquals(456.ID, firstReply.id)
}

@Test
fun messagesToSegmentsWithMessageReferenceTest() = runTest {
val messages = buildMessages {
+"Hello"
+MessageIdReference(123.ID)
+Face(111.ID)
}

val segments = messages.resolveToOneBotSegmentList(null)
assertEquals(3, segments.size)
val reply = assertNotNull(
segments.firstNotNullOfOrNull { it as? OneBotReply }
)

assertEquals(123.ID, reply.id)
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package love.forte.simbot.component.onebot.v11.core

import io.mockk.coVerify
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
import love.forte.simbot.component.onebot.v11.core.api.OneBotApi
import love.forte.simbot.component.onebot.v11.core.api.OneBotApiExecutable
import love.forte.simbot.component.onebot.v11.core.api.inExecutableScope
import kotlin.test.Test

/**
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package love.forte.simbot.component.onebot.v11.core

import io.ktor.client.engine.java.Java
import io.ktor.http.Url
import love.forte.simbot.application.listeners
Expand Down Expand Up @@ -34,7 +36,7 @@ suspend fun main() {
eventServerHost = Url("ws://localhost:3001")
wsClientEngineFactory = Java
apiClientEngineFactory = Java
accessToken = "test"
accessToken("test")
}
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package love.forte.simbot.component.onebot.v11.core

import kotlinx.coroutines.test.runTest
import love.forte.simbot.component.onebot.v11.core.bot.firstOneBotBotManager
import love.forte.simbot.component.onebot.v11.core.bot.register
import love.forte.simbot.component.onebot.v11.core.useOneBot11
import love.forte.simbot.component.onebot.v11.message.resolveToOneBotSegment
import love.forte.simbot.component.onebot.v11.message.segment.OneBotImage
import love.forte.simbot.core.application.launchSimpleApplication
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public abstract interface class love/forte/simbot/component/onebot/v11/message/O
public abstract fun getMessages ()Llove/forte/simbot/message/Messages;
public abstract fun getPlainText ()Ljava/lang/String;
public abstract fun getSourceSegments ()Ljava/util/List;
public fun reference (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun reference$suspendImpl (Llove/forte/simbot/component/onebot/v11/message/OneBotMessageContent;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public abstract interface class love/forte/simbot/component/onebot/v11/message/OneBotMessageElement : love/forte/simbot/message/Message$Element {
Expand Down Expand Up @@ -918,14 +920,14 @@ public final class love/forte/simbot/component/onebot/v11/message/segment/OneBot
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class love/forte/simbot/component/onebot/v11/message/segment/OneBotReply : love/forte/simbot/component/onebot/v11/message/segment/OneBotMessageSegment {
public final class love/forte/simbot/component/onebot/v11/message/segment/OneBotReply : love/forte/simbot/component/onebot/v11/message/segment/OneBotMessageSegment, love/forte/simbot/message/MessageReference {
public static final field Factory Llove/forte/simbot/component/onebot/v11/message/segment/OneBotReply$Factory;
public static final field TYPE Ljava/lang/String;
public synthetic fun <init> (Llove/forte/simbot/component/onebot/v11/message/segment/OneBotReply$Data;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public static final fun create (Llove/forte/simbot/common/id/ID;)Llove/forte/simbot/component/onebot/v11/message/segment/OneBotReply;
public synthetic fun getData ()Ljava/lang/Object;
public fun getData ()Llove/forte/simbot/component/onebot/v11/message/segment/OneBotReply$Data;
public final fun getId ()Llove/forte/simbot/common/id/ID;
public fun getId ()Llove/forte/simbot/common/id/ID;
}

public synthetic class love/forte/simbot/component/onebot/v11/message/segment/OneBotReply$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,24 @@ public suspend fun Message.Element.resolveToOneBotSegment(
is Face -> OneBotFace.create(id)
is At -> OneBotAt.create(target)
is AtAll -> OneBotAt.createAtAll()
is Image -> {
when (this) {
// offline image
is OfflineImage -> suspendCancellableCoroutine<OneBotMessageSegment?> { continuation ->
offlineImageResolver(defaultImageAdditionalParams)
.resolve(this, continuation)
}

// remote images, OneBot组件中实际上没有此类型的实现
// 将它的 id 直接视为 file
is RemoteImage -> OneBotImage.create(id.literal)

// 其他未知类型,不管
else -> null
is Image -> when (this) {
// offline image
is OfflineImage -> suspendCancellableCoroutine<OneBotMessageSegment?> { continuation ->
offlineImageResolver(defaultImageAdditionalParams)
.resolve(this, continuation)
}

// remote images, OneBot组件中实际上没有此类型的实现
// 将它的 id 直接视为 file
is RemoteImage -> OneBotImage.create(id.literal)

// 其他未知类型,不管
else -> null
}

// since 1.2.0
is MessageReference -> OneBotReply.create(id)

// 其他未知类型,不管
else -> null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ import love.forte.simbot.ability.StandardDeleteOption
import love.forte.simbot.common.id.ID
import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegment
import love.forte.simbot.component.onebot.v11.message.segment.OneBotMessageSegmentElement
import love.forte.simbot.component.onebot.v11.message.segment.OneBotReply
import love.forte.simbot.component.onebot.v11.message.segment.OneBotText
import love.forte.simbot.message.MessageContent
import love.forte.simbot.message.Messages
import love.forte.simbot.message.PlainText
import love.forte.simbot.suspendrunner.STP


/**
Expand Down Expand Up @@ -55,6 +57,19 @@ public interface OneBotMessageContent : MessageContent {
*/
override val messages: Messages

/**
* 寻找 [messages] 中第一个 [OneBotReply] 类型的元素,
* 如果没有则得到 `null`。
* 寻找的过程是即时的,不会发生挂起。
*
* @since 1.2.0
* @see messages
* @see OneBotReply
*/
@STP
override suspend fun reference(): OneBotReply? =
messages.firstNotNullOfOrNull { it as? OneBotReply }

/**
* 消息中所有的 [文本消息][PlainText]
* (或者说 [sourceSegments] 中所有的 [OneBotText])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package love.forte.simbot.component.onebot.v11.message.segment
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import love.forte.simbot.common.id.ID
import love.forte.simbot.message.MessageReference
import kotlin.jvm.JvmStatic


Expand All @@ -32,14 +33,14 @@ import kotlin.jvm.JvmStatic
@SerialName(OneBotReply.TYPE)
public class OneBotReply private constructor(
override val data: Data
) : OneBotMessageSegment {
) : OneBotMessageSegment, MessageReference {

/**
* The [Data.id].
*
* @see Data.id
*/
public val id: ID
override val id: ID
get() = data.id

public companion object Factory {
Expand Down