diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a9c888f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,49 @@
+# rcov generated
+coverage
+coverage.data
+
+# rdoc generated
+rdoc
+
+# yard generated
+doc
+.yardoc
+
+# bundler
+.bundle
+
+# jeweler generated
+pkg
+
+# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
+#
+# * Create a file at ~/.gitignore
+# * Include files you want ignored
+# * Run: git config --global core.excludesfile ~/.gitignore
+#
+# After doing this, these files will be ignored in all your git projects,
+# saving you from having to 'pollute' every project you touch with them
+#
+# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
+#
+# For MacOS:
+#
+#.DS_Store
+
+# For TextMate
+#*.tmproj
+#tmtags
+
+# For emacs:
+#*~
+#\#*
+#.\#*
+
+# For vim:
+#*.swp
+
+# For redcar:
+#.redcar
+
+# For rubinius:
+#*.rbc
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..261da03
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+source "https://rubygems.org"
+
+# gem "rails"
+
+group :development do
+ gem "shoulda", ">= 0"
+ gem "rdoc", "~> 3.12"
+ gem "bundler", "~> 1.0"
+ gem "jeweler", "~> 2.3.0"
+ gem "simplecov", ">= 0"
+end
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..f5c2439
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,87 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ activesupport (5.1.1)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (~> 0.7)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ addressable (2.4.0)
+ builder (3.2.3)
+ concurrent-ruby (1.0.5)
+ descendants_tracker (0.0.4)
+ thread_safe (~> 0.3, >= 0.3.1)
+ docile (1.1.5)
+ faraday (0.9.2)
+ multipart-post (>= 1.2, < 3)
+ git (1.3.0)
+ github_api (0.16.0)
+ addressable (~> 2.4.0)
+ descendants_tracker (~> 0.0.4)
+ faraday (~> 0.8, < 0.10)
+ hashie (>= 3.4)
+ mime-types (>= 1.16, < 3.0)
+ oauth2 (~> 1.0)
+ hashie (3.5.5)
+ highline (1.7.8)
+ i18n (0.8.4)
+ jeweler (2.3.6)
+ builder
+ bundler (>= 1)
+ git (>= 1.2.5)
+ github_api (~> 0.16.0)
+ highline (>= 1.6.15)
+ nokogiri (>= 1.5.10)
+ psych (~> 2.2)
+ rake
+ rdoc
+ semver2
+ json (1.8.6)
+ jwt (1.5.6)
+ mime-types (2.99.3)
+ mini_portile2 (2.2.0)
+ minitest (5.10.2)
+ multi_json (1.12.1)
+ multi_xml (0.6.0)
+ multipart-post (2.0.0)
+ nokogiri (1.8.0)
+ mini_portile2 (~> 2.2.0)
+ oauth2 (1.3.1)
+ faraday (>= 0.8, < 0.12)
+ jwt (~> 1.0)
+ multi_json (~> 1.3)
+ multi_xml (~> 0.5)
+ rack (>= 1.2, < 3)
+ psych (2.2.4)
+ rack (2.0.3)
+ rake (12.0.0)
+ rdoc (3.12.2)
+ json (~> 1.4)
+ semver2 (3.4.2)
+ shoulda (3.5.0)
+ shoulda-context (~> 1.0, >= 1.0.1)
+ shoulda-matchers (>= 1.4.1, < 3.0)
+ shoulda-context (1.2.2)
+ shoulda-matchers (2.8.0)
+ activesupport (>= 3.0.0)
+ simplecov (0.14.1)
+ docile (~> 1.1.0)
+ json (>= 1.8, < 3)
+ simplecov-html (~> 0.10.0)
+ simplecov-html (0.10.1)
+ thread_safe (0.3.6)
+ tzinfo (1.2.3)
+ thread_safe (~> 0.1)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ bundler (~> 1.0)
+ jeweler (~> 2.3.0)
+ rdoc (~> 3.12)
+ shoulda
+ simplecov
+
+BUNDLED WITH
+ 1.15.1
diff --git a/README.md b/README.md
index 30a57ae..53a2d9b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,130 @@
# sendpulse-rest-api-ruby
+
A simple SendPulse REST client library and example for Ruby.
+
+Includes a REST API and a Rails ActionMailer Delivery Method using the REST API.
+
+## REST API Pre-requisites
+
+Please activate REST API and obtain your API Client ID and Secret values by following these instructions:
+- Login to login.sendpulse.com
+- Go to Account Settings -> API tab
+- Activate REST API (if not already activated).
+- Copy and paste ID and Secret from there
+
+## Setup Instructions
+
+### Ruby without Bundler
+
+Run the following command in your terminal:
+```bash
+gem install sendpulse-rest-api-ruby
+```
+
+Add the following require line to your ruby code:
+```ruby
+require 'sendpulse-rest-api-ruby'
+```
+
+### Rails or Ruby with Bundler
+
+Add the following to `Gemfile`:
+```ruby
+gem 'sendpulse-rest-api-ruby'
+```
+
+Run the following command in your terminal:
+
+```bash
+bundle
+```
+
+Outside of Rails, you'd have to add a require line like the one in "Ruby without Bundler".
+
+### Rails REST API Configuration
+
+In Rails, you'd also have to configure the `API_CLIENT_ID` and `API_CLIENT_SECRET` variables at minimum.
+
+It is recommended to do so by adding a Rails initializer as follows:
+- Under `config/initializers`, create a file named `sendpulse_initializer.rb`
+- Add the following code to it (entering the correct values):
+```ruby
+Sendpulse.configure do |config|
+ config.api_client_id = 'apiclientidvalue'
+ config.api_client_secret = 'apiclientsecretvalue'
+end
+```
+
+For use with Heroku, it is recommended you configure Rails initializer via environment variables as follows:
+
+```ruby
+Sendpulse.configure do |config|
+ config.api_client_id = ENV['SENDPULSE_API_CLIENT_ID']
+ config.api_client_secret = ENV['SENDPULSE_API_CLIENT_SECRET']
+end
+```
+
+Then run the following command to configure these environment variables in Heroku:
+```bash
+heroku config:add SENDPULSE_API_CLIENT_ID=apiclientidvalue SENDPULSE_API_CLIENT_SECRET=apiclientsecretvalue
+```
+
+### Rails ActionMailer Delivery Method Configuration
+
+This depends on Rails REST API Configuration being done.
+
+Simply set your `config.action_mailer.delivery_method` to `:sendpulse` in your environment config file.
+
+For example, you can add the following to `config/environments/production.rb` for production's deployment:
+```ruby
+config.action_mailer.delivery_method = :sendpulse
+```
+
+## API Example
+
+```ruby
+require 'sendpulse-rest-api-ruby'
+require 'yaml'
+
+API_CLIENT_ID = 'apiclientidvalue'
+API_CLIENT_SECRET = 'apiclientsecretvalue'
+API_PROTOCOL = 'https'
+API_TOKEN = ''
+
+sendpulse_api = SendpulseApi.new(API_CLIENT_ID, API_CLIENT_SECRET, API_PROTOCOL, API_TOKEN)
+
+result = sendpulse_api.get_token
+YAML::dump(result)
+
+result = sendpulse_api.create_campaign('Name', 'example@gmail.com', 'Example subject', 'Example', 'book_id') #+
+YAML::dump(result)
+
+result = sendpulse_api.add_sender('Some name', 'example@gmail.com')
+YAML::dump(result)
+
+result = sendpulse_api.get_balance
+YAML::dump(result)
+
+email = {
+ html: '
TEXT
',
+ text: 'TEST',
+ subject: 'Test, test test test',
+ from: { name: 'some', email: 'example@gmail.com' },
+ to: [
+ { name: 'some1', email: 'example1@gmail.com' },
+ { name: 'some3', email: 'example3@divermail.com' },
+ ],
+ bcc: [{ name: 'some2', email: 'example2@gmail.com' }]
+}
+
+result = sendpulse_api.smtp_send_mail(email)
+YAML::dump(result)
+```
+
+## License
+
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+Copyright 2015 SendPulse
+See `LICENSE` for more details.
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..5e2ac60
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,44 @@
+# encoding: utf-8
+
+require 'rubygems'
+require 'bundler'
+begin
+ Bundler.setup(:default, :development)
+rescue Bundler::BundlerError => e
+ $stderr.puts e.message
+ $stderr.puts "Run `bundle install` to install missing gems"
+ exit e.status_code
+end
+require 'rake'
+
+require 'jeweler'
+Jeweler::Tasks.new do |gem|
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
+ gem.name = "sendpulse-rest-api-ruby"
+ gem.homepage = "http://github.com/sendpulse/sendpulse-rest-api-ruby"
+ gem.license = "MIT"
+ gem.summary = %Q{A simple SendPulse REST client library and example for Ruby.}
+ gem.description = %Q{A simple SendPulse REST client library and example for Ruby.}
+ gem.email = "tech@sendpulse.com"
+ gem.authors = ["SendPulse Tech Team"]
+ # dependencies defined in Gemfile
+end
+Jeweler::RubygemsDotOrgTasks.new
+
+desc "Code coverage detail"
+task :simplecov do
+ ENV['COVERAGE'] = "true"
+ Rake::Task['test'].execute
+end
+
+task :default => :version #TODO change to test/rspec once added
+
+require 'rdoc/task'
+Rake::RDocTask.new do |rdoc|
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
+
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = "sendpulse-rest-api-ruby #{version}"
+ rdoc.rdoc_files.include('README*')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..3eefcb9
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+1.0.0
diff --git a/example.rb b/example.rb
index 69b1aed..6db26e9 100644
--- a/example.rb
+++ b/example.rb
@@ -1,4 +1,4 @@
-require './api/sendpulse_api'
+require_relative 'lib/sendpulse-rest-api-ruby'
require 'yaml'
API_CLIENT_ID = ''
@@ -33,4 +33,4 @@
}
result = sendpulse_api.smtp_send_mail(email)
-YAML::dump(result)
\ No newline at end of file
+YAML::dump(result)
diff --git a/lib/action_mailer/sendpulse.rb b/lib/action_mailer/sendpulse.rb
new file mode 100644
index 0000000..a1b74f8
--- /dev/null
+++ b/lib/action_mailer/sendpulse.rb
@@ -0,0 +1,15 @@
+module Sendpulse
+
+ def self.configuration
+ @configration ||= Configuration.new
+ end
+
+ def self.configure
+ yield(configuration)
+ end
+end
+
+require_relative 'sendpulse/configuration'
+require_relative 'sendpulse/delivery_method'
+require_relative 'sendpulse/message'
+require_relative 'sendpulse/railtie' if defined?(Rails::Railtie)
diff --git a/lib/action_mailer/sendpulse/configuration.rb b/lib/action_mailer/sendpulse/configuration.rb
new file mode 100644
index 0000000..1f78127
--- /dev/null
+++ b/lib/action_mailer/sendpulse/configuration.rb
@@ -0,0 +1,10 @@
+module Sendpulse
+ class Configuration
+ attr_accessor :api_client_id, :api_client_secret, :api_protocol, :options, :logger
+
+ def initialize
+ @api_protocol = 'https'
+ @logger = Rails.logger if defined?(Rails)
+ end
+ end
+end
diff --git a/lib/action_mailer/sendpulse/delivery_method.rb b/lib/action_mailer/sendpulse/delivery_method.rb
new file mode 100644
index 0000000..c6b9a2c
--- /dev/null
+++ b/lib/action_mailer/sendpulse/delivery_method.rb
@@ -0,0 +1,43 @@
+require "digest/sha1"
+begin
+ require "mail"
+ require "mail/check_delivery_params"
+ require 'sendpulse-rest-api-ruby'
+rescue LoadError
+end
+
+module Sendpulse
+ class DeliveryMethod
+ include Mail::CheckDeliveryParams if defined?(Mail::CheckDeliveryParams)
+
+ class InvalidOption < StandardError; end
+
+ attr_accessor :settings
+
+ def initialize(options={})
+ Sendpulse.configuration.options = options
+ self.settings = Sendpulse.configuration
+ end
+
+ def deliver!(mail)
+ check_delivery_params(mail) if respond_to?(:check_delivery_params)
+ api_client_id = settings.api_client_id
+ api_client_secret = settings.api_client_secret
+ api_protocol = settings.api_protocol
+
+ sendpulse_api = SendpulseApi.new(api_client_id, api_client_secret, api_protocol)
+
+ email = {
+ html: mail.html_part.decoded,
+ text: mail.html_part.encoded,
+ subject: mail.subject,
+ from: { name: mail.from.first, email: mail.from_addrs.first },
+ to: mail.to_addrs.map {|addrs| {name: addrs, email: addrs}},
+ bcc: mail.bcc_addrs.map {|addrs| {name: addrs, email: addrs}}
+ }
+
+ result = sendpulse_api.smtp_send_mail(email)
+ settings.logger.info("[sendpulse_api.smtp_send_mail] result:\n#{YAML::dump(result)}") if settings.logger
+ end
+ end
+end
diff --git a/lib/action_mailer/sendpulse/message.rb b/lib/action_mailer/sendpulse/message.rb
new file mode 100644
index 0000000..9bd6a50
--- /dev/null
+++ b/lib/action_mailer/sendpulse/message.rb
@@ -0,0 +1,125 @@
+require "cgi"
+require "erb"
+require "fileutils"
+require "uri"
+
+module Sendpulse
+ class Message
+ attr_reader :mail
+
+ def self.rendered_messages(mail, options = {})
+ messages = []
+ messages << new(mail, options.merge(part: mail.html_part)) if mail.html_part
+ messages << new(mail, options.merge(part: mail.text_part)) if mail.text_part
+ messages << new(mail, options) if messages.empty?
+ messages.each(&:render)
+ messages.sort
+ end
+
+ def initialize(mail, options = {})
+ @mail = mail
+ @location = options[:location]
+ @part = options[:part]
+ @template = options[:message_template]
+ @attachments = []
+ end
+
+ def render
+ FileUtils.mkdir_p(@location)
+
+ if mail.attachments.any?
+ attachments_dir = File.join(@location, 'attachments')
+ FileUtils.mkdir_p(attachments_dir)
+ mail.attachments.each do |attachment|
+ filename = attachment_filename(attachment)
+ path = File.join(attachments_dir, filename)
+
+ unless File.exist?(path) # true if other parts have already been rendered
+ File.open(path, 'wb') { |f| f.write(attachment.body.raw_source) }
+ end
+
+ @attachments << [attachment.filename, "attachments/#{CGI.escape(filename)}"]
+ end
+ end
+
+ File.open(filepath, 'w') do |f|
+ f.write ERB.new(template).result(binding)
+ end
+ end
+
+ def template
+ File.read(File.expand_path("../templates/#{@template}.html.erb", __FILE__))
+ end
+
+ def filepath
+ File.join(@location, "#{type}.html")
+ end
+
+ def content_type
+ @part && @part.content_type || @mail.content_type
+ end
+
+ def body
+ @body ||= begin
+ body = (@part || @mail).decoded
+
+ mail.attachments.each do |attachment|
+ body.gsub!(attachment.url, "attachments/#{attachment_filename(attachment)}")
+ end
+
+ body
+ end
+ end
+
+ def from
+ @from ||= Array(@mail['from']).join(", ")
+ end
+
+ def sender
+ @sender ||= Array(@mail['sender']).join(", ")
+ end
+
+ def to
+ @to ||= Array(@mail['to']).join(", ")
+ end
+
+ def cc
+ @cc ||= Array(@mail['cc']).join(", ")
+ end
+
+ def bcc
+ @bcc ||= Array(@mail['bcc']).join(", ")
+ end
+
+ def reply_to
+ @reply_to ||= Array(@mail['reply-to']).join(", ")
+ end
+
+ def type
+ content_type =~ /html/ ? "rich" : "plain"
+ end
+
+ def encoding
+ body.respond_to?(:encoding) ? body.encoding : "utf-8"
+ end
+
+ def auto_link(text)
+ text.gsub(URI::Parser.new.make_regexp(%W[https http])) do |link|
+ "#{ link }"
+ end
+ end
+
+ def h(content)
+ CGI.escapeHTML(content)
+ end
+
+ def attachment_filename(attachment)
+ attachment.filename.gsub(/[^\w\-_.]/, '_')
+ end
+
+ def <=>(other)
+ order = %w[rich plain]
+ order.index(type) <=> order.index(other.type)
+ end
+ end
+end
diff --git a/lib/action_mailer/sendpulse/railtie.rb b/lib/action_mailer/sendpulse/railtie.rb
new file mode 100644
index 0000000..b503349
--- /dev/null
+++ b/lib/action_mailer/sendpulse/railtie.rb
@@ -0,0 +1,12 @@
+module Sendpulse
+ class Railtie < Rails::Railtie
+ initializer "sendpulse.add_delivery_method" do
+ ActiveSupport.on_load :action_mailer do
+ ActionMailer::Base.add_delivery_method(
+ :sendpulse,
+ Sendpulse::DeliveryMethod
+ )
+ end
+ end
+ end
+end
diff --git a/api/sendpulse_api.rb b/lib/api/sendpulse_api.rb
similarity index 99%
rename from api/sendpulse_api.rb
rename to lib/api/sendpulse_api.rb
index f1405aa..c9abd48 100644
--- a/api/sendpulse_api.rb
+++ b/lib/api/sendpulse_api.rb
@@ -114,7 +114,7 @@ def send_request(path, method = 'GET', data = {}, use_token = true)
http.use_ssl = true if @protocol == 'https'
token = {}
- token.merge!( 'authorization' => @token ) if use_token
+ token.merge!( 'Authorization' => "Bearer #{@token}" ) if use_token
case method
when 'POST'
@@ -637,4 +637,4 @@ def smtp_send_mail(email)
send_request('smtp/emails', 'POST', data)
end
-end
\ No newline at end of file
+end
diff --git a/lib/sendpulse-rest-api-ruby.rb b/lib/sendpulse-rest-api-ruby.rb
new file mode 100644
index 0000000..953369f
--- /dev/null
+++ b/lib/sendpulse-rest-api-ruby.rb
@@ -0,0 +1,2 @@
+require_relative 'api/sendpulse_api.rb'
+require_relative 'action_mailer/sendpulse.rb'
diff --git a/sendpulse-rest-api-ruby.gemspec b/sendpulse-rest-api-ruby.gemspec
new file mode 100644
index 0000000..247da51
--- /dev/null
+++ b/sendpulse-rest-api-ruby.gemspec
@@ -0,0 +1,61 @@
+# Generated by jeweler
+# DO NOT EDIT THIS FILE DIRECTLY
+# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
+# -*- encoding: utf-8 -*-
+# stub: sendpulse-rest-api-ruby 1.0.0 ruby lib
+
+Gem::Specification.new do |s|
+ s.name = "sendpulse-rest-api-ruby".freeze
+ s.version = "1.0.0"
+
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
+ s.require_paths = ["lib".freeze]
+ s.authors = ["SendPulse Tech Team".freeze]
+ s.date = "2017-06-09"
+ s.description = "A simple SendPulse REST client library and example for Ruby.".freeze
+ s.email = "tech@sendpulse.com".freeze
+ s.extra_rdoc_files = [
+ "LICENSE",
+ "README.md"
+ ]
+ s.files = [
+ "Gemfile",
+ "Gemfile.lock",
+ "LICENSE",
+ "README.md",
+ "Rakefile",
+ "VERSION",
+ "example.rb",
+ "lib/api/sendpulse_api.rb",
+ "lib/sendpulse-rest-api-ruby.rb"
+ ]
+ s.homepage = "http://github.com/sendpulse/sendpulse-rest-api-ruby".freeze
+ s.licenses = ["MIT".freeze]
+ s.rubygems_version = "2.6.12".freeze
+ s.summary = "A simple SendPulse REST client library and example for Ruby.".freeze
+
+ if s.respond_to? :specification_version then
+ s.specification_version = 4
+
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
+ s.add_development_dependency(%q.freeze, [">= 0"])
+ s.add_development_dependency(%q.freeze, ["~> 3.12"])
+ s.add_development_dependency(%q.freeze, ["~> 1.0"])
+ s.add_development_dependency(%q.freeze, ["~> 2.3.0"])
+ s.add_development_dependency(%q.freeze, [">= 0"])
+ else
+ s.add_dependency(%q.freeze, [">= 0"])
+ s.add_dependency(%q.freeze, ["~> 3.12"])
+ s.add_dependency(%q.freeze, ["~> 1.0"])
+ s.add_dependency(%q.freeze, ["~> 2.3.0"])
+ s.add_dependency(%q.freeze, [">= 0"])
+ end
+ else
+ s.add_dependency(%q.freeze, [">= 0"])
+ s.add_dependency(%q.freeze, ["~> 3.12"])
+ s.add_dependency(%q.freeze, ["~> 1.0"])
+ s.add_dependency(%q.freeze, ["~> 2.3.0"])
+ s.add_dependency(%q.freeze, [">= 0"])
+ end
+end
+