madmimi 1.0.14 → 1.0.15
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/README.rdoc +8 -0
- data/VERSION +1 -1
- data/lib/madmimi.rb +62 -21
- data/madmimi.gemspec +2 -2
- data/test/helper.rb +1 -1
- data/test/test_madmimi.rb +31 -1
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -15,6 +15,8 @@ mimi = MadMimi.new('emailaddress', 'api_key')
|
|
15
15
|
|
16
16
|
mimi.lists -> get all of your Mad Mimi lists returned as a hash
|
17
17
|
|
18
|
+
=== Audience Members and Lists
|
19
|
+
|
18
20
|
mimi.memberships('email') -> returns a hash of the lists that specific email address is subscribed to
|
19
21
|
|
20
22
|
mimi.new_list('New list name') -> make a new list
|
@@ -29,8 +31,12 @@ mimi.remove_from_list('dave@example.com', 'Test List') -> remove this email addr
|
|
29
31
|
|
30
32
|
mimi.suppressed_since('unix timestamp') -> get a TXT of all addresses that were suppressed since this timestamp
|
31
33
|
|
34
|
+
=== Promotions
|
35
|
+
|
32
36
|
mimi.promotions -> returns a hash of your promotions
|
33
37
|
|
38
|
+
mimi.save_promotion('promotion_name', 'raw_html', 'plain_text') -> saves a promotion (creates the promotion if it does not exist)
|
39
|
+
|
34
40
|
mimi.mailing_stats('promotion_id', 'mailing_id') -> get stats on a specific mailing
|
35
41
|
|
36
42
|
== Sending E-Mail (using the Mailer API)
|
@@ -84,6 +90,8 @@ If it exists and you specify raw_html, the promotion body will be replaced.
|
|
84
90
|
'list_name': For all of the #send methods, if 'list_name' is provided, the recipients
|
85
91
|
will be those for an already-existing "audience."
|
86
92
|
|
93
|
+
'to_all': Set to true to send a promotion, plain_text or raw_html to all your audience members
|
94
|
+
|
87
95
|
== Note on Patches/Pull Requests
|
88
96
|
|
89
97
|
* Fork the project.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.15
|
data/lib/madmimi.rb
CHANGED
@@ -37,17 +37,23 @@ class MadMimi
|
|
37
37
|
class MadMimiError < StandardError; end
|
38
38
|
|
39
39
|
BASE_URL = 'api.madmimi.com'
|
40
|
+
|
40
41
|
NEW_LISTS_PATH = '/audience_lists'
|
41
42
|
AUDIENCE_MEMBERS_PATH = '/audience_members'
|
42
43
|
AUDIENCE_LISTS_PATH = '/audience_lists/lists.xml'
|
43
44
|
MEMBERSHIPS_PATH = '/audience_members/%email%/lists.xml'
|
44
45
|
SUPPRESSED_SINCE_PATH = '/audience_members/suppressed_since/%timestamp%.txt'
|
45
46
|
SUPPRESS_USER_PATH = ' /audience_members/%email%/suppress_email'
|
47
|
+
SEARCH_PATH = '/audience_members/search.xml'
|
48
|
+
|
46
49
|
PROMOTIONS_PATH = '/promotions.xml'
|
50
|
+
PROMOTION_SAVE_PATH = '/promotions/save'
|
51
|
+
|
47
52
|
MAILING_STATS_PATH = '/promotions/%promotion_id%/mailings/%mailing_id%.xml'
|
48
|
-
|
53
|
+
|
49
54
|
MAILER_PATH = '/mailer'
|
50
55
|
MAILER_TO_LIST_PATH = '/mailer/to_list'
|
56
|
+
MAILER_TO_ALL_PATH = '/mailer/to_all'
|
51
57
|
MAILER_STATUS_PATH = '/mailers/status'
|
52
58
|
|
53
59
|
def initialize(username, api_key)
|
@@ -66,6 +72,7 @@ class MadMimi
|
|
66
72
|
{ :username => username, :api_key => api_key }
|
67
73
|
end
|
68
74
|
|
75
|
+
# Audience and lists
|
69
76
|
def lists
|
70
77
|
request = do_request(AUDIENCE_LISTS_PATH, :get)
|
71
78
|
Crack::XML.parse(request)
|
@@ -109,49 +116,69 @@ class MadMimi
|
|
109
116
|
do_request(SUPPRESS_USER_PATH.gsub('%email%', email), :post)
|
110
117
|
end
|
111
118
|
|
119
|
+
def audience_search(query_string, raw = false)
|
120
|
+
request = do_request(SEARCH_PATH, :get, :raw => raw, :query => query_string)
|
121
|
+
Crack::XML.parse(request)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Not the most elegant, but it works for now. :)
|
125
|
+
def add_users_to_list(list_name, arr)
|
126
|
+
arr.each do |a|
|
127
|
+
a[:add_list] = list_name
|
128
|
+
add_user(a)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Promotions
|
112
133
|
def promotions
|
113
134
|
request = do_request(PROMOTIONS_PATH, :get)
|
114
135
|
Crack::XML.parse(request)
|
115
136
|
end
|
116
|
-
|
137
|
+
|
138
|
+
def save_promotion(promotion_name, raw_html, plain_text = nil)
|
139
|
+
options = { :promotion_name => promotion_name }
|
140
|
+
|
141
|
+
unless raw_html.nil?
|
142
|
+
check_for_tracking_beacon raw_html
|
143
|
+
check_for_opt_out raw_html
|
144
|
+
options[:raw_html] = raw_html
|
145
|
+
end
|
146
|
+
|
147
|
+
unless plain_text.nil?
|
148
|
+
check_for_opt_out plain_text
|
149
|
+
options[:raw_plain_text] = plain_text
|
150
|
+
end
|
151
|
+
|
152
|
+
do_request PROMOTION_SAVE_PATH, :post, options
|
153
|
+
end
|
154
|
+
|
155
|
+
# Stats
|
117
156
|
def mailing_stats(promotion_id, mailing_id)
|
118
157
|
path = MAILING_STATS_PATH.gsub('%promotion_id%', promotion_id).gsub('%mailing_id%', mailing_id)
|
119
158
|
request = do_request(path, :get)
|
120
159
|
Crack::XML.parse(request)
|
121
160
|
end
|
122
161
|
|
123
|
-
|
124
|
-
request = do_request(SEARCH_PATH, :get, :raw => raw, :query => query_string)
|
125
|
-
Crack::XML.parse(request)
|
126
|
-
end
|
127
|
-
|
162
|
+
# Mailer API
|
128
163
|
def send_mail(opt, yaml_body)
|
129
164
|
options = opt.dup
|
130
165
|
options[:body] = yaml_body.to_yaml
|
131
|
-
if !options[:list_name].nil?
|
132
|
-
do_request(MAILER_TO_LIST_PATH, :post, options, true)
|
166
|
+
if !options[:list_name].nil? || options[:to_all]
|
167
|
+
do_request(options[:to_all] ? MAILER_TO_ALL_PATH : MAILER_TO_LIST_PATH, :post, options, true)
|
133
168
|
else
|
134
169
|
do_request(MAILER_PATH, :post, options, true)
|
135
170
|
end
|
136
171
|
end
|
137
172
|
|
138
|
-
# Not the most elegant, but it works for now. :)
|
139
|
-
def add_users_to_list(list_name, arr)
|
140
|
-
arr.each do |a|
|
141
|
-
a[:add_list] = list_name
|
142
|
-
add_user(a)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
173
|
def send_html(opt, html)
|
147
174
|
options = opt.dup
|
148
175
|
if html.include?('[[tracking_beacon]]') || html.include?('[[peek_image]]')
|
149
176
|
options[:raw_html] = html
|
150
|
-
if !options[:list_name].nil?
|
177
|
+
if !options[:list_name].nil? || options[:to_all]
|
151
178
|
unless html.include?('[[unsubscribe]]') || html.include?('[[opt_out]]')
|
152
179
|
raise MadMimiError, "When specifying list_name, include the [[unsubscribe]] or [[opt_out]] macro in your HTML before sending."
|
153
180
|
end
|
154
|
-
do_request(MAILER_TO_LIST_PATH, :post, options, true)
|
181
|
+
do_request(options[:to_all] ? MAILER_TO_ALL_PATH : MAILER_TO_LIST_PATH, :post, options, true)
|
155
182
|
else
|
156
183
|
do_request(MAILER_PATH, :post, options, true)
|
157
184
|
end
|
@@ -163,9 +190,9 @@ class MadMimi
|
|
163
190
|
def send_plaintext(opt, plaintext)
|
164
191
|
options = opt.dup
|
165
192
|
options[:raw_plain_text] = plaintext
|
166
|
-
if !options[:list_name].nil?
|
193
|
+
if !options[:list_name].nil? || options[:to_all]
|
167
194
|
if plaintext.include?('[[unsubscribe]]') || plaintext.include?('[[opt_out]]')
|
168
|
-
do_request(MAILER_TO_LIST_PATH, :post, options, true)
|
195
|
+
do_request(options[:to_all] ? MAILER_TO_ALL_PATH : MAILER_TO_LIST_PATH, :post, options, true)
|
169
196
|
else
|
170
197
|
raise MadMimiError, "You'll need to include either the [[unsubscribe]] or [[opt_out]] macro in your text before sending."
|
171
198
|
end
|
@@ -235,4 +262,18 @@ class MadMimi
|
|
235
262
|
end
|
236
263
|
end
|
237
264
|
end
|
265
|
+
|
266
|
+
def check_for_tracking_beacon(content)
|
267
|
+
unless content.include?('[[tracking_beacon]]') || content.include?('[[peek_image]]')
|
268
|
+
raise MadMimiError, "You'll need to include either the [[tracking_beacon]] or [[peek_image]] macro in your HTML before sending."
|
269
|
+
end
|
270
|
+
true
|
271
|
+
end
|
272
|
+
|
273
|
+
def check_for_opt_out(content)
|
274
|
+
unless content.include?('[[opt_out]]') || content.include?('[[unsubscribe]]')
|
275
|
+
raise MadMimiError, "When specifying list_name or sending to all, include the [[unsubscribe]] or [[opt_out]] macro in your HTML before sending."
|
276
|
+
end
|
277
|
+
true
|
278
|
+
end
|
238
279
|
end
|
data/madmimi.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{madmimi}
|
8
|
-
s.version = "1.0.
|
8
|
+
s.version = "1.0.15"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Nicholas Young", "Marc Heiligers"]
|
12
|
-
s.date = %q{2011-03-
|
12
|
+
s.date = %q{2011-03-21}
|
13
13
|
s.description = %q{Send emails, track statistics, and manage your subscriber base with ease.}
|
14
14
|
s.email = %q{nicholas@madmimi.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/test/helper.rb
CHANGED
@@ -33,7 +33,7 @@ def stub_get(url, options = {})
|
|
33
33
|
FakeWeb.register_uri(:get, madmimi_url(url, https), options)
|
34
34
|
end
|
35
35
|
|
36
|
-
def stub_post(url,
|
36
|
+
def stub_post(url, options)
|
37
37
|
https = options.delete(:https)
|
38
38
|
|
39
39
|
filename = options.delete(:filename)
|
data/test/test_madmimi.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "#{File.dirname(__FILE__)}/helper"
|
2
2
|
|
3
3
|
class TestMadmimi < Test::Unit::TestCase
|
4
4
|
context "An API call" do
|
@@ -24,6 +24,36 @@ class TestMadmimi < Test::Unit::TestCase
|
|
24
24
|
flunk "No users found." unless response.kind_of?(Hash) || !response.empty?
|
25
25
|
end
|
26
26
|
|
27
|
+
should "save a raw html promotion" do
|
28
|
+
response_body = 'Saved test_promotion (1)'
|
29
|
+
stub_post('/promotions/save', { :body => response_body })
|
30
|
+
response = @mimi.save_promotion('test_promotion', '<html><body>Hi there!<br>[[unsubscribe]][[tracking_beacon]]</body></html>')
|
31
|
+
assert_equal response_body, response
|
32
|
+
end
|
33
|
+
|
34
|
+
should "save a text promotion" do
|
35
|
+
response_body = 'Saved test_promotion (1)'
|
36
|
+
stub_post('/promotions/save', { :body => response_body })
|
37
|
+
response = @mimi.save_promotion('test_promotion', nil, "Hi there!\n\n[[unsubscribe]]")
|
38
|
+
assert_equal response_body, response
|
39
|
+
end
|
40
|
+
|
41
|
+
should "raise exception on saving a raw html promotion without the required macros" do
|
42
|
+
assert_raises MadMimi::MadMimiError do
|
43
|
+
@mimi.save_promotion('test_promotion', '<html><body>Hi there!<br>[[tracking_beacon]]</body></html>')
|
44
|
+
end
|
45
|
+
|
46
|
+
assert_raises MadMimi::MadMimiError do
|
47
|
+
@mimi.save_promotion('test_promotion', '<html><body>Hi there!<br>[[unsubscribe]]</body></html>')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
should "raise exception on saving a plain text promotion without the required macro" do
|
52
|
+
assert_raises MadMimi::MadMimiError do
|
53
|
+
@mimi.save_promotion('test_promotion', 'Hi there')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
27
57
|
should "get a transactional mailing status" do
|
28
58
|
stub_get('/mailers/status/1234', { :https => true, :body => "sent" })
|
29
59
|
response = @mimi.status(1234)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: madmimi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 15
|
10
|
+
version: 1.0.15
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Nicholas Young
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-03-
|
19
|
+
date: 2011-03-21 00:00:00 +02:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|