openmarket 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 313f1285d8dfc0d1a615e4d0e34b8d833df72e35
4
+ data.tar.gz: 54bf9d7d27719f8883faf50abc03ccba6619e6a5
5
+ SHA512:
6
+ metadata.gz: 4b97d23e3d060dae73ae4489b75e2291ff8b8f491ab05be1d5dd76e6512a9584fc5234580e353b9a8848ea7fc1f262dc7215cbea5ad3757675def646e8662ede
7
+ data.tar.gz: f9e13cf97a53740a26f755e7d201cf92048c521cc78ccbaac75452462de1bb023e74e884d9787092ce42b4b875d66d0c3a8b2f9e2d6ece78c1947ef1a647484e
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ secrets.yml
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --order random
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in open_market.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Isaac Betesh
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,129 @@
1
+ # OpenMarket
2
+
3
+ We use HTTParty to send SMS messages using the OpenMarket API. See USAGE below for details.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'openmarket'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install openmarket
20
+
21
+ ## Usage
22
+
23
+ ### Configuratiion
24
+
25
+ The openmarket gem requires you to provide an id, password, program_id and short_code. Configure them before attempting any API calls.
26
+
27
+ ```ruby
28
+ OpenMarket.configure do |config|
29
+ config.id = "000-000-000-00000"
30
+ config.password = "Re@llyL0ngR&om$tr1ng"
31
+ config.program_id = "ABC"
32
+ config.short_code = 99999 # You can override this on an individual message if necessary
33
+ end
34
+ ```
35
+
36
+ Since the openmarket gem depends on sms_validation (https://github.com/betesh/sms_validation/), it is also recommended that you configure sms_validation.
37
+ openmarket uses sms_validation's logger. In a Rails environment, you will probably want to rely on the default configuration,
38
+ but outside of Rails, you will need to configure it if you want any logging:
39
+
40
+ ```ruby
41
+ SmsValidation.configure do |config|
42
+ config.logger = ::Logger.new(STDOUT)
43
+ end
44
+ ```
45
+
46
+ ### API calls
47
+
48
+ `OpenMarket::API` supports 3 API calls: `carrier_lookup`, `send_sms`, and `status`.
49
+
50
+ #### carrier_lookup
51
+
52
+ ```ruby
53
+ require 'openmarket'
54
+ phone = 2125551212
55
+ result = OpenMarket::API.carrier_lookup(phone)
56
+
57
+ # First, make sure the call succeeded
58
+ puts result.code # should be 0
59
+ puts result.description # should be 'No Error'
60
+
61
+ # If the call succeeded, you can check the carrier_id:
62
+ puts result.carrier_id # You are probably most interested in the carrier_id
63
+ puts result.inspect # But there are a lot of other attributes returned by this API call as well
64
+ ```
65
+
66
+ #### send_sms
67
+
68
+ ```ruby
69
+ require 'openmarket'
70
+ phone = 2125551212
71
+ message = "Hello, this is a test of the OpenMarket API"
72
+ result = OpenMarket::API.send_sms(phone, message)
73
+
74
+ # First, make sure the call succeeded
75
+ puts result.code # should be 2
76
+ puts result.description # should be 'Message received.'
77
+
78
+ # Save the ticket ID for later. We'll use this to query the status of the ticket.
79
+ ticket_id = result.ticket_id
80
+
81
+ # Save the carrier ID for later. We'll use this next time we send an SMS to this number.
82
+ carrier_id = result.carrier_id
83
+
84
+ # There are some options you can pass along as well:
85
+ result = OpenMarket::API.send_sms(
86
+ phone,
87
+ message,
88
+
89
+ # If you want to receive DR's, you must pass a dr_url option. If you don't pass a URL, no DR will be sent to the default URL.
90
+ dr_url: "http://www.example.com/drs",
91
+
92
+ # It is highly recommended to pass a carrier_id. If you don't, the openmarket gem will make an extra API call to look up the carrier before sending the message.
93
+ carrier_id: carrier_id, # Remember the carrier ID we saved from the previous SMS?
94
+
95
+ # If you don't want to the short_code you configured above, provide another short_code to send to:
96
+ short_code: 33333,
97
+
98
+ # By default, OpenMarket re-attempts delivery for 3 days. To make OpenMarket give up and report it as a failure sooner, pass a number of minutes you would like to retry for:
99
+ minutes_to_retry: 120, # 2 hours
100
+
101
+ note: "Information that will be passed on to the DR",
102
+
103
+ ticket_id_for_retry: ticket_id # If this is a re-try of a failed ticket.
104
+ )
105
+
106
+ ```
107
+ #### status
108
+
109
+ ```ruby
110
+ require 'openmarket'
111
+ result = OpenMarket::API.status(ticket_id) # Remember the ticket ID we saved from #send_sms?
112
+
113
+ # First, make sure the call succeeded
114
+ puts result.code # should be 0
115
+ puts result.description # should be 'No Error'
116
+
117
+ # Check the result of the SMS message
118
+ puts result.status_code
119
+ puts result.status_description
120
+
121
+ ```
122
+
123
+ ## Contributing
124
+
125
+ 1. Fork it ( https://github.com/betesh/open_market/fork )
126
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
127
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
128
+ 4. Push to the branch (`git push origin my-new-feature`)
129
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,4 @@
1
+ require "open_market/api"
2
+
3
+ module OpenMarket
4
+ end
@@ -0,0 +1,83 @@
1
+ require "open_market/configuration"
2
+ require "open_market/response"
3
+ require "open_market/version"
4
+
5
+ require "builder"
6
+ require "httparty"
7
+ require "sms_validation"
8
+
9
+ module OpenMarket
10
+ class Api
11
+ class Http
12
+ include HTTParty
13
+ base_uri "https://smsc.openmarket.com"
14
+ end
15
+
16
+ ALLOWED_OPTIONS = [:dr_url, :ticket_id_for_retry, :carrier_id, :note, :minutes_to_retry, :short_code]
17
+ class InvalidOptions < ::StandardError; end
18
+
19
+ def carrier_lookup(phone)
20
+ CarrierLookupResponse.new(post(:preview) do |b|
21
+ b.destination(ton: 1, address: "1#{phone.to_s[-10..-1]}")
22
+ end)
23
+ end
24
+
25
+ def send_sms(phone, message, options = {})
26
+ phone = SmsValidation::Sms.new(phone, message).phone
27
+ options = options.inject({}) { |hash, (k,v)| hash[k.to_sym] = v; hash }
28
+ unrecognized_keys = options.keys - ALLOWED_OPTIONS
29
+ raise InvalidOptions, "#{unrecognized_keys.join(", ")} #{1 == unrecognized_keys.size ? "is not a" : "are not"} valid option#{:s if unrecognized_keys.size > 1}" unless unrecognized_keys.empty?
30
+ request_options = options.select{ |k,v| k.to_sym == :ticket_id_for_retry }
31
+ carrier_id = options[:carrier_id] || carrier_lookup(phone).carrier_id
32
+ SendSmsResponse.new(post(:submit, request_options) do |b|
33
+ b.delivery(receipt_requested: true, url: options[:dr_url]) if options[:dr_url]
34
+ b.option((options[:note] ? { note: options[:note] } : {}).merge(charge_type: 0, program_id: configuration.program_id, mlc: message_length_control))
35
+ b.source(ton: 3, address: options[:short_code] || configuration.short_code)
36
+ b.destination(ton: 1, address: phone, carrier: carrier_id)
37
+ b.message((options[:minutes_to_retry] ? { validity_period: (options[:minutes_to_retry].to_f * 60).round } : {}).merge(text: message))
38
+ end, carrier_id)
39
+ end
40
+
41
+ def status(ticket_id)
42
+ StatusResponse.new(post(:query) do |b|
43
+ b.ticket(id: ticket_id)
44
+ end)
45
+ end
46
+
47
+ private
48
+ def configuration
49
+ @configuration ||= Module.nesting.last.configuration
50
+ end
51
+
52
+ def filtered(value)
53
+ [:account, :user].inject(value) { |v, k| v.gsub(/<#{k}.*?\/>/, "") }
54
+ end
55
+
56
+ def post(type, options = {})
57
+ builder = Builder::XmlMarkup.new
58
+ builder.instruct!(:xml, version: 1.0)
59
+ body = builder.request(options.merge(version: 3.0, protocol: :wmp, type: type)) do |r|
60
+ r.user(agent: "openmarket_rubygem/SMS/#{OpenMarket::VERSION}")
61
+ r.account(id: configuration.id, password: configuration.password)
62
+ yield r
63
+ end
64
+ SmsValidation.log { "OpenMarket API: POST #{filtered(body)}" }
65
+ Http.post("/wmp", body: body.to_s).tap do |result|
66
+ SmsValidation.log { "OpenMarket API Result: #{result.respond_to?(:body) ? result.body : result}" }
67
+ end
68
+ end
69
+
70
+ def message_length_control
71
+ case SmsValidation.configuration.on_message_too_long
72
+ when :truncate
73
+ 1
74
+ when :raise_error
75
+ 0
76
+ when :split
77
+ 2
78
+ end
79
+ end
80
+ end
81
+
82
+ API ||= Api.new
83
+ end
@@ -0,0 +1,38 @@
1
+ module OpenMarket
2
+ class << self
3
+ def configuration
4
+ @configuration ||= Configuration.new
5
+ end
6
+
7
+ def configure
8
+ yield configuration
9
+ end
10
+ end
11
+
12
+ class Configuration
13
+ class Error < ::StandardError; end
14
+ CONFIGURATION_OPTIONS = [:id, :password, :program_id, :short_code]
15
+
16
+ (CONFIGURATION_OPTIONS - [:short_code]).each do |accessor|
17
+ define_method(:"#{accessor}=") do |arg|
18
+ raise Error, "#{accessor} must be a String" unless arg.nil? || arg.is_a?(String)
19
+ raise Error, "#{accessor} cannot be blank" if arg.nil? || arg.empty?
20
+ instance_variable_set("@#{accessor}", arg)
21
+ end
22
+ end
23
+
24
+ def short_code=(arg)
25
+ raise Error, "short_code cannot be blank" if arg.nil?
26
+ raise Error, "short_code must be a 5-digit number" unless arg.to_s.scan(/\A[0-9]{5}\z/)
27
+ @short_code = arg
28
+ end
29
+
30
+ CONFIGURATION_OPTIONS.each do |accessor|
31
+ define_method(accessor) do
32
+ instance_variable_get("@#{accessor}").tap do |result|
33
+ raise Error, "#{accessor} has not been set. Set it with `#{Module.nesting.last}.configuration.#{accessor} = ...`" if result.nil?
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,27 @@
1
+ require "rexml/document"
2
+
3
+ module OpenMarket
4
+ class DR
5
+ attr_reader :code, :description, :note, :parent_ticket_id, :segment_number, :state_description, :state_id, :ticket_id, :timestamp
6
+ def initialize(data)
7
+ (class << self; self; end).class_eval do
8
+ # Defining a member variable for xml would pollute #inspect
9
+ # This solution is inspired by https://github.com/jordansissel/software-patterns/tree/master/dont-log-secrets/ruby
10
+ define_method(:xml) { REXML::Document.new(data).root }
11
+ private :xml
12
+ end
13
+ @ticket_id = xml.attributes["ticketId"]
14
+ @parent_ticket_id = xml.attributes["parentTicketId"]
15
+ @note = xml.attributes["note"]
16
+ response = xml.elements["response"]
17
+ @description = response.attributes["description"]
18
+ @code = response.attributes["code"].to_i
19
+ message = xml.elements["message"]
20
+ @segment_number = message.attributes["segmentNumber"]
21
+ @timestamp = DateTime.strptime(message.attributes["deliveryDate"] + "+0000", '%FT%T.%LZ%z').utc
22
+ state = message.elements["state"]
23
+ @state_id = state.attributes["id"].to_i
24
+ @state_description = state.attributes["description"]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,37 @@
1
+ require "rexml/document"
2
+
3
+ module OpenMarket
4
+ class MO
5
+ attr_reader :account_id, :carrier_id, :data, :data_coding, :destination_address, :destination_ton, :source_address, :source_ton, :ticket_id, :udhi
6
+ def initialize(data)
7
+ (class << self; self; end).class_eval do
8
+ # Defining a member variable for xml would pollute #inspect
9
+ # This solution is inspired by https://github.com/jordansissel/software-patterns/tree/master/dont-log-secrets/ruby
10
+ define_method(:xml) { REXML::Document.new(data).root }
11
+ private :xml
12
+ end
13
+ if ticket = xml.elements["ticket"]
14
+ @ticket_id = ticket.attributes["id"]
15
+ end
16
+ if account = xml.elements["account"]
17
+ @account_id = account.attributes["id"]
18
+ end
19
+ if source = xml.elements["source"]
20
+ @carrier_id = source.elements["carrier"]
21
+ @source_ton = source.elements["ton"]
22
+ @source_address = source.elements["address"]
23
+ end
24
+ if destination = xml.elements["destination"]
25
+ @destination_ton = destination.elements["ton"]
26
+ @destination_address = destination.elements["address"]
27
+ end
28
+ if option = xml.elements["option"]
29
+ @data_coding = option.attributes["datacoding"]
30
+ end
31
+ if message = xml.elements["message"]
32
+ @udhi = message.attributes["udhi"] == true
33
+ @data = message.attributes["data"]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,98 @@
1
+ require "rexml/document"
2
+
3
+ module OpenMarket
4
+ class Response
5
+ attr_reader :code, :description
6
+ def initialize(http_response)
7
+ (class << self; self; end).class_eval do
8
+ # Defining a member variable for xml would pollute #inspect
9
+ # This solution is inspired by https://github.com/jordansissel/software-patterns/tree/master/dont-log-secrets/ruby
10
+ define_method(:xml) do
11
+ if http_response.respond_to?(:body)
12
+ REXML::Document.new(http_response.body).root
13
+ else
14
+ REXML::Document.new(http_response.to_xml).root.elements["response"]
15
+ end
16
+ end
17
+ private :xml
18
+ end
19
+ error = xml.elements["error"]
20
+ @code = (error.attributes["code"] || error.elements["code"].text).to_i
21
+ @description = error.attributes["description"] || error.elements["description"].text
22
+ end
23
+ end
24
+
25
+ class CarrierLookupResponse < Response
26
+ attr_reader :country_code, :national_number, :intl_notation, :area_code, :area_code_length, :num_min_length, :num_max_length, :na_nxx, :na_line, :local_notation, :local_format, :digits_all, :digits_local, :ported, :ported_from
27
+ attr_reader :city, :country, :country_name, :estimated_latitude, :estimated_longitude, :region, :region_name, :timezone_min, :timezone_max, :zone, :zone_name
28
+ attr_reader :carrier_id, :name, :binary_length, :text_length, :unicode_length, :binary, :ems, :smart_messaging, :unicode, :wap_push
29
+
30
+ def initialize(http_response)
31
+ super
32
+ if destination = xml.elements["destination"]
33
+ @country_code = destination.attributes["country_code"].to_i
34
+ @national_number = destination.attributes["national_number"]
35
+ @intl_notation = destination.attributes["intl_notation"]
36
+ @area_code = destination.attributes["area_code"]
37
+ @area_code_length = destination.attributes["area_code_length"].to_i
38
+ @num_min_length = destination.attributes["num_min_length"].to_i
39
+ @num_max_length = destination.attributes["num_max_length"].to_i
40
+ @na_nxx = destination.attributes["na_nxx"]
41
+ @na_line = destination.attributes["na_line"]
42
+ @local_notation = destination.attributes["local_notation"]
43
+ @local_format = destination.attributes["local_format"]
44
+ @digits_all = destination.attributes["digits_all"].to_i
45
+ @digits_local = destination.attributes["digits_local"].to_i
46
+ @ported = destination.attributes["ported"] == "true"
47
+ @ported_from = destination.attributes["ported_from"]
48
+ end
49
+ if location = xml.elements["location"]
50
+ @city = location.attributes["city"]
51
+ @country = location.attributes["country"]
52
+ @country_name = location.attributes["country_name"]
53
+ @estimated_latitude = location.attributes["estimated_latitude"].to_f
54
+ @estimated_longitude = location.attributes["estimated_longitude"].to_f
55
+ @region = location.attributes["region"]
56
+ @region_name = location.attributes["region_name"]
57
+ @timezone_min = location.attributes["timezone_min"].to_i
58
+ @timezone_max= location.attributes["timezone_max"].to_i
59
+ @zone = location.attributes["zone"].to_i
60
+ @zone_name = location.attributes["zone_name"]
61
+ end
62
+ if operator = xml.elements["operator"]
63
+ @carrier_id = operator.attributes["id"].to_i
64
+ @name = operator.attributes["name"]
65
+ @binary_length = operator.attributes["binary_length"].to_i
66
+ @text_length = operator.attributes["text_length"].to_i
67
+ @unicode_length = operator.attributes["unicode_length"].to_i
68
+ @binary = operator.attributes["binary"] == "true"
69
+ @ems = operator.attributes["ems"] == "true"
70
+ @smart_messaging = operator.attributes["smart_messaging"] == "true"
71
+ @unicode = operator.attributes["unicode"] == "true"
72
+ @wap_push = operator.attributes["wap_push"] == "true"
73
+ end
74
+ end
75
+ end
76
+
77
+ class SendSmsResponse < Response
78
+ attr_reader :ticket_id, :carrier_id
79
+ def initialize(http_response, carrier_id)
80
+ super(http_response)
81
+ @carrier_id = carrier_id
82
+ if ticket = xml.elements["ticket"]
83
+ @ticket_id = ticket.attributes["id"]
84
+ end
85
+ end
86
+ end
87
+
88
+ class StatusResponse < Response
89
+ attr_reader :status_code, :status_description
90
+ def initialize(http_response)
91
+ super
92
+ if status = xml.elements["status"]
93
+ @status_code = status.attributes["code"].to_i
94
+ @status_description = status.attributes["description"]
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,3 @@
1
+ module OpenMarket
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1 @@
1
+ require "open_market"
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'open_market/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "openmarket"
8
+ spec.version = OpenMarket::VERSION
9
+ spec.authors = ["Isaac Betesh"]
10
+ spec.email = ["iybetesh@gmail.com"]
11
+ spec.summary = "Send SMS messages using the OpenMarket API"
12
+ spec.description = `cat README.md`
13
+ spec.homepage = "https://github.com/betesh/open_market"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3"
24
+
25
+ spec.add_dependency "sms_validation", "~> 0.0.2"
26
+ spec.add_dependency "httparty"
27
+ spec.add_dependency "builder"
28
+ end
@@ -0,0 +1,220 @@
1
+ require "open_market/api"
2
+ require "support/configuration_from_yaml"
3
+
4
+ describe OpenMarket::Api do
5
+ subject { OpenMarket::API }
6
+
7
+ describe "#carrier_lookup" do
8
+ it "should succeed without a 1 preceding the phone number" do
9
+ result = subject.carrier_lookup(phone)
10
+ expect(result).to be_a(OpenMarket::CarrierLookupResponse)
11
+ expect(result.code).to eq(0)
12
+ expect(result.description).to eq("No Error")
13
+ expect(result.carrier_id).to eq(carrier_id)
14
+ end
15
+
16
+ it "should succeed with a 1 preceding the phone number" do
17
+ result = subject.carrier_lookup("1#{phone}")
18
+ expect(result).to be_a(OpenMarket::CarrierLookupResponse)
19
+ expect(result.code).to eq(0)
20
+ expect(result.description).to eq("No Error")
21
+ expect(result.carrier_id).to eq(carrier_id)
22
+ end
23
+ end
24
+
25
+ describe "#send_sms" do
26
+ it "should send an SMS" do
27
+ result = subject.send_sms(phone, "Test of OpenMarket API", carrier_id: carrier_id)
28
+ expect(result.code).to eq(2)
29
+ expect(result.description).to eq("Message received.")
30
+ expect(result.ticket_id).not_to be_nil
31
+ end
32
+
33
+ it "looks up the carrier_id if it is not passed as an option and returns it" do
34
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
35
+ expect(args[0]).to eq("/wmp")
36
+ puts args[1][:body].inspect
37
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"preview\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><destination ton=\"1\" address=\"1#{phone}\"\/><\/request>\z/
38
+ original.call(*args, &block)
39
+ end
40
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
41
+ expect(args[0]).to eq("/wmp")
42
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><option charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"0\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message text=\"Test of OpenMarket API\"\/><\/request>\z/
43
+ original.call(*args, &block)
44
+ end
45
+ result = subject.send_sms(phone, "Test of OpenMarket API")
46
+ expect(result.carrier_id).to eq(carrier_id)
47
+ end
48
+
49
+ describe "message_length_control" do
50
+ describe "when SmsValidation.configuration.on_message_too_long is truncate" do
51
+ it "should be 1" do
52
+ SmsValidation.configuration.on_message_too_long = :truncate
53
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
54
+ expect(args[0]).to eq("/wmp")
55
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><option charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"1\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message text=\"Test of OpenMarket API\"\/><\/request>\z/
56
+ original.call(*args, &block)
57
+ end
58
+ subject.send_sms(phone, "Test of OpenMarket API", carrier_id: carrier_id)
59
+ end
60
+ end
61
+
62
+ describe "when SmsValidation.configuration.on_message_too_long is split" do
63
+ it "should be 2" do
64
+ SmsValidation.configuration.on_message_too_long = :split
65
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
66
+ expect(args[0]).to eq("/wmp")
67
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><option charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"2\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message text=\"Test of OpenMarket API\"\/><\/request>\z/
68
+ original.call(*args, &block)
69
+ end
70
+ subject.send_sms(phone, "Test of OpenMarket API", carrier_id: carrier_id)
71
+ end
72
+ end
73
+
74
+ describe "when SmsValidation.configuration.on_message_too_long is raise_error" do
75
+ it "should be 0" do
76
+ SmsValidation.configuration.on_message_too_long = :raise_error
77
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
78
+ expect(args[0]).to eq("/wmp")
79
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><option charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"0\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message text=\"Test of OpenMarket API\"\/><\/request>\z/
80
+ original.call(*args, &block)
81
+ end
82
+ subject.send_sms(phone, "Test of OpenMarket API", carrier_id: carrier_id)
83
+ end
84
+ end
85
+ end
86
+
87
+ describe "invalid keys" do
88
+ it "should raise a gramatically correct error with 1 unknown option" do
89
+ expect{subject.send_sms(phone, "Test of OpenMarket API", carrier_id: carrier_id, unknown_option: true)}.to raise_error(OpenMarket::Api::InvalidOptions, "unknown_option is not a valid option")
90
+ end
91
+
92
+ it "should raise a gramatically correct error with 2 unknown options" do
93
+ expect{subject.send_sms(phone, "Test of OpenMarket API", carrier_id: carrier_id, unknown_option: true, other_unknown: false)}.to raise_error(OpenMarket::Api::InvalidOptions, "unknown_option, other_unknown are not valid options")
94
+ end
95
+
96
+ it "automatically converts String keys to Symbol" do
97
+ expect{subject.send_sms(phone, "Test of OpenMarket API", "carrier_id" => carrier_id, "ticket_id_for_retry" => "ABC", "dr_url" => dr_url, "note" => "ABCDEFFF", "minutes_to_retry" => 10, "short_code" => 99998)}.not_to raise_error
98
+ end
99
+ end
100
+
101
+ describe "valid keys" do
102
+ describe "carrier_id" do
103
+ let(:carrier_id) { 1000000 }
104
+ it "should be in the XML" do
105
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
106
+ expect(args[0]).to eq("/wmp")
107
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><option charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"0\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message text=\"Test of OpenMarket API\"\/><\/request>\z/
108
+ original.call(*args, &block)
109
+ end
110
+ subject.send_sms(phone, "Test of OpenMarket API", carrier_id: carrier_id)
111
+ end
112
+ end
113
+
114
+ describe "note" do
115
+ let(:note) { "The quick brown fox jumps over the lazy dog" }
116
+ it "should be in the XML" do
117
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
118
+ expect(args[0]).to eq("/wmp")
119
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><option note=\"#{note}\" charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"0\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message text=\"Test of OpenMarket API\"\/><\/request>\z/
120
+ original.call(*args, &block)
121
+ end
122
+ subject.send_sms(phone, "Test of OpenMarket API", carrier_id: carrier_id, note: note)
123
+ end
124
+ end
125
+
126
+ describe "ticket_id_for_retry" do
127
+ let(:ticket_id_for_retry) { 1999998888 }
128
+ it "should be in the XML" do
129
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
130
+ expect(args[0]).to eq("/wmp")
131
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request ticket_id_for_retry=\"#{ticket_id_for_retry}\" version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><option charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"0\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message text=\"Test of OpenMarket API\"\/><\/request>\z/
132
+ original.call(*args, &block)
133
+ end
134
+ subject.send_sms(phone, "Test of OpenMarket API", carrier_id: carrier_id, ticket_id_for_retry: ticket_id_for_retry)
135
+ end
136
+ end
137
+
138
+ describe "dr_url" do
139
+ let(:dr_url) { "example.com" }
140
+ it "should be in the XML" do
141
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
142
+ expect(args[0]).to eq("/wmp")
143
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><delivery receipt_requested=\"true\" url=\"#{dr_url}\"\/><option charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"0\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message text=\"Test of OpenMarket API\"\/><\/request>\z/
144
+ original.call(*args, &block)
145
+ end
146
+ subject.send_sms(phone, "Test of OpenMarket API", dr_url: dr_url, carrier_id: carrier_id)
147
+ end
148
+ end
149
+
150
+ describe "minutes_to_retry" do
151
+ it "should be in the XML" do
152
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
153
+ expect(args[0]).to eq("/wmp")
154
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><delivery receipt_requested=\"true\" url=\"#{dr_url}\"\/><option charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"0\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message validity_period=\"1080\" text=\"Test of OpenMarket API\"\/><\/request>\z/
155
+ original.call(*args, &block)
156
+ end
157
+ subject.send_sms(phone, "Test of OpenMarket API", dr_url: dr_url, carrier_id: carrier_id, minutes_to_retry: 18)
158
+ end
159
+
160
+ describe "can be a fraction of a number and is rounded to the nearest integer number of seconds" do
161
+ [19, 20, 21].each do |divisor|
162
+ describe do
163
+ it "should be in the XML" do
164
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
165
+ expect(args[0]).to eq("/wmp")
166
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><delivery receipt_requested=\"true\" url=\"#{dr_url}\"\/><option charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"0\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message validity_period=\"3\" text=\"Test of OpenMarket API\"\/><\/request>\z/
167
+ original.call(*args, &block)
168
+ end
169
+ subject.send_sms(phone, "Test of OpenMarket API", dr_url: dr_url, carrier_id: carrier_id, minutes_to_retry: 1.0/divisor )
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ describe "short_code" do
177
+ let(:short_code) { 66666 }
178
+ it "should be in the XML" do
179
+ expect(OpenMarket::Api::Http).to receive(:post).and_wrap_original do |original, *args, &block|
180
+ expect(args[0]).to eq("/wmp")
181
+ expect(args[1][:body]).to match /\A<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><request version=\"3.0\" protocol=\"wmp\" type=\"submit\"><user agent=\"openmarket_rubygem\/SMS\/0\.0\.1\"\/><account id=\"#{id}\" password=\"#{password}\"\/><option charge_type=\"0\" program_id=\"#{program_id}\" mlc=\"0\"\/><source ton=\"3\" address=\"#{short_code}\"\/><destination ton=\"1\" address=\"1#{phone}\" carrier=\"#{carrier_id}\"\/><message text=\"Test of OpenMarket API\"\/><\/request>\z/
182
+ original.call(*args, &block)
183
+ end
184
+ subject.send_sms(phone, "Test of OpenMarket API", carrier_id: carrier_id, short_code: short_code)
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ describe "#status" do
191
+ let(:sms) { subject.send_sms(phone, "Test of OpenMarket API") }
192
+ let(:ticket_id) { sms.ticket_id }
193
+
194
+ def get_status
195
+ subject.status(ticket_id)
196
+ end
197
+
198
+ it "should look up the status of a ticket" do
199
+ status = get_status
200
+ expect(status.code).to eq(0)
201
+ expect(status.description).to eq("No Error")
202
+ expect(status.status_code).to eq(3)
203
+ expect(status.status_description).to eq("Message buffered with carrier and waiting for delivery response.")
204
+ print "Waiting for the message to be delivered..."
205
+ i = 0
206
+ SmsValidation.configuration.logger = nil
207
+ begin
208
+ sleep 1
209
+ print "."
210
+ status = get_status
211
+ break if 4 == status.status_code
212
+ i += 1
213
+ end while i < 5
214
+ expect(status.code).to eq(0)
215
+ expect(status.description).to eq("No Error")
216
+ expect(status.status_code).to eq(4)
217
+ expect(status.status_description).to eq("Message successfully delivered.")
218
+ end
219
+ end
220
+ end
@@ -0,0 +1,35 @@
1
+ require "support/configuration_from_yaml"
2
+ require "open_market/configuration"
3
+
4
+ describe OpenMarket::Configuration do
5
+ subject { OpenMarket.configuration }
6
+ let(:skip_open_market_configuration) { true }
7
+
8
+ [:id, :password, :program_id].each do |configuration_option|
9
+ describe "##{configuration_option}" do
10
+ it "cannot be nil" do
11
+ expect{subject.public_send("#{configuration_option}=", nil)}.to raise_error(OpenMarket::Configuration::Error, "#{configuration_option} cannot be blank")
12
+ end
13
+
14
+ it "cannot be an empty String" do
15
+ expect{subject.public_send("#{configuration_option}=", "")}.to raise_error(OpenMarket::Configuration::Error, "#{configuration_option} cannot be blank")
16
+ end
17
+
18
+ it "cannot be a Hash" do
19
+ expect{subject.public_send("#{configuration_option}=", {})}.to raise_error(OpenMarket::Configuration::Error, "#{configuration_option} must be a String")
20
+ end
21
+
22
+ it "must be set before accessing it" do
23
+ expect{subject.public_send(configuration_option)}.to raise_error(OpenMarket::Configuration::Error, "#{configuration_option} has not been set. Set it with `OpenMarket.configuration.#{configuration_option} = ...`")
24
+ end
25
+
26
+ describe "when configured" do
27
+ let(:skip_open_market_configuration) { false }
28
+
29
+ it "is accessible" do
30
+ expect(subject.public_send(configuration_option)).to eq(public_send(configuration_option))
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ require "yaml"
2
+ require "logger"
3
+ require "rspec/core/shared_context"
4
+ require "sms_validation"
5
+
6
+ module ConfigurationFromYaml
7
+ extend RSpec::Core::SharedContext
8
+ SECRETS = YAML::load(File.open(File.expand_path("#{__FILE__}/../secrets.yml")))
9
+
10
+ SECRETS.keys.each do |key|
11
+ let(key) { SECRETS[key] }
12
+ end
13
+
14
+ let(:skip_open_market_configuration) { false }
15
+
16
+ before(:each) do
17
+ SmsValidation.configure do |config|
18
+ config.logger = ::Logger.new(STDOUT)
19
+ end
20
+ OpenMarket.configure do |config|
21
+ config.id, config.password, config.short_code, config.program_id = id, password, short_code, program_id
22
+ end unless skip_open_market_configuration
23
+ end
24
+
25
+ after(:each) do
26
+ OpenMarket.instance_variable_set("@configuration", nil)
27
+ SmsValidation.instance_variable_set("@configuration", nil)
28
+ end
29
+ end
30
+
31
+ RSpec.configure do |config|
32
+ config.include ConfigurationFromYaml
33
+ end
@@ -0,0 +1,7 @@
1
+ id: 000-000-000-00000
2
+ password: Re@llyL0ngR&om$tr1ng
3
+ short_code: 99999
4
+ program_id: ABC
5
+ phone: 2125551212
6
+ carrier_id: 788
7
+ dr_url: http://www.example.com/drs
metadata ADDED
@@ -0,0 +1,280 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: openmarket
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Isaac Betesh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sms_validation
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.0.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.0.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: httparty
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: builder
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: |
98
+ # OpenMarket
99
+
100
+ We use HTTParty to send SMS messages using the OpenMarket API. See USAGE below for details.
101
+
102
+ ## Installation
103
+
104
+ Add this line to your application's Gemfile:
105
+
106
+ ```ruby
107
+ gem 'openmarket'
108
+ ```
109
+
110
+ And then execute:
111
+
112
+ $ bundle
113
+
114
+ Or install it yourself as:
115
+
116
+ $ gem install openmarket
117
+
118
+ ## Usage
119
+
120
+ ### Configuratiion
121
+
122
+ The openmarket gem requires you to provide an id, password, program_id and short_code. Configure them before attempting any API calls.
123
+
124
+ ```ruby
125
+ OpenMarket.configure do |config|
126
+ config.id = "000-000-000-00000"
127
+ config.password = "Re@llyL0ngR&om$tr1ng"
128
+ config.program_id = "ABC"
129
+ config.short_code = 99999 # You can override this on an individual message if necessary
130
+ end
131
+ ```
132
+
133
+ Since the openmarket gem depends on sms_validation (https://github.com/betesh/sms_validation/), it is also recommended that you configure sms_validation.
134
+ openmarket uses sms_validation's logger. In a Rails environment, you will probably want to rely on the default configuration,
135
+ but outside of Rails, you will need to configure it if you want any logging:
136
+
137
+ ```ruby
138
+ SmsValidation.configure do |config|
139
+ config.logger = ::Logger.new(STDOUT)
140
+ end
141
+ ```
142
+
143
+ ### API calls
144
+
145
+ `OpenMarket::API` supports 3 API calls: `carrier_lookup`, `send_sms`, and `status`.
146
+
147
+ #### carrier_lookup
148
+
149
+ ```ruby
150
+ require 'openmarket'
151
+ phone = 2125551212
152
+ result = OpenMarket::API.carrier_lookup(phone)
153
+
154
+ # First, make sure the call succeeded
155
+ puts result.code # should be 0
156
+ puts result.description # should be 'No Error'
157
+
158
+ # If the call succeeded, you can check the carrier_id:
159
+ puts result.carrier_id # You are probably most interested in the carrier_id
160
+ puts result.inspect # But there are a lot of other attributes returned by this API call as well
161
+ ```
162
+
163
+ #### send_sms
164
+
165
+ ```ruby
166
+ require 'openmarket'
167
+ phone = 2125551212
168
+ message = "Hello, this is a test of the OpenMarket API"
169
+ result = OpenMarket::API.send_sms(phone, message)
170
+
171
+ # First, make sure the call succeeded
172
+ puts result.code # should be 2
173
+ puts result.description # should be 'Message received.'
174
+
175
+ # Save the ticket ID for later. We'll use this to query the status of the ticket.
176
+ ticket_id = result.ticket_id
177
+
178
+ # Save the carrier ID for later. We'll use this next time we send an SMS to this number.
179
+ carrier_id = result.carrier_id
180
+
181
+ # There are some options you can pass along as well:
182
+ result = OpenMarket::API.send_sms(
183
+ phone,
184
+ message,
185
+
186
+ # If you want to receive DR's, you must pass a dr_url option. If you don't pass a URL, no DR will be sent to the default URL.
187
+ dr_url: "http://www.example.com/drs",
188
+
189
+ # It is highly recommended to pass a carrier_id. If you don't, the openmarket gem will make an extra API call to look up the carrier before sending the message.
190
+ carrier_id: carrier_id, # Remember the carrier ID we saved from the previous SMS?
191
+
192
+ # If you don't want to the short_code you configured above, provide another short_code to send to:
193
+ short_code: 33333,
194
+
195
+ # By default, OpenMarket re-attempts delivery for 3 days. To make OpenMarket give up and report it as a failure sooner, pass a number of minutes you would like to retry for:
196
+ minutes_to_retry: 120, # 2 hours
197
+
198
+ note: "Information that will be passed on to the DR",
199
+
200
+ ticket_id_for_retry: ticket_id # If this is a re-try of a failed ticket.
201
+ )
202
+
203
+ ```
204
+ #### status
205
+
206
+ ```ruby
207
+ require 'openmarket'
208
+ result = OpenMarket::API.status(ticket_id) # Remember the ticket ID we saved from #send_sms?
209
+
210
+ # First, make sure the call succeeded
211
+ puts result.code # should be 0
212
+ puts result.description # should be 'No Error'
213
+
214
+ # Check the result of the SMS message
215
+ puts result.status_code
216
+ puts result.status_description
217
+
218
+ ```
219
+
220
+ ## Contributing
221
+
222
+ 1. Fork it ( https://github.com/betesh/open_market/fork )
223
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
224
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
225
+ 4. Push to the branch (`git push origin my-new-feature`)
226
+ 5. Create a new Pull Request
227
+ email:
228
+ - iybetesh@gmail.com
229
+ executables: []
230
+ extensions: []
231
+ extra_rdoc_files: []
232
+ files:
233
+ - ".gitignore"
234
+ - ".rspec"
235
+ - Gemfile
236
+ - LICENSE.txt
237
+ - README.md
238
+ - Rakefile
239
+ - lib/open_market.rb
240
+ - lib/open_market/api.rb
241
+ - lib/open_market/configuration.rb
242
+ - lib/open_market/dr.rb
243
+ - lib/open_market/mo.rb
244
+ - lib/open_market/response.rb
245
+ - lib/open_market/version.rb
246
+ - lib/openmarket.rb
247
+ - open_market.gemspec
248
+ - spec/api_spec.rb
249
+ - spec/configuration_spec.rb
250
+ - spec/support/configuration_from_yaml.rb
251
+ - spec/support/secrets.yml.example
252
+ homepage: https://github.com/betesh/open_market
253
+ licenses:
254
+ - MIT
255
+ metadata: {}
256
+ post_install_message:
257
+ rdoc_options: []
258
+ require_paths:
259
+ - lib
260
+ required_ruby_version: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
265
+ required_rubygems_version: !ruby/object:Gem::Requirement
266
+ requirements:
267
+ - - ">="
268
+ - !ruby/object:Gem::Version
269
+ version: '0'
270
+ requirements: []
271
+ rubyforge_project:
272
+ rubygems_version: 2.4.3
273
+ signing_key:
274
+ specification_version: 4
275
+ summary: Send SMS messages using the OpenMarket API
276
+ test_files:
277
+ - spec/api_spec.rb
278
+ - spec/configuration_spec.rb
279
+ - spec/support/configuration_from_yaml.rb
280
+ - spec/support/secrets.yml.example