Browse Source

fix: make webhook call async and add retry mechanism

fix(init.go): wrap forwardToWebhook call in a goroutine to make it async
feat(webhook.go): add timestamp field to the webhook payload
fix(webhook.go): implement retry logic for submitWebhook with exponential backoff
pull/221/head
Aldino Kemal 1 year ago
parent
commit
d2fe0fce32
  1. 8
      src/pkg/whatsapp/init.go
  2. 16
      src/pkg/whatsapp/webhook.go

8
src/pkg/whatsapp/init.go

@ -152,9 +152,11 @@ func handler(rawEvt interface{}) {
if config.WhatsappWebhook != "" &&
!strings.Contains(evt.Info.SourceString(), "broadcast") &&
!isFromMySelf(evt.Info.SourceString()) {
if err := forwardToWebhook(evt); err != nil {
logrus.Error("Failed forward to webhook: ", err)
}
go func(evt *events.Message) {
if err := forwardToWebhook(evt); err != nil {
logrus.Error("Failed forward to webhook: ", err)
}
}(evt)
}
case *events.Receipt:
if evt.Type == types.ReceiptTypeRead || evt.Type == types.ReceiptTypeReadSelf {

16
src/pkg/whatsapp/webhook.go

@ -57,6 +57,7 @@ func createPayload(evt *events.Message) (map[string]interface{}, error) {
"video": videoMedia,
"view_once": evt.IsViewOnce,
"forwarded": forwarded,
"timestamp": evt.Info.Timestamp.Format(time.RFC3339),
}
if imageMedia != nil {
@ -120,8 +121,17 @@ func submitWebhook(payload map[string]interface{}) error {
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Hub-Signature-256", fmt.Sprintf("sha256=%s", signature))
if _, err = client.Do(req); err != nil {
return pkgError.WebhookError(fmt.Sprintf("error when submit webhook %v", err))
var attempt int
var maxAttempts = 5
var sleepDuration = 1 * time.Second
for attempt = 0; attempt < maxAttempts; attempt++ {
if _, err = client.Do(req); err == nil {
return nil
}
time.Sleep(sleepDuration)
sleepDuration *= 2
}
return nil
return pkgError.WebhookError(fmt.Sprintf("error when submit webhook after %d attempts: %v", attempt, err))
}
Loading…
Cancel
Save