Envoyer un email transactionnel en Go avec un client minimal

Le SDK Go Spore reste volontairement petit : bibliothèque standard, contexte, timeout et erreurs HTTP explicites. Vous gardez les conventions de votre service sans embarquer une pile SMTP dans le binaire.

Le résultat attendu

Une fonction qui respecte l’annulation du contexte, borne le temps réseau et peut être rejouée sans envoyer deux fois le même email.

1. Installer le module

go get github.com/lalternative/packages/spore/sdk-go@latest
export SPORE_API_KEY="spore_api_key_here"

Si le dépôt de packages est privé dans votre environnement, configurez aussi GOPRIVATE=github.com/lalternative/* et votre accès GitHub.

2. Construire le client

package mailer
 
import (
    "net/http"
    "os"
    "time"
 
    spore "github.com/lalternative/packages/spore/sdk-go"
)
 
var client = spore.NewClient(
    os.Getenv("SPORE_API_KEY"),
    spore.WithHTTPClient(&http.Client{Timeout: 10 * time.Second}),
)

Dans une application réelle, validez la présence de SPORE_API_KEY au démarrage et injectez le client dans votre service.

3. Envoyer avec le contexte appelant

type User struct {
    ID    string
    Email string
}
 
func SendWelcomeEmail(ctx context.Context, user User) (string, error) {
    result, err := client.SendEmail(ctx, spore.SendEmailRequest{
        From:    "hello@votredomaine.fr",
        To:      []string{user.Email},
        Subject: "Bienvenue",
        HTML:    "<p>Votre compte est prêt.</p>",
    }, spore.WithIdempotencyKey("welcome:"+user.ID))
    if err != nil {
        return "", err
    }
 
    return result.MessageID, nil
}

Le contexte de votre handler, worker ou commande arrête proprement l’appel si le travail est annulé. La clé stable protège la reprise après un timeout.

4. Classer les erreurs API

if apiErr, ok := spore.IsAPIError(err); ok {
    log.Printf("spore status=%d body=%s", apiErr.StatusCode, apiErr.Body)
}

Ne retentez pas aveuglément les 4xx : ils indiquent généralement une clé invalide, un domaine non vérifié ou un corps incorrect. Les pannes réseau et certains 5xx peuvent être retentés avec la même clé d’idempotence.

5. Observer la livraison

Le retour contient MessageID, RFC5322ID et le statut initial queued. Le 202 ne bloque pas votre goroutine jusqu’au serveur du destinataire. Pour la suite, stockez MessageID et consommez les webhooks de livraison.

Continuez avec la référence de sendEmail ou la référence API complète.