Git Product home page Git Product logo

sendgrid_toolkit's Introduction

SendgridToolkit

Build Status

SendgridToolkit is a Ruby wrapper for the SendGrid Web API

Supported Modules

SendgridToolkit provides a class for interacting with each of the following SendGrid API modules:

  • Bounces
  • InvalidEmails
  • Lists
  • ListEmails
  • Mail
  • SpamReports
  • Statistics
  • Unsubscribes

Consuming the SendGrid API is as simple as instantiating a class and making the call:

unsubscribes = SendgridToolkit::Unsubscribes.new("username", "api_key")
unsubscribes.add :email => "[email protected]"

Two lines, and voila!

Common actions are documented below under each module. For more details, visit the SendGrid Web API Documentation

Contributing

  • Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
  • Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
  • Fork the project
  • Start a feature/bugfix branch
  • Commit and push until you are happy with your contribution
  • Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
  • Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

Big thanks to James Brennan for refactoring old code and writing the Bounces, InvalidEmails and SpamReports modules.

Install

Via rubygems.org:

$ gem install sendgrid_toolkit

Or add it to your Gemfile

gem 'sendgrid_toolkit', '>= 1.1.1'

Setting your API credentials globally

Setting your API user and key once globally for all API access:

SendgridToolkit.api_user = "bob"
SendgridToolkit.api_key = "x123y"

If you do this when you create individual API objects you will not need to pass the api_user or api_key

bounces = SendgridToolkit::Bounces.new

Bounces Module

The bounces module provides access to all of your bounces.


Instantiate the Bounces object:

bounces = SendgridToolkit::Bounces.new(api_user, api_key)

Retrieve bounces:

all_bounces = bounces.retrieve

all_bounces will be an array of hashes, each of which contains the following keys:

  • email: the recipient's email address
  • status: the status of email
  • reason: the reason for the bounce, as specified by the recipient's email server

Get the timestamp of each bounce:

all_bounces = bounces.retrieve_with_timestamps

Each hash in all_bounces will now contain a created key, which holds a Ruby Time object.


If you believe an email address will no longer bounce and would like SendGrid to deliver future emails to that address, you may delete the Bounce entry:

bounces.delete :email => "[email protected]"

InvalidEmails Module

The InvalidEmails module provides access to all of your email addresses.


Instantiate the InvalidEmails object:

invalid_emails_obj = SendgridToolkit::InvalidEmails.new(api_user, api_key)

Retrieve invalid emails:

invalid_emails = invalid_emails_obj.retrieve

invalid_emails will be an array of hashes, each of which contains the following keys:

  • email: the recipient's email address
  • reason: the reason the email address is believed to be invalid

Get the timestamp that each email was determined to be invalid:

invalid_emails = invalid_emails_obj.retrieve_with_timestamps

Each hash in invalid_emails will now contain a created key, which holds a Ruby Time object.


If you believe a once-invalid email address is now valid and would like SendGrid to deliver future emails to that address, you may delete the InvalidEmail entry:

invalid_emails.delete :email => "[email protected]"

Lists Module

The Lists module lets you manage your recipient lists associated with the marketing email feature via the marketing emails API.


Instantiate the Lists object:

lists_obj = SendgridToolkit::Lists.new(api_user, api_key)

Retrieve lists:

lists = lists_obj.get

lists will be an array of hashes, each of which contains a list key, which contain the name of the lists.


Create list:

response = lists_obj.add :list => 'new_list_name'

response will be a hash containing a message key, which contains either success or error. If it is error, it will additionally contain the errors key, which contains an array of error messages.

When creating a list you can also specify a custom column name for the name associated with email addresses.

Example:

response = lists_obj.add :list => 'new_list_name', :name => 'customer_name'

Edit list:

response = lists_obj.edit :list => 'some_old_name', :new_list => 'some_new_name'

response will be a hash containing a message key, which contains either success or error. If it is error, it will additionally contain the errors key, which contains an array of error messages.


Delete list:

response = lists_obj.delete :list => 'some_list_name'

response will be a hash containing a message key, which contains either success or error. If it is error, it will additionally contain the errors key, which contains an array of error messages.

ListEmails Module

The ListEmails module lets you manage your emails in your recipient lists associated with the marketing email feature via the marketing emails API.


Instantiate the ListEmails object:

list_emails_obj = SendgridToolkit::ListEmails.new(api_user, api_key)

Count emails:

count_hash = list_emails_obj.count :list => 'some_list_name'

count will be a hash, with one element whose key is 'count' and value is the number of subscribers on the specified list.


Get emails:

list_emails = list_emails_obj.get :list => 'some_list_name'

list_emails will be an array of hashes, each of which contains the following keys:

  • email: The email address of the recipient
  • name: The name of the recipient. This key may be different if you changed the column name

Add email:

response = list_emails_obj.add :list => 'some_list_name', :data => { :email => '[email protected]', :name => 'some_new_person'}

Add multiple emails:

This is limited to 1,000 entries by the API

response = list_emails_obj.add :list => 'some_list_name', :data => [
  { :email => '[email protected]', :name => 'some_new_person1'},
  { :email => '[email protected]', :name => 'some_new_person2'},
  { :email => '[email protected]', :name => 'some_new_person3'}
]

response will be a hash containing a inserted key, which contains the number of emails inserted into the list.


Remove email:

response = list_emails_obj.delete :list => 'some_list_name', :email => '[email protected]'

response will be a hash containing a removed key, which contains the number of emails removed from the list.

Mail Module

The Mail module lets you send email via the web API.


Call :send_mail (chosen to avoid conflicts with Object:send) with the standard parameters:

SendgridToolkit::Mail.new(api_user, api_key).send_mail :to => "[email protected]", :from => "[email protected]", :subject => "Some Subject", :text => "Some text"

The complete set of "x-smtpapi" options are also supported. You can use them like:

SendgridToolkit::Mail.new(api_user, api_key).send_mail :to => "[email protected]", :from => "[email protected]", :subject => "Some Subject", :text => "Some text", "x-smtpapi" => {:category => "Retention"}

SpamReports Module

The SpamReports module provides access to all email addresses that have reported you for spam.


Instantiate the SpamReports object:

spam_reports_obj = SendgridToolkit::SpamReports.new(api_user, api_key)

Retrieve spam reports:

spam_reports = spam_reports_obj.retrieve

spam_reports will be an array of hashes, each of which contains an email key, indicating the email address that reported you for spam.


Get the timestamp of each spam report:

spam_reports = spam_reports_obj.retrieve_with_timestamps

Each hash in spam_reports will now contain a created key, which holds a Ruby Time object.


If you believe a user will no longer consider your content to be spam, you may delete the SpamReport entry:

spam_reports.delete :email => "[email protected]"

Statistics Module

The statistics module provides access to all of your email statistics.


Instantiate the Statistics object:

statistics = SendgridToolkit::Statistics.new(api_user, api_key)

Retrieve statistics:

stats = statistics.retrieve

stats will be an array of hashes, each of which contains the following keys:

  • date: The date to which the statistics in this hash refer to
  • requests: The number of emails you requested be sent
  • delivered: The number of emails delivered to email servers
  • bounces: The number of emails which were rejected by email servers
  • repeat_bounces: The number of emails which bounced repeatedly
  • blocked: The number of emails which were suppressed by SendGrid
  • spam_drop: The number of emails which SendGrid dropped as spam
  • clicks: The number of clicks on links in your emails
  • unique_clicks: The number of users who clicked on a link in your email
  • opens: The number of users who opened your email
  • unique_opens: The number of users who opened your email
  • spamreports: The number of users who have reported your emails as spam
  • unsubscribes: The number of unsubscribes your messages have received (if you are using the subscription tracking app
  • repeat_unsubscribes: The number of repeat unsubscribes (if a user unsubscribed, resubscribed and then unsubscribed again)
  • bounces: The number of emails that bounced

To narrow your retrieval to the past 5 days:

stats = statistics.retrieve :days => 5

To narrow your retrieval to emails within the last month but before one week ago:

stats = statistics.retrieve :start_date => 1.month.ago, :end_date => 1.week.ago

To narrow your search to a particular category (applicable only if you use this SendGrid feature):

stats = statistics.retrieve :category => "NameOfYourCategory"

Note: You may combine a category query with other options, i.e.:

stats = statistics.retrieve :category => "NameOfYourCategory", :days => 5

Receive your all-time statistics:

stats = statistics.retrieve_aggregate

stats will be a single hash containing all of the aforementioned keys except date.


If you use SendGrid's category feature, you can list your categories:

cats = statistics.list_categories

cats is an array of hashes, each of which has a category key that holds the name of a category.

Unsubscribes Module

The unsubscribes module manages your list of unsubscribed email addresses.


Instantiate the Unsubscribes object:

unsubscribes = SendgridToolkit::Unsubscribes.new(api_user, api_key)

List everybody who has unsubscribed from your emails with:

listing = unsubscribes.retrieve

listing will be an array of hashes, each of which has an email key.


Get the timestamp when each user unsubscribed:

listing = unsubscribes.retrieve_with_timestamps

Each hash in listing will now contain a created key, which holds a Ruby Time object.


Unsubscribe a user from your SendGrid email:

unsubscribes.add :email => "[email protected]"

SendgridToolkit will throw UnsubscribeEmailAlreadyExists if the email you specified is already on the list


Remove a user from your unsubscribe list:

unsubscribes.delete :email => "email@that_is.unsubscribed"

SendgridToolkit will throw UnsubscribeEmailDoesNotExist if the email you specified is not on the list

Sendgrid Groups V3 (branch master for now)

Use groups

groups = SendgridToolkit::V3::Groups.new(SENDGRID_USERNAME, SENDGRID_PASSWORD)
groups.get # get all groups
groups.get(group_id) # get group by id

groups.add(options = {}) 
groups.delete(options = {})

Add emails to the groups (unsubscribes)

unsubscribes = SendgridToolkit::V3::Unsubscribes.new(SENDGRID_USERNAME, SENDGRID_PASSWORD)
unsubscribes.add(group_id: group_id, recipient_emails: [emails]) # add one / a few emails to the group
unsubscribes.delete(group_id: group_id, email: email)

A note about authentication

Each class is initialized with api_user and api_key parameters. api_user is your SendGrid account email address, and api_key is your SendGrid password.

If you don't supply api_user or api_key, SendgridToolkit will look for the SMTP_USERNAME or SMTP_PASSWORD environment variables. If they are not found, SendgridToolkit will throw NoAPIKeySpecified or NoAPIUserSpecified, depending on what you omitted.

If authentication fails during an API request, SendgridToolkit throws AuthenticationFailed.

In Case You're Curious...

API requests are made and responses are received in JSON. All requests are made as POSTs unless noted otherwise (some of SendGrid's examples are via GET, but they support POST)

Each class takes a final options parameter in the form of a hash. You may use this parameter to pass additional options to the SendGrid API. For example, let's say you are using the unsubscribes function:

unsubscribes = SendgridToolkit::Unsubscribes.new(api_user, api_key)
listing = unsubscribes.retrieve

If SendGrid were to add a only_verified option to this API call, you could call:

listing = unsubscribes.retrieve :only_verified => true

to make use of it.

Testing

In addition to unit tests, SendgridToolkit comes with a limited suite of "webconnect" tests that will actually hit SendGrid's servers and perform various actions for purposes of real-world testing. In order to use these tests, you must:

  1. Create a test account with SendGrid and store the credentials in TEST_SMTP_USERNAME and TEST_SMTP_PASSWORD environment variables. This is so that actions are performed on a test account and not your real SendGrid account. If you forget, don't worry -- the tests will fail but they will not fall back on the account that uses SMTP_USERNAME and SMTP_PASSWORD.
  2. Change "xit" it "it" on the tests you wish to run.

Running rspec out of the box will run the standard suite of tests (all network access is stubbed out).

sendgrid_toolkit's People

Contributors

alexklim avatar badosu avatar bodhi avatar dlackty avatar freerobby avatar gerrywastaken avatar hampei avatar hoenth avatar joshgoebel avatar michaelherold avatar nquinlan avatar phallstrom avatar scottberke avatar theycallmeswift avatar threedaymonk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

sendgrid_toolkit's Issues

Unable to fetch campaigns

I was willing to integrate SendGrid with my app and for that i was thinking of using this gem. But i was unable to find any call, class or method for fetching campaigns. I searched through README but was unable to find anything then i tried looking into code and was still not able to find anything.

Please add functionality for fetching campaigns or if it exists already let me know how to do it.

Thanks,
Vinay

Travis-CI failing

Travis-CI is failing when attempting to run the spec tests. It runs 'Bundle Exec Rake', but since there is no default task set up in the RakeFile, it fails with: Don't know how to build task 'default'

To fix the issue, add the following lines to the RakeFile:

task :default => :spec

require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new

Mail#send_mail cannot handle a large multiline x-smtpapi header

SendgridToolkit::AbstractSendgridClient#api_post calls HTTParty.post using the options key "query" rather than "body".
When using the key "query", HTTParty appends the urlencoded options to the URI.

With a large x-smtpapi header (eg. sending to hundreds of recipients) via Mail#send_mail, this causes SendGrid's servers to return a "414 Request-URI Too Large" (they also incorrectly return the error as text/html rather than just headers :/ ).

Since SendgridToolkit sends all requests as POST, I think it'd be safe to always send the request parameters as the request body rather than in the query string.

Adding multiple recipients to a legacy newletter recipient list fails

The documentation for SendgridToolkit::ListEmails says you can add single recipients to a list, or an array of recipients, but adding an array doesn't seem to work:

  • abstract_sendgrid_client.rb:17 forces all data into the URL. It's a POST request, and data should be in the body instead of the URL. It works, but you're limited to a few thousand characters instead of a thousand recipients.
  • The data is getting serialized strangely. data: [{a:1,b:2}, {a:3,c:4}] becomes data[][a]=1&data[][b]=2&data[][a]=3&data[][c]=4 instead of data[]=%7B%22a%22%3A1%2C%22b%22%3A2%7D&data[]=%7B%22a%22%3A3%2C%22c%22%3A4%7D

Sendgrid responds with {"error": "error in data: data is required"}

Edit: Looks like you've already switched HTTParty.post(..., query => ... to HTTParty.post(..., body => ..., but the gem hasn't been updated?

Is the gem being updated for the latest version of Sendgrid

Hi there,
I recently stumbled on this gem, its a while since anything has been done but keen to know if this is gem works on the current API.

I see that there is a branch for V3 in the code for the API but as far as I can see it isnt in the gem that is packed for 1.4.0 when I add it to the gemfile.

Also I cant see that an api_user is used anymore, its just Bearer api_key - so has anyone updated this in the forks to get this working?

Small typo in the readme

When following the readme I noticed you are specifying "send_email" as the method to trigger email delivery but in the codebase it is actually "send_mail".

Happy Holidays,
Mark

x-smtpapi param doesn't work as described in readme

Instead of

send_email "x-smtpapi" => {:category => "foo"}

I had to do

send_email "x-smtpapi" => {:category => "foo"}.to_json

for sendgrid to pick up the parameters. Not sure if this is just a docs change or should be changed in the code.

Thanks

Error when sendgrid unavailable

Edit: let me start off by thanking you for a really useful gem!

Just now sendgrid API was down due to problems on their end. A couple of minutes later they changed the error 500 into a nice message stating the bounces API was not available. Maybe it would be good to check for this and handle the resulting error properly and returning an empty result e.g.?

all_bounces = bounces.retrieve_with_timestamps
NoMethodError: undefined method has_key?' for ["error", {"code"=>500, "message"=>nil}]:Array from /usr/local/lib/ruby/gems/1.8/gems/sendgrid_toolkit-1.0.1/lib/sendgrid_toolkit/common.rb:14:inretrieve_with_timestamps'
from /usr/local/lib/ruby/gems/1.8/gems/httparty-0.6.1/lib/httparty/response.rb:55:in each' from /usr/local/lib/ruby/gems/1.8/gems/httparty-0.6.1/lib/httparty/response.rb:55:insend'
from /usr/local/lib/ruby/gems/1.8/gems/httparty-0.6.1/lib/httparty/response.rb:55:in method_missing' from /usr/local/lib/ruby/gems/1.8/gems/sendgrid_toolkit-1.0.1/lib/sendgrid_toolkit/common.rb:13:inretrieve_with_timestamps'
from (irb):5

all_bounces = bounces.retrieve_with_timestamps
NoMethodError: undefined method has_key?' for "The service is not available. Please try again later.":String from /usr/local/lib/ruby/gems/1.8/gems/sendgrid_toolkit-1.0.1/lib/sendgrid_toolkit/common.rb:14:inretrieve_with_timestamps'
from /usr/local/lib/ruby/gems/1.8/gems/httparty-0.6.1/lib/httparty/response.rb:55:in each' from /usr/local/lib/ruby/gems/1.8/gems/httparty-0.6.1/lib/httparty/response.rb:55:insend'
from /usr/local/lib/ruby/gems/1.8/gems/httparty-0.6.1/lib/httparty/response.rb:55:in method_missing' from /usr/local/lib/ruby/gems/1.8/gems/sendgrid_toolkit-1.0.1/lib/sendgrid_toolkit/common.rb:13:inretrieve_with_timestamps'
from (irb):6

Authentication errors are being thrown as Server errors

When Sendgrid returns 403 bad user/pass you'd expect a SendgridTookit::AuthenticationFailed error but get a SendgirdToolkit::SendgridServerError instead:

pry(SendGridExporter)> e.class
=> SendgridToolkit::SendgridServerError
pry(SendGridExporter)> e.message
=> "The sengrid server returned an error. #<HTTParty::Response:0x1064a2638 parsed_response={\"error\"=>\"Bad username / password\"}, @response=#<Net::HTTPForbidden 403 Forbidden readbody=true>, @headers={\"server\"=>[\"nginx/1.4.4\"], \"date\"=>[\"Tue, 09 Sep 2014 09:01:26 GMT\"], \"content-type\"=>[\"text/html\"], \"transfer-encoding\"=>[\"chunked\"], \"connection\"=>[\"close\"]}>"

error when retrieving statistics-aggregate with specific :category option

Hello,

when requesting the aggregate statistics for a sendgrid category, for example like this:

statistics.retrieve_aggregate :category => "my_category"

an exception is thrown (NoMethodError: undefined method `has_key?' for #HTTParty::Response:0x106a6c708)
from sendgrid_toolkit-1.0.5/lib/sendgrid_toolkit/statistics.rb:12

from what I see, retrieve_aggregate returns a Hash if no category is specified, in which case has_key? does exist. OR it returns an array with one hash if a :category was specified, like:
(without specifying category:)
irb> r = HTTParty.post("https://sendgrid.com/api/stats.get.json?", :query => get_credentials.merge(:aggregate => 1), :format => :json)
{"repeat_spamreports"=>19,
"invalid_email"=>17,
"spamreports"=>21,
"bounces"=>177,
"delivered"=>12977,
"blocked"=>23,
"unique_clicks"=>124,
"clicks"=>218,
"requests"=>13460,
"unsubscribes"=>11,
"unique_opens"=>3847,
"repeat_bounces"=>248,
"spam_drop"=>0,
"opens"=>7740,
"repeat_unsubscribes"=>37}

(specifying a category:)
r = HTTParty.post("https://sendgrid.com/api/stats.get.json?", :query => get_credentials.merge(:aggregate => 1,:category => "my_category"), :format => :json)
[{"repeat_spamreports"=>0,
"invalid_email"=>3,
"name"=>"my_category",
"spamreports"=>6,
"bounces"=>98,
"delivered"=>3245,
"blocked"=>6,
"unique_clicks"=>0,
"clicks"=>0,
"requests"=>3337,
"unsubscribes"=>0,
"unique_opens"=>763,
"repeat_bounces"=>11,
"spam_drop"=>0,
"opens"=>1227,
"repeat_unsubscribes"=>0}]

so a solution would be to check if its an array in lib/sendgrid_toolkit/statistics.rb#retrieve_aggregate

thanks !

Elias

Sending attachments

Hi,

I can send mail using the mail api but I am not sure how to send attachments. Has anyone done this?

Regards,
Gavin

day parameter

SendGrid Api use day parameter for bounced email. If day=1 then only 1 day bounced emails we'll get. How to use the same for sandgrid_toolkit. So that we'll get only 1 day bounced emails.

Sending Attachments

Any information now available on how to send attachments using sendgrid_toolkit as per previously logged issue #33

Subuser API

Hi,

Has anyone looked at adding the subuser API?

Regards,
Gavin

Missing latest commit

When I install the gem, I don't get the commit that allows for bulk-inserting e-mails. It looks like the gemspec's version wasn't bumped up after that commit was merged in.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.