diff --git a/background/background.go b/background/background.go index 8ebded61..79055e68 100644 --- a/background/background.go +++ b/background/background.go @@ -5,6 +5,8 @@ import ( "fmt" "sync" + commsemail "github.com/Gleipnir-Technology/nidus-sync/comms/email" + "github.com/Gleipnir-Technology/nidus-sync/config" "github.com/Gleipnir-Technology/nidus-sync/db" "github.com/Gleipnir-Technology/nidus-sync/db/enums" "github.com/Gleipnir-Technology/nidus-sync/db/models" @@ -23,6 +25,12 @@ func Start(ctx context.Context) { channelJobEmail = make(chan email.Job, 100) // Buffered channel to prevent blocking channelJobText = make(chan text.Job, 100) // Buffered channel to prevent blocking + waitGroup.Add(1) + go func() { + defer waitGroup.Done() + commsemail.StartWebsocket(ctx, config.ForwardEmailAPIToken) + }() + waitGroup.Add(1) go func() { defer waitGroup.Done() diff --git a/comms/email/email.go b/comms/email/email.go index 429396ce..0df084df 100644 --- a/comms/email/email.go +++ b/comms/email/email.go @@ -64,7 +64,7 @@ type emailResponse struct { Message string `json:"message"` } -var FORWARDEMAIL_API = "https://api.forwardemail.net/v1/emails" +var FORWARDEMAIL_EMAIL_POST_API = "https://api.forwardemail.net/v1/emails" func Send(ctx context.Context, email Request) (response emailResponse, err error) { payload, err := json.Marshal(email) @@ -72,7 +72,7 @@ func Send(ctx context.Context, email Request) (response emailResponse, err error return response, fmt.Errorf("Failed to marshal email request: %w", err) } - req, _ := http.NewRequest("POST", FORWARDEMAIL_API, bytes.NewReader(payload)) + req, _ := http.NewRequest("POST", FORWARDEMAIL_EMAIL_POST_API, bytes.NewReader(payload)) req.SetBasicAuth(config.ForwardEmailAPIToken, "") req.Header.Add("Content-Type", "application/json") diff --git a/comms/email/websocket.go b/comms/email/websocket.go new file mode 100644 index 00000000..0e85d7c6 --- /dev/null +++ b/comms/email/websocket.go @@ -0,0 +1,62 @@ +package email + +import ( + "context" + "errors" + "fmt" + "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, api_token string) { + + var conn *websocket.Conn + for { + err := ensureConnected(conn, api_token) + 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, api_token string) error { + if conn != nil { + return nil + } + url := FORWARDEMAIL_WS_API + "?token=" + api_token + for { + new_conn, _, err := websocket.DefaultDialer.Dial(url, nil) + if err == nil { + log.Info().Msg("Connected to mail websocket") + *conn = *new_conn + return nil + } + if errors.Is(err, websocket.ErrBadHandshake) { + return 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) + + } +} diff --git a/go.mod b/go.mod index 8bb3e416..e00984d4 100644 --- a/go.mod +++ b/go.mod @@ -48,6 +48,7 @@ require ( github.com/golang-jwt/jwt/v5 v5.2.2 // indirect github.com/golang/mock v1.6.0 // indirect github.com/gorilla/schema v1.4.1 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/invopop/jsonschema v0.13.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect diff --git a/go.sum b/go.sum index 70db511c..c0995069 100644 --- a/go.sum +++ b/go.sum @@ -98,6 +98,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= diff --git a/html/template/sync/sudo.html b/html/template/sync/sudo.html index 2cb776dd..f8695c77 100644 --- a/html/template/sync/sudo.html +++ b/html/template/sync/sudo.html @@ -145,7 +145,7 @@ Email Testing