Possinote Ruby SDK
Official Ruby SDK for the PossiNote API - Send SMS, emails, and schedule messages with ease.
Installation
Add this line to your application's Gemfile:
gem 'possinote'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install possinote
Quick Start
require 'possinote'
client = Possinote::Client.new(api_key: 'your_api_key_here')
response = client.sms.send(
to: '+233244123456',
message: 'Hello from Possinote!',
sender_id: 'YourSenderID'
)
response = client.email.send(
recipient: 'user@example.com',
subject: 'Welcome to Possinote',
content: '<h1>Hello!</h1><p>Welcome to our platform.</p>',
sender_name: 'Your Company'
)
API Reference
Authentication
All API requests require authentication using your API key:
client = Possinote::Client.new(api_key: 'your_api_key_here')
SMS Operations
Send Single SMS
response = client.sms.send(
to: '+233244123456',
message: 'Your message here',
sender_id: 'YourSenderID'
)
{
"success" => true,
"data" => {
"message_id" => "msg_123456789",
"to" => "+233244123456",
"status" => "queued",
"cost" => 1.0,
"created_at" => "2025-08-11T11:30:00Z"
}
}
Send Bulk SMS
response = client.sms.send_bulk(
sender_id: 'YourSenderID',
messages: [
{ to: '+233244123456', message: 'Message 1' },
{ to: '+233244123457', message: 'Message 2' }
]
)
{
"success" => true,
"data" => {
"batch_id" => "batch_123456789",
"total_messages" => 2,
"successful" => 2,
"failed" => 0,
"total_cost" => 2.0,
"messages" => [
{ "message_id" => "msg_1", "to" => "+233244123456", "status" => "queued" },
{ "message_id" => "msg_2", "to" => "+233244123457", "status" => "queued" }
]
}
}
Schedule Single SMS
response = client.sms.schedule(
recipient: '+233244123456',
message: 'Scheduled message',
sender_id: 'YourSenderID',
scheduled_at: '2025-08-11T12:00:00Z'
)
{
"success" => true,
"data" => {
"id" => "schedule_123456789",
"recipient" => "+233244123456",
"message" => "Scheduled message",
"scheduled_at" => "2025-08-11T12:00:00Z",
"status" => "pending",
"cost" => "1.0"
}
}
Schedule Bulk SMS
response = client.sms.schedule_bulk(
sender_id: 'YourSenderID',
messages: [
{ recipient: '+233244123456', message: 'Scheduled message 1' },
{ recipient: '+233244123457', message: 'Scheduled message 2' }
],
scheduled_at: '2025-08-11T12:00:00Z'
)
{
"success" => true,
"data" => {
"batch_id" => "batch_123456789",
"scheduled_count" => 2,
"total_cost" => 2.0,
"scheduled_at" => "2025-08-11T12:00:00Z",
"messages" => [
{ "id" => "schedule_1", "recipient" => "+233244123456", "status" => "pending" },
{ "id" => "schedule_2", "recipient" => "+233244123457", "status" => "pending" }
]
}
}
Email Operations
Send Single Email
response = client.email.send(
recipient: 'user@example.com',
subject: 'Welcome Email',
content: '<h1>Welcome!</h1><p>Thank you for joining us.</p>',
sender_name: 'Your Company'
)
{
"success" => true,
"message" => "Email queued for delivery",
"recipient" => "user@example.com",
"message_id" => "email_123456789"
}
Send Bulk Email
response = client.email.send_bulk(
subject: 'Newsletter',
content: '<h1>Newsletter</h1><p>This is our monthly newsletter.</p>',
recipients: ['user1@example.com', 'user2@example.com'],
sender_name: 'Your Company'
)
{
"success" => true,
"message" => "Bulk emails queued for delivery",
"queued_count" => 2,
"total_count" => 2,
"batch_id" => "batch_123456789",
"emails" => [
{ "message_id" => "email_1", "recipient" => "user1@example.com", "status" => "queued" },
{ "message_id" => "email_2", "recipient" => "user2@example.com", "status" => "queued" }
]
}
Scheduling Operations
Schedule Single Email
response = client.scheduling.schedule_email(
recipient: 'user@example.com',
subject: 'Scheduled Email',
content: '<h1>Scheduled Content</h1>',
scheduled_at: '2025-08-11T12:00:00Z',
sender_name: 'Your Company'
)
{
"success" => true,
"data" => {
"id" => "email_schedule_123456789",
"recipient" => "user@example.com",
"subject" => "Scheduled Email",
"scheduled_at" => "2025-08-11T12:00:00Z",
"status" => "pending",
"cost" => "1.0"
}
}
Schedule Bulk Individual Emails
response = client.scheduling.schedule_multiple_emails([
{
recipient: 'user1@example.com',
subject: 'Personalized Email 1',
content: '<h1>Hello User 1!</h1>',
scheduled_at: '2025-08-11T12:00:00Z',
sender_name: 'Your Company'
},
{
recipient: 'user2@example.com',
subject: 'Personalized Email 2',
content: '<h1>Hello User 2!</h1>',
scheduled_at: '2025-08-11T12:00:00Z',
sender_name: 'Your Company'
}
])
{
"success" => true,
"data" => {
"batch_id" => "batch_123456789",
"total_scheduled" => 2,
"total_cost" => 2.0,
"scheduled_emails" => [
{ "id" => "email_1", "recipient" => "user1@example.com", "status" => "pending" },
{ "id" => "email_2", "recipient" => "user2@example.com", "status" => "pending" }
]
}
}
Framework Integration
Rails Integration
1. Add to Gemfile
gem 'possinote'
2. Configure in Application
require 'possinote'
POSSINOTE_CLIENT = Possinote::Client.new(
api_key: Rails.application.credentials.possinote[:api_key]
)
3. Use in Controllers
class NotificationsController < ApplicationController
def send_sms
begin
response = POSSINOTE_CLIENT.sms.send(
to: params[:phone_number],
message: params[:message],
sender_id: 'YourBrand'
)
if response['success']
render json: { message: 'SMS sent successfully', data: response['data'] }
else
render json: { error: 'Failed to send SMS' }, status: :unprocessable_entity
end
rescue Possinote::AuthenticationError => e
render json: { error: 'Authentication failed' }, status: :unauthorized
rescue Possinote::PaymentRequiredError => e
render json: { error: 'Insufficient credits' }, status: :payment_required
rescue Possinote::ValidationError => e
render json: { error: e.message }, status: :bad_request
rescue => e
render json: { error: 'An error occurred' }, status: :internal_server_error
end
end
def send_bulk_sms
begin
response = POSSINOTE_CLIENT.sms.send_bulk(
sender_id: 'YourBrand',
messages: params[:messages]
)
render json: { message: 'Bulk SMS sent', data: response['data'] }
rescue => e
render json: { error: e.message }, status: :internal_server_error
end
end
def send_email
begin
response = POSSINOTE_CLIENT.email.send(
recipient: params[:email],
subject: params[:subject],
content: params[:content],
sender_name: 'Your Company'
)
render json: { message: 'Email sent successfully', data: response }
rescue => e
render json: { error: e.message }, status: :internal_server_error
end
end
end
4. Use in Services
class NotificationService
def initialize
@client = POSSINOTE_CLIENT
end
def send_welcome_sms(user)
@client.sms.send(
to: user.phone_number,
message: "Welcome #{user.name}! Your account has been created successfully.",
sender_id: 'YourBrand'
)
end
def send_password_reset_email(user, reset_token)
@client.email.send(
recipient: user.email,
subject: 'Password Reset Request',
content: generate_password_reset_html(user, reset_token),
sender_name: 'Your Company'
)
end
def send_bulk_newsletter(users, newsletter_content)
messages = users.map do |user|
{
to: user.phone_number,
message: "Newsletter: #{newsletter_content[:title]}"
}
end
@client.sms.send_bulk(
sender_id: 'YourBrand',
messages: messages
)
end
def schedule_reminder_email(user, appointment)
@client.scheduling.schedule_email(
recipient: user.email,
subject: 'Appointment Reminder',
content: generate_appointment_reminder_html(appointment),
scheduled_at: appointment.datetime - 1.hour,
sender_name: 'Your Company'
)
end
private
def generate_password_reset_html(user, token)
<<~HTML
<h1>Password Reset Request</h1>
<p>Hello #{user.name},</p>
<p>You requested a password reset. Click the link below to reset your password:</p>
<a href="#{Rails.application.routes.url_helpers.reset_password_url(token: token)}">
Reset Password
</a>
<p>This link will expire in 1 hour.</p>
HTML
end
def generate_appointment_reminder_html(appointment)
<<~HTML
<h1>Appointment Reminder</h1>
<p>Hello #{appointment.user.name},</p>
<p>This is a reminder for your appointment:</p>
<ul>
<li><strong>Date:</strong> #{appointment.datetime.strftime('%B %d, %Y')}</li>
<li><strong>Time:</strong> #{appointment.datetime.strftime('%I:%M %p')}</li>
<li><strong>Location:</strong> #{appointment.location}</li>
</ul>
HTML
end
end
5. Use in Background Jobs
class SendNotificationJob < ApplicationJob
queue_as :default
def perform(notification_type, user_id, options = {})
user = User.find(user_id)
service = NotificationService.new
case notification_type
when 'welcome_sms'
service.send_welcome_sms(user)
when 'password_reset_email'
service.send_password_reset_email(user, options[:reset_token])
when 'bulk_newsletter'
service.send_bulk_newsletter(options[:users], options[:content])
when 'scheduled_reminder'
service.schedule_reminder_email(user, options[:appointment])
end
end
end
SendNotificationJob.perform_later('welcome_sms', user.id)
SendNotificationJob.perform_later('password_reset_email', user.id, reset_token: token)
6. Environment Configuration
possinote:
api_key: your_api_key_here
POSSINOTE_CLIENT = Possinote::Client.new(
api_key: ENV['POSSINOTE_API_KEY']
)
Error Handling
The SDK provides specific exception classes for different error types:
begin
response = client.sms.send(to: '+233244123456', message: 'Hello', sender_id: 'SenderID')
rescue Possinote::AuthenticationError => e
puts "Authentication failed: #{e.message}"
rescue Possinote::PaymentRequiredError => e
puts "Payment required: #{e.message}"
rescue Possinote::RateLimitError => e
puts "Rate limit exceeded: #{e.message}"
rescue Possinote::ValidationError => e
puts "Validation error: #{e.message}"
rescue Possinote::APIError => e
puts "API error: #{e.message}"
end
Error Types
Possinote::AuthenticationError
- Invalid API key (401)
Possinote::PaymentRequiredError
- Insufficient credits (402)
Possinote::RateLimitError
- Rate limit exceeded (429)
Possinote::ValidationError
- Invalid request data (400)
Possinote::APIError
- Other API errors
Configuration
Base URL
The SDK uses the production API by default. For testing, you can modify the base URL:
BASE_URI = 'https://notifyapi.possitech.net/api/v1'
Timeout Settings
HTTP requests use default timeout settings. You can customize them in the client:
Requirements
- Ruby >= 2.6.0
- HTTParty gem
- JSON gem
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/possitech/possinote-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Support
For support, email support@possitech.net or visit our documentation.
Changelog
1.0.0
- Initial release
- SMS sending and scheduling
- Email sending and scheduling
- Comprehensive error handling
- Full API coverage