mailjet 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env rake
2
+ require 'rake/testtask'
3
+
4
+ $:.push File.expand_path("../lib", __FILE__)
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'lib'
8
+ t.libs << 'test'
9
+ t.pattern = 'test/**/*_test.rb'
10
+ t.verbose = true
11
+ end
12
+
13
+
14
+ task :default => :test
data/lib/mailjet.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'active_support'
2
+ require 'ostruct'
3
+ require 'mailjet/core_extensions/ostruct'
4
+ require 'mailjet/api'
5
+ require 'mailjet/api_request'
6
+ require 'mailjet/api_error'
7
+ require 'mailjet/configuration'
8
+ require 'mailjet/contact'
9
+ require 'mailjet/list'
10
+ require 'mailjet/campaign'
11
+ require 'mailjet/template_category'
12
+ require 'mailjet/template_model'
13
+ require 'mailjet/reporting'
14
+ require 'mailjet/click'
15
+ require 'mailjet/email'
16
+
17
+
18
+ module Mailjet
19
+ def self.configure
20
+ yield Mailjet::Configuration
21
+ end
22
+
23
+ def self.config
24
+ Mailjet::Configuration
25
+ end
26
+ end
27
+
28
+ if defined?(ActionMailer)
29
+ require 'action_mailer/version'
30
+ require 'mailjet/mailer' if 3 == ActionMailer::VERSION::MAJOR
31
+ end
32
+
33
+ require 'mailjet/rack/endpoint'
@@ -0,0 +1,20 @@
1
+ module Mailjet
2
+ class Api
3
+ def initialize(api_key = Mailjet.config.api_key, secret_key = Mailjet.config.secret_key)
4
+ @api_key = api_key
5
+ @secret_key = secret_key
6
+ end
7
+
8
+ def method_missing(method_name, *args, &block)
9
+ params, request_type = args
10
+ request = ApiRequest.new(method_name, params, request_type, @api_key, @secret_key)
11
+ request.response
12
+ end
13
+
14
+ class << self
15
+ def singleton
16
+ @@singleton ||= self.new
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ require 'active_support'
3
+
4
+ module Mailjet
5
+ class ApiError < StandardError
6
+ def initialize(code, res, request, request_path, params)
7
+ # code is ugly, output is pretty
8
+ super("error #{code} while sending #{request.inspect} to #{request_path} with #{params.inspect}\n\n" +
9
+ (res['errors'].present? ?
10
+ (res['errors'] || []).map do |param, text|
11
+ [param, text].map(&:to_s).reject(&:blank?).join(': ')
12
+ end.join("\n") :
13
+ res.inspect
14
+ ) +
15
+ "\n\nPlease see http://api.mailjet.com/0.1/HelpStatus for more informations on error numbers.\n\n"
16
+ )
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+ require 'active_support/core_ext/string'
3
+ require 'net/http'
4
+ require "net/https"
5
+ require 'json'
6
+ require 'cgi'
7
+
8
+ module Mailjet
9
+ class ApiRequest
10
+ MAILJET_HOST = 'api.mailjet.com'
11
+
12
+ def initialize(method_name, params = {}, request_type = nil, auth_user = Mailjet.config.api_key, auth_password = Mailjet.config.secret_key)
13
+ @method_name = method_name.to_s.camelize(:lower)
14
+ @params = (params || {}).merge(:output => 'json')
15
+ @request_type = (request_type || guess_request_type).camelize
16
+ @auth_user = auth_user
17
+ @auth_password = auth_password
18
+ end
19
+
20
+ def response
21
+ @response ||= begin
22
+ http = Net::HTTP.new(MAILJET_HOST, request_port)
23
+ http.use_ssl = Mailjet.config.use_https
24
+ res = http.request(request)
25
+
26
+ case res
27
+ when Net::HTTPSuccess
28
+ JSON.parse(res.body || '{}')
29
+ when Net::HTTPNotModified
30
+ {"status" => "NotModified"}
31
+ else
32
+ raise ApiError.new(res.code, JSON.parse(res.body.presence || '{}'), request, request_path, @params)
33
+ end
34
+ end
35
+ end
36
+
37
+ private
38
+ def request
39
+ @request ||= begin
40
+ req = "Net::HTTP::#{@request_type}".constantize.new(request_path)
41
+ Net::HTTP::Get
42
+ req.basic_auth @auth_user, @auth_password
43
+ req.set_form_data(@params)
44
+ req
45
+ end
46
+ end
47
+
48
+ def request_path
49
+ @request_path ||= begin
50
+ path = "/#{Mailjet.config.api_version}/#{@method_name}"
51
+ if @request_type == 'Get'
52
+ path << '?' + @params.collect { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.join('&')
53
+ end
54
+ path
55
+ end
56
+ end
57
+
58
+ def request_port
59
+ Mailjet.config.use_https ? 443 : 80
60
+ end
61
+
62
+ def guess_request_type
63
+ if @method_name =~ /(?:Create|Add|Remove|Delete|Update)(?:[A-Z]|$)/
64
+ 'Post'
65
+ else
66
+ 'Get'
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,62 @@
1
+ require 'mailjet/api'
2
+ require 'mailjet/list'
3
+ require 'mailjet/contact'
4
+
5
+ module Mailjet
6
+ class Campaign < OpenStruct
7
+
8
+ def update(options = {})
9
+ (options.delete(:api) || Mailjet::Api.singleton).messageUpdatecampaign(options.reverse_merge(:id => self.id), 'Post')["status"]
10
+ end
11
+
12
+ def contacts(options = {})
13
+ ((options.delete(:api) || Mailjet::Api.singleton).messageContacts(options.reverse_merge(:id => self.stats_campaign_id))["result"] || []).map do |contact|
14
+ Mailjet::Contact.new(contact)
15
+ end
16
+ end
17
+
18
+ def send!(options = {})
19
+ (options.delete(:api) || Mailjet::Api.singleton).messageSendcampaign(options.reverse_merge(:id => self.id), 'Post')["status"]
20
+ end
21
+
22
+ def test(*params)
23
+ options = params.last.is_a?(Hash) ? params.pop : {}
24
+ email = params.first
25
+ (options.delete(:api) || Mailjet::Api.singleton).messageTestcampaign(options.reverse_merge(:id => self.id, :email => email), 'Post')["status"]
26
+ end
27
+
28
+ def statistics(options = {})
29
+ (options.delete(:api) || Mailjet::Api.singleton).messageStatistics(options.reverse_merge(:id => self.stats_campaign_id))["result"]
30
+ end
31
+
32
+ def html(options = {})
33
+ (options.delete(:api) || Mailjet::Api.singleton).messageHtmlcampaign(options.reverse_merge(:id => self.id))["html"]
34
+ end
35
+
36
+ def duplicate(options = {})
37
+ new_id = (options.delete(:api) || Mailjet::Api.singleton).messageDuplicatecampaign(options.reverse_merge(:id => self.id), 'Post')['new_id']
38
+ self.class.new(:id => new_id)
39
+ end
40
+
41
+ class << self
42
+ def create(options = {})
43
+ campaign_attr = (options.delete(:api) || Mailjet::Api.singleton).messageCreatecampaign(options, 'Post')["campaign"]
44
+ campaign = find(campaign_attr["id"]).tap{ |c| campaign_attr.each{ |k, v| c.send("#{k}=", v) } }
45
+ puts campaign.inspect
46
+ campaign
47
+ end
48
+
49
+ def all(options = {})
50
+ (options.delete(:api) || Mailjet::Api.singleton).messageCampaigns(options)["result"].map do |result_hash|
51
+ self.new(result_hash)
52
+ end
53
+ end
54
+
55
+ def find(*params)
56
+ options = params.last.is_a?(Hash) ? params.pop : {}
57
+ ids = params.flatten.map(&:to_s).reject(&:blank?)
58
+ self.all(options).find{|c| c.id.to_s.in?(ids)}
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,15 @@
1
+ require 'mailjet/api'
2
+ require 'mailjet/contact'
3
+ require 'mailjet/email'
4
+
5
+ module Mailjet
6
+ class Click < OpenStruct
7
+ def contact
8
+ Mailjet::Contact.new(:email => self.by_email, :id => self.by_id)
9
+ end
10
+
11
+ def email
12
+ Mailjet::Email.new(:id => self.email_id)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+
3
+ module Mailjet
4
+ module Configuration
5
+ mattr_accessor :api_version
6
+ mattr_accessor :api_key
7
+ mattr_accessor :secret_key
8
+ mattr_accessor :use_https
9
+ mattr_accessor :domain
10
+ mattr_accessor :default_from
11
+
12
+ @@use_https = true
13
+ @@api_version = 0.1
14
+ @@domain = ''
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'mailjet/api'
2
+
3
+ module Mailjet
4
+ class Contact < OpenStruct
5
+ def infos(options = {})
6
+ (options.delete(:api) || Mailjet::Api.singleton).contactInfos(options.reverse_merge(:contact => (self.id || self.email)))["contact"]
7
+ end
8
+
9
+ class << self
10
+ def all(options = {})
11
+ verb = options.delete(:openers) ? 'contactOpeners' : 'contactList'
12
+ (options.delete(:api) || Mailjet::Api.singleton).send(verb, options)["result"].map do |result_hash|
13
+ self.new(result_hash)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ class OpenStruct
2
+
3
+ # when asked for id, ruby 1.8.7's implementation of OpenStruct returns object's inner id instead of table's value if present. Evilishish infamous Monkey-Patch.
4
+ if RUBY_VERSION =~ /1\.8\./
5
+ def id
6
+ send(:eval, "@table[:id]")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ module Mailjet
2
+ class Email < OpenStruct
3
+ end
4
+ end
@@ -0,0 +1,52 @@
1
+ require 'mailjet/api'
2
+ require 'mailjet/contact'
3
+
4
+ module Mailjet
5
+ class List < OpenStruct
6
+ def update(options = {})
7
+ (options.delete(:api) || Mailjet::Api.singleton).listsUpdate(options.reverse_merge(:id => self.id), 'Post')["status"]
8
+ end
9
+
10
+ def add_contacts(*params)
11
+ options = params.last.is_a?(Hash) ? params.pop : {}
12
+ contacts = params.map{|p| p.is_a?(Mailjet::Contact) ? p.email.to_s : p.to_s }.reject(&:blank?)
13
+ (options.delete(:api) || Mailjet::Api.singleton).listsAddmanycontacts(options.reverse_merge(:contacts => contacts.to_json, :id => self.id), 'Post')["status"]
14
+ end
15
+
16
+ def remove_contacts(*params)
17
+ options = params.last.is_a?(Hash) ? params.pop : {}
18
+ contacts = params.map{|p| p.is_a?(Mailjet::Contact) ? p.email.to_s : p.to_s }.reject(&:blank?)
19
+ (options.delete(:api) || Mailjet::Api.singleton).listsRemovemanycontacts(options.reverse_merge(:contacts => contacts.to_json, :id => self.id), 'Post')["status"]
20
+ end
21
+
22
+ def contacts(options = {})
23
+ (options.delete(:api) || Mailjet::Api.singleton).listsContacts(options.reverse_merge(:id => self.id))["result"].map do |contact|
24
+ Mailjet::Contact.new(contact)
25
+ end
26
+ end
27
+
28
+ def email(options = {})
29
+ (options.delete(:api) || Mailjet::Api.singleton).listsEmail(options.reverse_merge(:id => self.id))["email"]
30
+ end
31
+
32
+ def statistics(options = {})
33
+ (options.delete(:api) || Mailjet::Api.singleton).listsStatistics(options.reverse_merge(:id => self.id))["statistics"]
34
+ end
35
+
36
+ def delete(options = {})
37
+ (options.delete(:api) || Mailjet::Api.singleton).listsDelete(options.reverse_merge(:id => self.id))["status"]
38
+ end
39
+
40
+ class << self
41
+ def create(options = {})
42
+ self.new(options.merge(:id => (options.delete(:api) || Mailjet::Api.singleton).listsCreate(options)["list_id"].to_s))
43
+ end
44
+
45
+ def all(options = {})
46
+ ((options.delete(:api) || Mailjet::Api.singleton).listsAll(options)["lists"] || []).map do |result_hash|
47
+ self.new(result_hash)
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,19 @@
1
+ require 'action_mailer'
2
+ require 'mail'
3
+
4
+ class Mailjet::Mailer < ::Mail::SMTP
5
+ def initialize options = {}
6
+ ActionMailer::Base.default(:from => Mailjet.config.default_from) if Mailjet.config.default_from.present?
7
+ super({
8
+ :address => "in.mailjet.com",
9
+ :port => 587,
10
+ :authentication => 'plain',
11
+ :user_name => Mailjet.config.api_key,
12
+ :password => Mailjet.config.secret_key,
13
+ :domain => Mailjet.config.domain,
14
+ :enable_starttls_auto => true
15
+ }.merge(options))
16
+ end
17
+ end
18
+
19
+ ActionMailer::Base.add_delivery_method :mailjet, Mailjet::Mailer
@@ -0,0 +1,24 @@
1
+ require 'active_support'
2
+ require 'rack/request'
3
+
4
+
5
+ module Mailjet
6
+ module Rack
7
+ class Endpoint
8
+ def initialize(app, path, &block)
9
+ @app = app
10
+ @path = path
11
+ @block = block
12
+ end
13
+
14
+ def call(env)
15
+ if env['PATH_INFO'] == @path && (content = env['rack.input'].read)
16
+ @block.call(ActiveSupport::JSON.decode(content))
17
+ [200, { 'Content-Type' => 'text/html', 'Content-Length' => '0' }, []]
18
+ else
19
+ @app.call(env)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,41 @@
1
+ require 'mailjet/api'
2
+ require 'mailjet/click'
3
+
4
+ module Mailjet
5
+ class Reporting
6
+ class << self
7
+ def clicks(options = {})
8
+ ((options.delete(:api) || Mailjet::Api.singleton).reportClick(options)["clicks"] || []).map do |click|
9
+ Mailjet::Click.new(click)
10
+ end
11
+ end
12
+
13
+ def domains(options = {})
14
+ (options.delete(:api) || Mailjet::Api.singleton).reportDomain(options)["domains"] || []
15
+ end
16
+
17
+ def clients(options = {})
18
+ (options.delete(:api) || Mailjet::Api.singleton).reportEmailclients(options)["email_clients"] || []
19
+ end
20
+
21
+ def emails(options = {})
22
+ ((options.delete(:api) || Mailjet::Api.singleton).reportEmailsent(options)["emails"] || []).map do |email|
23
+ Mailjet::Email.new(email)
24
+ end
25
+ end
26
+
27
+ def statistics(options = {})
28
+ (options.delete(:api) || Mailjet::Api.singleton).reportEmailstatistics(options)["stats"]
29
+ end
30
+
31
+ def geolocation(options = {})
32
+ (options.delete(:api) || Mailjet::Api.singleton).reportGeoip(options)["geos"]
33
+ end
34
+
35
+ def agents(options = {})
36
+ (options.delete(:api) || Mailjet::Api.singleton).reportUseragents(options)["user_agents"] || []
37
+ end
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,13 @@
1
+ require 'mailjet/api'
2
+
3
+ module Mailjet
4
+ class TemplateCategory < OpenStruct
5
+ class << self
6
+ def all(options = {})
7
+ (options.delete(:api) || Mailjet::Api.singleton).messageTplcategories(options)["categories"].map do |result_hash|
8
+ self.new(result_hash)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end