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("Status: %s\n", result.Status)
fmt.Printf("Score: %.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)
// 设置自定义 API 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("Status: %s\n", result.Status)
fmt.Printf("Score: %.2f\n", result.Score)
fmt.Printf("Disposable: %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("Job ID: %s\n", job.ID)检查状态
status, err := client.GetBulkJobStatus(ctx, job.ID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Status: %s\n", status.Status)
fmt.Printf("Progress: %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"),
)并发验证
使用 Goroutine
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
}
}()
}
// 发送邮箱
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
}完整示例
邮箱验证服务
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"))
}