2025-01-25 10:20:51 +00:00

191 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Lark } from "../types"
import LarkBaseService from "./base"
class LarkMessageService extends LarkBaseService {
/**
* 发送卡片
* @param receiveIdType 消息接收者id类型 open_id/user_id/union_id/email/chat_id
* @param receiveId 消息接收者的IDID类型应与查询参数receiveIdType 对应
* @param msgType 消息类型 包括text、post、image、file、audio、media、sticker、interactive、share_chat、share_user
* @param content 消息内容JSON结构序列化后的字符串。不同msgType对应不同内容
*/
async send(
receiveIdType: Lark.ReceiveIDType,
receiveId: string,
msgType: Lark.MsgType,
content: string | Record<string, any>
) {
if (!content) return { code: 1, message: "content is required" }
const path = `/im/v1/messages?receive_id_type=${receiveIdType}`
if (typeof content === "object") {
content = JSON.stringify(content)
}
if (msgType === "text" && !content.includes('"text"')) {
content = JSON.stringify({ text: content })
}
return this.post<Lark.BaseRes<{ message_id: string }>>(path, {
receive_id: receiveId,
msg_type: msgType,
content,
})
}
/**
* 发送卡片信息
* @param receiveId 消息接收者的IDID类型应与查询参数receiveIdType 对应
* @param content 消息内容
*/
async sendCard2Chat(
receiveId: string,
content: string | Record<string, any>
) {
return this.send("chat_id", receiveId, "interactive", content)
}
/**
* 发送文本信息
* @param receiveId 消息接收者的IDID类型应与查询参数receiveIdType 对应
* @param content 消息内容
* @param title 消息标题
*/
async sendText2Chat(receiveId: string, content: string, title?: string) {
const messageContent = title ? `<b>${title}</b>\n${content}` : content
return this.send("chat_id", receiveId, "text", messageContent)
}
/**
* 更新卡片
* @param messageId 消息id
* @param content 消息内容JSON结构序列化后的字符串。不同msgType对应不同内容
*/
async update(
messageId: string,
content: string | Record<string, any>,
isText: boolean = false
) {
if (!content) return { code: 1, message: "content is required" }
const path = `/im/v1/messages/${messageId}`
if (typeof content === "object") {
content = JSON.stringify(content)
}
if (isText && !content.includes('"text"')) {
content = JSON.stringify({ text: content })
}
if (!isText) return this.patch<Lark.BaseRes>(path, { content })
return this.put<Lark.BaseRes>(path, { content, msg_type: "text" })
}
/**
* 获取消息历史记录
* @param chatId 会话ID
* @param startTime 开始时间 秒级时间戳
* @param endTime 结束时间 秒级时间戳
*/
async getHistory(chatId: string, startTime: string, endTime: string) {
const path = `/im/v1/messages`
const messageList = [] as Lark.MessageData[]
let hasMore = true
let pageToken = ""
while (hasMore) {
const { code, data } = await this.get<Lark.BaseListRes<Lark.MessageData>>(
path,
{
container_id_type: "chat",
container_id: chatId,
start_time: startTime,
end_time: endTime,
page_size: 50,
page_token: pageToken,
}
)
if (code !== 0) break
messageList.push(...data.items)
hasMore = data.has_more
pageToken = data.page_token
}
return {
code: 0,
data: messageList,
message: "ok",
}
}
/**
* 回复消息
* @param messageId 消息ID
* @param msgType 消息类型 包括text、post、image、file、audio、media、sticker、interactive、share_chat、share_user
* @param content 消息内容
*/
async reply(
messageId: string,
msgType: Lark.MsgType,
content: string | Record<string, any>
) {
if (!content) return { code: 1, message: "content is required" }
const path = `/im/v1/messages/${messageId}/reply`
if (typeof content === "object") {
content = JSON.stringify(content)
}
if (msgType === "text" && !content.includes('"text"')) {
content = JSON.stringify({ text: content })
}
return this.post<Lark.BaseRes<{ message_id: string }>>(path, {
msg_type: msgType,
content,
})
}
/**
* 回复卡片消息
* @param messageId 消息ID
* @param content 消息内容
*/
async replyCard(messageId: string, content: string | Record<string, any>) {
return this.reply(messageId, "interactive", content)
}
private repliedMessageId: string = ""
private replyMessageId: string = ""
private replyMsgType: "text" | "interactive" = "interactive"
/**
* 设置回复消息的ID和类型
* @param messageId 消息ID
* @param msgType 消息类型 包括text、interactive
*/
setReplyMessage(
messageId: string,
msgType: "text" | "interactive" = "interactive"
) {
this.replyMessageId = messageId
this.replyMsgType = msgType
}
/**
* 更新或回复消息
* @param content 消息内容
* @returns 更新或回复的消息ID
*/
async updateOrReply(content: string) {
if (this.repliedMessageId) {
await this.update(
this.repliedMessageId,
content,
this.replyMsgType === "text"
)
return this.repliedMessageId
}
const res = await this.reply(
this.replyMessageId,
this.replyMsgType,
content
)
if ("data" in res) {
this.repliedMessageId = res.data.message_id
}
return this.repliedMessageId
}
}
export default LarkMessageService