chenhg5/cc-connect · error

dingtalk: get access token for emotion: %w

Error message

dingtalk: get access token for emotion: %w

What it means

This error is returned by Platform.sendEmotion when the call to p.getAccessToken() fails while trying to send an emotion (typing indicator, done reaction, recall) through the DingTalk robot emotion API. The DingTalk emotion endpoints require a fresh access token, obtained by exchanging the configured appKey/appSecret with DingTalk's token endpoint; this error wraps whatever went wrong during that exchange (network failure, invalid credentials, or a non-success response from the token API). It means the emotion could not even be attempted because no valid token was available.

Source

Thrown at platform/dingtalk/dingtalk.go:927

	RobotCode          string              `json:"robotCode"`
	OpenMsgID          string              `json:"openMsgId"`
	OpenConversationID string              `json:"openConversationId"`
	EmotionType        int                 `json:"emotionType"`
	EmotionName        string              `json:"emotionName"`
	TextEmotion        dingtalkTextEmotion `json:"textEmotion"`
}

func (p *Platform) sendEmotion(ctx context.Context, rc replyContext, emoji string, recall bool) error {
	emoji = strings.TrimSpace(emoji)
	if emoji == "" || rc.messageID == "" || rc.conversationId == "" {
		return nil
	}
	if p.httpClient == nil {
		p.httpClient = &http.Client{Timeout: 30 * time.Second}
	}
	token, err := p.getAccessToken()
	if err != nil {
		return fmt.Errorf("dingtalk: get access token for emotion: %w", err)
	}

	path := "/v1.0/robot/emotion/reply"
	if recall {
		path = "/v1.0/robot/emotion/recall"
	}
	requestBody := dingtalkEmotionRequest{
		RobotCode:          p.robotCode,
		OpenMsgID:          rc.messageID,
		OpenConversationID: rc.conversationId,
		EmotionType:        2,
		EmotionName:        emoji,
		TextEmotion: dingtalkTextEmotion{
			EmotionID:    customTextEmotionID,
			EmotionName:  emoji,
			Text:         emoji,
			BackgroundID: customTextEmotionBackground,
		},

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Verify appKey and appSecret are set and correct in the DingTalk platform config
  2. Test network reachability to DingTalk's token endpoint from the host (curl the token URL)
  3. Check the DingTalk developer console to confirm the app is enabled and credentials are current
  4. Retry; if intermittent, check for rate limits or transient network issues

Example fix

// before (config)
[platforms.dingtalk]
appKey = ""
appSecret = "forgot"
// after
[platforms.dingtalk]
appKey = "ding0123456789abcdef"
appSecret = "real-secret-from-dingtalk-console"
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: verify credentials exist before attempting emotion send
if p.appKey == "" || p.appSecret == "" {
    return errors.New("dingtalk: appKey/appSecret not configured")
}

Try / catch

if err := p.StartTyping(ctx, rctx); err != nil {
    var tokErr *url.Error
    if errors.As(err, &tokErr) {
        slog.Warn("dingtalk token fetch network failure", "err", err)
    } else {
        slog.Error("dingtalk emotion token error", "err", err)
    }
}

Prevention

When it happens

Trigger: Calling StartTyping, AddDoneReaction, or sendEmotion (reply/recall) when getAccessToken() fails — e.g. DingTalk token endpoint unreachable, p.appKey/p.appSecret empty or wrong, token response missing accessToken, or the cached token expired and refresh failed.

Common situations: Missing or mistyped appKey/appSecret in config.toml; DingTalk app disabled or key rotated; corporate firewall/DNS blocking oapi.dingtalk.com; rate limiting or outage on the token endpoint.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/a549ebcdf7b9475e. Report an issue: GitHub.