burstsms 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.gitignore +5 -0
  2. data/.travis.yml +4 -0
  3. data/Gemfile +4 -0
  4. data/LICENCE +20 -0
  5. data/README.md +128 -0
  6. data/Rakefile +6 -0
  7. data/burstsms.gemspec +27 -0
  8. data/lib/burstsms.rb +37 -0
  9. data/lib/burstsms/api.rb +78 -0
  10. data/lib/burstsms/lists_add.rb +30 -0
  11. data/lib/burstsms/lists_add_recipient.rb +34 -0
  12. data/lib/burstsms/lists_delete.rb +28 -0
  13. data/lib/burstsms/lists_delete_recipient.rb +29 -0
  14. data/lib/burstsms/lists_get.rb +38 -0
  15. data/lib/burstsms/lists_get_recipients.rb +42 -0
  16. data/lib/burstsms/lists_get_unsubscribed.rb +42 -0
  17. data/lib/burstsms/message_responses.rb +41 -0
  18. data/lib/burstsms/messages_add.rb +39 -0
  19. data/lib/burstsms/messages_get.rb +44 -0
  20. data/lib/burstsms/messages_multiple.rb +32 -0
  21. data/lib/burstsms/version.rb +3 -0
  22. data/spec/burst_sms_spec.rb +171 -0
  23. data/spec/contact_lists_spec.rb +188 -0
  24. data/spec/fixtures/api_requests/lists_add.txt +10 -0
  25. data/spec/fixtures/api_requests/lists_add_recipient.txt +13 -0
  26. data/spec/fixtures/api_requests/lists_delete.txt +10 -0
  27. data/spec/fixtures/api_requests/lists_delete_recipient.txt +11 -0
  28. data/spec/fixtures/api_requests/lists_get.txt +11 -0
  29. data/spec/fixtures/api_requests/lists_get_recipients.txt +12 -0
  30. data/spec/fixtures/api_requests/lists_get_unsubscribed.txt +12 -0
  31. data/spec/fixtures/api_requests/message_responses.txt +12 -0
  32. data/spec/fixtures/api_requests/messages_add.txt +12 -0
  33. data/spec/fixtures/api_requests/messages_get.txt +11 -0
  34. data/spec/fixtures/api_requests/messages_multiple.txt +12 -0
  35. data/spec/fixtures/api_responses/generic_failure.txt +7 -0
  36. data/spec/fixtures/api_responses/lists_add_recipient_success.txt +11 -0
  37. data/spec/fixtures/api_responses/lists_add_success.txt +12 -0
  38. data/spec/fixtures/api_responses/lists_delete_recipient_success.txt +8 -0
  39. data/spec/fixtures/api_responses/lists_delete_success.txt +8 -0
  40. data/spec/fixtures/api_responses/lists_get_recipients_success.txt +33 -0
  41. data/spec/fixtures/api_responses/lists_get_success.txt +19 -0
  42. data/spec/fixtures/api_responses/lists_get_unsubscribed_success.txt +33 -0
  43. data/spec/fixtures/api_responses/message_responses_success.txt +16 -0
  44. data/spec/fixtures/api_responses/messages_add_success.txt +17 -0
  45. data/spec/fixtures/api_responses/messages_get_success.txt +53 -0
  46. data/spec/fixtures/api_responses/send_message_success.txt +14 -0
  47. data/spec/spec_helper.rb +36 -0
  48. metadata +173 -0
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rvmrc
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in burst_sms.gemspec
4
+ gemspec
data/LICENCE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Made in Data Pty Ltd and David Barlow
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,128 @@
1
+ # Burst Sms [![Build Status](https://secure.travis-ci.org/madeindata/Burst-Sms.png?branch=master)](http://travis-ci.org/madeindata/Burst-Sms)
2
+
3
+ Rubygem for the Burst SMS API. Sends SMS to Australian mobiles
4
+ For use with a [burstsms.com.au](http://burstsms.com.au) account.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ gem install 'burstsms'
10
+
11
+ or add the following line to Gemfile:
12
+
13
+ gem 'burstsms'
14
+
15
+ and run `bundle` from your shell.
16
+
17
+ Usage
18
+ -----
19
+ **Create an authenticated instance**
20
+
21
+ @burstsms = BurstSms::API.new('api_key', 'secret')
22
+
23
+ **Responses**
24
+ Responses from the API are converted into ruby objects with attributes you can access.
25
+
26
+ Available attributes for each method are listed in their description below.
27
+
28
+ Every method will return a `error` attribute if something goes wrong
29
+
30
+
31
+ **Send a SMS** - [messages.multiple](http://burstsms.com/api-documentation/messages.multiple)
32
+
33
+ @burstsms.send_message('caller_id', 'recipients', 'message')
34
+
35
+ Response attributes :result :total_recipients :total_recipients_queued :message_id :contact_list_addition
36
+
37
+ `caller_id` Can be a Number upto 15 digits or a alpha-numeric string upto 11 characters.
38
+ `recipient/s` A single mobile number or an array of mobile numbers for multiple recipients.
39
+ `message` String containing sms message to send.
40
+ optional:
41
+ `sendtime` Set specific time to send message.
42
+ `contact_list` Add recipients to an existing contact list in your account.
43
+
44
+ *__NOTE:__The gem handles conversion of mobile numbers to the format required by the API. Also duplicate and invalid numbers will be deleted from the array.*
45
+ __example__: you can pass in an array of numbers like `['+61 414 899 766', '0403 855 555', '0403-855-445']` and it will be converted to `['61414899766', '61403855555', '61403855445']`
46
+
47
+ ------
48
+
49
+ Additional Methods
50
+ ------------------
51
+
52
+ **Send a SMS to an existing list** - [messages.add](http://burstsms.com/api-documentation/messages.add)
53
+
54
+ @burstsms.add_message('caller_id', 'list_id', 'message')
55
+
56
+ #returns :total :time :result :message_id :list_id :message :cost :balance :charge_error
57
+
58
+ **Retrieve history of sent messages** - [messages.get](http://burstsms.com/api-documentation/messages.get)
59
+
60
+ @burstsms.get_messages() #takes optional arguments offset and limit(default is 50)
61
+
62
+ #returns :total :time :messages
63
+ #messages return :id :list_id :mobile_from :message :datetime_send :datetime_actioned :recipient_count :status :schedule
64
+
65
+ **Retrieve responses from a message** - [messages.responses](http://burstsms.com/api-documentation/messages.responses)
66
+
67
+ @burstsms.message_responses('message_id') #takes optional arguments offset and limit(default is 50)
68
+
69
+ #returns :total :time :replies
70
+ #replies return :firstname :lastname :mobile :message :datetime_entry_orig
71
+
72
+ **Retrieve Contact Lists** - [contact-lists.get](http://burstsms.com/api-documentation/contact-lists.get)
73
+
74
+ @burstsms.get_lists() #takes optional arguments offset and limit(default is 50)
75
+
76
+ #returns :total :time :lists
77
+ #lists return :id :name :recipient_count
78
+
79
+ **Add Contact List** - [contact-lists.add](http://burstsms.com/api-documentation/contact-lists.add)
80
+
81
+ @burstsms.add_list('name of new list')
82
+
83
+ #returns :total :time :name :list_id :recipient_count
84
+
85
+ **Delete Contact List** - [contact-lists.delete](http://burstsms.com/api-documentation/contact-lists.delete)
86
+
87
+ @burstsms.delete_list('list_id')
88
+
89
+ #returns :total :time :response
90
+
91
+ **Retrieve Contact List Recipients** - [contact-lists.get-recipients](http://burstsms.com/api-documentation/contact-lists.get-recipients)
92
+
93
+ @burstsms.get_list_recipients('list_id') #takes optional arguments offset and limit(default is 50)
94
+
95
+ #returns :total :time :recipients
96
+ #recipients return :firstname :lastname :mobile :datetime_entry :dest_country :bounce_count
97
+
98
+ **Retrieve Contact List Unsubscribed** - [contact-lists.get-unsubscribed](http://burstsms.com/api-documentation/contact-lists.get-unsubscribed)
99
+
100
+ @burstsms.get_list_unsubscribed('list_id') #takes optional arguments offset and limit(default is 50)
101
+
102
+ #returns :total :time :recipients
103
+ #recipients return :firstname :lastname :mobile :datetime_entry :dest_country :bounce_count
104
+
105
+ **Add Contact List Recipient** - [contact-lists.add-recipient](http://burstsms.com/api-documentation/contact-lists.add-recipient)
106
+
107
+ @burstsms.add_list_recipient("list_id", "mobile_number", :firstname => 'Bob', :lastname => 'Smith') #name fields optional
108
+
109
+ #returns :total :time :result :list_id
110
+ #refer to Burst Sms docs for possible result values
111
+
112
+ **Delete Contact List Recipient** - [contact-lists.delete-recipient](http://burstsms.com/api-documentation/contact-lists.delete-recipient)
113
+
114
+ @burstsms.delete_list_recipient("list_id", "mobile_number")
115
+
116
+ #returns :total :time :result
117
+ #refer to Burst Sms docs for possible result values
118
+
119
+ ------
120
+ **TODO**
121
+
122
+ - Complete 'contact-lists.add-multiple-recipients'
123
+ - Add reseller API functions.
124
+
125
+ Licence
126
+ -------
127
+
128
+ Copyright © 2012 *Made in Data Pty Ltd* and *David Barlow* [@madeindata](http://twitter.com/madeindata). Refer to terms in LICENCE file.
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ task :default => :spec
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "burstsms/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "burstsms"
7
+ s.version = BurstSms::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["David Barlow"]
10
+ s.email = ["david@madeindata.com"]
11
+ s.homepage = "https://github.com/madeindata/Burst-Sms"
12
+ s.summary = %q{Ruby Interface for the Burst SMS gateway}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+
20
+ s.add_dependency "unhappymapper"
21
+ s.add_dependency "httparty"
22
+
23
+ s.add_development_dependency "rspec", "~> 2.6"
24
+ s.add_development_dependency "webmock", "~> 1.7.10"
25
+ s.add_development_dependency 'rake'
26
+
27
+ end
@@ -0,0 +1,37 @@
1
+ require 'uri'
2
+ require 'happymapper'
3
+ require 'httparty'
4
+
5
+
6
+ module BurstSms
7
+
8
+ class ParamBuilder
9
+ include HappyMapper
10
+ tag 'params'
11
+ def initialize(parameters={})
12
+ parameters.each do |property,value|
13
+ self.class.element property, String unless respond_to?("#{property}=")
14
+ send("#{property}=",value) if respond_to?("#{property}=")
15
+ end
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+
22
+ require 'burstsms/messages_multiple'
23
+ require 'burstsms/messages_get'
24
+ require 'burstsms/messages_add'
25
+ require 'burstsms/message_responses'
26
+ require 'burstsms/lists_get'
27
+ require 'burstsms/lists_add'
28
+ require 'burstsms/lists_delete'
29
+ require 'burstsms/lists_get_recipients'
30
+ require 'burstsms/lists_get_unsubscribed'
31
+ require 'burstsms/lists_add_recipient'
32
+ require 'burstsms/lists_delete_recipient'
33
+
34
+
35
+ require 'burstsms/api'
36
+
37
+
@@ -0,0 +1,78 @@
1
+ require 'happymapper'
2
+
3
+ module BurstSms
4
+ API_URL = "https://burstsms.com/api"
5
+ API_VERSION = 0.3
6
+
7
+ class API
8
+ include HappyMapper
9
+
10
+ include MessagesMultiple
11
+ include MessagesGet
12
+ include MessagesAdd
13
+ include MessageResponses
14
+
15
+ include ListsGet
16
+ include ListsAdd
17
+ include ListsDelete
18
+ include ListsGetRecipients
19
+ include ListsGetUnsubscribed
20
+ include ListsAddRecipient
21
+ include ListsDeleteRecipient
22
+
23
+ tag 'request'
24
+
25
+ element :version, Float
26
+ element :key, String
27
+ element :secret, String
28
+ element :api_method, String, :tag => 'method_'
29
+
30
+ has_one :params, String
31
+
32
+
33
+
34
+ def initialize(api_key, api_secret)
35
+ self.key = api_key
36
+ self.secret = api_secret
37
+ self.version = BurstSms::API_VERSION
38
+ end
39
+
40
+
41
+
42
+ private
43
+
44
+ def sanitize_numbers(recipients)
45
+ Array(recipients).map{|n| n.gsub(/[^0-9]/i, '').gsub(/\A(04)|\A(4)/, '614')}.delete_if{|n| n.length != 11 || !n.start_with?('614')}.uniq.join(',')
46
+ end
47
+
48
+ def encode_msg(message)
49
+ URI.escape( message, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
50
+ end
51
+
52
+ def check_valid_sender(from)
53
+ sender = from.gsub(/[^0-9a-z_\s]/i, '')
54
+ if sender =~ /\D/
55
+ raise "Sender ID is too Long" if sender.length > 11
56
+ else
57
+ raise "Sender Number is too Long" if sender.length > 15
58
+ end
59
+ return sender
60
+ end
61
+
62
+ def build_request(api_call, parameters={})
63
+ self.params = ParamBuilder.new(parameters)
64
+ self.api_method = api_call
65
+ self.to_xml()
66
+ end
67
+
68
+ def post_to_api(request_xml)
69
+ #XML request has to be wrapped as a 'request' param in body
70
+ response = HTTParty.post( BurstSms::API_URL, :body => "request=#{request_xml}" )
71
+ end
72
+
73
+ end
74
+
75
+
76
+
77
+
78
+ end
@@ -0,0 +1,30 @@
1
+ require 'happymapper'
2
+
3
+ module BurstSms
4
+ module ListsAdd
5
+
6
+ def add_list(name)
7
+ response = post_to_api(add_list_body(name))
8
+ Response.parse(response.body)
9
+ end
10
+
11
+ def add_list_body(name)
12
+ build_request("contact-lists.add", :name => name)
13
+ end
14
+
15
+ class Response
16
+ include HappyMapper
17
+ tag 'xml'
18
+
19
+ element :total, String
20
+ element :time, Time
21
+ element :timestamp, String
22
+ element :error, String
23
+
24
+ element :name, String, :xpath => "data/name"
25
+ element :recipient_count, String, :xpath => "data/recipient_count"
26
+ element :list_id, String, :xpath => "data/id"
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ require 'happymapper'
2
+
3
+ module BurstSms
4
+ module ListsAddRecipient
5
+
6
+ def add_list_recipient(list_id, mobile, options={})
7
+ response = post_to_api(add_list_recipient_body(list_id, mobile, options))
8
+ Response.parse(response.body)
9
+ end
10
+
11
+ def add_list_recipient_body(list_id, mobile, options={})
12
+ build_request("contact-lists.add-recipient", :list_id => list_id,
13
+ :mobile => mobile,
14
+ :firstname => (options.has_key?(:firstname) ? options[:firstname] : nil),
15
+ :lastname => (options.has_key?(:lastname) ? options[:lastname] : nil),
16
+ :mobile_dest_country => (options.has_key?(:mobile_dest_country) ? options[:mobile_dest_country] : nil)
17
+ )
18
+ end
19
+
20
+ class Response
21
+ include HappyMapper
22
+ tag 'xml'
23
+
24
+ element :total, String
25
+ element :time, Time
26
+ element :timestamp, String
27
+ element :error, String
28
+
29
+ element :result, String, :xpath => "data/result"
30
+ element :list_id, String, :xpath => "data/list_id"
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ require 'happymapper'
2
+
3
+ module BurstSms
4
+ module ListsDelete
5
+
6
+ def delete_list(id)
7
+ @response = post_to_api(delete_list_body(id))
8
+ Response.parse(@response.body)
9
+ end
10
+
11
+ def delete_list_body(id)
12
+ build_request("contact-lists.delete", :id => id)
13
+ end
14
+
15
+ class Response
16
+ include HappyMapper
17
+ tag 'xml'
18
+
19
+ element :error, String
20
+ element :total, String
21
+ element :time, String
22
+ element :timestamp, String
23
+ element :response, String
24
+
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ require 'happymapper'
2
+
3
+ module BurstSms
4
+ module ListsDeleteRecipient
5
+
6
+ def delete_list_recipient(list_id, mobile)
7
+ @response = post_to_api(delete_list_recipient_body(list_id, mobile))
8
+ Response.parse(@response.body)
9
+ end
10
+
11
+ def delete_list_recipient_body(list_id, mobile)
12
+ build_request("contact-lists.delete-recipient", :list_id => list_id,
13
+ :mobile => mobile)
14
+ end
15
+
16
+ class Response
17
+ include HappyMapper
18
+ tag 'xml'
19
+
20
+ element :error, String
21
+ element :total, String
22
+ element :time, String
23
+ element :timestamp, String
24
+ element :result, String
25
+
26
+
27
+ end
28
+ end
29
+ end