[core] ForwardMessage refine by light app (#2675)

This commit is contained in:
微莹·纤绫 2023-05-29 02:20:12 +08:00 committed by GitHub
parent e89d245ca0
commit 97f85bc8b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -9,13 +9,16 @@
package net.mamoe.mirai.internal.message.data
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.*
import net.mamoe.mirai.Bot
import net.mamoe.mirai.Mirai
import net.mamoe.mirai.internal.message.RefinableMessage
import net.mamoe.mirai.internal.message.RefineContext
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.map
import net.mamoe.mirai.utils.safeCast
internal data class LightAppInternal(
@ -25,7 +28,17 @@ internal data class LightAppInternal(
AbstractPolymorphicMessageKey<RichMessage, LightAppInternal>(RichMessage, { it.safeCast() })
override fun tryRefine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message {
val struct = tryDeserialize() ?: return LightApp(content)
val contentJson = runCatching {
json.parseToJsonElement(content).jsonObject
}.getOrNull() ?: return LightApp(content)
val struct = contentJson.tryDeserialize() ?: return LightApp(content)
return lightRefine(struct, contentJson) ?: LightApp(content)
}
private fun lightRefine(struct: LightAppStruct, contentJson: JsonObject): Message? {
struct.run {
if (meta.music != null) {
MusicKind.values().find { it.appId == meta.music.appid }?.let { musicType ->
@ -43,7 +56,42 @@ internal data class LightAppInternal(
}
}
return LightApp(content)
return null
}
override suspend fun refine(bot: Bot, context: MessageChain, refineContext: RefineContext): Message? {
val contentJson = runCatching {
json.parseToJsonElement(content).jsonObject
}.getOrNull() ?: return LightApp(content)
val struct = contentJson.tryDeserialize() ?: return LightApp(content)
if (struct.app == "com.tencent.multimsg") {
runCatching {
json.decodeFromJsonElement(
LightAppStruct.Meta.MultiMsgDetail.serializer(),
contentJson["meta"]!!.jsonObject["detail"]!!
)
}.onSuccess { detail ->
return MessageOrigin(
LightApp(content),
detail.resId,
MessageOriginKind.FORWARD,
) + ForwardMessage(
preview = listOf(), // FIXME preview with LightApp
title = detail.source.trim(),
brief = struct.prompt.trim(),
source = detail.source.trim(),
summary = detail.summary.trim(),
nodeList = Mirai.downloadForwardMessage(bot, detail.resId),
)
}.onFailure { err ->
bot.logger.warning("Exception when refining forward message", err)
}
}
return lightRefine(struct, contentJson) ?: LightApp(content)
}
}
@ -52,9 +100,9 @@ private val json = Json {
isLenient = true
}
internal fun LightAppInternal.tryDeserialize(): LightAppStruct? {
private fun JsonElement.tryDeserialize(): LightAppStruct? {
return kotlin.runCatching {
json.decodeFromString(LightAppStruct.serializer(), this.content)
json.decodeFromJsonElement(LightAppStruct.serializer(), this)
}.getOrNull()
}
@ -98,6 +146,50 @@ EXAMPLE LightAppStruct for MusicShare
"view": "music"
}
*/
/*
EXAMPLE LightAppStruct for ForwardMessage
{
"app": "com.tencent.multimsg",
"desc": "[聊天记录]",
"bizsrc": "",
"view": "contact",
"ver": "0.0.0.5",
"prompt": "[聊天记录]",
"appID": "",
"sourceName": "",
"actionData": "",
"actionData_A": "",
"sourceUrl": "",
"meta": {
"detail": {
"news": [
{
"text": "纤绫·洛雨: [动画表情]"
},
{
"text": "纤绫·洛雨: [图片]"
}
],
"uniseq": "7238251206428406430",
"resid": "...",
"summary": "查看2条转发消息",
"source": "群聊的聊天记录"
}
},
"config": {
"round": 1,
"forward": 1,
"autosize": 1,
"type": "normal",
"width": 300
},
"text": "",
"sourceAd": "",
"extra": "{\"tsum\":2,\"filename\":\"7238251206428406430\"}"
}
*/
@Serializable
internal data class LightAppStruct(
@ -107,8 +199,8 @@ internal data class LightAppStruct(
val config: Config = Config(),
@SerialName("desc")
val desc: String = "",
@SerialName("extra")
val extra: Extra = Extra(),
// @SerialName("extra")
// val extra: Extra = Extra(),
@SerialName("meta")
val meta: Meta = Meta(),
@SerialName("prompt")
@ -121,10 +213,12 @@ internal data class LightAppStruct(
@Serializable
data class Config(
@SerialName("autosize")
@Serializable(BadBooleanSerializer::class)
val autosize: Boolean = false,
@SerialName("ctime")
val ctime: Long = 0,
@SerialName("forward")
@Serializable(BadBooleanSerializer::class)
val forward: Boolean = false,
@SerialName("token")
val token: String = "",
@ -176,5 +270,31 @@ internal data class LightAppStruct(
@SerialName("title")
val title: String = "",
)
@Serializable
data class MultiMsgDetail(
@SerialName("uniseq")
val fileName: String,
@SerialName("resid")
val resId: String,
@SerialName("summary")
val summary: String = "",
@SerialName("source")
val source: String = "",
)
}
}
private object BadBooleanSerializer : KSerializer<Boolean> by JsonPrimitive.serializer().map(
JsonPrimitive.serializer().descriptor,
deserialize = { prime ->
prime.booleanOrNull?.let { return@map it }
prime.intOrNull?.let { return@map it != 0 }
return@map prime.content.toBoolean()
},
serialize = { JsonPrimitive(it) }
)