feat(whatsmeow): add per-user proxy support (HTTP/HTTPS/SOCKS5) #152
Conversation
…e connect Read users.proxy_url and apply proxy to both Resty HTTP client and whatsmeow client before Connect() Use SetProxyAddress for HTTP/HTTPS and SetSOCKSProxy for SOCKS5 Add POST /session/proxy to set/clear proxy; requires the client to be disconnected Supports URLs like http://user:pass@host:port and socks5://user:pass@host:port Refs: Client.SetProxy docs https://pkg.go.dev/go.mau.fi/whatsmeow#Client.SetProxy
Summary of ChangesHello @vitorsilvalima, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request enhances the application's networking capabilities by integrating robust per-user proxy support. It allows individual WhatsApp client connections to be routed through specified HTTP/HTTPS or SOCKS5 proxies, which is crucial for users operating in restricted network environments. The changes ensure that all network traffic, including both control plane (websockets) and data plane (media), adheres to the configured proxy settings, providing a more flexible and compliant solution for diverse operational contexts. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request adds per-user proxy support for whatsmeow connections, which is a great feature for environments requiring traffic to be routed through proxies. The implementation correctly handles HTTP/HTTPS and SOCKS5 proxies. My main feedback is to refactor the proxy application logic to be more atomic, ensuring that both the resty and whatsmeow clients are configured consistently. This will prevent situations where a proxy is only partially applied if the configuration is invalid for one of the clients.
| // Apply proxy to Resty HTTP client for webhooks/downloads | ||
| httpClient.SetProxy(proxyURL) | ||
|
|
||
| // Also configure whatsmeow client's proxy BEFORE connecting | ||
| if parsed, perr := url.Parse(proxyURL); perr == nil { | ||
| if parsed.Scheme == "socks5" || parsed.Scheme == "socks5h" { | ||
| // Build SOCKS dialer from URL (supports user:pass in URL) | ||
| dialer, derr := proxy.FromURL(parsed, nil) | ||
| if derr != nil { | ||
| log.Warn().Err(derr).Str("proxy", proxyURL).Msg("Failed to build SOCKS proxy dialer") | ||
| } else { | ||
| client.SetSOCKSProxy(dialer, whatsmeow.SetProxyOptions{}) | ||
| } | ||
| } else { | ||
| // http/https proxies | ||
| client.SetProxyAddress(parsed.String(), whatsmeow.SetProxyOptions{}) | ||
| } | ||
| } |
There was a problem hiding this comment.
The current implementation sets the proxy for the resty HTTP client before fully validating it for the whatsmeow client. If parsing the URL or creating the SOCKS dialer fails, the whatsmeow client won't use the proxy, but the resty client will have already been configured. This leads to inconsistent proxy behavior.
To ensure both clients are configured atomically, the proxy URL should be fully validated first. The proxy should only be applied to both clients if it's valid for both.
// Parse and apply proxy configuration to ensure both clients use it consistently.
parsed, perr := url.Parse(proxyURL)
if perr != nil {
log.Warn().Err(perr).Str("proxy", proxyURL).Msg("Invalid proxy URL, skipping proxy setup")
} else {
if parsed.Scheme == "socks5" || parsed.Scheme == "socks5h" {
dialer, derr := proxy.FromURL(parsed, nil)
if derr != nil {
log.Warn().Err(derr).Str("proxy", proxyURL).Msg("Failed to build SOCKS proxy dialer, skipping proxy setup")
} else {
// Apply proxy to both clients now that we know it's valid.
httpClient.SetProxy(proxyURL)
client.SetSOCKSProxy(dialer, whatsmeow.SetProxyOptions{})
}
} else {
// For http/https, apply to both clients.
httpClient.SetProxy(proxyURL)
client.SetProxyAddress(parsed.String(), whatsmeow.SetProxyOptions{})
}
}…ient-proxy feat(whatsmeow): add per-user proxy support (HTTP/HTTPS/SOCKS5)
Overview
Adds per-user proxy configuration for WhatsApp client connections.
Applies proxy to both the internal Resty HTTP client and whatsmeow.Client before any Connect() calls.
Supports HTTP/HTTPS via SetProxyAddress and SOCKS5 via SetSOCKSProxy.
Provides an API to set/clear proxy per session.
Why
Some environments require routing WhatsApp websocket and media traffic through corporate or regional proxies.
Ensures consistent proxying for websocket signaling and media upload/download.
What changed
Apply proxy from users.proxy_url in wmiau.go:
HTTP/HTTPS: client.SetProxyAddress(, whatsmeow.SetProxyOptions{})
SOCKS5: client.SetSOCKSProxy(, whatsmeow.SetProxyOptions{})
Resty client also uses SetProxy()
New/updated endpoint: POST /session/proxy to set or clear the proxy; refuses changes while connected.