fix: improve access token handling and refresh logic in WeComAppChannel

This commit is contained in:
Zhang Rui 2026-02-23 14:11:04 +08:00
parent 4cc8b90da9
commit eda7eb3d9f

View file

@ -215,7 +215,15 @@ func (c *WeComAppChannel) Send(ctx context.Context, msg bus.OutboundMessage) err
accessToken := c.getAccessToken() accessToken := c.getAccessToken()
if accessToken == "" { if accessToken == "" {
return fmt.Errorf("no valid access token available") // Token expired or not yet acquired — attempt an on-demand refresh
logger.WarnC("wecom_app", "Access token missing or expired, attempting on-demand refresh")
if err := c.refreshAccessToken(); err != nil {
return fmt.Errorf("access token unavailable and refresh failed: %w", err)
}
accessToken = c.getAccessToken()
if accessToken == "" {
return fmt.Errorf("no valid access token available after refresh")
}
} }
logger.DebugCF("wecom_app", "Sending message", map[string]any{ logger.DebugCF("wecom_app", "Sending message", map[string]any{
@ -453,14 +461,29 @@ func (c *WeComAppChannel) processMessage(ctx context.Context, msg WeComXMLMessag
// tokenRefreshLoop periodically refreshes the access token // tokenRefreshLoop periodically refreshes the access token
func (c *WeComAppChannel) tokenRefreshLoop() { func (c *WeComAppChannel) tokenRefreshLoop() {
ticker := time.NewTicker(5 * time.Minute) const fallbackInterval = 30 * time.Minute
defer ticker.Stop() const earlyRefresh = 5 * time.Minute
for { for {
// Calculate sleep duration based on current token expiry
c.tokenMu.RLock()
expiry := c.tokenExpiry
c.tokenMu.RUnlock()
var sleepDur time.Duration
if expiry.IsZero() {
// Token never successfully acquired
sleepDur = fallbackInterval
} else {
sleepDur = max(time.Until(expiry.Add(-earlyRefresh)),
// minimum 1 minute to avoid tight loop
time.Minute)
}
select { select {
case <-c.ctx.Done(): case <-c.ctx.Done():
return return
case <-ticker.C: case <-time.After(sleepDur):
if err := c.refreshAccessToken(); err != nil { if err := c.refreshAccessToken(); err != nil {
logger.ErrorCF("wecom_app", "Failed to refresh access token", map[string]any{ logger.ErrorCF("wecom_app", "Failed to refresh access token", map[string]any{
"error": err.Error(), "error": err.Error(),