forked from sendgrid/sendgrid-ruby
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request sendgrid#234 from awinabi/stats-helpers
Helpers for email statistics - global, category, subuser
- Loading branch information
Showing
8 changed files
with
391 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
require 'sendgrid-ruby' | ||
require 'date' | ||
|
||
include SendGrid | ||
|
||
sg_client = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY']).client | ||
stats = SendGrid::EmailStats.new(sendgrid_client: sg_client) | ||
|
||
# Fetch stats by day, between 2 dates | ||
from = Date.new(2017, 10, 01) | ||
to = Date.new(2017, 10, 12) | ||
|
||
email_stats = stats.by_day(from, to) | ||
|
||
email_stats.metrics | ||
|
||
if !email_stats.error? | ||
email_stats.metrics.each do |metric| | ||
puts "Date - #{metric.date}" | ||
puts "Number of Requests - #{metric.requests}" | ||
puts "Bounces - #{metric.bounces}" | ||
puts "Opens - #{metric.opens}" | ||
puts "Clicks - #{metric.clicks}" | ||
end | ||
end | ||
|
||
# Fetch stats by week, between 2 dates for a category | ||
from = Date.new(2017, 10, 01) | ||
to = Date.new(2017, 10, 12) | ||
category = 'abcd' | ||
|
||
email_stats = stats.by_week(from, to, category) | ||
|
||
if !email_stats.error? | ||
email_stats.metrics.each do |metric| | ||
puts "Date - #{metric.date}" | ||
puts "Number of Requests - #{metric.requests}" | ||
puts "Bounces - #{metric.bounces}" | ||
puts "Opens - #{metric.opens}" | ||
puts "Clicks - #{metric.clicks}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
require 'json' | ||
|
||
module SendGrid | ||
class EmailStats | ||
def initialize(args) | ||
@sendgrid_client = args[:sendgrid_client] | ||
end | ||
|
||
def by_day(start_date, end_date, categories = nil, subusers = nil) | ||
get('day', start_date, end_date, categories, subusers) | ||
end | ||
|
||
def by_week(start_date, end_date, categories = nil, subusers = nil) | ||
get('week', start_date, end_date, categories, subusers) | ||
end | ||
|
||
def by_month(start_date, end_date, categories = nil, subusers = nil) | ||
get('month', start_date, end_date, categories, subusers) | ||
end | ||
|
||
def get(aggregated_by, start_date, end_date, categories = nil, subusers = nil) | ||
params = query_params(aggregated_by, start_date, end_date, categories, subusers) | ||
|
||
response_body = @sendgrid_client.stats.get(query_params: params).body | ||
build_response(response_body) | ||
end | ||
|
||
private | ||
|
||
def query_params(aggregated_by, start_date, end_date, categories, subusers) | ||
params = { | ||
aggregated_by: aggregated_by, | ||
start_date: start_date, | ||
end_date: end_date | ||
} | ||
params.merge(categories: categories) if categories | ||
params.merge(subusers: subusers) if subusers | ||
params | ||
end | ||
|
||
def build_response(response_body) | ||
response_json = JSON.parse(response_body) | ||
StatsResponse.new(response_json) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
require 'json' | ||
|
||
module SendGrid | ||
class Metrics | ||
attr_reader :blocks, :bounce_drops, | ||
:bounces, :clicks, :deferred, :delivered, | ||
:invalid_emails, :opens, :processed, :requests, | ||
:spam_report_drops, :spam_reports, :unique_clicks, | ||
:unique_opens, :unsubscribe_drops, :unsubscribes | ||
|
||
def initialize(args={}) | ||
@date = args['date'] | ||
@blocks = args['blocks'] | ||
@bounce_drops = args['bounce_drops'] | ||
@bounces = args['bounces'] | ||
@clicks = args['clicks'] | ||
@deferred = args['deferred'] | ||
@delivered = args['delivered'] | ||
@invalid_emails = args['invalid_emails'] | ||
@opens = args['opens'] | ||
@processed = args['processed'] | ||
@requests = args['requests'] | ||
@spam_report_drops = args['spam_report_drops'] | ||
@spam_reports = args['spam_reports'] | ||
@unique_clicks = args['unique_clicks'] | ||
@unique_opens = args['unique_opens'] | ||
@unsubscribe_drops = args['unsubscribe_drops'] | ||
@unsubscribes = args['unsubscribes'] | ||
end | ||
|
||
def date | ||
Date.parse(@date) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require 'json' | ||
|
||
module SendGrid | ||
class StatsResponse | ||
def initialize(args) | ||
@errors = args['errors'] if args.is_a? Hash | ||
@stats = args if args.is_a? Array | ||
end | ||
|
||
def errors | ||
@errors.map do |error| | ||
error['message'] | ||
end | ||
end | ||
|
||
def error? | ||
!@errors.nil? | ||
end | ||
|
||
def metrics | ||
@stats.flat_map do |stat| | ||
starting_date = stat['date'] | ||
all_stats_for_date = stat['stats'] | ||
|
||
metrics = all_stats_for_date.map do |metric| | ||
Metrics.new(metric['metrics'].merge('date' => starting_date)) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
require 'spec_helper' | ||
|
||
describe SendGrid::EmailStats do | ||
let(:sg_client) { SendGrid::API.new(api_key: 'abcd').client } | ||
let(:stats) { SendGrid::EmailStats.new(sendgrid_client: sg_client) } | ||
let(:sg_response) { double('SendGrid::Response') } | ||
|
||
let(:sample_response) do | ||
[{ | ||
"date" => "2017-10-01", | ||
"stats" => [ | ||
{"metrics" => | ||
{ | ||
"blocks" => 101, | ||
"bounce_drops" => 102, | ||
"bounces" => 103, | ||
"clicks" => 104, | ||
"deferred" => 105, | ||
"delivered" => 106, | ||
"invalid_emails" => 107, | ||
"opens" => 108, | ||
"processed" => 109, | ||
"requests" => 110, | ||
"spam_report_drops" => 111, | ||
"spam_reports" => 112, | ||
"unique_clicks" => 113, | ||
"unique_opens" => 114, | ||
"unsubscribe_drops" => 115, | ||
"unsubscribes" => 116 | ||
} | ||
} | ||
] | ||
}] | ||
end | ||
|
||
let(:error_response) do | ||
{ | ||
"errors" => [ | ||
{ | ||
"message" => "end_date should be a YYYY-MM-DD formatted date" | ||
} | ||
] | ||
} | ||
end | ||
|
||
describe '.new' do | ||
it 'initializes with SendGrid::Client' do | ||
expect(stats).to be_a SendGrid::EmailStats | ||
end | ||
end | ||
|
||
describe 'successful response' do | ||
before do | ||
allow_any_instance_of(SendGrid::Response).to receive(:body) { sample_response.to_json } | ||
end | ||
|
||
describe '#by_day' do | ||
it 'fetches data aggregated by day' do | ||
day_stats = stats.by_day('2017-10-01', '2017-10-02') | ||
day_metrics = day_stats.metrics.first | ||
|
||
expect(day_metrics).to be_a SendGrid::Metrics | ||
expect(day_metrics.date.to_s).to eq('2017-10-01') | ||
expect(day_metrics.requests).to eq(110) | ||
expect(day_metrics.clicks).to eq(104) | ||
expect(day_metrics.bounces).to eq(103) | ||
expect(day_metrics.opens).to eq(108) | ||
end | ||
end | ||
|
||
describe '#by_week' do | ||
it 'fetches data aggregated by week' do | ||
day_stats = stats.by_week('2017-10-01', '2017-10-12') | ||
day_metrics = day_stats.metrics.first | ||
|
||
expect(day_metrics).to be_a SendGrid::Metrics | ||
expect(day_metrics.date.to_s).to eq('2017-10-01') | ||
expect(day_metrics.requests).to eq(110) | ||
expect(day_metrics.clicks).to eq(104) | ||
expect(day_metrics.bounces).to eq(103) | ||
expect(day_metrics.opens).to eq(108) | ||
end | ||
end | ||
|
||
describe '#by_month' do | ||
it 'fetches data aggregated by month' do | ||
day_stats = stats.by_month('2017-10-01', '2017-11-01') | ||
day_metrics = day_stats.metrics.first | ||
|
||
expect(day_metrics).to be_a SendGrid::Metrics | ||
expect(day_metrics.date.to_s).to eq('2017-10-01') | ||
expect(day_metrics.requests).to eq(110) | ||
expect(day_metrics.clicks).to eq(104) | ||
expect(day_metrics.bounces).to eq(103) | ||
expect(day_metrics.opens).to eq(108) | ||
end | ||
end | ||
end | ||
|
||
describe 'error response' do | ||
before do | ||
allow_any_instance_of(SendGrid::Response).to receive(:body) { error_response.to_json } | ||
end | ||
|
||
it 'fetches data aggregated by month' do | ||
day_stats = stats.by_month('2017-10-01', '2017-10-02') | ||
|
||
expect(day_stats.errors).to include('end_date should be a YYYY-MM-DD formatted date') | ||
expect(day_stats.error?).to be_truthy | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
require 'spec_helper' | ||
|
||
describe SendGrid::Metrics do | ||
let(:params) do | ||
{ | ||
"date" => "2017-10-01", | ||
"blocks" => 101, | ||
"bounce_drops" => 102, | ||
"bounces" => 103, | ||
"clicks" => 104, | ||
"deferred" => 105, | ||
"delivered" => 106, | ||
"invalid_emails" => 107, | ||
"opens" => 108, | ||
"processed" => 109, | ||
"requests" => 110, | ||
"spam_report_drops" => 111, | ||
"spam_reports" => 112, | ||
"unique_clicks" => 113, | ||
"unique_opens" => 114, | ||
"unsubscribe_drops" => 115, | ||
"unsubscribes" => 116 | ||
} | ||
end | ||
|
||
subject { described_class.new(params) } | ||
|
||
it 'initializes with metric parameters' do | ||
expect(subject).to be_a SendGrid::Metrics | ||
end | ||
|
||
it 'returns date as object' do | ||
expect(subject.date).to be_a Date | ||
end | ||
|
||
%w( | ||
blocks bounce_drops bounces clicks deferred delivered invalid_emails | ||
opens processed requests spam_report_drops spam_reports unique_clicks | ||
unique_opens unsubscribe_drops unsubscribes | ||
).each do |attribute| | ||
it "responds to #{attribute}" do | ||
expect(subject).to respond_to(attribute.to_sym) | ||
end | ||
end | ||
|
||
end |
Oops, something went wrong.