Commit 3d2cc9a9ae6191cb65658b538cca31e855d858bd
1 parent
95a78db4
Exists in
master
init
Showing
13 changed files
with
235 additions
and
1 deletions
Show diff stats
LICENSE
... | ... | @@ -0,0 +1,20 @@ |
1 | +Copyright 2016 Towon Zhou | |
2 | + | |
3 | +Permission is hereby granted, free of charge, to any person obtaining | |
4 | +a copy of this software and associated documentation files (the | |
5 | +"Software"), to deal in the Software without restriction, including | |
6 | +without limitation the rights to use, copy, modify, merge, publish, | |
7 | +distribute, sublicense, and/or sell copies of the Software, and to | |
8 | +permit persons to whom the Software is furnished to do so, subject to | |
9 | +the following conditions: | |
10 | + | |
11 | +The above copyright notice and this permission notice shall be | |
12 | +included in all copies or substantial portions of the Software. | |
13 | + | |
14 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
15 | +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
16 | +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
17 | +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
18 | +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
19 | +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
20 | +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ... | ... |
... | ... | @@ -0,0 +1,23 @@ |
1 | +begin | |
2 | + require 'bundler/setup' | |
3 | +rescue LoadError | |
4 | + puts 'You must `gem install bundler` and `bundle install` to run rake tasks' | |
5 | +end | |
6 | + | |
7 | +require 'rdoc/task' | |
8 | + | |
9 | +RDoc::Task.new(:rdoc) do |rdoc| | |
10 | + rdoc.rdoc_dir = 'rdoc' | |
11 | + rdoc.title = 'Rails' | |
12 | + rdoc.options << '--line-numbers' | |
13 | + rdoc.rdoc_files.include('README.rdoc') | |
14 | + rdoc.rdoc_files.include('lib/**/*.rb') | |
15 | +end | |
16 | + | |
17 | +Bundler::GemHelper.install_tasks | |
18 | + | |
19 | +require 'rspec/core/rake_task' | |
20 | + | |
21 | +RSpec::Core::RakeTask.new(:spec) | |
22 | + | |
23 | +task default: :spec | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +module Sendcloud | |
2 | + class Attachment < StringIO | |
3 | + attr_reader :original_filename, :content_type, :path | |
4 | + | |
5 | + def initialize (attachment, *rest) | |
6 | + @path = '' | |
7 | + if rest.detect {|opt| opt[:inline] } | |
8 | + basename = @original_filename = attachment.cid | |
9 | + else | |
10 | + basename = @original_filename = attachment.filename | |
11 | + end | |
12 | + @content_type = attachment.content_type.split(';')[0] | |
13 | + super attachment.body.decoded | |
14 | + end | |
15 | + end | |
16 | +end | ... | ... |
... | ... | @@ -0,0 +1,24 @@ |
1 | +require 'rest_client' | |
2 | + | |
3 | +module Sendcloud | |
4 | + class Client | |
5 | + attr_reader :api_key, :domain | |
6 | + | |
7 | + def initialize(api_key, domain) | |
8 | + @api_key = api_key | |
9 | + @domain = domain | |
10 | + end | |
11 | + | |
12 | + def send_message(options) | |
13 | + RestClient.post sendcloud_url, options | |
14 | + end | |
15 | + | |
16 | + def sendcloud_url | |
17 | + api_url+"/messages" | |
18 | + end | |
19 | + | |
20 | + def api_url | |
21 | + "http://api.sendcloud.net/apiv2/mail" | |
22 | + end | |
23 | + end | |
24 | +end | ... | ... |
... | ... | @@ -0,0 +1,94 @@ |
1 | +module Sendcloud | |
2 | + class Deliverer | |
3 | + | |
4 | + attr_accessor :settings | |
5 | + | |
6 | + def initialize(settings) | |
7 | + self.settings = settings | |
8 | + end | |
9 | + | |
10 | + def domain | |
11 | + self.settings[:domain] | |
12 | + end | |
13 | + | |
14 | + def api_key | |
15 | + self.settings[:api_key] | |
16 | + end | |
17 | + | |
18 | + def deliver!(rails_message) | |
19 | + response = sendcloud_client.send_message build_sendcloud_message_for(rails_message) | |
20 | + if response.code == 200 | |
21 | + sendcloud_message_id = JSON.parse(response.to_str)["id"] | |
22 | + rails_message.message_id = sendcloud_message_id | |
23 | + end | |
24 | + response | |
25 | + end | |
26 | + | |
27 | + private | |
28 | + | |
29 | + def build_sendcloud_message_for(rails_message) | |
30 | + sendcloud_message = build_basic_sendcloud_message_for rails_message | |
31 | + #transform_sendcloud_attributes_from_rails rails_message, sendcloud_message | |
32 | + remove_empty_values sendcloud_message | |
33 | + | |
34 | + sendcloud_message | |
35 | + end | |
36 | + | |
37 | + def build_basic_sendcloud_message_for(rails_message) | |
38 | + sendcloud_message = { | |
39 | + from: rails_message[:from].formatted, | |
40 | + to: rails_message[:to].formatted, | |
41 | + subject: rails_message.subject, | |
42 | + html: extract_html(rails_message), | |
43 | + text: extract_text(rails_message) | |
44 | + } | |
45 | + | |
46 | + [:cc, :bcc].each do |key| | |
47 | + sendcloud_message[key] = rails_message[key].formatted if rails_message[key] | |
48 | + end | |
49 | + | |
50 | + return sendcloud_message | |
51 | + end | |
52 | + | |
53 | + def transform_sendcloud_attributes_from_rails(rails_message, sendcloud_message) | |
54 | + transform_reply_to rails_message, sendcloud_message if rails_message.reply_to | |
55 | + transform_custom_headers rails_message, sendcloud_message | |
56 | + end | |
57 | + | |
58 | + def transform_reply_to(rails_message, sendcloud_message) | |
59 | + sendcloud_message['h:Reply-To'] = rails_message[:reply_to].formatted.first | |
60 | + end | |
61 | + | |
62 | + def extract_html(rails_message) | |
63 | + if rails_message.html_part | |
64 | + rails_message.html_part.body.decoded | |
65 | + else | |
66 | + rails_message.content_type =~ /text\/html/ ? rails_message.body.decoded : nil | |
67 | + end | |
68 | + end | |
69 | + | |
70 | + def extract_text(rails_message) | |
71 | + if rails_message.multipart? | |
72 | + rails_message.text_part ? rails_message.text_part.body.decoded : nil | |
73 | + else | |
74 | + rails_message.content_type =~ /text\/plain/ ? rails_message.body.decoded : nil | |
75 | + end | |
76 | + end | |
77 | + | |
78 | + def transform_custom_headers(rails_message, sendcloud_message) | |
79 | + rails_message.sendcloud_headers.try(:each) do |name, value| | |
80 | + sendcloud_message["h:#{name}"] = value | |
81 | + end | |
82 | + end | |
83 | + | |
84 | + def remove_empty_values(sendcloud_message) | |
85 | + sendcloud_message.delete_if { |key, value| value.nil? } | |
86 | + end | |
87 | + | |
88 | + def sendcloud_client | |
89 | + @sendcloud_client ||= Client.new(api_key, domain) | |
90 | + end | |
91 | + end | |
92 | +end | |
93 | + | |
94 | +ActionMailer::Base.add_delivery_method :sendcloud, Sendcloud::Deliverer | ... | ... |
... | ... | @@ -0,0 +1,26 @@ |
1 | +$:.push File.expand_path("../lib", __FILE__) | |
2 | + | |
3 | +# Maintain your gem's version: | |
4 | +require "sendcloud/version" | |
5 | + | |
6 | +# Describe your gem and declare its dependencies: | |
7 | +Gem::Specification.new do |s| | |
8 | + s.name = "sendcloud_rails" | |
9 | + s.version = Sendcloud::VERSION | |
10 | + s.authors = ["Towon Zhou"] | |
11 | + s.email = ["towonzhou@gmail.com"] | |
12 | + s.homepage = "" | |
13 | + s.summary = "Rails Action Mailer adapter for Sendcloud" | |
14 | + s.description = "An adapter for using Sendcloud with Rails and Action Mailer" | |
15 | + s.license = 'MIT' | |
16 | + | |
17 | + s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.rdoc"] | |
18 | + s.test_files = Dir["test/**/*"] | |
19 | + | |
20 | + s.add_dependency "actionmailer", ">= 3.2.13" | |
21 | + s.add_dependency "json", ">= 1.7.7" | |
22 | + s.add_dependency "rest-client", ">= 1.6.7" | |
23 | + | |
24 | + s.add_development_dependency "rspec", '~> 2.14.1' | |
25 | + s.add_development_dependency "rails", ">= 3.2.13" | |
26 | +end | ... | ... |