From f4020e4a03a6868ac358dc665bbbf4e4beb3703d Mon Sep 17 00:00:00 2001
From: ryoii <ryoii@foxmail.com>
Date: Sun, 23 Feb 2020 23:58:01 +0800
Subject: [PATCH] Http api support recall

---
 mirai-api-http/README_CH.md                   | 33 +++++++++++++++++++
 .../mirai/api/http/queue/MessageQueue.kt      | 17 +++++-----
 .../api/http/route/MessageRouteModule.kt      | 19 +++++++----
 3 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/mirai-api-http/README_CH.md b/mirai-api-http/README_CH.md
index 30f52fce4..ff595681d 100644
--- a/mirai-api-http/README_CH.md
+++ b/mirai-api-http/README_CH.md
@@ -297,6 +297,39 @@ Content-Type:multipart/form-data
 
 
 
+### 撤回消息
+
+```
+[POST] /recall
+```
+
+使用此方法撤回指定消息。对于bot发送的消息,又2分钟时间限制。对于撤回群聊中群员的消息,需要有相应权限
+
+#### 请求
+
+```json5
+{
+    "sessionKey": "YourSession",
+    "target": 987654321
+}
+```
+
+| 名字         | 类型   | 可选  | 举例        | 说明                             |
+| ------------ | ------ | ----- | ----------- | -------------------------------- |
+| sessionKey   | String | false | YourSession | 已经激活的Session                |
+| target       | Long   | false | 987654321   | 需要撤回的消息的messageId        |
+
+#### 响应: 返回统一状态码
+
+```json5
+{
+    "code": 0,
+    "msg": "success"
+}
+```
+
+
+
 ### 获取Bot收到的消息和事件
 
 ```
diff --git a/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/queue/MessageQueue.kt b/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/queue/MessageQueue.kt
index 83250127a..f39a3e8e8 100644
--- a/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/queue/MessageQueue.kt
+++ b/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/queue/MessageQueue.kt
@@ -13,7 +13,6 @@ import net.mamoe.mirai.api.http.data.common.EventDTO
 import net.mamoe.mirai.api.http.data.common.IgnoreEventDTO
 import net.mamoe.mirai.api.http.data.common.toDTO
 import net.mamoe.mirai.event.events.BotEvent
-import net.mamoe.mirai.message.GroupMessage
 import net.mamoe.mirai.message.MessagePacket
 import net.mamoe.mirai.message.data.MessageSource
 import net.mamoe.mirai.utils.firstKey
@@ -21,8 +20,8 @@ import java.util.concurrent.ConcurrentLinkedDeque
 
 class MessageQueue : ConcurrentLinkedDeque<BotEvent>() {
 
-    val quoteCacheSize = 4096
-    val quoteCache = LinkedHashMap<Long, MessagePacket<*, *>>()
+    val cacheSize = 4096
+    val cache = LinkedHashMap<Long, MessagePacket<*, *>>()
 
     suspend fun fetch(size: Int): List<EventDTO> {
         var count = size
@@ -45,13 +44,13 @@ class MessageQueue : ConcurrentLinkedDeque<BotEvent>() {
         return ret
     }
 
-    fun cacheQuote(messageId: Long) =
-        quoteCache[messageId] ?: throw NoSuchElementException()
+    fun cache(messageId: Long) =
+        cache[messageId] ?: throw NoSuchElementException()
 
-    private fun addQuoteCache(msg: MessagePacket<*, *>) {
-        quoteCache[msg.message[MessageSource].id] = msg
-        if (quoteCache.size > quoteCacheSize) {
-            quoteCache.remove(quoteCache.firstKey())
+    fun addQuoteCache(msg: MessagePacket<*, *>) {
+        cache[msg.message[MessageSource].id] = msg
+        if (cache.size > cacheSize) {
+            cache.remove(cache.firstKey())
         }
     }
 }
\ No newline at end of file
diff --git a/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/MessageRouteModule.kt b/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/MessageRouteModule.kt
index 7e59e6e43..46a555a99 100644
--- a/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/MessageRouteModule.kt
+++ b/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/route/MessageRouteModule.kt
@@ -29,6 +29,8 @@ import net.mamoe.mirai.api.http.data.common.VerifyDTO
 import net.mamoe.mirai.api.http.data.common.toMessageChain
 import net.mamoe.mirai.api.http.util.toJson
 import net.mamoe.mirai.contact.Contact
+import net.mamoe.mirai.message.FriendMessage
+import net.mamoe.mirai.message.GroupMessage
 import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.message.data.*
 import net.mamoe.mirai.message.uploadImage
@@ -59,26 +61,30 @@ fun Application.messageModule() {
 
         miraiVerify<SendDTO>("/sendFriendMessage") {
             val quote = it.quote?.let { q ->
-                it.session.messageQueue.cacheQuote(q).run {
+                it.session.messageQueue.cache(q).run {
                     this[MessageSource].quote(sender)
                 }}
 
             it.session.bot.getFriend(it.target).apply {
                 val receipt = sendMessage(quote, it.messageChain.toMessageChain(this), this)
                 receipt.source.ensureSequenceIdAvailable()
+
+                it.session.messageQueue.addQuoteCache(FriendMessage(bot.selfQQ, receipt.source.toChain()))
                 call.respondDTO(SendRetDTO(messageId = receipt.source.id))
             }
         }
 
         miraiVerify<SendDTO>("/sendGroupMessage") {
             val quote = it.quote?.let { q ->
-                it.session.messageQueue.cacheQuote(q).run {
+                it.session.messageQueue.cache(q).run {
                     this[MessageSource].quote(sender)
                 }}
 
             it.session.bot.getGroup(it.target).apply {
                 val receipt = sendMessage(quote, it.messageChain.toMessageChain(this), this)
                 receipt.source.ensureSequenceIdAvailable()
+
+                it.session.messageQueue.addQuoteCache(GroupMessage("", botPermission, botAsMember, receipt.source.toChain()))
                 call.respondDTO(SendRetDTO(messageId = receipt.source.id))
             }
         }
@@ -123,8 +129,10 @@ fun Application.messageModule() {
         }
 
         miraiVerify<RecallDTO>("recall") {
-            // TODO
-            call.respond(HttpStatusCode.NotFound, "未完成")
+            it.session.messageQueue.cache(it.target).apply {
+                it.session.bot.recall(get(MessageSource))
+            }
+            call.respondStateCode(StateCode.Success)
         }
     }
 }
@@ -156,6 +164,5 @@ private class SendRetDTO(
 @Serializable
 private data class RecallDTO(
     override val sessionKey: String,
-    val target: Long,
-    val sender: Long
+    val target: Long
 ) : VerifyDTO()