postmark_ruby_client
A clean, extensible Ruby client for the Postmark transactional email API. Built with Faraday and designed for Rails 8+ applications.
Features
- Simple API: Intuitive Ruby interface for sending emails
- Extensible Design: Base client class makes it easy to add new API endpoints
- Full Email Support: HTML/text bodies, attachments, custom headers, metadata, tracking
- Batch Sending: Send up to 500 emails in a single API call
- Type Safety: Validation before API calls to catch errors early
- Configurable: Global configuration with per-request overrides
Installation
Add this line to your application's Gemfile:
gem 'postmark_ruby_client'
And then execute:
bundle install
Or install it yourself:
gem install postmark_ruby_client
Configuration
Configure the gem with your Postmark server API token. In a Rails application, create an initializer:
# config/initializers/postmark_ruby_client.rb
PostmarkClient.configure do |config|
config.api_token = ENV["POSTMARK_API_TOKEN"]
# Optional settings with defaults
config. = "outbound" # Default message stream
config.timeout = 30 # Request timeout in seconds
config.open_timeout = 10 # Connection timeout in seconds
config.track_opens = false # Default open tracking
config.track_links = "None" # Default link tracking
end
The API token can also be set via the POSTMARK_API_TOKEN environment variable.
Usage
Sending a Simple Email
# Using the convenience method
response = PostmarkClient.deliver(
from: "[email protected]",
to: "[email protected]",
subject: "Hello!",
text_body: "Hello, World!"
)
if response.success?
puts "Email sent! Message ID: #{response.message_id}"
else
puts "Error: #{response.message}"
end
Using the Email Model
email = PostmarkClient::Email.new(
from: "John Doe <[email protected]>",
to: ["[email protected]", "[email protected]"],
cc: "[email protected]",
bcc: "[email protected]",
subject: "Monthly Report",
html_body: "<h1>Report</h1><p>See attached.</p>",
text_body: "Report - See attached.",
reply_to: "[email protected]",
tag: "monthly-report",
track_opens: true,
track_links: "HtmlAndText",
metadata: { "client_id" => "12345" }
)
client = PostmarkClient::Resources::Emails.new
response = client.send(email)
Adding Attachments
email = PostmarkClient::Email.new(
from: "[email protected]",
to: "[email protected]",
subject: "Files attached",
text_body: "Please see the attached files."
)
# Add attachment from parameters
email.(
name: "document.pdf",
content: File.binread("path/to/document.pdf"),
content_type: "application/pdf"
)
# Or attach directly from a file path
email.attach_file("path/to/image.png")
# Inline attachments for HTML emails
email.html_body = '<p>Logo: <img src="cid:logo.png"/></p>'
email.(
name: "logo.png",
content: File.binread("logo.png"),
content_type: "image/png",
content_id: "cid:logo.png"
)
Custom Headers
email = PostmarkClient::Email.new(
from: "[email protected]",
to: "[email protected]",
subject: "Custom headers",
text_body: "Hello"
)
email.add_header(name: "X-Custom-Header", value: "custom-value")
email.add_header(name: "X-Priority", value: "1")
Batch Sending
Send up to 500 emails in a single API call:
emails = users.map do |user|
{
from: "[email protected]",
to: user.email,
subject: "Your weekly digest",
text_body: "Here's what you missed..."
}
end
client = PostmarkClient::Resources::Emails.new
responses = client.send_batch(emails)
responses.each do |response|
if response.success?
puts "Sent to #{response.to}"
else
puts "Failed: #{response.message}"
end
end
Using a Custom API Token
Override the global configuration for specific requests:
# For a different Postmark server
client = PostmarkClient::Resources::Emails.new(api_token: "different-token")
response = client.send(email)
# Or with the convenience method
client = PostmarkClient.emails(api_token: "different-token")
response = client.send_email(
from: "[email protected]",
to: "[email protected]",
subject: "Hello",
text_body: "World"
)
Error Handling
begin
response = PostmarkClient.deliver(email)
rescue PostmarkClient::ValidationError => e
# Email failed local validation before sending
puts "Validation error: #{e.message}"
rescue PostmarkClient::ApiError => e
# Postmark API returned an error
puts "API error #{e.error_code}: #{e.message}"
puts "Full response: #{e.response}"
rescue PostmarkClient::ConnectionError => e
# Network connectivity issues
puts "Connection error: #{e.message}"
rescue PostmarkClient::ConfigurationError => e
# Missing or invalid configuration
puts "Configuration error: #{e.message}"
end
API Reference
PostmarkClient::Email
| Attribute | Type | Description |
|---|---|---|
from |
String | Sender email (required) |
to |
String/Array | Recipient email(s) (required) |
cc |
String/Array | CC recipient(s) |
bcc |
String/Array | BCC recipient(s) |
subject |
String | Email subject |
html_body |
String | HTML email body |
text_body |
String | Plain text body |
reply_to |
String | Reply-to address |
tag |
String | Email tag for categorization |
headers |
Array | Custom email headers |
track_opens |
Boolean | Enable open tracking |
track_links |
String | Link tracking ("None", "HtmlAndText", "HtmlOnly", "TextOnly") |
attachments |
Array | Email attachments |
metadata |
Hash | Custom metadata key-value pairs |
message_stream |
String | Message stream identifier |
PostmarkClient::EmailResponse
| Method | Returns | Description |
|---|---|---|
success? |
Boolean | True if email was sent successfully |
error? |
Boolean | True if there was an error |
message_id |
String | Unique message identifier |
to |
String | Recipient address |
submitted_at |
Time | Timestamp when email was submitted |
error_code |
Integer | Postmark error code (0 = success) |
message |
String | Response message |
raw_response |
Hash | Full API response |
Development
After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests.
# Install dependencies
bundle install
# Run tests
bundle exec rspec
# Generate documentation
bundle exec yard doc
View documentation in browser
bundle exec yard server
Then open http://localhost:8808
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/yourusername/postmark_ruby_client.
- Fork the repository
- Create your feature branch (
git checkout -b feature/my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin feature/my-new-feature) - Create a new Pull Request
License
The gem is available as open source under the terms of the MIT License.