mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-08-17 11:37:06 +08:00
87 lines
2.2 KiB
Go
87 lines
2.2 KiB
Go
package messaging
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/Wxw-Gu/WechatExplorer/services/wechat-connector/ilink"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// NewClientID generates a new unique client ID for message correlation.
|
|
func NewClientID() string {
|
|
return uuid.New().String()
|
|
}
|
|
|
|
// SendTypingState sends a typing indicator to a user via the iLink sendtyping API.
|
|
// It first fetches a typing_ticket via getconfig, then sends the typing status.
|
|
func SendTypingState(ctx context.Context, client *ilink.Client, userID, contextToken string) error {
|
|
// Get typing ticket
|
|
configResp, err := client.GetConfig(ctx, userID, contextToken)
|
|
if err != nil {
|
|
return fmt.Errorf("get config for typing: %w", err)
|
|
}
|
|
if configResp.TypingTicket == "" {
|
|
return fmt.Errorf("no typing_ticket returned from getconfig")
|
|
}
|
|
|
|
// Send typing
|
|
if err := client.SendTyping(ctx, userID, configResp.TypingTicket, ilink.TypingStatusTyping); err != nil {
|
|
return fmt.Errorf("send typing: %w", err)
|
|
}
|
|
|
|
log.Printf("[sender] sent typing indicator to %s", userID)
|
|
return nil
|
|
}
|
|
|
|
// SendTextReply sends a text reply to a user through the iLink API.
|
|
// If clientID is empty, a new one is generated.
|
|
func SendTextReply(ctx context.Context, client *ilink.Client, toUserID, text, contextToken, clientID string) error {
|
|
if clientID == "" {
|
|
clientID = NewClientID()
|
|
}
|
|
|
|
// Convert markdown to plain text for WeChat display
|
|
plainText := MarkdownToPlainText(text)
|
|
|
|
req := &ilink.SendMessageRequest{
|
|
Msg: ilink.SendMsg{
|
|
FromUserID: client.BotID(),
|
|
ToUserID: toUserID,
|
|
ClientID: clientID,
|
|
MessageType: ilink.MessageTypeBot,
|
|
MessageState: ilink.MessageStateFinish,
|
|
ItemList: []ilink.MessageItem{
|
|
{
|
|
Type: ilink.ItemTypeText,
|
|
TextItem: &ilink.TextItem{
|
|
Text: plainText,
|
|
},
|
|
},
|
|
},
|
|
ContextToken: contextToken,
|
|
},
|
|
BaseInfo: ilink.BaseInfo{},
|
|
}
|
|
|
|
resp, err := client.SendMessage(ctx, req)
|
|
if err != nil {
|
|
return fmt.Errorf("send message: %w", err)
|
|
}
|
|
|
|
if resp.Ret != 0 {
|
|
return fmt.Errorf("send message failed: ret=%d errmsg=%s", resp.Ret, resp.ErrMsg)
|
|
}
|
|
|
|
log.Printf("[sender] sent reply to %s: %q", toUserID, truncate(text, 50))
|
|
return nil
|
|
}
|
|
|
|
func truncate(s string, n int) string {
|
|
if len(s) <= n {
|
|
return s
|
|
}
|
|
return s[:n] + "..."
|
|
}
|