Permalink
Browse files

Added save_promotion method plus option to send to_all

  • Loading branch information...
1 parent 07122e7 commit 194f1d1c8ea48c81a88d4eaf339119b3de9e72d3 @marcheiligers marcheiligers committed Mar 21, 2011
Showing with 102 additions and 23 deletions.
  1. +8 −0 README.rdoc
  2. +62 −21 lib/madmimi.rb
  3. +1 −1 test/helper.rb
  4. +31 −1 test/test_madmimi.rb
View
@@ -15,6 +15,8 @@ mimi = MadMimi.new('emailaddress', 'api_key')
mimi.lists -> get all of your Mad Mimi lists returned as a hash
+=== Audience Members and Lists
+
mimi.memberships('email') -> returns a hash of the lists that specific email address is subscribed to
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
mimi.suppressed_since('unix timestamp') -> get a TXT of all addresses that were suppressed since this timestamp
+=== Promotions
+
mimi.promotions -> returns a hash of your promotions
+mimi.save_promotion('promotion_name', 'raw_html', 'plain_text') -> saves a promotion (creates the promotion if it does not exist)
+
mimi.mailing_stats('promotion_id', 'mailing_id') -> get stats on a specific mailing
== 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.
'list_name': For all of the #send methods, if 'list_name' is provided, the recipients
will be those for an already-existing "audience."
+'to_all': Set to true to send a promotion, plain_text or raw_html to all your audience members
+
== Note on Patches/Pull Requests
* Fork the project.
View
@@ -37,17 +37,23 @@ class MadMimi
class MadMimiError < StandardError; end
BASE_URL = 'api.madmimi.com'
+
NEW_LISTS_PATH = '/audience_lists'
AUDIENCE_MEMBERS_PATH = '/audience_members'
AUDIENCE_LISTS_PATH = '/audience_lists/lists.xml'
MEMBERSHIPS_PATH = '/audience_members/%email%/lists.xml'
SUPPRESSED_SINCE_PATH = '/audience_members/suppressed_since/%timestamp%.txt'
SUPPRESS_USER_PATH = ' /audience_members/%email%/suppress_email'
+ SEARCH_PATH = '/audience_members/search.xml'
+
PROMOTIONS_PATH = '/promotions.xml'
+ PROMOTION_SAVE_PATH = '/promotions/save'
+
MAILING_STATS_PATH = '/promotions/%promotion_id%/mailings/%mailing_id%.xml'
- SEARCH_PATH = '/audience_members/search.xml'
+
MAILER_PATH = '/mailer'
MAILER_TO_LIST_PATH = '/mailer/to_list'
+ MAILER_TO_ALL_PATH = '/mailer/to_all'
MAILER_STATUS_PATH = '/mailers/status'
def initialize(username, api_key)
@@ -66,6 +72,7 @@ def default_opt
{ :username => username, :api_key => api_key }
end
+ # Audience and lists
def lists
request = do_request(AUDIENCE_LISTS_PATH, :get)
Crack::XML.parse(request)
@@ -109,49 +116,69 @@ def suppress_email(email)
do_request(SUPPRESS_USER_PATH.gsub('%email%', email), :post)
end
+ def audience_search(query_string, raw = false)
+ request = do_request(SEARCH_PATH, :get, :raw => raw, :query => query_string)
+ Crack::XML.parse(request)
+ end
+
+ # Not the most elegant, but it works for now. :)
+ def add_users_to_list(list_name, arr)
+ arr.each do |a|
+ a[:add_list] = list_name
+ add_user(a)
+ end
+ end
+
+ # Promotions
def promotions
request = do_request(PROMOTIONS_PATH, :get)
Crack::XML.parse(request)
end
-
+
+ def save_promotion(promotion_name, raw_html, plain_text = nil)
+ options = { :promotion_name => promotion_name }
+
+ unless raw_html.nil?
+ check_for_tracking_beacon raw_html
+ check_for_opt_out raw_html
+ options[:raw_html] = raw_html
+ end
+
+ unless plain_text.nil?
+ check_for_opt_out plain_text
+ options[:raw_plain_text] = plain_text
+ end
+
+ do_request PROMOTION_SAVE_PATH, :post, options
+ end
+
+ # Stats
def mailing_stats(promotion_id, mailing_id)
path = MAILING_STATS_PATH.gsub('%promotion_id%', promotion_id).gsub('%mailing_id%', mailing_id)
request = do_request(path, :get)
Crack::XML.parse(request)
end
- def audience_search(query_string, raw = false)
- request = do_request(SEARCH_PATH, :get, :raw => raw, :query => query_string)
- Crack::XML.parse(request)
- end
-
+ # Mailer API
def send_mail(opt, yaml_body)
options = opt.dup
options[:body] = yaml_body.to_yaml
- if !options[:list_name].nil?
- do_request(MAILER_TO_LIST_PATH, :post, options, true)
+ if !options[:list_name].nil? || options[:to_all]
+ do_request(options[:to_all] ? MAILER_TO_ALL_PATH : MAILER_TO_LIST_PATH, :post, options, true)
else
do_request(MAILER_PATH, :post, options, true)
end
end
- # Not the most elegant, but it works for now. :)
- def add_users_to_list(list_name, arr)
- arr.each do |a|
- a[:add_list] = list_name
- add_user(a)
- end
- end
-
def send_html(opt, html)
options = opt.dup
if html.include?('[[tracking_beacon]]') || html.include?('[[peek_image]]')
options[:raw_html] = html
- if !options[:list_name].nil?
+ if !options[:list_name].nil? || options[:to_all]
unless html.include?('[[unsubscribe]]') || html.include?('[[opt_out]]')
raise MadMimiError, "When specifying list_name, include the [[unsubscribe]] or [[opt_out]] macro in your HTML before sending."
end
- do_request(MAILER_TO_LIST_PATH, :post, options, true)
+ do_request(options[:to_all] ? MAILER_TO_ALL_PATH : MAILER_TO_LIST_PATH, :post, options, true)
else
do_request(MAILER_PATH, :post, options, true)
end
@@ -163,9 +190,9 @@ def send_html(opt, html)
def send_plaintext(opt, plaintext)
options = opt.dup
options[:raw_plain_text] = plaintext
- if !options[:list_name].nil?
+ if !options[:list_name].nil? || options[:to_all]
if plaintext.include?('[[unsubscribe]]') || plaintext.include?('[[opt_out]]')
- do_request(MAILER_TO_LIST_PATH, :post, options, true)
+ do_request(options[:to_all] ? MAILER_TO_ALL_PATH : MAILER_TO_LIST_PATH, :post, options, true)
else
raise MadMimiError, "You'll need to include either the [[unsubscribe]] or [[opt_out]] macro in your text before sending."
end
@@ -235,4 +262,18 @@ def build_csv(hash)
end
end
end
+
+ def check_for_tracking_beacon(content)
+ unless content.include?('[[tracking_beacon]]') || content.include?('[[peek_image]]')
+ raise MadMimiError, "You'll need to include either the [[tracking_beacon]] or [[peek_image]] macro in your HTML before sending."
+ end
+ true
+ end
+
+ def check_for_opt_out(content)
+ unless content.include?('[[opt_out]]') || content.include?('[[unsubscribe]]')
+ raise MadMimiError, "When specifying list_name or sending to all, include the [[unsubscribe]] or [[opt_out]] macro in your HTML before sending."
+ end
+ true
+ end
end
View
@@ -33,7 +33,7 @@ def stub_get(url, options = {})
FakeWeb.register_uri(:get, madmimi_url(url, https), options)
end
-def stub_post(url, filename = nil, status = nil)
+def stub_post(url, options)
https = options.delete(:https)
filename = options.delete(:filename)
View
@@ -1,4 +1,4 @@
-require 'helper'
+require "#{File.dirname(__FILE__)}/helper"
class TestMadmimi < Test::Unit::TestCase
context "An API call" do
@@ -24,6 +24,36 @@ class TestMadmimi < Test::Unit::TestCase
flunk "No users found." unless response.kind_of?(Hash) || !response.empty?
end
+ should "save a raw html promotion" do
+ response_body = 'Saved test_promotion (1)'
+ stub_post('/promotions/save', { :body => response_body })
+ response = @mimi.save_promotion('test_promotion', '<html><body>Hi there!<br>[[unsubscribe]][[tracking_beacon]]</body></html>')
+ assert_equal response_body, response
+ end
+
+ should "save a text promotion" do
+ response_body = 'Saved test_promotion (1)'
+ stub_post('/promotions/save', { :body => response_body })
+ response = @mimi.save_promotion('test_promotion', nil, "Hi there!\n\n[[unsubscribe]]")
+ assert_equal response_body, response
+ end
+
+ should "raise exception on saving a raw html promotion without the required macros" do
+ assert_raises MadMimi::MadMimiError do
+ @mimi.save_promotion('test_promotion', '<html><body>Hi there!<br>[[tracking_beacon]]</body></html>')
+ end
+
+ assert_raises MadMimi::MadMimiError do
+ @mimi.save_promotion('test_promotion', '<html><body>Hi there!<br>[[unsubscribe]]</body></html>')
+ end
+ end
+
+ should "raise exception on saving a plain text promotion without the required macro" do
+ assert_raises MadMimi::MadMimiError do
+ @mimi.save_promotion('test_promotion', 'Hi there')
+ end
+ end
+
should "get a transactional mailing status" do
stub_get('/mailers/status/1234', { :https => true, :body => "sent" })
response = @mimi.status(1234)

0 comments on commit 194f1d1

Please sign in to comment.