Skip to content

Commit

Permalink
Support modifying forward message display content #680
Browse files Browse the repository at this point in the history
  • Loading branch information
ryoii committed Feb 10, 2023
1 parent fb309eb commit b729fc1
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 15 deletions.
30 changes: 19 additions & 11 deletions docs/api/MessageType.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,13 @@
```json5
{
"type": "Forward",
"display": {
"title": "群聊的聊天记录",
"brief": "[聊天记录]",
"source": "聊天记录",
"preview": ["msg1", "msg2", "msg3", "msg4"],
"summary": "查看x条转发消息"
},
"nodeList": [
{
"senderId": 123,
Expand All @@ -457,17 +464,18 @@
}
```

| 名字 | 类型 | 说明 |
|----------------------|--------|----------------------------------------|
| nodeList | object | 消息节点 |
| senderId | Long | 发送人QQ号 |
| time | Int | 发送时间 |
| senderName | String | 显示名称 |
| messageChain | Array | 消息数组 |
| messageId | Int | 可以只使用消息messageId,从当前对话上下文缓存中读取一条消息作为节点 |
| messageRef | object | 引用缓存中其他对话上下文的消息作为节点 |
| messageRef.messageId | Int | 引用的 messageId |
| messageRef.target | Int | 引用的上下文目标,群号、好友账号 |
| 名字 | 类型 | 说明 |
|----------------------|--------|----------------------------------------------------------|
| display | object | 转发消息的卡片显示文本,参考上文json确认参数含义,值为表示使用客户端默认值;display为空表示全用默认值 |
| nodeList | object | 消息节点 |
| senderId | Long | 发送人QQ号 |
| time | Int | 发送时间 |
| senderName | String | 显示名称 |
| messageChain | Array | 消息数组 |
| messageId | Int | 可以只使用消息messageId,从当前对话上下文缓存中读取一条消息作为节点 |
| messageRef | object | 引用缓存中其他对话上下文的消息作为节点 |
| messageRef.messageId | Int | 引用的 messageId |
| messageRef.target | Int | 引用的上下文目标,群号、好友账号 |

> (senderId, time, senderName, messageChain), messageId, messageRef 是三种不同构造引用节点的方式,选其中一个/组传参即可
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ internal suspend fun MessageDTO.toMessage(contact: Contact, cache: Persistence)
name.isNotEmpty() -> Face(FaceMap[name])
else -> Face(255)
}

is PlainDTO -> PlainText(text)
is ImageDTO -> imageLikeToMessage(contact)
is FlashImageDTO -> imageLikeToMessage(contact)?.flash()
Expand All @@ -80,6 +81,7 @@ internal suspend fun MessageDTO.toMessage(contact: Contact, cache: Persistence)
is DiceDTO -> Dice(value)
is MusicShareDTO -> MusicShare(MusicKind.valueOf(kind), title, summary, jumpUrl, pictureUrl, musicUrl, brief)
is ForwardMessageDTO -> buildForwardMessage(contact) {
display?.let { displayStrategy = display }
nodeList.forEach {
if (it.messageId != null) {
cache.getMessageOrNull(Context(intArrayOf(it.messageId), contact))?.apply {
Expand All @@ -95,6 +97,7 @@ internal suspend fun MessageDTO.toMessage(contact: Contact, cache: Persistence)
}
}
}

is MiraiCodeDTO -> MiraiCode.deserializeMiraiCode(code)
// ignore
is QuoteDTO,
Expand All @@ -112,33 +115,47 @@ private suspend fun ImageLikeDTO.imageLikeToMessage(contact: Contact) = when {
size = this@imageLikeToMessage.size
isEmoji = this@imageLikeToMessage.isEmoji
}

!url.isNullOrBlank() -> withContext(Dispatchers.IO) {
url!!.useUrl { it.uploadAsImage(contact) }
}

!path.isNullOrBlank() -> with(File(path!!)) {
if (exists()) {
inputStream().useStream { it.uploadAsImage(contact) }
} else throw NoSuchFileException(this)
}

!base64.isNullOrBlank() -> with(Base64.getDecoder().decode(base64)) {
inputStream().useStream { it.uploadAsImage(contact) }
}

else -> null
}

private suspend fun VoiceLikeDTO.voiceLikeToMessage(contact: Contact) = when {
contact !is AudioSupported -> null
!voiceId.isNullOrBlank() -> OfflineAudio.Factory.create(voiceId!!, voiceId!!.substringBefore(".").toHexArray(), 0, AudioCodec.SILK, null)
!voiceId.isNullOrBlank() -> OfflineAudio.Factory.create(
voiceId!!,
voiceId!!.substringBefore(".").toHexArray(),
0,
AudioCodec.SILK,
null
)

!url.isNullOrBlank() -> withContext(Dispatchers.IO) {
url!!.useUrl { contact.uploadAudio(it) }
}

!path.isNullOrBlank() -> with(File(path!!)) {
if (exists()) {
inputStream().useStream { contact.uploadAudio(it) }
} else throw NoSuchFileException(this)
}

!base64.isNullOrBlank() -> with(Base64.getDecoder().decode(base64)) {
inputStream().useStream { contact.uploadAudio(it) }
}

else -> null
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ internal suspend fun Message.toDTO() = when (this) {
is Dice -> DiceDTO(value)
is MarketFace -> MarketFaceDTO(id, name)
is MusicShare -> MusicShareDTO(kind.name, title, summary, jumpUrl, pictureUrl, musicUrl, brief)
is ForwardMessage -> ForwardMessageDTO(nodeList.map {
is ForwardMessage -> ForwardMessageDTO(null, nodeList.map {
ForwardMessageNode(it.senderId, it.time, it.senderName, it.messageChain.toDTO { d -> d != UnknownMessageDTO })
})
is FileMessage -> FileDTO(id, name, size)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ package net.mamoe.mirai.api.http.adapter.internal.dto
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import net.mamoe.mirai.api.http.adapter.internal.dto.parameter.MessageIdDTO
import net.mamoe.mirai.message.data.ForwardMessage
import net.mamoe.mirai.message.data.RawForwardMessage

@Serializable
internal sealed class MessagePacketDTO : EventDTO() {
Expand Down Expand Up @@ -172,7 +174,7 @@ internal data class DiceDTO(
@Serializable
@SerialName("MarketFace")
internal data class MarketFaceDTO(
val id: Int,
val id: Int,
val name: String,
) : MessageDTO()

Expand All @@ -191,9 +193,25 @@ internal data class MusicShareDTO(
@Serializable
@SerialName("Forward")
internal data class ForwardMessageDTO(
val nodeList: List<ForwardMessageNode>
val display: ForwardMessageDisplayDTO?,
val nodeList: List<ForwardMessageNode>,
) : MessageDTO()

@Serializable
internal data class ForwardMessageDisplayDTO(
val brief: String?,
val preview: List<String>?,
val source: String?,
val summary: String?,
val title: String?,
) : ForwardMessage.DisplayStrategy {
override fun generateBrief(forward: RawForwardMessage) = brief ?: super.generateBrief(forward)
override fun generatePreview(forward: RawForwardMessage) = preview ?: super.generatePreview(forward)
override fun generateSource(forward: RawForwardMessage) = source ?: super.generateSource(forward)
override fun generateSummary(forward: RawForwardMessage) = summary ?: super.generateSummary(forward)
override fun generateTitle(forward: RawForwardMessage) = title ?: super.generateTitle(forward)
}

@Serializable
internal data class ForwardMessageNode(
val senderId: Long? = null,
Expand Down

0 comments on commit b729fc1

Please sign in to comment.