mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-12 22:10:14 +08:00
[core] ForwardMessage refine by light app (#2675)
This commit is contained in:
parent
e89d245ca0
commit
97f85bc8b9
@ -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) }
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user