PageRenderTime 50ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/pigeon/nuntium.rb

https://bitbucket.org/instedd/pigeon
Ruby | 295 lines | 172 code | 47 blank | 76 comment | 18 complexity | d93afa2a077dd8d14da7d6d41f24fae5 MD5 | raw file
  1. # Provides access to the Nuntium Public API.
  2. # Taken from the nuntium-api-ruby gem version 0.21
  3. # See http://bitbucket.org/instedd/nuntium-api-ruby
  4. require 'net/http'
  5. require 'json'
  6. require 'rest_client'
  7. require 'cgi'
  8. require 'pigeon/errors'
  9. require 'pigeon/utils'
  10. module Pigeon
  11. class Nuntium
  12. include Pigeon::Utils
  13. def self.error_class
  14. Pigeon::NuntiumException
  15. end
  16. def self.from_config
  17. config = Pigeon.config
  18. Nuntium.new config.nuntium_host, config.nuntium_account, config.nuntium_app, config.nuntium_app_password
  19. end
  20. # Creates an application-authenticated Nuntium api access.
  21. def initialize(url, account, application, password)
  22. @url = url
  23. @account = account
  24. @application = application
  25. @options = {
  26. :user => "#{account}/#{application}",
  27. :password => password,
  28. :headers => {:content_type => 'application/json'},
  29. }
  30. end
  31. # Gets the list of countries known to Nuntium as an array of hashes.
  32. #
  33. # Raises ::Pigeon::NuntiumException if something goes wrong.
  34. def countries
  35. get_json "/api/countries.json"
  36. end
  37. # Gets a country as a hash given its iso2 or iso3 code, or nil if a country with that iso does not exist.
  38. #
  39. # Raises ::Pigeon::NuntiumException if something goes wrong.
  40. def country(iso)
  41. get_json "/api/countries/#{iso}.json"
  42. end
  43. # Gets the list of carriers known to Nuntium that belong to a country as an array of hashes, given its
  44. # iso2 or iso3 code. Gets all carriers as an array of hashes if no country is specified.
  45. #
  46. # Raises ::Pigeon::NuntiumException if something goes wrong.
  47. def carriers(country_id = nil)
  48. if country_id
  49. get_json "/api/carriers.json?country_id=#{country_id}"
  50. else
  51. get_json "/api/carriers.json"
  52. end
  53. end
  54. # Gets a carrier as a hash given its guid, or nil if a carrier with that guid does not exist.
  55. #
  56. # Raises ::Pigeon::NuntiumException if something goes wrong.
  57. def carrier(guid)
  58. get_json "/api/carriers/#{guid}.json"
  59. end
  60. # Returns the list of channels belonging to the application or that don't
  61. # belong to any application, as an array of hashes.
  62. #
  63. # Raises ::Pigeon::NuntiumException if something goes wrong.
  64. def channels
  65. get "/api/channels.json" do |response, error|
  66. raise ::Pigeon::NuntiumException.new error.message if error
  67. channels = JSON.parse response.body
  68. channels.map! do |channel|
  69. read_configuration channel
  70. with_indifferent_access channel
  71. end
  72. channels
  73. end
  74. end
  75. # Returns a channel given its name. Raises when the channel does not exist.
  76. #
  77. # Raises ::Pigeon::NuntiumException if something goes wrong.
  78. def channel(name)
  79. get("/api/channels/#{name}.json") do |response, error|
  80. raise ::Pigeon::NuntiumException.new error.message if error
  81. channel = JSON.parse response.body
  82. read_configuration channel
  83. with_indifferent_access channel
  84. end
  85. end
  86. # Creates a channel.
  87. #
  88. # create_channel :name => 'foo', :kind => 'qst_server', :protocol => 'sms', :configuration => {:password => 'bar'}
  89. #
  90. # Raises ::Pigeon::NuntiumException if something goes wrong. You can access specific errors on properties via the properties
  91. # accessor of the exception.
  92. def create_channel(channel)
  93. channel = channel.dup
  94. write_configuration channel
  95. post "/api/channels.json", channel.to_json do |response, error|
  96. handle_channel_error error if error
  97. channel = JSON.parse response.body
  98. read_configuration channel
  99. with_indifferent_access channel
  100. end
  101. end
  102. # Updates a channel.
  103. #
  104. # update_channel :name => 'foo', :kind => 'qst_server', :protocol => 'sms', :configuration => {:password => 'bar'}
  105. #
  106. # Raises ::Pigeon::NuntiumException if something goes wrong. You can access specific errors on properties via the properties
  107. # accessor of the exception.
  108. def update_channel(channel)
  109. channel = channel.dup
  110. write_configuration channel
  111. channel_name = channel['name'] || channel[:name]
  112. put "/api/channels/#{channel_name}.json", channel.to_json do |response, error|
  113. handle_channel_error error if error
  114. channel = JSON.parse response.body
  115. read_configuration channel
  116. with_indifferent_access channel
  117. end
  118. end
  119. # Deletes a chnanel given its name.
  120. #
  121. # Raises ::Pigeon::NuntiumException if something goes wrong.
  122. def delete_channel(name)
  123. delete "/api/channels/#{name}" do |response, error|
  124. raise ::Pigeon::NuntiumException.new error.message if error
  125. response
  126. end
  127. end
  128. # Returns the list of candidate channels when simulating routing the given AO message.
  129. #
  130. # candidate_channels_for_ao :from => 'sms://1', :to => 'sms://2', :subject => 'hello', :body => 'hi!'
  131. #
  132. # Raises ::Pigeon::NuntiumException if something goes wrong.
  133. def candidate_channels_for_ao(message)
  134. get_channels "/api/candidate/channels.json?#{to_query message}"
  135. end
  136. # Sends one or many AO messages.
  137. #
  138. # To send a token, just include it in the message as :token => 'my_token'
  139. #
  140. # send_ao :from => 'sms://1', :to => 'sms://2', :subject => 'hello', :body => 'hi!'
  141. # send_ao [{:from => 'sms://1', :to => 'sms://2', :subject => 'hello', :body => 'hi!'}, {...}]
  142. #
  143. # Returns a hash with :id, :guid and :token keys if a single message was sent, otherwise
  144. # returns a hash with a :token key.
  145. #
  146. # Raises ::Pigeon::NuntiumException if something goes wrong.
  147. def send_ao(messages)
  148. if messages.is_a? Array
  149. post "/#{@account}/#{@application}/send_ao.json", messages.to_json do |response, error|
  150. raise ::Pigeon::NuntiumException.new error.message if error
  151. with_indifferent_access({:token => response.headers[:x_nuntium_token]})
  152. end
  153. else
  154. get "/#{@account}/#{@application}/send_ao?#{to_query messages}" do |response, error|
  155. raise ::Pigeon::NuntiumException.new error.message if error
  156. with_indifferent_access(
  157. {
  158. :id => response.headers[:x_nuntium_id],
  159. :guid => response.headers[:x_nuntium_guid],
  160. :token => response.headers[:x_nuntium_token],
  161. }
  162. )
  163. end
  164. end
  165. end
  166. # Gets AO messages that have the given token. The response is an array of hashes with the messages' attributes.
  167. #
  168. # Raises ::Pigeon::NuntiumException if something goes wrong.
  169. def get_ao(token)
  170. get_json "/#{@account}/#{@application}/get_ao.json?token=#{token}"
  171. end
  172. # Gets the custom attributes specified for a given address. Returns a hash with the attributes
  173. #
  174. # Raises ::Pigeon::NuntiumException if something goes wrong.
  175. def get_custom_attributes(address)
  176. get_json "/api/custom_attributes?address=#{address}"
  177. end
  178. # Sets custom attributes of a given address.
  179. #
  180. # Raises ::Pigeon::NuntiumException if something goes wrong.
  181. def set_custom_attributes(address, attributes)
  182. post "/api/custom_attributes?address=#{address}", attributes.to_json do |response, error|
  183. raise ::Pigeon::NuntiumException.new error.message if error
  184. nil
  185. end
  186. end
  187. # Creates a friendship between the channel's twitter account and the given user.
  188. # Returns the response from twitter.
  189. # Refer to Twitter's documentation: https://dev.twitter.com/docs/api/1/post/friendships/create
  190. #
  191. # Raises ::Pigeon::NuntiumException if something goes wrong.
  192. def twitter_friendship_create(channel_name, user, follow = true)
  193. get("/api/channels/#{channel_name}/twitter/friendships/create?user=#{CGI.escape user}&follow=#{follow}") do |response, error|
  194. raise ::Pigeon::NuntiumException.new error.message if error
  195. response
  196. end
  197. end
  198. # Returns a URL to authorize the given twitter channel, which will eventually redirect
  199. # to the given callback URL.
  200. #
  201. # Raises ::Pigeon::NuntiumException if something goes wrong.
  202. def twitter_authorize(channel_name, callback)
  203. get_text("/api/channels/#{channel_name}/twitter/authorize?callback=#{CGI.escape callback}")
  204. end
  205. # Adds an xmpp conact to the xmpp account associated to the given channel.
  206. #
  207. # Raises ::Pigeon::NuntiumException if something goes wrong.
  208. def xmpp_add_contact(channel_name, jid)
  209. get("/api/channels/#{channel_name}/xmpp/add_contact?jid=#{CGI.escape jid}") do |response, error|
  210. raise ::Pigeon::NuntiumException.new error.message if error
  211. response
  212. end
  213. end
  214. private
  215. def write_configuration(channel)
  216. return unless channel[:configuration] || channel['configuration']
  217. configuration = []
  218. (channel[:configuration] || channel['configuration']).each do |name, value|
  219. configuration << {:name => name, :value => value}
  220. end
  221. if channel[:configuration]
  222. channel[:configuration] = configuration
  223. else
  224. channel['configuration'] = configuration
  225. end
  226. end
  227. def read_configuration(channel)
  228. channel['configuration'] = Hash[channel['configuration'].map { |e| [e['name'], e['value']] }]
  229. end
  230. def get_text(path)
  231. get(path) do |response, error|
  232. raise ::Pigeon::NuntiumException.new error.message if error
  233. response.body
  234. end
  235. end
  236. def get_channels(path)
  237. get(path) do |response, error|
  238. raise ::Pigeon::NuntiumException.new error.message if error
  239. channels = JSON.parse response.body
  240. channels.map! do |channel|
  241. read_configuration channel
  242. with_indifferent_access channel
  243. end
  244. channels
  245. end
  246. end
  247. end
  248. end