From 6c485634e10ffdd5b01444cf0d24f269d3d6d61c Mon Sep 17 00:00:00 2001
From: idranme <idranme@outlook.com>
Date: Wed, 18 Sep 2024 16:56:15 +0800
Subject: [PATCH] feat: `get_friend_msg_history` API

---
 electron.vite.config.ts                       |  1 -
 src/onebot11/action/index.ts                  |  2 +
 .../action/llonebot/GetFriendMsgHistory.ts    | 53 +++++++++++++++++++
 src/onebot11/action/types.ts                  |  1 +
 tsconfig.json                                 |  4 +-
 5 files changed, 58 insertions(+), 3 deletions(-)
 create mode 100644 src/onebot11/action/llonebot/GetFriendMsgHistory.ts

diff --git a/electron.vite.config.ts b/electron.vite.config.ts
index a16bf15..e6b320a 100644
--- a/electron.vite.config.ts
+++ b/electron.vite.config.ts
@@ -31,7 +31,6 @@ const config: ElectronViteConfig = {
     resolve: {
       alias: {
         '@': path.resolve(__dirname, './src'),
-        './lib-cov/fluent-ffmpeg': './lib/fluent-ffmpeg',
       },
     },
     plugins: [
diff --git a/src/onebot11/action/index.ts b/src/onebot11/action/index.ts
index ef11483..d18fabb 100644
--- a/src/onebot11/action/index.ts
+++ b/src/onebot11/action/index.ts
@@ -65,6 +65,7 @@ import { SendGroupNotice } from './go-cqhttp/SendGroupNotice'
 import { GetProfileLike } from './llonebot/GetProfileLike'
 import { FetchEmojiLike } from './llonebot/FetchEmojiLike'
 import { FetchCustomFace } from './llonebot/FetchCustomFace'
+import { GetFriendMsgHistory } from './llonebot/GetFriendMsgHistory'
 
 export function initActionMap(adapter: Adapter) {
   const actionHandlers = [
@@ -78,6 +79,7 @@ export function initActionMap(adapter: Adapter) {
     new GetEvent(adapter),
     new SetOnlineStatus(adapter),
     new GetProfileLike(adapter),
+    new GetFriendMsgHistory(adapter),
     // onebot11
     new SendLike(adapter),
     new GetMsg(adapter),
diff --git a/src/onebot11/action/llonebot/GetFriendMsgHistory.ts b/src/onebot11/action/llonebot/GetFriendMsgHistory.ts
new file mode 100644
index 0000000..9beee54
--- /dev/null
+++ b/src/onebot11/action/llonebot/GetFriendMsgHistory.ts
@@ -0,0 +1,53 @@
+import { BaseAction, Schema } from '../BaseAction'
+import { OB11Message } from '@/onebot11/types'
+import { ActionName } from '../types'
+import { ChatType, RawMessage } from '@/ntqqapi/types'
+import { MessageUnique } from '@/common/utils/messageUnique'
+import { OB11Entities } from '@/onebot11/entities'
+import { filterNullable } from '@/common/utils/misc'
+
+interface Payload {
+  user_id: number | string
+  message_seq?: number | string
+  message_id?: number | string
+  count: number | string
+  reverseOrder: boolean
+}
+
+interface Response {
+  messages: OB11Message[]
+}
+
+export class GetFriendMsgHistory extends BaseAction<Payload, Response> {
+  actionName = ActionName.GetFriendMsgHistory
+  payloadSchema = Schema.object({
+    user_id: Schema.union([Number, String]).required(),
+    message_seq: Schema.union([Number, String]),
+    message_id: Schema.union([Number, String]),
+    count: Schema.union([Number, String]).default(20),
+    reverseOrder: Schema.boolean().default(false)
+  })
+
+  async _handle(payload: Payload): Promise<Response> {
+    const startMsgId = payload.message_seq ?? payload.message_id
+    let msgList: RawMessage[]
+    if (startMsgId) {
+      const msgInfo = await MessageUnique.getMsgIdAndPeerByShortId(+startMsgId)
+      if (!msgInfo) throw new Error(`消息${startMsgId}不存在`)
+      msgList = (await this.ctx.ntMsgApi.getMsgHistory(msgInfo.Peer, msgInfo.MsgId, +payload.count)).msgList
+    } else {
+      const uid = await this.ctx.ntUserApi.getUidByUin(payload.user_id.toString())
+      if (!uid) throw new Error(`记录${payload.user_id}不存在`)
+      const isBuddy = await this.ctx.ntFriendApi.isBuddy(uid)
+      const peer = { chatType: isBuddy ? ChatType.friend : ChatType.temp, peerUid: uid }
+      msgList = (await this.ctx.ntMsgApi.getAioFirstViewLatestMsgs(peer, +payload.count)).msgList
+    }
+    if (msgList.length === 0) throw new Error('未找到消息')
+    if (payload.reverseOrder) msgList.reverse()
+    msgList.map(msg => {
+      msg.msgShortId = MessageUnique.createMsg({ chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId)
+    })
+    const ob11MsgList = await Promise.all(msgList.map(msg => OB11Entities.message(this.ctx, msg)))
+    return { messages: filterNullable(ob11MsgList) }
+  }
+}
diff --git a/src/onebot11/action/types.ts b/src/onebot11/action/types.ts
index ea309b0..fb47c39 100644
--- a/src/onebot11/action/types.ts
+++ b/src/onebot11/action/types.ts
@@ -23,6 +23,7 @@ export enum ActionName {
   GetProfileLike = 'get_profile_like',
   FetchEmojiLike = 'fetch_emoji_like',
   FetchCustomFace = 'fetch_custom_face',
+  GetFriendMsgHistory = 'get_friend_msg_history',
   // onebot 11
   SendLike = 'send_like',
   GetLoginInfo = 'get_login_info',
diff --git a/tsconfig.json b/tsconfig.json
index a383f6f..21e5d46 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -15,7 +15,7 @@
         "./src/common/*"
       ],
       "@/onebot11/*": [
-        "./src/onebot11"
+        "./src/onebot11/*"
       ],
       "@/ntqqapi/*": [
         "./src/ntqqapi/*"
@@ -27,4 +27,4 @@
     "src",
     "scripts"
   ]
-}
\ No newline at end of file
+}