EmailVerify LogoEmailVerify

Go SDK

Go email checker SDK. Install, configure, verify emails with Golang. Code examples included.

Официальный EmailVerify SDK для Go предоставляет идиоматические Go-интерфейсы для проверки email со встроенной поддержкой конкурентности.

Установка

go get github.com/emailverify/go-sdk

Быстрый старт

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("Статус: %s\n", result.Status)
    fmt.Printf("Оценка: %.2f\n", result.Score)
}

Конфигурация

Параметры клиента

client := emailverify.NewClient(
    os.Getenv("EMAILVERIFY_API_KEY"),
    emailverify.WithTimeout(30*time.Second),
    emailverify.WithRetries(3),
    emailverify.WithBaseURL("https://api.emailverify.ai"),
)

Доступные параметры

// Установка таймаута запроса
emailverify.WithTimeout(30 * time.Second)

// Установка количества повторных попыток
emailverify.WithRetries(3)

// Установка пользовательского базового URL
emailverify.WithBaseURL("https://custom-api.example.com")

// Установка пользовательского HTTP-клиента
emailverify.WithHTTPClient(&http.Client{
    Timeout: 30 * time.Second,
})

Типы

Результат проверки

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"`
}

Массовая задача

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"`
}

Единичная проверка

Базовая проверка

ctx := context.Background()
result, err := client.Verify(ctx, "user@example.com")
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Email: %s\n", result.Email)
fmt.Printf("Статус: %s\n", result.Status)
fmt.Printf("Оценка: %.2f\n", result.Score)
fmt.Printf("Одноразовый: %v\n", result.Result.Disposable)

С параметрами

result, err := client.Verify(ctx, "user@example.com",
    emailverify.WithSMTPCheck(true),
    emailverify.WithVerifyTimeout(5*time.Second),
)

Контекст с таймаутом

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("Превышено время ожидания проверки")
    }
    log.Fatal(err)
}

Массовая проверка

Отправка задачи

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 задачи: %s\n", job.ID)

Проверка статуса

status, err := client.GetBulkJobStatus(ctx, job.ID)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Статус: %s\n", status.Status)
fmt.Printf("Прогресс: %d/%d\n", status.Processed, status.Total)

Получение результатов

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)
}

С вебхуком

job, err := client.VerifyBulk(ctx, emails,
    emailverify.WithWebhookURL("https://your-domain.com/webhooks/emailverify"),
)

Конкурентная проверка

Использование горутин

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("Ошибка проверки %s: %v", email, err)
                return
            }
            results[idx] = *result
        }(i, email)
    }

    wg.Wait()
    return results
}

С пулом воркеров

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))

    // Запуск воркеров
    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("Ошибка: %v", err)
                    continue
                }
                resultChan <- result
            }
        }()
    }

    // Отправка email
    go func() {
        for _, email := range emails {
            emailChan <- email
        }
        close(emailChan)
    }()

    // Закрытие результатов после завершения
    go func() {
        wg.Wait()
        close(resultChan)
    }()

    return resultChan
}

// Использование
results := verifyWithWorkerPool(ctx, client, emails, 10)
for result := range results {
    fmt.Printf("%s: %s\n", result.Email, result.Status)
}

Использование 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 // захват переменных цикла
        g.Go(func() error {
            result, err := client.Verify(ctx, email)
            if err != nil {
                return fmt.Errorf("проверка %s: %w", email, err)
            }
            results[i] = result
            return nil
        })
    }

    if err := g.Wait(); err != nil {
        return nil, err
    }

    return results, nil
}

Обработка ошибок

Типы ошибок

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("Неверный API-ключ")
    case *errors.RateLimitError:
        log.Printf("Превышен лимит запросов. Повторите через %v", e.RetryAfter)
    case *errors.ValidationError:
        log.Printf("Неверные входные данные: %s", e.Message)
    case *errors.APIError:
        log.Printf("Ошибка API: %s (код: %s)", e.Message, e.Code)
    default:
        log.Printf("Неизвестная ошибка: %v", err)
    }
}

Пользовательский обработчик ошибок

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

        // Проверка, нужно ли повторить
        if rateLimitErr, ok := err.(*errors.RateLimitError); ok {
            time.Sleep(rateLimitErr.RetryAfter)
            continue
        }

        // Не повторять ошибки валидации
        if _, ok := err.(*errors.ValidationError); ok {
            return nil, err
        }

        // Экспоненциальная задержка для других ошибок
        time.Sleep(time.Duration(attempt+1) * time.Second)
    }

    return nil, lastErr
}

Управление кредитами

credits, err := client.GetCredits(ctx)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("Доступно: %d\n", credits.Available)
fmt.Printf("Использовано: %d\n", credits.Used)
fmt.Printf("Всего: %d\n", credits.Total)

Интеграция с фреймворками

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": "Ошибка проверки"})
            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": "Неверный запрос"})
        }

        result, err := client.Verify(c.Request().Context(), req.Email)
        if err != nil {
            return c.JSON(500, map[string]string{"error": "Ошибка проверки"})
        }

        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": "Неверный запрос"})
        }

        result, err := client.Verify(context.Background(), req.Email)
        if err != nil {
            return c.Status(500).JSON(fiber.Map{"error": "Ошибка проверки"})
        }

        return c.JSON(result)
    })

    return app
}

Полный пример

Сервис валидации email

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: "Не удалось проверить email-адрес",
        }
    }

    // Отклонить недействительные email
    if result.Status == "invalid" {
        return ValidationResult{
            Valid:   false,
            Reason:  "invalid_email",
            Message: "Этот email-адрес недействителен",
        }
    }

    // Отклонить одноразовые email
    if result.Result.Disposable {
        return ValidationResult{
            Valid:   false,
            Reason:  "disposable",
            Message: "Пожалуйста, используйте постоянный email-адрес",
        }
    }

    // Предупреждение о ролевых email, но разрешить
    if result.Result.Role {
        return ValidationResult{
            Valid:   true,
            Reason:  "role_based",
            Message: "Рекомендуется использовать личный email",
            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("Недействительный: %s - %s", result.Reason, result.Message)
        return
    }

    log.Printf("Действительный email с оценкой: %.2f", result.Score)
}

Лучшие практики

1. Всегда используйте контекст

// Установка таймаута для всех операций
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

result, err := client.Verify(ctx, email)

2. Обрабатывайте nil-указатели

if result.Result.Deliverable != nil {
    fmt.Printf("Доставляемый: %v\n", *result.Result.Deliverable)
}

3. Используйте пул соединений

// Переиспользуйте клиент между запросами
var client *emailverify.Client

func init() {
    client = emailverify.NewClient(os.Getenv("EMAILVERIFY_API_KEY"))
}

Следующие шаги

On this page