Go SDK
Go 1.19+
Go Modules
Send emails with Go using the official Laneful Go SDK. Built for modern Go applications with comprehensive features and type safety.
Full Feature Support
Templates, attachments, tracking, webhooks
Type Safe
Built-in validation & error handling
Modern Go
Go 1.19+ with context support
On this page
Prerequisites
To get the most out of this guide, you'll need:
- • Go 1.19 or higher
- • Go modules enabled
- • A Laneful account with API key
- • Verified domain for sending emails
Installation
Go Modules
Add the following dependency to your go.mod
:
go get github.com/lanefulhq/laneful-go
Quick Start
Send your first email in minutes:
Send Simple Text Email
package main import ( "context" "log" "github.com/lanefulhq/laneful-go" ) func main() { // Create client client := laneful.NewLanefulClient( "https://your-endpoint.send.laneful.net", "your-auth-token", ) // Create email email := laneful.Email{ From: laneful.Address{ Email: "sender@example.com", Name: "Your Name", }, To: []laneful.Address{ {Email: "recipient@example.com", Name: "Recipient Name"}, }, Subject: "Hello from Laneful!", TextContent: "This is a simple test email sent using the Laneful Go SDK.", } // Send email resp, err := client.SendEmail(context.Background(), email) if err != nil { log.Fatal("Failed to send email:", err) } log.Printf("✓ Email sent successfully! Status: %s", resp.Status) }
Examples
Common use cases and patterns:
HTML Email with Tracking
// Create tracking settings tracking := &laneful.TrackingSettings{ Opens: true, Clicks: true, } email := laneful.Email{ From: laneful.Address{ Email: "sender@example.com", Name: "Your Name", }, To: []laneful.Address{ {Email: "recipient@example.com", Name: "Recipient Name"}, }, Subject: "HTML Email with Tracking", HTMLContent: "<h1>Welcome!</h1><p>This is an <strong>HTML email</strong> with tracking enabled.</p>", TextContent: "Welcome! This is an HTML email with tracking enabled.", Tracking: tracking, Tag: "welcome-email", } resp, err := client.SendEmail(context.Background(), email)
Template Email
email := laneful.Email{ From: laneful.Address{Email: "sender@example.com"}, To: []laneful.Address{{Email: "user@example.com"}}, TemplateID: "welcome-template", TemplateData: map[string]interface{}{ "name": "John Doe", "company": "Acme Corporation", "activation_link": "https://example.com/activate", }, } resp, err := client.SendEmail(context.Background(), email)
Email with Attachments
import ( "encoding/base64" "io/ioutil" ) // Read file and encode as base64 fileData, err := ioutil.ReadFile("/path/to/document.pdf") if err != nil { log.Fatal(err) } email := laneful.Email{ From: laneful.Address{Email: "sender@example.com"}, To: []laneful.Address{{Email: "user@example.com"}}, Subject: "Document Attached", TextContent: "Please find the document attached.", Attachments: []laneful.Attachment{ { FileName: "document.pdf", Content: base64.StdEncoding.EncodeToString(fileData), ContentType: "application/pdf", }, }, } resp, err := client.SendEmail(context.Background(), email)
Multiple Recipients with Reply-To
email := laneful.Email{ From: laneful.Address{ Email: "sender@example.com", Name: "Your Name", }, To: []laneful.Address{ {Email: "user1@example.com", Name: "User One"}, {Email: "user2@example.com", Name: "User Two"}, }, CC: []laneful.Address{ {Email: "cc@example.com", Name: "CC Recipient"}, }, BCC: []laneful.Address{ {Email: "bcc@example.com", Name: "BCC Recipient"}, }, ReplyTo: &laneful.Address{ Email: "reply@example.com", Name: "Reply To", }, Subject: "Email to Multiple Recipients", TextContent: "This email is being sent to multiple recipients.", } resp, err := client.SendEmail(context.Background(), email)
Scheduled Email
import "time" // Schedule for 24 hours from now sendTime := time.Now().Add(24 * time.Hour).Unix() email := laneful.Email{ From: laneful.Address{Email: "sender@example.com"}, To: []laneful.Address{{Email: "user@example.com"}}, Subject: "Scheduled Email", TextContent: "This email was scheduled.", SendTime: sendTime, } resp, err := client.SendEmail(context.Background(), email)
Batch Email Sending
emails := []laneful.Email{ { From: laneful.Address{Email: "sender@example.com"}, To: []laneful.Address{{Email: "user1@example.com"}}, Subject: "Email 1", TextContent: "First email content.", }, { From: laneful.Address{Email: "sender@example.com"}, To: []laneful.Address{{Email: "user2@example.com"}}, Subject: "Email 2", TextContent: "Second email content.", }, } resp, err := client.SendEmails(context.Background(), emails)
Webhook Handler Example
import ( "encoding/json" "net/http" "github.com/lanefulhq/laneful-go" ) // Complete webhook handler implementation func handleWebhook(w http.ResponseWriter, r *http.Request) { // Read the request body body, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, "Failed to read body", http.StatusBadRequest) return } // Extract signature from headers signature := r.Header.Get("x-webhook-signature") if signature == "" { http.Error(w, "Missing signature", http.StatusUnauthorized) return } // Verify signature if !laneful.VerifyWebhookSignature(webhookSecret, string(body), signature) { http.Error(w, "Invalid signature", http.StatusUnauthorized) return } // Parse webhook data var webhookData struct { Events []map[string]interface{} `json:"events"` } if err := json.Unmarshal(body, &webhookData); err != nil { http.Error(w, "Invalid JSON", http.StatusBadRequest) return } // Process events for _, event := range webhookData.Events { eventType, _ := event["event"].(string) email, _ := event["email"].(string) switch eventType { case "delivery": log.Printf("Email delivered to: %s", email) case "open": log.Printf("Email opened by: %s", email) case "click": if url, ok := event["url"].(string); ok { log.Printf("Link clicked by %s: %s", email, url) } case "bounce": if isHard, ok := event["is_hard"].(bool); ok { log.Printf("Email bounced (%s) for: %s", map[bool]string{true: "hard", false: "soft"}[isHard], email) } } } w.WriteHeader(http.StatusOK) w.Write([]byte("Webhook processed successfully")) }
API Reference
LanefulClient
Constructors
- •
NewLanefulClient(baseURL, authToken string) *LanefulClient
- Creates a new client with default timeout (30 seconds)
Methods
- •
SendEmail(ctx context.Context, email Email) (*ApiResponse, error)
- Send single email - •
SendEmails(ctx context.Context, emails []Email) (*ApiResponse, error)
- Send multiple emails
Email Struct
Required Fields
- •
From Address
- Sender address
Optional Fields
- •
To []Address
- Recipient addresses - •
CC []Address
- CC recipient addresses - •
BCC []Address
- BCC recipient addresses - •
ReplyTo *Address
- Reply-to address - •
Subject string
- Email subject - •
TextContent string
- Plain text content - •
HTMLContent string
- HTML content - •
TemplateID string
- Template ID - •
TemplateData map[string]interface
- Template data - •
Attachments []Attachment
- File attachments - •
SendTime int64
- Scheduled send time (Unix timestamp) - •
Tracking *TrackingSettings
- Email tracking configuration - •
Tag string
- Email tag for categorization - •
Headers map[string]string
- Custom headers - •
WebhookData map[string]string
- Webhook metadata
Utility Structs
- •
Address{Email, Name string}
- Email address with optional name - •
Attachment{FileName, Content, ContentType, InlineID string}
- File attachment - •
TrackingSettings{Opens, Clicks, Unsubscribes bool, UnsubscribeGroupID *int64}
- Email tracking configuration - •
ApiResponse{Status string}
- API response structure
Webhook Functions
Signature Verification
- •
VerifyWebhookSignature(secret, payload, signature string) bool
- Verifies webhook signature using HMAC-SHA256
Error Handling
Comprehensive error handling with Go's standard error interface:
import ( "context" "fmt" "log" "github.com/lanefulhq/laneful-go" ) func sendEmailWithErrorHandling(client *laneful.LanefulClient, email laneful.Email) { resp, err := client.SendEmail(context.Background(), email) if err != nil { // Handle different types of errors switch { case strings.Contains(err.Error(), "validation"): log.Printf("✗ Validation error: %v", err) log.Println("Please check your email configuration") case strings.Contains(err.Error(), "API error"): log.Printf("✗ API error: %v", err) log.Println("Please check your API credentials and endpoint") case strings.Contains(err.Error(), "failed to send request"): log.Printf("✗ Network error: %v", err) log.Println("Please check your network connection and endpoint URL") default: log.Printf("✗ Unexpected error: %v", err) } return } log.Printf("✓ Email sent successfully! Status: %s", resp.Status) }
Error Types
- •
Validation errors
- Invalid input data - •
API errors
- API returns error response
Check error message for details - •
Network errors
- HTTP communication fails
Check connection and endpoint URL - •
JSON errors
- Response parsing fails
Best Practices
- • Always check errors from API calls
- • Use context for request cancellation
- • Log errors with context information
- • Implement retry logic for transient failures
- • Use structured logging for better debugging
Webhook Handling
Secure webhook handling with signature verification:
Basic Signature Verification
import ( "net/http" "github.com/lanefulhq/laneful-go" ) func webhookHandler(w http.ResponseWriter, r *http.Request) { // Read the request body body, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, "Failed to read body", http.StatusBadRequest) return } // Get signature from headers signature := r.Header.Get("x-webhook-signature") secret := "your-webhook-secret" // Verify signature if laneful.VerifyWebhookSignature(secret, string(body), signature) { // Process webhook data processWebhookData(body) w.WriteHeader(http.StatusOK) } else { http.Error(w, "Invalid signature", http.StatusUnauthorized) } }
Advanced Webhook Processing
import ( "encoding/json" "net/http" "github.com/lanefulhq/laneful-go" ) type WebhookEvent struct { Event string `json:"event"` Email string `json:"email"` Data map[string]interface{} `json:"data"` } type WebhookPayload struct { Events []WebhookEvent `json:"events"` } func advancedWebhookHandler(w http.ResponseWriter, r *http.Request) { // Step 1: Read raw payload body, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, "Failed to read body", http.StatusBadRequest) return } // Step 2: Extract signature signature := r.Header.Get("x-webhook-signature") if signature == "" { http.Error(w, "Missing signature", http.StatusUnauthorized) return } // Step 3: Verify signature if !laneful.VerifyWebhookSignature(webhookSecret, string(body), signature) { http.Error(w, "Invalid signature", http.StatusUnauthorized) return } // Step 4: Parse payload var payload WebhookPayload if err := json.Unmarshal(body, &payload); err != nil { http.Error(w, "Invalid JSON", http.StatusBadRequest) return } // Step 5: Process events for _, event := range payload.Events { switch event.Event { case "delivery": handleDeliveryEvent(event) case "open": handleOpenEvent(event) case "click": handleClickEvent(event) case "bounce": handleBounceEvent(event) case "drop": handleDropEvent(event) case "spam_complaint": handleSpamComplaintEvent(event) case "unsubscribe": handleUnsubscribeEvent(event) } } w.WriteHeader(http.StatusOK) w.Write([]byte("Webhook processed successfully")) }
Supported Webhook Events
Delivery Events
- •
delivery
- Email delivered successfully - •
bounce
- Email bounced (hard or soft) - •
drop
- Email dropped (spam, invalid, etc.) - •
spam_complaint
- Recipient marked email as spam
Engagement Events
- •
open
- Email opened by recipient - •
click
- Link clicked in email - •
unsubscribe
- Recipient unsubscribed
Webhook Features
Security
- • HMAC-SHA256 signature verification
- • Constant-time comparison (timing attack protection)
- • Standard HTTP header support
Integration
- • Works with any HTTP framework
- • Context-aware request handling
- • Easy error handling with Go idioms
Ready to Get Started?
Start sending emails with Go in minutes. Check out the examples and integrate with your application.