Go SDK
Go email checker SDK. Install, configure, verify emails with Golang. Code examples included.
El SDK oficial de EmailVerify para Go proporciona interfaces idiomáticas de Go para verificación de correo electrónico con soporte de concurrencia integrado.
Instalación
go get github.com/emailverify/go-sdkInicio rápido
package main
import (
"context"
"fmt"
"os"
emailverify "github.com/emailverify/go-sdk"
)
func main() {
client := emailverify.NewClient(os.Getenv("EMAILVERIFY_API_KEY"))
ctx := context.Background()
result, err := client.Verify(ctx, "user@example.com")
if err != nil {
panic(err)
}
fmt.Printf("Estado: %s\n", result.Status)
fmt.Printf("Puntuación: %.2f\n", result.Score)
}Configuración
Opciones del cliente
client := emailverify.NewClient(
os.Getenv("EMAILVERIFY_API_KEY"),
emailverify.WithTimeout(30*time.Second),
emailverify.WithRetries(3),
emailverify.WithBaseURL("https://api.emailverify.ai"),
)Opciones disponibles
// Establecer tiempo de espera de solicitud
emailverify.WithTimeout(30 * time.Second)
// Establecer número de reintentos
emailverify.WithRetries(3)
// Establecer URL base personalizada
emailverify.WithBaseURL("https://custom-api.example.com")
// Establecer cliente HTTP personalizado
emailverify.WithHTTPClient(&http.Client{
Timeout: 30 * time.Second,
})Tipos
Resultado de verificación
type VerificationResult struct {
Email string `json:"email"`
Status string `json:"status"` // "valid", "invalid", "unknown", "accept_all"
Result ResultDetails `json:"result"`
Score float64 `json:"score"`
Reason *string `json:"reason"`
}
type ResultDetails struct {
Deliverable *bool `json:"deliverable"`
ValidFormat bool `json:"valid_format"`
ValidDomain bool `json:"valid_domain"`
ValidMX bool `json:"valid_mx"`
Disposable bool `json:"disposable"`
Role bool `json:"role"`
Catchall bool `json:"catchall"`
Free bool `json:"free"`
SMTPValid *bool `json:"smtp_valid"`
}Trabajo masivo
type BulkJob struct {
ID string `json:"id"`
Status string `json:"status"` // "pending", "processing", "completed", "failed"
Total int `json:"total"`
Processed int `json:"processed"`
Valid int `json:"valid"`
Invalid int `json:"invalid"`
Unknown int `json:"unknown"`
CreatedAt time.Time `json:"created_at"`
CompletedAt *time.Time `json:"completed_at"`
}Verificación individual
Verificación básica
ctx := context.Background()
result, err := client.Verify(ctx, "user@example.com")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Correo electrónico: %s\n", result.Email)
fmt.Printf("Estado: %s\n", result.Status)
fmt.Printf("Puntuación: %.2f\n", result.Score)
fmt.Printf("Desechable: %v\n", result.Result.Disposable)Con opciones
result, err := client.Verify(ctx, "user@example.com",
emailverify.WithSMTPCheck(true),
emailverify.WithVerifyTimeout(5*time.Second),
)Contexto con tiempo de espera
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
result, err := client.Verify(ctx, "user@example.com")
if err != nil {
if ctx.Err() == context.DeadlineExceeded {
log.Println("Se agotó el tiempo de verificación")
}
log.Fatal(err)
}Verificación masiva
Enviar trabajo
emails := []string{
"user1@example.com",
"user2@example.com",
"user3@example.com",
}
job, err := client.VerifyBulk(ctx, emails)
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID del trabajo: %s\n", job.ID)Verificar estado
status, err := client.GetBulkJobStatus(ctx, job.ID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Estado: %s\n", status.Status)
fmt.Printf("Progreso: %d/%d\n", status.Processed, status.Total)Obtener resultados
results, err := client.GetBulkJobResults(ctx, job.ID)
if err != nil {
log.Fatal(err)
}
for _, result := range results {
fmt.Printf("%s: %s\n", result.Email, result.Status)
}Con webhook
job, err := client.VerifyBulk(ctx, emails,
emailverify.WithWebhookURL("https://tu-dominio.com/webhooks/emailverify"),
)Verificación concurrente
Usando Goroutines
func verifyEmails(ctx context.Context, client *emailverify.Client, emails []string) []VerificationResult {
results := make([]VerificationResult, len(emails))
var wg sync.WaitGroup
for i, email := range emails {
wg.Add(1)
go func(idx int, email string) {
defer wg.Done()
result, err := client.Verify(ctx, email)
if err != nil {
log.Printf("Error al verificar %s: %v", email, err)
return
}
results[idx] = *result
}(i, email)
}
wg.Wait()
return results
}Con pool de trabajadores
func verifyWithWorkerPool(ctx context.Context, client *emailverify.Client, emails []string, workers int) <-chan *emailverify.VerificationResult {
emailChan := make(chan string, len(emails))
resultChan := make(chan *emailverify.VerificationResult, len(emails))
// Iniciar trabajadores
var wg sync.WaitGroup
for i := 0; i < workers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for email := range emailChan {
result, err := client.Verify(ctx, email)
if err != nil {
log.Printf("Error: %v", err)
continue
}
resultChan <- result
}
}()
}
// Enviar correos electrónicos
go func() {
for _, email := range emails {
emailChan <- email
}
close(emailChan)
}()
// Cerrar resultados cuando termine
go func() {
wg.Wait()
close(resultChan)
}()
return resultChan
}
// Uso
results := verifyWithWorkerPool(ctx, client, emails, 10)
for result := range results {
fmt.Printf("%s: %s\n", result.Email, result.Status)
}Usando errgroup
import "golang.org/x/sync/errgroup"
func verifyEmailsConcurrently(ctx context.Context, client *emailverify.Client, emails []string) ([]*emailverify.VerificationResult, error) {
g, ctx := errgroup.WithContext(ctx)
results := make([]*emailverify.VerificationResult, len(emails))
for i, email := range emails {
i, email := i, email // capturar variables de bucle
g.Go(func() error {
result, err := client.Verify(ctx, email)
if err != nil {
return fmt.Errorf("verificar %s: %w", email, err)
}
results[i] = result
return nil
})
}
if err := g.Wait(); err != nil {
return nil, err
}
return results, nil
}Manejo de errores
Tipos de errores
import "github.com/emailverify/go-sdk/errors"
result, err := client.Verify(ctx, email)
if err != nil {
switch e := err.(type) {
case *errors.AuthenticationError:
log.Fatal("Clave API inválida")
case *errors.RateLimitError:
log.Printf("Límite de tasa alcanzado. Reintentar después de %v", e.RetryAfter)
case *errors.ValidationError:
log.Printf("Entrada inválida: %s", e.Message)
case *errors.APIError:
log.Printf("Error de API: %s (código: %s)", e.Message, e.Code)
default:
log.Printf("Error desconocido: %v", err)
}
}Manejador de errores personalizado
func verifyWithRetry(ctx context.Context, client *emailverify.Client, email string) (*emailverify.VerificationResult, error) {
var lastErr error
for attempt := 0; attempt < 3; attempt++ {
result, err := client.Verify(ctx, email)
if err == nil {
return result, nil
}
lastErr = err
// Verificar si debemos reintentar
if rateLimitErr, ok := err.(*errors.RateLimitError); ok {
time.Sleep(rateLimitErr.RetryAfter)
continue
}
// No reintentar errores de validación
if _, ok := err.(*errors.ValidationError); ok {
return nil, err
}
// Retroceso exponencial para otros errores
time.Sleep(time.Duration(attempt+1) * time.Second)
}
return nil, lastErr
}Gestión de créditos
credits, err := client.GetCredits(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Disponibles: %d\n", credits.Available)
fmt.Printf("Usados: %d\n", credits.Used)
fmt.Printf("Total: %d\n", credits.Total)Integración con frameworks
Gin
import "github.com/gin-gonic/gin"
func setupRouter(client *emailverify.Client) *gin.Engine {
r := gin.Default()
r.POST("/verify", func(c *gin.Context) {
var req struct {
Email string `json:"email" binding:"required,email"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
result, err := client.Verify(c.Request.Context(), req.Email)
if err != nil {
c.JSON(500, gin.H{"error": "Verificación fallida"})
return
}
c.JSON(200, result)
})
return r
}Echo
import "github.com/labstack/echo/v4"
func setupRoutes(e *echo.Echo, client *emailverify.Client) {
e.POST("/verify", func(c echo.Context) error {
var req struct {
Email string `json:"email"`
}
if err := c.Bind(&req); err != nil {
return c.JSON(400, map[string]string{"error": "Solicitud inválida"})
}
result, err := client.Verify(c.Request().Context(), req.Email)
if err != nil {
return c.JSON(500, map[string]string{"error": "Verificación fallida"})
}
return c.JSON(200, result)
})
}Fiber
import "github.com/gofiber/fiber/v2"
func setupFiber(client *emailverify.Client) *fiber.App {
app := fiber.New()
app.Post("/verify", func(c *fiber.Ctx) error {
var req struct {
Email string `json:"email"`
}
if err := c.BodyParser(&req); err != nil {
return c.Status(400).JSON(fiber.Map{"error": "Solicitud inválida"})
}
result, err := client.Verify(context.Background(), req.Email)
if err != nil {
return c.Status(500).JSON(fiber.Map{"error": "Verificación fallida"})
}
return c.JSON(result)
})
return app
}Ejemplo completo
Servicio de validación de correo electrónico
package main
import (
"context"
"log"
"os"
emailverify "github.com/emailverify/go-sdk"
)
type ValidationResult struct {
Valid bool `json:"valid"`
Reason string `json:"reason,omitempty"`
Message string `json:"message,omitempty"`
Score float64 `json:"score,omitempty"`
}
type EmailValidator struct {
client *emailverify.Client
}
func NewEmailValidator() *EmailValidator {
return &EmailValidator{
client: emailverify.NewClient(os.Getenv("EMAILVERIFY_API_KEY")),
}
}
func (v *EmailValidator) ValidateForRegistration(ctx context.Context, email string) ValidationResult {
result, err := v.client.Verify(ctx, email)
if err != nil {
return ValidationResult{
Valid: false,
Reason: "verification_error",
Message: "No se pudo verificar la dirección de correo electrónico",
}
}
// Rechazar correos electrónicos inválidos
if result.Status == "invalid" {
return ValidationResult{
Valid: false,
Reason: "invalid_email",
Message: "Esta dirección de correo electrónico es inválida",
}
}
// Rechazar correos electrónicos desechables
if result.Result.Disposable {
return ValidationResult{
Valid: false,
Reason: "disposable",
Message: "Por favor usa una dirección de correo electrónico permanente",
}
}
// Advertir sobre correos electrónicos basados en roles pero permitir
if result.Result.Role {
return ValidationResult{
Valid: true,
Reason: "role_based",
Message: "Se recomienda usar un correo electrónico personal",
Score: result.Score,
}
}
return ValidationResult{
Valid: true,
Score: result.Score,
}
}
func main() {
validator := NewEmailValidator()
ctx := context.Background()
result := validator.ValidateForRegistration(ctx, "user@example.com")
if !result.Valid {
log.Printf("Inválido: %s - %s", result.Reason, result.Message)
return
}
log.Printf("Correo electrónico válido con puntuación: %.2f", result.Score)
}Mejores prácticas
1. Usar siempre contexto
// Establecer tiempo de espera para todas las operaciones
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
result, err := client.Verify(ctx, email)2. Manejar punteros nulos
if result.Result.Deliverable != nil {
fmt.Printf("Entregable: %v\n", *result.Result.Deliverable)
}3. Usar pooling de conexiones
// Reutilizar el cliente en todas las solicitudes
var client *emailverify.Client
func init() {
client = emailverify.NewClient(os.Getenv("EMAILVERIFY_API_KEY"))
}