Skip to content

Commit 17b5a1d

Browse files
authored
Merge pull request #190 from cleitonme/bugcrashesproxy
bug proxy crashes
2 parents 7a567c9 + 6b92a83 commit 17b5a1d

File tree

1 file changed

+70
-22
lines changed

1 file changed

+70
-22
lines changed

wmiau.go

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,10 @@ func parseJID(arg string) (types.JID, bool) {
363363
func (s *server) startClient(userID string, textjid string, token string, subscriptions []string) {
364364
log.Info().Str("userid", userID).Str("jid", textjid).Msg("Starting websocket connection to Whatsapp")
365365

366+
// Connection retry constants
367+
const maxConnectionRetries = 3
368+
const connectionRetryBaseWait = 5 * time.Second
369+
366370
var deviceStore *store.Device
367371
var err error
368372

@@ -396,25 +400,14 @@ func (s *server) startClient(userID string, textjid string, token string, subscr
396400

397401
// Now we can use the client with the manager
398402
clientManager.SetWhatsmeowClient(userID, client)
399-
if textjid != "" {
400-
jid, _ := parseJID(textjid)
401-
deviceStore, err = container.GetDevice(context.Background(), jid)
402-
if err != nil {
403-
panic(err)
404-
}
405-
} else {
406-
log.Warn().Msg("No jid found. Creating new device")
407-
deviceStore = container.NewDevice()
408-
}
409403

410404
store.DeviceProps.PlatformType = waCompanionReg.DeviceProps_UNKNOWN.Enum()
411405
store.DeviceProps.Os = osName
412406

413-
clientManager.SetWhatsmeowClient(userID, client)
414407
mycli := MyClient{client, 1, userID, token, subscriptions, s.db, s}
415408
mycli.eventHandlerID = mycli.WAClient.AddEventHandler(mycli.myEventHandler)
416409

417-
// CORREÇÃO: Armazenar o MyClient no clientManager
410+
// Store the MyClient in clientManager
418411
clientManager.SetMyClient(userID, &mycli)
419412

420413
httpClient := resty.New()
@@ -433,32 +426,32 @@ func (s *server) startClient(userID string, textjid string, token string, subscr
433426
}
434427
})
435428

436-
// NEW: set proxy if defined in DB (assumes users table contains proxy_url column)
429+
// Set proxy if defined in DB (assumes users table contains proxy_url column)
437430
var proxyURL string
438431
err = s.db.Get(&proxyURL, "SELECT proxy_url FROM users WHERE id=$1", userID)
439432
if err == nil && proxyURL != "" {
440-
441433
parsed, perr := url.Parse(proxyURL)
442434
if perr != nil {
443435
log.Warn().Err(perr).Str("proxy", proxyURL).Msg("Invalid proxy URL, skipping proxy setup")
444436
} else {
437+
438+
log.Info().Str("proxy", proxyURL).Msg("Configuring proxy")
439+
445440
if parsed.Scheme == "socks5" || parsed.Scheme == "socks5h" {
446-
// Build SOCKS dialer from URL (supports user:pass in URL)
447441
dialer, derr := proxy.FromURL(parsed, nil)
448442
if derr != nil {
449443
log.Warn().Err(derr).Str("proxy", proxyURL).Msg("Failed to build SOCKS proxy dialer, skipping proxy setup")
450444
} else {
451-
// Apply proxy to both clients now that we know it's valid.
452445
httpClient.SetProxy(proxyURL)
453446
client.SetSOCKSProxy(dialer, whatsmeow.SetProxyOptions{})
447+
log.Info().Msg("SOCKS proxy configured successfully")
454448
}
455449
} else {
456-
// For http/https, apply to both clients.
457450
httpClient.SetProxy(proxyURL)
458451
client.SetProxyAddress(parsed.String(), whatsmeow.SetProxyOptions{})
452+
log.Info().Msg("HTTP/HTTPS proxy configured successfully")
459453
}
460454
}
461-
462455
}
463456
clientManager.SetHTTPClient(userID, httpClient)
464457

@@ -472,7 +465,7 @@ func (s *server) startClient(userID string, textjid string, token string, subscr
472465
return
473466
}
474467
} else {
475-
err = client.Connect() // Si no conectamos no se puede generar QR
468+
err = client.Connect() // Must connect to generate QR code
476469
if err != nil {
477470
log.Error().Err(err).Msg("Failed to connect client")
478471
return
@@ -555,9 +548,64 @@ func (s *server) startClient(userID string, textjid string, token string, subscr
555548
} else {
556549
// Already logged in, just connect
557550
log.Info().Msg("Already logged in, just connect")
558-
err = client.Connect()
559-
if err != nil {
560-
panic(err)
551+
552+
// Retry logic with linear backoff
553+
var lastErr error
554+
555+
for attempt := 0; attempt < maxConnectionRetries; attempt++ {
556+
if attempt > 0 {
557+
waitTime := time.Duration(attempt) * connectionRetryBaseWait
558+
log.Warn().
559+
Int("attempt", attempt+1).
560+
Int("max_retries", maxConnectionRetries).
561+
Dur("wait_time", waitTime).
562+
Msg("Retrying connection after delay")
563+
time.Sleep(waitTime)
564+
}
565+
566+
err = client.Connect()
567+
if err == nil {
568+
log.Info().
569+
Int("attempt", attempt+1).
570+
Msg("Successfully connected to WhatsApp")
571+
break
572+
}
573+
574+
lastErr = err
575+
log.Warn().
576+
Err(err).
577+
Int("attempt", attempt+1).
578+
Int("max_retries", maxConnectionRetries).
579+
Msg("Failed to connect to WhatsApp")
580+
}
581+
582+
if lastErr != nil {
583+
log.Error().
584+
Err(lastErr).
585+
Str("userid", userID).
586+
Int("attempts", maxConnectionRetries).
587+
Msg("Failed to connect to WhatsApp after all retry attempts")
588+
589+
clientManager.DeleteWhatsmeowClient(userID)
590+
clientManager.DeleteMyClient(userID)
591+
clientManager.DeleteHTTPClient(userID)
592+
593+
sqlStmt := `UPDATE users SET qrcode='', connected=0 WHERE id=$1`
594+
_, dbErr := s.db.Exec(sqlStmt, userID)
595+
if dbErr != nil {
596+
log.Error().Err(dbErr).Msg("Failed to update user status after connection error")
597+
}
598+
599+
// Use the existing mycli instance from outer scope
600+
postmap := make(map[string]interface{})
601+
postmap["event"] = "ConnectFailure"
602+
postmap["error"] = lastErr.Error()
603+
postmap["type"] = "ConnectFailure"
604+
postmap["attempts"] = maxConnectionRetries
605+
postmap["reason"] = "Failed to connect after retry attempts"
606+
sendEventWithWebHook(&mycli, postmap, "")
607+
608+
return
561609
}
562610
}
563611

0 commit comments

Comments
 (0)