mailjet 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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