EmailVerify LogoEmailVerify

Go SDK

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

官方 EmailVerify Go SDK 提供符合 Go 語言慣例的介面,內建並發支援。

安裝

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("郵箱: %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),
)

帶逾時的 Context

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

使用 Webhook

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

並發驗證

使用 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("驗證 %s 錯誤: %v", email, err)
                return
            }
            results[idx] = *result
        }(i, email)
    }

    wg.Wait()
    return results
}

使用 Worker Pool

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

    // 啟動 workers
    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
            }
        }()
    }

    // 發送郵箱
    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 Key")
    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
}

完整範例

郵箱驗證服務

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: "無法驗證郵箱地址",
        }
    }

    // 拒絕無效郵箱
    if result.Status == "invalid" {
        return ValidationResult{
            Valid:   false,
            Reason:  "invalid_email",
            Message: "此郵箱地址無效",
        }
    }

    // 拒絕一次性郵箱
    if result.Result.Disposable {
        return ValidationResult{
            Valid:   false,
            Reason:  "disposable",
            Message: "請使用永久郵箱地址",
        }
    }

    // 警告角色郵箱但允許
    if result.Result.Role {
        return ValidationResult{
            Valid:   true,
            Reason:  "role_based",
            Message: "建議使用個人郵箱",
            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("有效郵箱,分數: %.2f", result.Score)
}

最佳實踐

1. 總是使用 Context

// 為所有操作設定逾時
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