nidus-sync/comms/email/websocket.go

69 lines
1.7 KiB
Go

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)
}
}