訊息
im.messages 負責訊息列表、傳送、撤回、僅本人刪除、表情回應、置頂、已讀回執和本地搜尋。訊息的欄位、限制和內容格式見服務端的訊息格式。
| 要做什麼 | 看哪裡 |
|---|---|
| 顯示一個會話的訊息,翻看歷史 | 開啟訊息列表 |
| 發文字、圖片、檔案、自定義訊息 | 傳送內容 |
| @成員、引用、要求已讀回執,處理傳送失敗 | 傳送選項與佇列 |
| 撤回、刪除、表情回應、置頂 | 撤回、刪除、回應與置頂 |
| 本地搜尋、群訊息已讀人數 | 查詢與回執 |
| 發不儲存的臨時訊號 | 只發給線上裝置 |
開啟訊息列表
val list = im.messages.open(conversationKey)
try {
list.setViewing(atBottom = true, visible = true)
list.snapshot.collect { state ->
println(state.items.size)
println(state.error?.code)
}
} finally {
list.setViewing(visible = false)
list.close()
}快照包含 items、gaps、hasOlder、hasNewer、loading、pinned、error:
loadOlder()、loadNewer()載入更早或更新的訊息,jumpTo(seq)跳到某條訊息附近。gaps是還沒載入的範圍。kind為skipped的可以用loadGap(gap)載入;rejoin是重新入群之前的訊息,使用者看不到,不能載入。
頁面滾動或顯示、隱藏時呼叫 setViewing,報告使用者是否停在最新處、列表是否可見。開啟 autoMarkRead 後 SDK 據此自動推進已讀;沒開啟時,在使用者看到新訊息時呼叫 list.markRead()。完整的生命週期示例見介面與生命週期。
傳送內容
import com.deeprespond.im.*
val message = im.messages.send(
SendTarget.User("bob"),
OutgoingContent.Text("你好"),
SendOptions(waitUntilSent = true),
)SendTarget 有三種:User(username) 單聊、Group(groupId) 群聊、Conversation(conversationKey) 已有的會話。
| 內容 | 構造方式 |
|---|---|
| 文字 | OutgoingContent.Text(text) |
| 圖片 | OutgoingContent.Image(file, original = false) |
| 語音 | OutgoingContent.Voice(file, duration) |
| 影片 | OutgoingContent.Video(file) |
| 檔案 | OutgoingContent.File(file, name?) |
| 自定義 | OutgoingContent.Custom(body),接受 JsonObject 或 Map |
| 位置 | OutgoingContent.Location(latitude, longitude, name?, address?) |
| 已上傳附件 | OutgoingContent.Uploaded(type, body) |
| 轉發 | OutgoingContent.Forward(message) |
附件用 DRFile 傳入;從 URI 建立、錄音和上傳前的處理見檔案。
im.messages.send(
SendTarget.Group(groupId),
OutgoingContent.Custom(mapOf("card" to "order", "order_id" to "order-1")),
SendOptions(mentionUsernames = listOf("bob"), needReceipt = true),
)傳送選項與佇列
| SendOptions 欄位 | 預設值 | 用途 |
|---|---|---|
ext | null | JsonObject 擴充套件欄位 |
mentionUsernames、mentionAll | null、false | @成員、@全體 |
replyToSeq | null | 引用同一會話中的序號 |
needReceipt | false | 申請群已讀回執 |
excludeFromUnread | false | 不計入未讀,是否允許由策略決定 |
pushDisabled | null | 本條是否關閉推送 |
waitUntilSent | false | 等服務端確認後才返回 |
send 預設在訊息寫入傳送佇列後就返回。訊息的本地狀態依次為 queued(等待)、uploading(上傳中)、sending(傳送中),最後是 sent 或 failed。還沒發出的訊息 messageId、seq、conversationId 可能為 null,請用 clientMsgId 標識;上傳進度和錯誤在 message.local 中。
- 訊息進入佇列後,取消呼叫方的協程只是不再等結果,訊息仍會照常傳送。
discard(clientMsgId)刪除等待中或失敗的本地訊息,並取消上傳;resend(clientMsgId)重新傳送失敗的訊息。- 網路恢復後 SDK 自動繼續傳送佇列,不要為同一條訊息反覆呼叫
send。
撤回、刪除、回應與置頂
if (im.messages.canRecall(message)) {
val id = message.conversationId
val seq = message.seq
if (id != null && seq != null) im.messages.recall(id, seq)
}
im.messages.react(conversationId, seq, "like")
im.messages.unreact(conversationId, seq, "like")
im.messages.setPinned(conversationId, seq, true)撤回和置頂能否成功,以服務端的許可權和時限為準。deleteForMe(conversationId, seqs) 只刪除本人看到的訊息,每次最多 100 條;reactionUsers 查詢回應了某個表情的人。客戶端目前沒有編輯訊息的方法,不要照搬服務端 REST 介面中的編輯介面。
查詢與回執
lookup(conversationId, seqs)按序號取回訊息,返回items和取不到的missing。searchLocal(keyword, conversationId?, limit = 50)只在本機已儲存的文字訊息中查詢,不是服務端的全量搜尋。receipts(conversationId, seqs)查詢群訊息的已讀人數;getReceipt讀取記憶體中最近一次的結果。receiptUsers(..., ReceiptStatus.READ / UNREAD)分頁查詢已讀或未讀的成員,能否檢視由應用策略決定。
只發給線上裝置
sendOnline(target, body, ext?) 只能發 custom 內容:不進傳送佇列、不儲存,對方離線時收不到,失敗也不自動重試。連線暫停時以 network_error(paused)失敗。對方透過 MessageOnline 事件接收。適合“對方正在操作”這類臨時訊號,不要用它發需要可靠送達的通知。
全部方法和引數見MessagesModule。
