postageapp 0.0.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/LICENSE +1 -1
- data/README.md +176 -0
- data/Rakefile +14 -12
- data/VERSION +1 -1
- data/generators/postageapp/postageapp_generator.rb +34 -0
- data/generators/postageapp/templates/initializer.rb +3 -0
- data/generators/postageapp/templates/postageapp_tasks.rake +78 -0
- data/lib/generators/postageapp/postageapp_generator.rb +27 -0
- data/lib/postageapp.rb +56 -0
- data/lib/postageapp/configuration.rb +91 -0
- data/lib/postageapp/failed_request.rb +64 -0
- data/lib/postageapp/logger.rb +16 -0
- data/lib/postageapp/mailer.rb +48 -0
- data/lib/postageapp/mailer/mailer_2.rb +92 -0
- data/lib/postageapp/mailer/mailer_3.rb +192 -0
- data/lib/postageapp/rails.rb +14 -0
- data/lib/postageapp/request.rb +87 -0
- data/lib/postageapp/response.rb +39 -0
- data/lib/postageapp/utils.rb +30 -0
- data/lib/postageapp/version.rb +7 -0
- data/postageapp.gemspec +61 -7
- data/test/configuration_test.rb +66 -0
- data/test/failed_request_test.rb +79 -0
- data/test/helper.rb +66 -0
- data/test/mailer/action_mailer_2/notifier.rb +64 -0
- data/test/mailer/action_mailer_2/notifier/with_body_and_attachment.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_html_and_text_views.text.html.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_html_and_text_views.text.plain.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_simple_view.erb +1 -0
- data/test/mailer/action_mailer_2/notifier/with_text_only_view.text.plain.erb +1 -0
- data/test/mailer/action_mailer_3/notifier.rb +98 -0
- data/test/mailer/action_mailer_3/notifier/with_html_and_text_views.html.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_html_and_text_views.text.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_old_api.html.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_old_api.text.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_simple_view.erb +1 -0
- data/test/mailer/action_mailer_3/notifier/with_text_only_view.text.erb +1 -0
- data/test/mailer_2_test.rb +87 -0
- data/test/mailer_3_test.rb +104 -0
- data/test/mailer_helper_methods_test.rb +24 -0
- data/test/postageapp_test.rb +18 -0
- data/test/rails_initialization_test.rb +29 -0
- data/test/request_integration_test.rb +78 -0
- data/test/request_test.rb +81 -0
- data/test/response_test.rb +40 -0
- metadata +84 -9
- data/README.rdoc +0 -17
- data/test/test_postageapp.rb +0 -7
data/.gitignore
CHANGED
data/LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
PostageApp Gem
|
2
|
+
==============
|
3
|
+
|
4
|
+
This is the gem used to integrate Ruby apps with PostageApp service.
|
5
|
+
Personalized, mass email sending can be offloaded to PostageApp via JSON based API.
|
6
|
+
|
7
|
+
Problems, questions, suggestions? Please go to: [help.postageapp.com](http://help.postageapp.com)
|
8
|
+
|
9
|
+
Installation
|
10
|
+
------------
|
11
|
+
|
12
|
+
### Rails 3.x
|
13
|
+
Add postageapp gem to your Gemfile:
|
14
|
+
|
15
|
+
gem 'postageapp'
|
16
|
+
|
17
|
+
Then from the Rails project's root run:
|
18
|
+
|
19
|
+
bundle install
|
20
|
+
script/rails generate postageapp --api-key PROJECT_API_KEY
|
21
|
+
|
22
|
+
### Rails 2.x
|
23
|
+
In config/environment.rb add the following:
|
24
|
+
|
25
|
+
config.gem 'postageapp'
|
26
|
+
|
27
|
+
Then from the Rails project's root run:
|
28
|
+
|
29
|
+
rake gems:install
|
30
|
+
rake gems:unpack GEM=postageapp
|
31
|
+
script/generate postageapp --api-key PROJECT_API_KEY
|
32
|
+
|
33
|
+
### Sinatra / Rack / Others
|
34
|
+
You'll need to install the gem first:
|
35
|
+
|
36
|
+
$ sudo gem install postageapp
|
37
|
+
|
38
|
+
And then it's as simple as doing something like this:
|
39
|
+
|
40
|
+
require 'postageapp'
|
41
|
+
|
42
|
+
PostageApp.configure do |config|
|
43
|
+
config.api_key = 'PROJECT_API_KEY'
|
44
|
+
end
|
45
|
+
|
46
|
+
Usage
|
47
|
+
-----
|
48
|
+
Here's an example of sending a message ([See full API documentation](http://TODO/)):
|
49
|
+
|
50
|
+
request = PostageApp::Request.new(:send_message, {
|
51
|
+
'headers' => { 'from' => 'sender@example.com',
|
52
|
+
'subject' => 'Email Subject' },
|
53
|
+
'recipients' => 'recipient@example.com',
|
54
|
+
'content' => {
|
55
|
+
'text/plain' => 'text email content',
|
56
|
+
'text/html' => 'html email content'
|
57
|
+
}
|
58
|
+
})
|
59
|
+
response = request.send
|
60
|
+
|
61
|
+
`PostageApp::Response` object allows you to check the status:
|
62
|
+
|
63
|
+
>> response.status
|
64
|
+
=> 'ok'
|
65
|
+
|
66
|
+
Alternatively you may use:
|
67
|
+
|
68
|
+
>> response.fail?
|
69
|
+
=> false
|
70
|
+
>> response.ok?
|
71
|
+
=> true
|
72
|
+
|
73
|
+
Response usually comes back with data:
|
74
|
+
|
75
|
+
>> response.data
|
76
|
+
=> { 'message' => { 'id' => '12345' }}
|
77
|
+
|
78
|
+
### Recipient Override
|
79
|
+
Sometimes you don't want to send emails to real people in your application. For that there's an ability to override to what address all emails will be delivered. All you need to do is modify configuration block like this (in Rails projects it's usually found in `RAILS_ROOT/config/initializers/postageapp.rb`):
|
80
|
+
|
81
|
+
PostageApp.configure do |config|
|
82
|
+
config.api_key = 'PROJECT_API_KEY'
|
83
|
+
config.recipient_override = 'you@example.com' unless Rails.env.production?
|
84
|
+
end
|
85
|
+
|
86
|
+
ActionMailer Integration
|
87
|
+
------------------------
|
88
|
+
You can quickly convert your existing mailers to use PostageApp service by simply changing `class MyMailer < ActionMailer::Base` to `class MyMailer < PostageApp::Mailer`. And don't forget to `require 'postageapp/mailer'`
|
89
|
+
|
90
|
+
### Rails 3.x
|
91
|
+
|
92
|
+
Here's an example of a mailer in Rails 3 environment:
|
93
|
+
|
94
|
+
require 'postageapp/mailer'
|
95
|
+
|
96
|
+
class Notifier < PostageApp::Mailer
|
97
|
+
|
98
|
+
def signup_notification
|
99
|
+
|
100
|
+
attachments['example.zip'] = File.read('/path/to/example.zip')
|
101
|
+
|
102
|
+
headers['Special-Header'] = 'SpecialValue'
|
103
|
+
|
104
|
+
# PostageApp specific elements:
|
105
|
+
postage_template 'example_template'
|
106
|
+
postage_variables 'global_variable' => 'value'
|
107
|
+
|
108
|
+
mail(
|
109
|
+
:from => 'test@test.test',
|
110
|
+
:subject => 'Test Message',
|
111
|
+
:to => {
|
112
|
+
'recipient_1@example.com' => { 'variable' => 'value' },
|
113
|
+
'recipient_2@example.com' => { 'variable' => 'value' }
|
114
|
+
})
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
API of previous ActionMailer is partially supported under Rails 3 environment. Please note that it's not 100% integrated, some methods/syntax will not work. You may still define you mailers in this way (but really shouldn't):
|
119
|
+
|
120
|
+
require 'postageapp/mailer'
|
121
|
+
|
122
|
+
class Notifier < PostageApp::Mailer
|
123
|
+
|
124
|
+
def signup_notification
|
125
|
+
from 'test@test.test'
|
126
|
+
subject 'Test Email'
|
127
|
+
recipients 'test@test.test'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
### Rails 2.x
|
132
|
+
|
133
|
+
Here's an example of a mailer you'd set in in a Rails 2 environment:
|
134
|
+
|
135
|
+
require 'postageapp/mailer'
|
136
|
+
|
137
|
+
class Notifier < PostageApp::Mailer
|
138
|
+
def signup_notification
|
139
|
+
|
140
|
+
from 'system@example.com'
|
141
|
+
subject 'New Account Information'
|
142
|
+
|
143
|
+
# Recipients can be in any format API allows.
|
144
|
+
# Here's an example of a hash format
|
145
|
+
recipients ({
|
146
|
+
'recipient_1@example.com' => { 'variable_name_1' => 'value',
|
147
|
+
'variable_name_2' => 'value' },
|
148
|
+
'recipient_2@example.com' => { 'variable_name_1' => 'value',
|
149
|
+
'variable_name_2' => 'value' },
|
150
|
+
})
|
151
|
+
|
152
|
+
attachment :content_type => 'application/zip',
|
153
|
+
:filename => 'example.zip',
|
154
|
+
:body => File.read('/path/to/example.zip')
|
155
|
+
|
156
|
+
# PostageApp specific elements:
|
157
|
+
postage_template 'example_template'
|
158
|
+
postage_variables 'global_variable' => 'value'
|
159
|
+
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
Automatic resending in case of failure
|
164
|
+
--------------------------------------
|
165
|
+
For those ultra rare occasions when api.postageapp.com is not reachable this gem will temporarily store requests and then will attempt to resend them with the next successful connection. In Rails environment it will create a folder: `RAILS_ROOT/tmp/postageapp_failed_requests` and save all failed requests there. On successful resend file for that request will be deleted.
|
166
|
+
|
167
|
+
For projects other than Rails you'll need to tell where there project_root is at:
|
168
|
+
|
169
|
+
PostageApp.configure do |config|
|
170
|
+
config.api_key = 'PROJECT_API_KEY'
|
171
|
+
config.project_root = "/path/to/your/project"
|
172
|
+
end
|
173
|
+
|
174
|
+
Copyright
|
175
|
+
---------
|
176
|
+
(C) 2010 [The Working Group, Inc](http://www.twg.ca/)
|
data/Rakefile
CHANGED
@@ -4,23 +4,25 @@ require 'rake'
|
|
4
4
|
begin
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
|
-
gem.name
|
8
|
-
gem.summary
|
9
|
-
gem.description =
|
10
|
-
gem.email
|
11
|
-
gem.homepage
|
12
|
-
gem.authors
|
13
|
-
|
7
|
+
gem.name = 'postageapp'
|
8
|
+
gem.summary = 'Easier way to send email from web apps'
|
9
|
+
gem.description = 'Gem that interfaces with PostageApp.com service to send emails from web apps'
|
10
|
+
gem.email = 'oleg@twg.ca'
|
11
|
+
gem.homepage = 'http://github.com/theworkinggroup/postageapp-gem'
|
12
|
+
gem.authors = ['Oleg Khabarov, The Working Group Inc']
|
13
|
+
|
14
|
+
gem.add_dependency 'json', '1.2.4' # newer versions crash at the moment
|
15
|
+
gem.add_development_dependency 'mocha', '>= 0.9.8'
|
14
16
|
end
|
15
17
|
Jeweler::GemcutterTasks.new
|
16
18
|
rescue LoadError
|
17
|
-
puts
|
19
|
+
puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
|
18
20
|
end
|
19
21
|
|
20
22
|
require 'rake/testtask'
|
21
23
|
Rake::TestTask.new(:test) do |test|
|
22
24
|
test.libs << 'lib' << 'test'
|
23
|
-
test.pattern = 'test
|
25
|
+
test.pattern = 'test/**/*_test.rb'
|
24
26
|
test.verbose = true
|
25
27
|
end
|
26
28
|
|
@@ -28,12 +30,12 @@ begin
|
|
28
30
|
require 'rcov/rcovtask'
|
29
31
|
Rcov::RcovTask.new do |test|
|
30
32
|
test.libs << 'test'
|
31
|
-
test.pattern = 'test
|
33
|
+
test.pattern = 'test/**/*_test.rb'
|
32
34
|
test.verbose = true
|
33
35
|
end
|
34
36
|
rescue LoadError
|
35
37
|
task :rcov do
|
36
|
-
abort
|
38
|
+
abort 'RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov'
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
@@ -44,7 +46,7 @@ task :default => :test
|
|
44
46
|
require 'rake/rdoctask'
|
45
47
|
Rake::RDocTask.new do |rdoc|
|
46
48
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
47
|
-
|
49
|
+
|
48
50
|
rdoc.rdoc_dir = 'rdoc'
|
49
51
|
rdoc.title = "postageapp #{version}"
|
50
52
|
rdoc.rdoc_files.include('README*')
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1.0.0
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Wrapper around rake manifest
|
2
|
+
Rails::Generator::Commands::Create.class_eval do
|
3
|
+
def rake(command)
|
4
|
+
system "rake #{command}"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
# Rails 2 Generator
|
9
|
+
class PostageappGenerator < Rails::Generator::Base
|
10
|
+
|
11
|
+
def add_options!(opt)
|
12
|
+
opt.on('-k=key', '--api-key=key') do |value|
|
13
|
+
options[:api_key] = value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def manifest
|
18
|
+
if !options[:api_key]
|
19
|
+
puts 'Must pass --api-key with API key of your PostageApp.com project'
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
|
23
|
+
record do |m|
|
24
|
+
m.template 'initializer.rb', 'config/initializers/postageapp.rb',
|
25
|
+
:assigns => { :api_key => options[:api_key] },
|
26
|
+
:collision => :force
|
27
|
+
m.directory 'lib/tasks'
|
28
|
+
m.file 'postageapp_tasks.rake', 'lib/tasks/postageapp_tasks.rake',
|
29
|
+
:collision => :force
|
30
|
+
m.rake 'postageapp:test'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
namespace :postageapp do
|
2
|
+
|
3
|
+
desc 'Verify postageapp gem installation by requesting project info from PostageApp.com'
|
4
|
+
task :test => :environment do
|
5
|
+
|
6
|
+
puts "Attempting to contact #{PostageApp.configuration.host} ..."
|
7
|
+
response = PostageApp::Request.new(:get_project_info).send
|
8
|
+
|
9
|
+
if response.ok?
|
10
|
+
project_name = response.data['project']['name']
|
11
|
+
project_url = response.data['project']['url']
|
12
|
+
user_emails = response.data['project']['users']
|
13
|
+
|
14
|
+
puts %{
|
15
|
+
Found Project:
|
16
|
+
----------------------------
|
17
|
+
Name: #{ project_name }
|
18
|
+
URL: #{ project_url }
|
19
|
+
Users: #{ user_emails.keys.join(', ') }
|
20
|
+
}
|
21
|
+
|
22
|
+
# Sending test email to all users in the project
|
23
|
+
# Most likely a single user if it's a new project
|
24
|
+
puts 'Sending test message to users in the project...'
|
25
|
+
r = send_test_message(user_emails)
|
26
|
+
if r.ok?
|
27
|
+
puts "Message was successfully sent!\n\n"
|
28
|
+
puts 'Your application is ready to use PostageApp!'
|
29
|
+
else
|
30
|
+
puts 'Failed to send test message. Please try again. Check logs if issue persists.'
|
31
|
+
puts 'This was the response:'
|
32
|
+
puts r.to_yaml
|
33
|
+
end
|
34
|
+
|
35
|
+
else
|
36
|
+
puts 'Failed to fetch information about your project. This was the response:'
|
37
|
+
puts response.to_yaml
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
HTML_MESSAGE = %{
|
44
|
+
<h3> Hello {{name}}, </h3>
|
45
|
+
<p> This is a html message generated by Postage plugin. </p>
|
46
|
+
<p> If you received this message it means that your application is properly configured and is ready to use PostageApp service. </p>
|
47
|
+
<p> Thank you, </p>
|
48
|
+
<p> The PostageApp Team </p>
|
49
|
+
}
|
50
|
+
|
51
|
+
TEXT_MESSAGE = %{
|
52
|
+
Hello {{name}}
|
53
|
+
|
54
|
+
This is a plain text message generated by Postage plugin.
|
55
|
+
If you received this message it means that your application is properly configured and is ready to use PostageApp service.
|
56
|
+
|
57
|
+
Thank you,
|
58
|
+
The PostageApp Team
|
59
|
+
}
|
60
|
+
|
61
|
+
def send_test_message(recipients)
|
62
|
+
recipients_with_variables = {}
|
63
|
+
recipients.each do |email, name|
|
64
|
+
recipients_with_variables[email] = { 'name' => name }
|
65
|
+
end
|
66
|
+
|
67
|
+
PostageApp::Request.new(:send_message,
|
68
|
+
:message => {
|
69
|
+
'text/html' => HTML_MESSAGE,
|
70
|
+
'text/plain' => TEXT_MESSAGE
|
71
|
+
},
|
72
|
+
:recipients => recipients_with_variables,
|
73
|
+
:headers => {
|
74
|
+
'Subject' => '[PostageApp] Test Message',
|
75
|
+
'From' => 'no-return@postageapp.com'
|
76
|
+
}
|
77
|
+
).send
|
78
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
# Rails 3 Generator
|
4
|
+
class PostageappGenerator < Rails::Generators::Base
|
5
|
+
|
6
|
+
class_option :api_key, :aliases => ['-k=value', '--api-key=value'], :type => :string, :desc => 'Your PostageApp API key'
|
7
|
+
|
8
|
+
def self.source_root
|
9
|
+
@_hoptoad_source_root ||= File.expand_path('../../../../generators/postageapp/templates', __FILE__)
|
10
|
+
end
|
11
|
+
|
12
|
+
def install
|
13
|
+
if !options[:api_key]
|
14
|
+
puts 'Must pass --api-key with API key of your PostageApp.com project'
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
|
18
|
+
template 'initializer.rb', 'config/initializers/postageapp.rb'
|
19
|
+
copy_file 'postageapp_tasks.rake', 'lib/tasks/postageapp_tasks.rake'
|
20
|
+
puts run('rake postageapp:test')
|
21
|
+
end
|
22
|
+
|
23
|
+
def api_key
|
24
|
+
options[:api_key]
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
data/lib/postageapp.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'digest'
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
require 'postageapp/utils'
|
9
|
+
require 'postageapp/version'
|
10
|
+
require 'postageapp/configuration'
|
11
|
+
require 'postageapp/logger'
|
12
|
+
require 'postageapp/request'
|
13
|
+
require 'postageapp/failed_request'
|
14
|
+
require 'postageapp/response'
|
15
|
+
|
16
|
+
module PostageApp
|
17
|
+
|
18
|
+
class Error < StandardError ; end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
|
22
|
+
# Accessor for the PostageApp::Configuration object
|
23
|
+
attr_accessor :configuration
|
24
|
+
|
25
|
+
# Call this method to modify your configuration
|
26
|
+
#
|
27
|
+
# Example:
|
28
|
+
# PostageApp.configure do |config|
|
29
|
+
# config.api_key = '1234567890abcdef'
|
30
|
+
# config.recipient_override = 'test@test.test' if Rails.env.staging?
|
31
|
+
# end
|
32
|
+
def configure
|
33
|
+
self.configuration ||= Configuration.new
|
34
|
+
yield self.configuration
|
35
|
+
end
|
36
|
+
|
37
|
+
# Logger for the plugin
|
38
|
+
def logger
|
39
|
+
raise Error, 'Need configuration to be set before logger can be used' if !configuration
|
40
|
+
@logger ||= begin
|
41
|
+
configuration.logger || PostageApp::Logger.new(
|
42
|
+
if configuration.project_root
|
43
|
+
FileUtils.mkdir_p(File.join(File.expand_path(configuration.project_root), 'log'))
|
44
|
+
File.join(configuration.project_root, "log/postageapp_#{configuration.environment}.log")
|
45
|
+
else
|
46
|
+
STDOUT
|
47
|
+
end
|
48
|
+
)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Loading Rails hook
|
56
|
+
require 'postageapp/rails' if defined?(Rails)
|