package email import ( "context" "encoding/base64" "errors" "fmt" "net/http" "time" "github.com/gorilla/websocket" "github.com/rs/zerolog/log" ) var FORWARDEMAIL_WS_API = "wss://api.forwardemail.net/v1/ws" func StartWebsocket(ctx context.Context, username, password string) { var err error var conn *websocket.Conn for { conn, err = ensureConnected(conn, username, password) if err != nil { log.Error().Err(err).Msg("Bailing on email websocket") return } select { case <-ctx.Done(): return default: // Read message message_type, message, err := conn.ReadMessage() if err != nil { if !websocket.IsCloseError(err, websocket.CloseNormalClosure) { conn = nil } log.Error().Err(err).Msg("Error reading message") } // Process and log the message log.Info().Int("message_type", message_type).Bytes("message", message).Msg("Got email notification") } } } func ensureConnected(conn *websocket.Conn, username, password string) (*websocket.Conn, error) { if conn != nil { return conn, nil } url := FORWARDEMAIL_WS_API for { encoded := base64.StdEncoding.EncodeToString([]byte(username + ":" + password)) h := http.Header{} h.Add("Authorization", "Basic "+encoded) new_conn, _, err := websocket.DefaultDialer.Dial(url, h) if err == nil { if new_conn == nil { log.Error().Msg("new connection is nil.") return nil, fmt.Errorf("nil new connection") } log.Info().Msg("Connected to mail websocket") return new_conn, nil } if errors.Is(err, websocket.ErrBadHandshake) { return nil, fmt.Errorf("Bad handshake connecting to email websocket, bailing.") } log.Error().Err(err).Str("url", url).Msg("Error connecting to WebSocket") time.Sleep(3 * time.Second) } }