Refactor SendPulse into shared service, wire app registration to Sojorn Members list (book 568122)
This commit is contained in:
parent
90ff6e223b
commit
2ad148f607
|
|
@ -1,11 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
|
@ -116,6 +112,7 @@ func main() {
|
|||
notificationService := services.NewNotificationService(notifRepo, pushService, userRepo)
|
||||
|
||||
emailService := services.NewEmailService(cfg)
|
||||
sendPulseService := services.NewSendPulseService(cfg.SendPulseID, cfg.SendPulseSecret)
|
||||
|
||||
// Load moderation configuration
|
||||
moderationConfig := config.NewModerationConfig()
|
||||
|
|
@ -133,7 +130,7 @@ func main() {
|
|||
userHandler := handlers.NewUserHandler(userRepo, postRepo, notificationService, assetService)
|
||||
postHandler := handlers.NewPostHandler(postRepo, userRepo, feedService, assetService, notificationService, moderationService, contentFilter)
|
||||
chatHandler := handlers.NewChatHandler(chatRepo, notificationService, hub)
|
||||
authHandler := handlers.NewAuthHandler(userRepo, cfg, emailService)
|
||||
authHandler := handlers.NewAuthHandler(userRepo, cfg, emailService, sendPulseService)
|
||||
categoryHandler := handlers.NewCategoryHandler(categoryRepo)
|
||||
keyHandler := handlers.NewKeyHandler(userRepo)
|
||||
backupHandler := handlers.NewBackupHandler(repository.NewBackupRepository(dbPool))
|
||||
|
|
@ -200,10 +197,8 @@ func main() {
|
|||
c.JSON(500, gin.H{"error": "Failed to join waitlist"})
|
||||
return
|
||||
}
|
||||
// Add to SendPulse in background
|
||||
go func(email string) {
|
||||
addToSendPulse(cfg, email)
|
||||
}(req.Email)
|
||||
// Add to SendPulse waitlist in background
|
||||
go sendPulseService.AddToWaitlist(req.Email)
|
||||
c.JSON(200, gin.H{"message": "You're on the list!"})
|
||||
})
|
||||
}
|
||||
|
|
@ -466,55 +461,3 @@ func main() {
|
|||
|
||||
log.Info().Msg("Server exiting")
|
||||
}
|
||||
|
||||
func addToSendPulse(cfg *config.Config, email string) {
|
||||
if cfg.SendPulseID == "" || cfg.SendPulseSecret == "" {
|
||||
return
|
||||
}
|
||||
|
||||
// 1. Get OAuth token
|
||||
tokenBody, _ := json.Marshal(map[string]string{
|
||||
"grant_type": "client_credentials",
|
||||
"client_id": cfg.SendPulseID,
|
||||
"client_secret": cfg.SendPulseSecret,
|
||||
})
|
||||
tokenResp, err := http.Post("https://api.sendpulse.com/oauth/access_token", "application/json", bytes.NewReader(tokenBody))
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("SendPulse: failed to get token")
|
||||
return
|
||||
}
|
||||
defer tokenResp.Body.Close()
|
||||
|
||||
var tokenData struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
}
|
||||
if err := json.NewDecoder(tokenResp.Body).Decode(&tokenData); err != nil || tokenData.AccessToken == "" {
|
||||
log.Error().Err(err).Msg("SendPulse: failed to parse token")
|
||||
return
|
||||
}
|
||||
|
||||
// 2. Add subscriber to Sojorn Waitlist (address book 568090)
|
||||
subBody, _ := json.Marshal(map[string]interface{}{
|
||||
"emails": []map[string]string{
|
||||
{"email": email},
|
||||
},
|
||||
})
|
||||
req, _ := http.NewRequest("POST", "https://api.sendpulse.com/addressbooks/568090/emails", bytes.NewReader(subBody))
|
||||
req.Header.Set("Authorization", "Bearer "+tokenData.AccessToken)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("SendPulse: failed to add subscriber")
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode >= 300 {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
log.Error().Str("status", fmt.Sprintf("%d", resp.StatusCode)).Str("body", string(body)).Msg("SendPulse: add subscriber failed")
|
||||
return
|
||||
}
|
||||
|
||||
log.Info().Str("email", email).Msg("SendPulse: subscriber added to waitlist")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,11 @@ type AuthHandler struct {
|
|||
repo *repository.UserRepository
|
||||
config *config.Config
|
||||
emailService *services.EmailService
|
||||
sendPulseService *services.SendPulseService
|
||||
}
|
||||
|
||||
func NewAuthHandler(repo *repository.UserRepository, cfg *config.Config, emailService *services.EmailService) *AuthHandler {
|
||||
return &AuthHandler{repo: repo, config: cfg, emailService: emailService}
|
||||
func NewAuthHandler(repo *repository.UserRepository, cfg *config.Config, emailService *services.EmailService, sendPulseService *services.SendPulseService) *AuthHandler {
|
||||
return &AuthHandler{repo: repo, config: cfg, emailService: emailService, sendPulseService: sendPulseService}
|
||||
}
|
||||
|
||||
type RegisterRequest struct {
|
||||
|
|
@ -154,6 +155,12 @@ func (h *AuthHandler) Register(c *gin.Context) {
|
|||
log.Printf("[Auth] Failed to send email to %s: %v", req.Email, err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Add to SendPulse Members list if user opted into newsletter
|
||||
if req.EmailNewsletter && h.sendPulseService != nil {
|
||||
go h.sendPulseService.AddToMembers(req.Email)
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{
|
||||
"message": "Registration successful. Please verify your email to activate your account.",
|
||||
"state": "verification_pending",
|
||||
|
|
|
|||
96
go-backend/internal/services/sendpulse_service.go
Normal file
96
go-backend/internal/services/sendpulse_service.go
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const (
|
||||
SendPulseWaitlistBookID = 568090
|
||||
SendPulseMembersBookID = 568122
|
||||
)
|
||||
|
||||
type SendPulseService struct {
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
}
|
||||
|
||||
func NewSendPulseService(clientID, clientSecret string) *SendPulseService {
|
||||
return &SendPulseService{ClientID: clientID, ClientSecret: clientSecret}
|
||||
}
|
||||
|
||||
func (s *SendPulseService) getToken() (string, error) {
|
||||
tokenBody, _ := json.Marshal(map[string]string{
|
||||
"grant_type": "client_credentials",
|
||||
"client_id": s.ClientID,
|
||||
"client_secret": s.ClientSecret,
|
||||
})
|
||||
resp, err := http.Post("https://api.sendpulse.com/oauth/access_token", "application/json", bytes.NewReader(tokenBody))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var data struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if data.AccessToken == "" {
|
||||
return "", fmt.Errorf("empty access token")
|
||||
}
|
||||
return data.AccessToken, nil
|
||||
}
|
||||
|
||||
func (s *SendPulseService) AddSubscriber(bookID int, email string) {
|
||||
if s.ClientID == "" || s.ClientSecret == "" {
|
||||
return
|
||||
}
|
||||
|
||||
token, err := s.getToken()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("SendPulse: failed to get token")
|
||||
return
|
||||
}
|
||||
|
||||
subBody, _ := json.Marshal(map[string]interface{}{
|
||||
"emails": []map[string]string{
|
||||
{"email": email},
|
||||
},
|
||||
})
|
||||
url := fmt.Sprintf("https://api.sendpulse.com/addressbooks/%d/emails", bookID)
|
||||
req, _ := http.NewRequest("POST", url, bytes.NewReader(subBody))
|
||||
req.Header.Set("Authorization", "Bearer "+token)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Int("book_id", bookID).Msg("SendPulse: failed to add subscriber")
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode >= 300 {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
log.Error().Int("status", resp.StatusCode).Str("body", string(body)).Int("book_id", bookID).Msg("SendPulse: add subscriber failed")
|
||||
return
|
||||
}
|
||||
|
||||
log.Info().Str("email", email).Int("book_id", bookID).Msg("SendPulse: subscriber added")
|
||||
}
|
||||
|
||||
// AddToWaitlist adds an email to the Sojorn Waitlist
|
||||
func (s *SendPulseService) AddToWaitlist(email string) {
|
||||
s.AddSubscriber(SendPulseWaitlistBookID, email)
|
||||
}
|
||||
|
||||
// AddToMembers adds an email to the Sojorn Members list
|
||||
func (s *SendPulseService) AddToMembers(email string) {
|
||||
s.AddSubscriber(SendPulseMembersBookID, email)
|
||||
}
|
||||
Loading…
Reference in a new issue