module TextMagic class API extend Charset extend Validation # Creates new API instance with specified credentials. These will be # used in all requests to the TextMagic SMS gateway done through # this instance. Multiple instances with different credentials can # be used at the same time. # # Example usage: # # api = TextMagic::API.new('fred', 'secret') def initialize(username, password) @username = username @password = password end # Executes an account command by sending a request to the TextMagic's # SMS gateway. # # This method returns an object with balance attribute. # In case the request to the SMS gateway is not successful or the server # returns an error response, an Error is raised. # # Example usage: # # api.account.balance # # => 314.15 def account hash = Executor.execute('account', @username, @password) TextMagic::API::Response.account(hash) end # Executes a send command by sending a request to the TextMagic's # SMS gateway. # # If called with a single phone number, this method returns a string message id. # If called with multiple phone numbers, it will return an hash of message ids # with phone numbers as keys. # In both cases the returned object is extended with +sent_text+ and +parts_count+ # attributes. # In case the request to the SMS gateway is not successful or the server returns # an error response, an Error is raised. # # The optional parameters you can specify in the options Hash are: # * +unicode+: accepted values are +true+, +false+, +0+ and +1+. If not specified, # the method will determine the unicode value based on the characters in # the text. # * +max_length+: accepted values are +nil+, +1+, +2+ and +3+, defaults to nil. # If not specified, the SMS gateway will apply its own default value. # * +send_time+: allows you to postpone sending of the message. Note that the message # will be sent to the SMS gateway immediately and will wait there until the specified # time. You can either supply a numeric value denoting number of seconds since # 1.1.1970, or a Time object. # # Example usage: # # api.send('Hi Wilma', '999314159265') # # => '141421' # response = api.send('Hello everybody', '999314159265', '999271828182', :max_length => 2) # # => { '999314159265' => '141421', '999271828182' => '173205' } # response.parts_count # # => 1 # # Multiple phone numbers can be supplied as an array or as a list of arguments: # # api.send('Hello everybody', ['999314159265', '999271828182']) # api.send('Hello everybody', '999314159265', '999271828182') # # If you want to send a message to a single phone number but still # want to get a hash response, put the phone number in an array: # # api.send('Hi Barney', ['999271828182']) # # Postponed sending: # # api.send('Two hours later', '999314159265', :send_time => Time.now.to_i + 7200) def send(text, *args) raise Error.new(1, 'Message text is empty') if text.nil? || text.blank? options = args.last.is_a?(Hash) ? args.pop : {} unicode = API.is_unicode(text) options[:unicode] = case options[:unicode] when 1, true: 1 when 0, false: 0 when nil: unicode ? 1 : 0 else raise Error.new(10, "Wrong parameter value #{options[:unicode]} for parameter unicode") end raise Error.new(6, 'Message contains invalid characters') if unicode && options[:unicode] == 0 raise Error.new(7, 'Message too long') unless API.validate_text_length(text, unicode) single = args.size == 1 && args.first.is_a?(String) phones = args.flatten raise Error.new(9, 'Invalid phone number format') unless API.validate_phones(phones) options[:send_time] = options[:send_time].to_i if options[:send_time] hash = Executor.execute('send', @username, @password, options.merge(:text => text, :phone => phones.join(','))) TextMagic::API::Response.send(hash, single) end # Executes a message_status command by sending a request to the TextMagic's # SMS gateway. # # If called with a single +id+, this method returns a single string value # denoting the message status. This string is extended with custom attributes # +text+, +status+, +created_time+, +completed_time+, +reply_number+ and # +credits_cost+. If called with multiple ids, it returns a hash of such # strings with message ids as keys. # In case the request to the SMS gateway is not successful or the server returns # an error response, an Error is raised. # # Example usage: # # status = api.message_status('141421') # # => 'd' # status.completed_time # # => Fri May 22 10:10:18 +0200 2009 # # Example with multiple ids: # # statuses = api.message_status('141421', '173205') # # => { '141421' => 'r', '173205' => 'd' } # statuses['141421'].text # # => 'Hi Wilma' # statuses['173205'].created_time # # => Thu May 28 16:41:45 +0200 2009 # # Multiple ids can be supplied as an array or as a list of arguments: # # api.send('Hello everybody', ['999314159265', '999271828182']) # api.send('Hello everybody', '999314159265', '999271828182') # # If you want to request status for a single message but still want to get # a hash response, put the id in an array: # # api.message_status(['141421']) # # It is strongly encouraged to setup callbacks to receive updates on message status # instead of using this method. def message_status(*ids) single = ids.size == 1 && ids.first.is_a?(String) ids.flatten! raise TextMagic::API::Error.new(4, 'Insufficient parameters') if ids.empty? hash = Executor.execute('message_status', @username, @password, :ids => ids.join(',')) TextMagic::API::Response.message_status(hash, single) end alias :status :message_status # Executes a receive command by sending a request to the TextMagic's # SMS gateway. # # This method returnes an array with retrieved messages. Every member of # the array is a string with +from+, +text+, +timestamp+ and +message_id+ # attributes. The value of every string contains a phone number and text. # In case the request to the SMS gateway is not successful or the server returns # an error response, an Error is raised. # # This method accepts an optional +last_retrieved_id+ value. If called # with this argument, the gateway will only return replies newer than the # one with specified id. # # Example usage: # # replies = api.receive # # => ['999271828182: Hello Fred', '999314159265: Good day'] # replies.first.text # # => 'Hello Fred' # replies.first.from # # => '999314159265' # replies.last.message_id # # => '223606' # api.receive '223606' # # => [] # # It is strongly encouraged to setup callbacks to receive replies instead of # using this method. def receive(last_retrieved_id = nil) hash = Executor.execute('receive', @username, @password, :last_retrieved_id => last_retrieved_id) TextMagic::API::Response.receive(hash) end # Executes a delete_reply command by sending a request to the TextMagic's # SMS gateway. # # This method always returns true. # In case the request to the SMS gateway is not successful or the server returns # an error response, an Error is raised. # # Example usage: # # api.delete_reply('141421') # api.delete_reply('173205', '223606') # api.delete_reply(['244948', '264575']) def delete_reply(*ids) single = ids.size == 1 && ids.first.is_a?(String) ids.flatten! raise TextMagic::API::Error.new(4, 'Insufficient parameters') if ids.empty? Executor.execute('delete_reply', @username, @password, :ids => ids.join(',')) true end alias :delete :delete_reply # Executes a check_number command by sending a request to the TextMagic's # SMS gateway. # # If called with a single phone number, this method returns an OpenStruct instance # with credit price and country code for the given phone number. If called with # multiple phone numbers, the method returns a hash of such instances with phone # numbers as keys. # In case the request to the SMS gateway is not successful or the server returns # an error response, an Error is raised. # # Example usage: # # check = api.check_number('447624800500') # check.price # # => 0.8 # check.country # # => 'GB' # # Example with multiple phone numbers: # # check = api.check_number('447624800500', '61428102137') # check['447624800500'].price # # => 0.8 # check['61428102137'].country # # => 'AU' # # Multiple phone number can be supplied as an array or as a list of arguments: # # api.check_number(['447624800500', '61428102137']) # api.check_number('447624800500', '61428102137') # # If you want to check a single phone number but still want to get # a hash response, put the number in an array: # # api.check_number(['447624800500']) def check_number(*phones) single = phones.size == 1 && phones.first.is_a?(String) phones.flatten! raise TextMagic::API::Error.new(4, 'Insufficient parameters') if phones.empty? hash = Executor.execute('check_number', @username, @password, :phone => phones.join(',')) TextMagic::API::Response.check_number(hash, single) end alias :check :check_number end end