package service import ( "fmt" "os" "strings" "github.com/resend/resend-go/v2" ) type EmailService struct { client *resend.Client fromEmail string } func NewEmailService() *EmailService { apiKey := os.Getenv("RESEND_API_KEY") from := os.Getenv("RESEND_FROM_EMAIL") if from == "" { from = "noreply@multica.ai" } var client *resend.Client if apiKey != "" { client = resend.NewClient(apiKey) } return &EmailService{ client: client, fromEmail: from, } } func (s *EmailService) SendVerificationCode(to, code string) error { if s.client == nil { fmt.Printf("[DEV] Verification code for %s: %s\n", to, code) return nil } params := &resend.SendEmailRequest{ From: s.fromEmail, To: []string{to}, Subject: "Your Multica verification code", Html: fmt.Sprintf( `

Your verification code

%s

This code expires in 10 minutes.

If you didn't request this code, you can safely ignore this email.

`, code), } _, err := s.client.Emails.Send(params) return err } // SendInvitationEmail notifies the invitee that they have been invited to a workspace. // invitationID is included in the URL so the email deep-links to /invite/{id}. func (s *EmailService) SendInvitationEmail(to, inviterName, workspaceName, invitationID string) error { appURL := strings.TrimSpace(os.Getenv("FRONTEND_ORIGIN")) if appURL == "" { appURL = "https://app.multica.ai" } inviteURL := fmt.Sprintf("%s/invite/%s", appURL, invitationID) if s.client == nil { fmt.Printf("[DEV] Invitation email to %s: %s invited you to %s — %s\n", to, inviterName, workspaceName, inviteURL) return nil } params := &resend.SendEmailRequest{ From: s.fromEmail, To: []string{to}, Subject: fmt.Sprintf("%s invited you to %s on Multica", inviterName, workspaceName), Html: fmt.Sprintf( `

You're invited to join %s

%s invited you to collaborate in the %s workspace on Multica.

Accept invitation

You'll need to log in to accept or decline the invitation.

`, workspaceName, inviterName, workspaceName, inviteURL), } _, err := s.client.Emails.Send(params) return err }