fix: improve access token handling and refresh logic in WeComAppChannel
This commit is contained in:
parent
4cc8b90da9
commit
eda7eb3d9f
1 changed files with 27 additions and 4 deletions
|
|
@ -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(),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue