weixin

package
v0.28.0 Latest Latest
Warning

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

Go to latest
Published: Mar 31, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultAPIBaseURL = "https://ilinkai.weixin.qq.com"
	DefaultCDNBaseURL = "https://novac2c.cdn.weixin.qq.com/c2c"

	SessionExpiredErrCode = -14

	// TypingStatus values for SendTyping.
	TypingStatusTyping = 1
	TypingStatusCancel = 2
)

Variables

This section is empty.

Functions

func AESECBPaddedSize added in v0.27.0

func AESECBPaddedSize(plaintextSize int) int

AESECBPaddedSize returns the size after AES-128-ECB encryption with PKCS7 padding. PKCS7 always adds at least 1 byte, so output = ceil((size+1)/16) * 16.

func ClearSession

func ClearSession(sandboxID string)

func DecryptAESECB added in v0.27.0

func DecryptAESECB(ciphertext, key []byte) ([]byte, error)

DecryptAESECB decrypts AES-128-ECB encrypted data with PKCS7 padding.

func DownloadAndDecryptMedia added in v0.27.0

func DownloadAndDecryptMedia(ctx context.Context, cdnBaseURL, encryptQueryParam, aesKeyBase64, fullURL string) ([]byte, error)

DownloadAndDecryptMedia downloads and decrypts a media file from iLink CDN. aesKeyBase64 is the base64-encoded AES key from the CDNMedia.aes_key field. Also supports hex-encoded keys wrapped in base64 (32 hex chars). fullURL, if non-empty, is used directly instead of constructing from encryptQueryParam.

func DownloadFromCDN added in v0.27.0

func DownloadFromCDN(ctx context.Context, cdnBaseURL, encryptQueryParam, fullURL string) ([]byte, error)

DownloadFromCDN downloads a file from the iLink CDN. Prefers fullURL (server-provided) over client-side URL construction from encrypt_query_param.

func EncryptAESECB added in v0.27.0

func EncryptAESECB(plaintext, key []byte) []byte

EncryptAESECB encrypts data with AES-128-ECB and PKCS7 padding.

func ExtractText added in v0.27.0

func ExtractText(msg WeixinMessage) string

ExtractText extracts the text content from a WeixinMessage. Mirrors openclaw-weixin's bodyFromItemList:

  • TEXT items with ref_msg get a "[引用: ...]" prefix (unless the ref is media)
  • VOICE items with speech-to-text use the transcribed text
  • ref_msg content is resolved recursively

func SendImageMessage added in v0.27.0

func SendImageMessage(ctx context.Context, apiBaseURL, botToken, toUserID string, encryptQueryParam, aesKeyHex string, ciphertextSize int, contextToken string) error

SendImageMessage sends an image message to a WeChat user via iLink.

func SendTextMessage added in v0.26.0

func SendTextMessage(ctx context.Context, apiBaseURL, botToken, toUserID, text, contextToken string) error

SendTextMessage sends a text message to a WeChat user via iLink.

func SendTyping added in v0.27.0

func SendTyping(ctx context.Context, apiBaseURL, botToken, userID, typingTicket string, status int) error

SendTyping sends a typing indicator to a WeChat user via iLink. status should be TypingStatusTyping (1) or TypingStatusCancel (2).

func SetSession

func SetSession(sandboxID string, s *Session)

func UploadAndSendImage added in v0.27.0

func UploadAndSendImage(ctx context.Context, apiBaseURL, cdnBaseURL, botToken, toUserID string, imageData []byte, contextToken string) error

UploadAndSendImage handles the complete flow: encrypt → CDN upload → send message.

func UploadToCDN added in v0.27.0

func UploadToCDN(ctx context.Context, cdnBaseURL, uploadParam, filekey string, ciphertext []byte) (string, error)

UploadToCDN uploads encrypted file data to the iLink CDN. Returns the download encrypt_query_param from the response header.

Types

type BaseInfo added in v0.26.0

type BaseInfo struct {
	ChannelVersion string `json:"channel_version,omitempty"`
}

BaseInfo is common metadata attached to every iLink API request.

type CDNMedia added in v0.27.0

type CDNMedia struct {
	EncryptQueryParam string `json:"encrypt_query_param,omitempty"`
	AESKey            string `json:"aes_key,omitempty"`      // base64-encoded
	EncryptType       int    `json:"encrypt_type,omitempty"` // 1 = full packet encryption
	FullURL           string `json:"full_url,omitempty"`     // server-provided download URL (preferred over client-side construction)
}

CDNMedia references a file uploaded to iLink CDN.

type FileItem added in v0.27.0

type FileItem struct {
	Media    *CDNMedia `json:"media,omitempty"`
	FileName string    `json:"file_name,omitempty"`
	Len      string    `json:"len,omitempty"`
}

FileItem holds file attachment metadata.

type GetConfigResponse added in v0.27.0

type GetConfigResponse struct {
	Ret          int    `json:"ret"`
	ErrMsg       string `json:"errmsg"`
	TypingTicket string `json:"typing_ticket"`
}

GetConfigResponse is the response from ilink/bot/getconfig.

func GetConfig added in v0.27.0

func GetConfig(ctx context.Context, apiBaseURL, botToken, userID, contextToken string) (*GetConfigResponse, error)

GetConfig fetches bot config for a user, including the typing_ticket needed for SendTyping.

type GetUpdatesRequest added in v0.26.0

type GetUpdatesRequest struct {
	GetUpdatesBuf string   `json:"get_updates_buf"`
	BaseInfo      BaseInfo `json:"base_info"`
}

GetUpdatesRequest is the body for POST /ilink/bot/getupdates.

type GetUpdatesResponse added in v0.26.0

type GetUpdatesResponse struct {
	Ret                  int             `json:"ret"`
	ErrCode              int             `json:"errcode,omitempty"`
	ErrMsg               string          `json:"errmsg,omitempty"`
	Msgs                 []WeixinMessage `json:"msgs,omitempty"`
	GetUpdatesBuf        string          `json:"get_updates_buf,omitempty"`
	LongPollingTimeoutMs int             `json:"longpolling_timeout_ms,omitempty"`
}

GetUpdatesResponse is the response from getupdates.

func GetUpdates added in v0.26.0

func GetUpdates(ctx context.Context, apiBaseURL, botToken, getUpdatesBuf string) (*GetUpdatesResponse, error)

GetUpdates long-polls iLink for new messages. Blocks for up to ~35s. Returns an empty response (Ret=0, no msgs) on client-side timeout.

type GetUploadURLResponse added in v0.27.0

type GetUploadURLResponse struct {
	UploadParam string `json:"upload_param"`
}

GetUploadURLResponse is the response from ilink/bot/getuploadurl.

func GetUploadURL added in v0.27.0

func GetUploadURL(ctx context.Context, apiBaseURL, botToken string, params map[string]interface{}) (*GetUploadURLResponse, error)

GetUploadURL obtains a pre-signed CDN upload URL from iLink.

type ImageItem added in v0.27.0

type ImageItem struct {
	Media      *CDNMedia `json:"media,omitempty"`
	ThumbMedia *CDNMedia `json:"thumb_media,omitempty"`
	AESKey     string    `json:"aeskey,omitempty"` // raw AES-128 key as hex string; preferred over media.aes_key for inbound
	URL        string    `json:"url,omitempty"`
	MidSize    int       `json:"mid_size,omitempty"`
	ThumbSize  int       `json:"thumb_size,omitempty"`
	HdSize     int       `json:"hd_size,omitempty"`
}

ImageItem holds the image data for an IMAGE message item.

type MessageItem added in v0.26.0

type MessageItem struct {
	Type      int         `json:"type,omitempty"` // 1=TEXT, 2=IMAGE, 3=VOICE, 4=FILE, 5=VIDEO
	TextItem  *TextItem   `json:"text_item,omitempty"`
	ImageItem *ImageItem  `json:"image_item,omitempty"`
	VoiceItem *VoiceItem  `json:"voice_item,omitempty"`
	FileItem  *FileItem   `json:"file_item,omitempty"`
	VideoItem *VideoItem  `json:"video_item,omitempty"`
	RefMsg    *RefMessage `json:"ref_msg,omitempty"`
}

MessageItem represents a single content item in a WeixinMessage.

type RefMessage added in v0.27.0

type RefMessage struct {
	MessageItem *MessageItem `json:"message_item,omitempty"`
	Title       string       `json:"title,omitempty"`
}

RefMessage holds a quoted/referenced message.

type SendMessageRequest added in v0.26.0

type SendMessageRequest struct {
	Msg      WeixinMessage `json:"msg"`
	BaseInfo BaseInfo      `json:"base_info"`
}

SendMessageRequest is the body for POST /ilink/bot/sendmessage.

type Session

type Session struct {
	QRCode    string // opaque qrcode string for status polling
	QRCodeURL string // image URL for frontend rendering
	StartedAt time.Time
}

Session holds the state of an in-progress QR login for a single sandbox.

func GetSession

func GetSession(sandboxID string) *Session

func StartLogin

func StartLogin(ctx context.Context, apiBaseURL string) (*Session, error)

StartLogin calls the ilink API to generate a new QR code for WeChat login.

func TakeSession

func TakeSession(sandboxID string) *Session

TakeSession atomically returns and removes the session (used on confirmed).

type StatusResult

type StatusResult struct {
	Status  string `json:"status"` // "wait", "scaned", "confirmed", "expired"
	Token   string `json:"bot_token,omitempty"`
	BotID   string `json:"ilink_bot_id,omitempty"`
	BaseURL string `json:"baseurl,omitempty"`
	UserID  string `json:"ilink_user_id,omitempty"`
}

StatusResult is the parsed response from get_qrcode_status.

func PollLoginStatus

func PollLoginStatus(ctx context.Context, apiBaseURL, qrcode string) (*StatusResult, error)

PollLoginStatus long-polls the ilink API for QR code scan status. Blocks for up to ~35 seconds (server-side long-poll).

type TextItem added in v0.26.0

type TextItem struct {
	Text string `json:"text,omitempty"`
}

TextItem holds the text content of a TEXT message item.

type VideoItem added in v0.27.0

type VideoItem struct {
	Media     *CDNMedia `json:"media,omitempty"`
	VideoSize int       `json:"video_size,omitempty"`
}

VideoItem holds video metadata.

type VoiceItem added in v0.27.0

type VoiceItem struct {
	Media      *CDNMedia `json:"media,omitempty"`
	EncodeType int       `json:"encode_type,omitempty"`
	SampleRate int       `json:"sample_rate,omitempty"`
	PlayTime   int       `json:"playtime,omitempty"`
	Text       string    `json:"text,omitempty"` // speech-to-text content
}

VoiceItem holds voice message data.

type WeixinMessage added in v0.26.0

type WeixinMessage struct {
	FromUserID   string        `json:"from_user_id"`
	ToUserID     string        `json:"to_user_id,omitempty"`
	ClientID     string        `json:"client_id,omitempty"`
	CreateTimeMs int64         `json:"create_time_ms,omitempty"`
	MessageType  int           `json:"message_type,omitempty"`  // 1=USER, 2=BOT
	MessageState int           `json:"message_state,omitempty"` // 0=NEW, 1=GENERATING, 2=FINISH
	ItemList     []MessageItem `json:"item_list,omitempty"`
	ContextToken string        `json:"context_token,omitempty"`
}

WeixinMessage is a message from/to iLink.

Jump to

Keyboard shortcuts

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