Skip to content

notify: update notify/wechat#2402

Closed
binacs wants to merge 3 commits intoprometheus:mainfrom
binacs:binacs-update-notify-wechat
Closed

notify: update notify/wechat#2402
binacs wants to merge 3 commits intoprometheus:mainfrom
binacs:binacs-update-notify-wechat

Conversation

@binacs
Copy link

@binacs binacs commented Oct 23, 2020

Accoding to WeChat Work API, we will get response such as:

{
   "errcode": 0,
   "errmsg": "ok",
   "access_token": "accesstoken000001",
   "expires_in": 7200
}

instead of:

{
   "code": 0,
   "error": "ok",
   "access_token": "accesstoken000001",
}

And sometimes the request fails because it uses an expired token

So I did these things to update the code:

  1. Update weChatResponse and tokenResponse;
  2. Use expireIn instead of 2 * time.Hour;
  3. Record the time before we send the request, not after we receive the response;

For test, I wrote the following code:

func TestNotify(t *testing.T) {
        // Use `*` to protect information
	secret := "d2mS-c3*********************************dwKLMbDI"
	u, err := url.Parse("https://qyapi.weixin.qq.com/cgi-bin/")
	require.NoError(t, err)
	n, err := New(
		&config.WechatConfig{
			APIURL:      &config.URL{URL: u},
			HTTPConfig:  &commoncfg.HTTPClientConfig{},
			ToUser:      "binacs",
			AgentID:     "*********",
			CorpID:      "******************",
			MessageType: "text",
			Message:     "binacs: send from prometheus/alertmanager unit test",
			APISecret:   config.Secret(secret),
		},
		test.CreateTmpl(t),
		log.NewJSONLogger(os.Stdout),
	)
	require.NoError(t, err)
	ok, err := n.Notify(context.Background(), []*types.Alert{
		&types.Alert{
			Alert: model.Alert{
				Labels: model.LabelSet{
					"lbl1": "val1",
				},
				StartsAt: time.Now(),
				EndsAt:   time.Now().Add(time.Hour),
			},
		},
	}...)
	t.Log(ok, err)
}

And it works:
notice
message

Thanks for your review.

@binacs binacs force-pushed the binacs-update-notify-wechat branch from 9914ebf to 7d20cc1 Compare October 23, 2020 03:19
Copy link
Member

@simonpasquier simonpasquier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, just a few remarks! Could you add tests too please?

// Refresh AccessToken over 2 hours
if n.accessToken == "" || time.Since(n.accessTokenAt) > 2*time.Hour {
// Refresh AccessToken over `expireIn`
if n.accessToken == "" || time.Since(n.accessTokenAt) > n.expireIn {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be safer to renew the token before it expires (for instance when it reached 90% of its validity).

n.accessToken = wechatToken.AccessToken
n.accessTokenAt = time.Now()
n.accessTokenAt = startTime
n.expireIn = time.Duration(wechatToken.ExpiresIn) * time.Second
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of storing the creation time of the token and its period, you could record its expiration time (minus a safety interval as described above).

Signed-off-by: BinacsLee <bin646891055@gmail.com>
Signed-off-by: BinacsLee <bin646891055@gmail.com>
Signed-off-by: BinacsLee <bin646891055@gmail.com>
@binacs
Copy link
Author

binacs commented Oct 29, 2020

Thank you very much for your advice!

I have submitted the latest code. Could you please review it again? @simonpasquier

And the unit test works like this:

1C972E920C46F5EAAF451D1219A4B6D9

@binacs binacs force-pushed the binacs-update-notify-wechat branch from 96bce15 to 43c7699 Compare October 29, 2020 14:57
type token struct {
AccessToken string `json:"access_token"`
accessToken string
expireAt time.Time
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
expireAt time.Time
tokenRenewAt time.Time

// the correct configuration: secret and WechatConfig.
// You can get a full description of the WechatConfig's fields on
// https://work.weixin.qq.com/api/doc/90001/90143/91199
func TestNotify(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unit test can't access the real WeChat endpoint. We need to mock the WeChat API to simulate the various responses. Since it isn't trivial, I can have a look at it. Also this code doesn't test anything.

@stale stale bot added the stale label Jan 5, 2021
@SoloJacobs SoloJacobs self-assigned this Dec 12, 2025
@SoloJacobs
Copy link
Contributor

Hi @binacs ,

it appears to me that we have not heard back from you after the latest review. In the meantime, a fix has been submitted in #3330 .

Hopefully, this addresses the issue. If not, I'm happy to review a PR, which is based of the state of main. Thank you for your contribution.

Kind regards

@SoloJacobs SoloJacobs closed this Jan 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants