chatmsg

package
v1.0.55-beta.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package chatmsg holds the shared, read-only projection helpers for DingTalk message-list responses (list_individual_chat_message, list_conversation_message_v2, search_at_me_message, search_messages_by_keyword, list_topic_replies, …). Several shortcuts reshape those raw responses into a clean speaker/text/time list; centralising the fiddly bits here keeps them consistent and fixed in one place:

  • Sender: the display name lives under the bare "sender" key, forwarded entries carry the literal string "null", and some responses nest the speaker in a {name:…} object — all handled here.
  • Text: out-of-office auto-replies / cards arrive as raw rich-content JSON, and card/robot messages arrive as undecryptable ciphertext; CleanText renders the former to readable text and marks the latter, WITHOUT ever rewriting ordinary text that merely contains a JSON fragment.
  • Forwarded: a forwarded chat record ("聊天记录") hides its real per-message bodies in forwardMessages while the top-level content is a lossy summary.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApplyMessagePagination

func ApplyMessagePagination(payload, data map[string]any, messages []map[string]any, direction string)

ApplyMessagePagination publishes message-list completeness without claiming the lower response's nextCursor is a valid CLI input. DingTalk's executable message-list contract paginates with the boundary message createTime, so the resume object uses exactly that accepted parameter.

func ApplyPagination

func ApplyPagination(payload, data map[string]any)

ApplyPagination carries lower-layer completeness facts into a projected Shortcut payload. It intentionally preserves cursor values only in the command output (where callers need them to continue); audit reports redact those values and retain only their presence.

func CleanText

func CleanText(s string) string

CleanText makes a message body human-readable WITHOUT ever rewriting ordinary text. It only transforms a body that is a genuine DingTalk structured message:

  • Encrypted card/robot ciphertext (base64 + "||v||t||len" trailer) → a clear "[加密消息]" marker instead of the raw base64.
  • A rich-content card (out-of-office auto-reply, link/preview card, …) whose lines include at least one recognised rich-content block → the readable text extracted from those blocks, with the card's decorative JSON lines and "empty" placeholders dropped.

Crucially, if NO line is a recognised rich-content block (e.g. ordinary text that merely embeds a `{"approved":false}` fragment), the original string is returned verbatim — a JSON line is never silently dropped.

func ConversationID

func ConversationID(m map[string]any) any

ConversationID preserves the stable conversation identity carried by list and search responses.

func CreateTime

func CreateTime(m map[string]any) any

CreateTime reads a message's create/send time under whichever candidate key is present, returning the raw value.

func Forwarded

func Forwarded(m map[string]any, project func(map[string]any) map[string]any) []map[string]any

Forwarded projects the nested messages of a forwarded chat record. The caller supplies its own per-message projection so each command keeps its own row shape; project is applied recursively, so multi-level forwards expand too.

func IsEncrypted

func IsEncrypted(s string) bool

IsEncrypted reports whether a message body is a raw DingTalk encrypted-message ciphertext: a base64 blob (DingTalk wraps it across several lines) followed by the "||v||t||len" trailer. It is intentionally strict — both the trailer and a pure-base64 body are required — so ordinary text (CJK, punctuation, …) never trips it.

func MessageID

func MessageID(m map[string]any) any

MessageID preserves the stable message identity needed by follow-up reply, reaction, resource and deduplication operations.

func MessageType

func MessageType(m map[string]any) any

MessageType preserves the lower message type when present.

func Pagination

func Pagination(data map[string]any) map[string]any

Pagination extracts hasMore/nextCursor from the response root or a common result/data envelope. When hasMore is present it also emits the explicit inverse "complete", making truncation hard for an Agent to overlook.

func QuotedMessage

func QuotedMessage(m map[string]any) map[string]any

QuotedMessage projects one level of quoted/replied-to context. It is deliberately non-recursive: a reply chain may be arbitrarily deep or even cyclic after gateway reshaping, while an Agent primarily needs the quoted message's stable identity, speaker, readable body and time.

func Reactions

func Reactions(m map[string]any) map[string]any

Reactions normalises DingTalk's inline emotionReplyList into one compact, Agent-friendly block. Unlike Lark, DingTalk already returns these reactions with message-list responses, so this projection performs no extra network request.

Output shape:

"reactions": {
  "counts":  [{"emoji": "赞", "count": 3}],
  "details": [{"emoji": "赞", "replyUsers": ["..."]}]
}

func Resources

func Resources(m map[string]any) []map[string]any

Resources extracts actionable media references from both structured message fields and the textual mediaId notation returned by older DingTalk message APIs. Every reference publishes the exact Shortcut arguments already known from the message, plus ready=false and missing fields when a follow-up lookup is still required. This shared shape is used by list, search, mget, quoted messages and thread replies.

func Sender

func Sender(m map[string]any) any

Sender reads a message's speaker display name, tolerating common sender-name keys. The message-list responses carry the display name under the bare "sender" key (verified live), so it is probed first; the remaining aliases and the *Id fallbacks keep the projection resilient to other shapes. The literal string "null" (forwarded entries) and the empty string are treated as absent, and a nested {name:…} sender object yields its display name rather than the raw object.

func Text

func Text(m map[string]any) any

Text reads a message's textual content (tolerating common text keys and one level of nesting) and runs it through CleanText.

func ThreadID

func ThreadID(m map[string]any) any

ThreadID preserves the stable topic/thread identity needed to continue from a message-list result into the thread-replies command.

func UpdateTime

func UpdateTime(m map[string]any) any

UpdateTime reads an edited message's update time. Gateways sometimes echo createTime as updateTime even when the message was never edited; omit that duplicate so Agents do not infer a nonexistent edit.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL