Go
Official Unsent Go SDK for sending emails and managing contacts.
This guide shows how to install and use the official unsent Go SDK.
Installation
Install the SDK using go get to add it to your project's dependencies:
go get github.com/souravsspace/unsent-goInitialize
To start using the SDK, you need to create a client instance. You'll need your API key, which you can find in your Unsent dashboard.
Import the package and create a new client using unsent.NewClient. You can pass the API key directly, or if you have the UNSENT_API_KEY environment variable set, you can pass an empty string.
package main
import (
"log"
"github.com/souravsspace/unsent-go"
)
func main() {
// Initialize with API key
client, err := unsent.NewClient("un_xxx")
// Or use environment variable UNSENT_API_KEY
// client, err := unsent.NewClient("")
if err != nil {
log.Fatal(err)
}
}Send an email
Now you're ready to send your first email. You can do this by creating an unsent.EmailCreate struct and passing it to the client.Emails.Send method.
Here is a simple example of sending an HTML email:
package main
import (
"fmt"
"log"
"github.com/souravsspace/unsent-go"
)
func main() {
// Initialize the client
client, err := unsent.NewClient("un_xxx")
if err != nil {
log.Fatal(err)
}
// Send the email
email, err := client.Emails.Send(unsent.EmailCreate{
To: "user@example.com",
From: "no-reply@yourdomain.com",
Subject: "Welcome",
HTML: "<strong>Hello!</strong>",
})
if err != nil {
log.Printf("Error: %v", err)
} else {
fmt.Printf("Email sent! ID: %s\n", email.ID)
}
}With attachments and scheduling
You can also send emails with attachments and schedule them for a later time.
- Attachments: Create a slice of
unsent.Attachmentstructs. The content must be a Base64 encoded string. - Scheduling: Set the
ScheduledAtfield with a pointer to atime.Timeobject.
import "time"
// Schedule for 10 minutes from now
scheduledTime := time.Now().Add(10 * time.Minute)
email, err := client.Emails.Create(unsent.EmailCreate{
To: "user@example.com",
From: "no-reply@yourdomain.com",
Subject: "Report",
Text: "See attached.",
Attachments: []unsent.Attachment{
{
Filename: "report.txt",
Content: "SGVsbG8gd29ybGQ=", // Content must be Base64 encoded
},
},
ScheduledAt: &scheduledTime,
})Batch send
If you need to send multiple emails at once, use the client.Emails.Batch method. This accepts a slice of unsent.EmailBatchItem.
emails := []unsent.EmailBatchItem{
{
To: "a@example.com",
From: "no-reply@yourdomain.com",
Subject: "A",
HTML: "<p>A</p>",
},
{
To: "b@example.com",
From: "no-reply@yourdomain.com",
Subject: "B",
HTML: "<p>B</p>",
},
}
response, err := client.Emails.Batch(emails)
if err != nil {
log.Printf("Error: %v", err)
} else {
fmt.Printf("Sent %d emails\n", len(response.Emails))
}Idempotent Retries
To safely retry requests, you can use unsent.WithIdempotencyKey.
// For single email
client.Emails.Send(email, unsent.WithIdempotencyKey("unique-key-123"))
// For batch emails
client.Emails.Batch(emails, unsent.WithIdempotencyKey("batch-unique-key-123"))Retrieve and manage emails
You can retrieve the status of sent emails, update their scheduled time, or cancel them if they haven't been sent yet.
Get an email
To check the status of a specific email, use client.Emails.Get with the email ID:
email, err := client.Emails.Get("email_123")
if err != nil {
log.Printf("Error: %v", err)
} else {
fmt.Printf("Email status: %s\n", email.Status)
}Update schedule time
If you need to change when a scheduled email will be sent, you can update its ScheduledAt property using client.Emails.Update:
import "time"
newTime := time.Now().Add(1 * time.Hour)
response, err := client.Emails.Update("email_123", unsent.EmailUpdate{
ScheduledAt: &newTime,
})Cancel a scheduled email
To stop a scheduled email from being sent, use the client.Emails.Cancel method:
response, err := client.Emails.Cancel("email_123")
if err != nil {
log.Printf("Error: %v", err)
} else {
fmt.Println("Email cancelled successfully")
}Contacts
Manage your audience by creating and updating contacts. Contacts can be organized into "contact books" (identified by book_id).
Create a contact
Add a new contact to a specific contact book. You can include metadata like their subscription plan.
contact, err := client.Contacts.Create("book_123", unsent.ContactCreate{
Email: "user@example.com",
FirstName: "Jane",
Metadata: map[string]interface{}{
"plan": "pro",
},
})Get a contact
Retrieve details about a specific contact using their ID and the book ID:
contact, err := client.Contacts.Get("book_123", "contact_456")Update a contact
Update a contact's information, such as their name or metadata:
response, err := client.Contacts.Update("book_123", "contact_456", unsent.ContactUpdate{
FirstName: "John",
Metadata: map[string]interface{}{
"plan": "enterprise",
},
})Upsert a contact
Use Upsert to create a contact if they don't exist, or update them if they do. This is useful for syncing data.
contact, err := client.Contacts.Upsert("book_123", "contact_456", unsent.ContactUpsert{
Email: "user@example.com",
FirstName: "Jane",
Metadata: map[string]interface{}{
"plan": "pro",
},
})Delete a contact
Remove a contact from a book:
response, err := client.Contacts.Delete("book_123", "contact_456")Campaigns
Campaigns allow you to send emails to an entire contact book.
Create a campaign
Create a new campaign by specifying the content and the target contact book ID.
campaign, err := client.Campaigns.Create(unsent.CampaignCreate{
Name: "Welcome Series",
Subject: "Welcome!",
HTML: "<p>Thanks for joining us!</p>",
From: "welcome@yourdomain.com",
ContactBookID: "book_123",
})Schedule a campaign
Once created, you can schedule the campaign to be sent at a specific time.
response, err := client.Campaigns.Schedule(campaign.ID, unsent.CampaignSchedule{
ScheduledAt: "2024-12-01T10:00:00Z",
})Pause and resume campaigns
You can pause a running or scheduled campaign and resume it later.
// Pause
pauseResp, err := client.Campaigns.Pause("campaign_123")
// Resume
resumeResp, err := client.Campaigns.Resume("campaign_123")Domains
Manage the domains you use to send emails.
List domains
Retrieve a list of all your domains and their verification status.
domains, err := client.Domains.List()
if err != nil {
log.Printf("Error: %v", err)
} else {
for _, domain := range domains {
fmt.Printf("Domain: %s, Status: %s\n", domain.Domain, domain.Status)
}
}Create a domain
Add a new domain to your account.
domain, err := client.Domains.Create(unsent.DomainCreate{
Domain: "yourdomain.com",
})Verify a domain
Check the verification status of a domain.
response, err := client.Domains.Verify(123)Error handling
The SDK supports different ways of handling errors.
Standard Error Handling (Default)
By default, the SDK methods return an error if the API request fails or returns a non-2xx status code. You can check for specific API errors by casting the error to *unsent.APIError.
import "github.com/souravsspace/unsent-go"
client, err := unsent.NewClient("un_xxx")
if err != nil {
log.Fatal(err)
}
email, err := client.Emails.Get("email_123")
if err != nil {
// Check if it's an API error
if apiErr, ok := err.(*unsent.APIError); ok {
fmt.Printf("API Error: %s - %s\n", apiErr.Code, apiErr.Message)
} else {
// Handle other errors (network, etc.)
log.Printf("Error: %v", err)
}
}Disable Automatic Error Raising
If you prefer to handle HTTP errors manually without the SDK treating non-2xx responses as errors, you can use unsent.WithRaiseOnError(false).
client, err := unsent.NewClient("un_xxx", unsent.WithRaiseOnError(false))Advanced Configuration
For advanced use cases, such as adding custom timeouts, proxies, or changing the base URL, you can provide options to NewClient.
Custom HTTP Client
import (
"net/http"
"time"
)
// Create a custom HTTP client with a timeout
httpClient := &http.Client{
Timeout: 30 * time.Second,
}
// Initialize the SDK with the custom client
client, err := unsent.NewClient("un_xxx", unsent.WithHTTPClient(httpClient))Custom Base URL
If you need to point the SDK to a different URL (e.g. for testing), you can use WithBaseURL.
client, err := unsent.NewClient("un_xxx", unsent.WithBaseURL("https://api.example.com"))