instedd-pigeon 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/app/helpers/pigeon/channel_helper.rb +6 -0
- data/app/models/pigeon/channel.rb +4 -0
- data/app/models/pigeon/channel_attribute.rb +1 -1
- data/app/models/pigeon/nuntium_channel.rb +10 -4
- data/app/models/pigeon/verboice_channel.rb +8 -5
- data/config/locales/en.yml +6 -0
- data/config/schemas/nuntium/nuntium.yml +17 -27
- data/config/schemas/nuntium/smpp.yml +71 -0
- data/lib/pigeon.rb +12 -0
- data/lib/pigeon/errors.rb +18 -0
- data/lib/pigeon/nuntium.rb +290 -5
- data/lib/pigeon/utils.rb +70 -0
- data/lib/pigeon/verboice.rb +149 -5
- data/lib/pigeon/version.rb +1 -1
- data/pigeon.gemspec +3 -3
- data/spec/lib/pigeon/nuntium_spec.rb +208 -0
- data/spec/lib/pigeon/verboice_spec.rb +181 -0
- metadata +25 -17
data/.rspec
ADDED
@@ -24,6 +24,12 @@ module Pigeon
|
|
24
24
|
choices = choices.map { |h| [h["display"], h["value"]] }
|
25
25
|
end
|
26
26
|
select_tag(field_name, options_for_select(choices, field_value), options)
|
27
|
+
when "multi"
|
28
|
+
choices = attribute.options
|
29
|
+
if choices.length > 0 && choices[0].is_a?(Hash)
|
30
|
+
choices = choices.map { |h| [h["display"], h["value"]] }
|
31
|
+
end
|
32
|
+
select_tag(field_name, options_for_select(choices, field_value), { :multiple => true }.merge(options))
|
27
33
|
when "timezone"
|
28
34
|
select_tag(field_name, time_zone_options_for_select(field_value), options)
|
29
35
|
when "boolean"
|
@@ -30,7 +30,7 @@ module Pigeon
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.valid_type?(type)
|
33
|
-
%w(string boolean password enum integer timezone hidden).include?(type.to_s)
|
33
|
+
%w(string boolean password enum multi integer timezone hidden).include?(type.to_s)
|
34
34
|
end
|
35
35
|
|
36
36
|
def self.build_default(name, hint_value = nil)
|
@@ -15,7 +15,7 @@ module Pigeon
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def nuntium
|
18
|
-
@nuntium ||= Nuntium.from_config
|
18
|
+
@nuntium ||= ::Pigeon::Nuntium.from_config
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
@@ -25,7 +25,13 @@ module Pigeon
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def load_schemas
|
28
|
-
Pigeon
|
28
|
+
if Pigeon.config.nuntium_configured?
|
29
|
+
Pigeon::ChannelSchema.list_from_hash(:nuntium, PigeonConfig::NuntiumChannelSchemas).reject do |schema|
|
30
|
+
schema.kind == 'twitter' && !Pigeon.config.twitter_configured?
|
31
|
+
end
|
32
|
+
else
|
33
|
+
[]
|
34
|
+
end
|
29
35
|
end
|
30
36
|
end
|
31
37
|
|
@@ -49,7 +55,7 @@ module Pigeon
|
|
49
55
|
self.class.nuntium.update_channel attributes
|
50
56
|
end
|
51
57
|
true
|
52
|
-
rescue
|
58
|
+
rescue Pigeon::NuntiumException => e
|
53
59
|
Rails.logger.warn "error saving Nuntium channel: #{e.message}"
|
54
60
|
e.properties.each do |name, message|
|
55
61
|
if attributes.include? name
|
@@ -71,7 +77,7 @@ module Pigeon
|
|
71
77
|
self.class.nuntium.delete_channel(name)
|
72
78
|
end
|
73
79
|
@destroyed = true
|
74
|
-
rescue
|
80
|
+
rescue Pigeon::NuntiumException => e
|
75
81
|
Rails.logger.warn "error deleting Nuntium channel: #{e.message}"
|
76
82
|
end
|
77
83
|
end
|
@@ -13,7 +13,7 @@ module Pigeon
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def verboice
|
16
|
-
@verboice ||= Verboice.from_config
|
16
|
+
@verboice ||= ::Pigeon::Verboice.from_config
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
@@ -23,7 +23,11 @@ module Pigeon
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def load_schemas
|
26
|
-
Pigeon
|
26
|
+
if Pigeon.config.verboice_configured?
|
27
|
+
Pigeon::ChannelSchema.list_from_hash(:verboice, PigeonConfig::VerboiceChannelSchemas)
|
28
|
+
else
|
29
|
+
[]
|
30
|
+
end
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
@@ -39,7 +43,6 @@ module Pigeon
|
|
39
43
|
return false unless valid?
|
40
44
|
|
41
45
|
begin
|
42
|
-
puts attributes
|
43
46
|
if !persisted?
|
44
47
|
self.class.verboice.create_channel attributes
|
45
48
|
@persisted = true
|
@@ -47,7 +50,7 @@ module Pigeon
|
|
47
50
|
self.class.verboice.update_channel attributes
|
48
51
|
end
|
49
52
|
true
|
50
|
-
rescue
|
53
|
+
rescue Pigeon::VerboiceException => e
|
51
54
|
Rails.logger.warn "error saving Verboice channel: #{e.message}"
|
52
55
|
e.properties.each do |name, message|
|
53
56
|
if attributes.include? name
|
@@ -69,7 +72,7 @@ module Pigeon
|
|
69
72
|
self.class.verboice.delete_channel(name)
|
70
73
|
end
|
71
74
|
@destroyed = true
|
72
|
-
rescue
|
75
|
+
rescue Pigeon::VerboiceException => e
|
73
76
|
Rails.logger.warn "error deleting Verboice channel: #{e.message}"
|
74
77
|
end
|
75
78
|
end
|
@@ -34,6 +34,9 @@ clickatell:
|
|
34
34
|
type: password
|
35
35
|
humanized_name: Incoming password
|
36
36
|
label: Incoming password (to use for the callback URLs)
|
37
|
+
- name: cost_per_credit
|
38
|
+
label: "Cost per credit (messages will get a 'cost' custom attribute with the value charge * cost_per_credit)"
|
39
|
+
default_value: 1
|
37
40
|
|
38
41
|
dtac:
|
39
42
|
humanized_name: 'DTAC channel'
|
@@ -43,7 +46,7 @@ dtac:
|
|
43
46
|
user: false
|
44
47
|
- name: configuration
|
45
48
|
attributes:
|
46
|
-
- name:
|
49
|
+
- name: user
|
47
50
|
- name: password
|
48
51
|
type: password
|
49
52
|
|
@@ -53,14 +56,20 @@ ipop:
|
|
53
56
|
- name: protocol
|
54
57
|
value: sms
|
55
58
|
user: false
|
59
|
+
- name: address
|
60
|
+
humanized_name: From address
|
61
|
+
label: 'Address (this is usually the "from" number)'
|
56
62
|
- name: configuration
|
57
63
|
attributes:
|
58
|
-
- name:
|
59
|
-
|
60
|
-
|
64
|
+
- name: mt_post_url
|
65
|
+
humanized_name: Post URL
|
66
|
+
label: Post URL
|
67
|
+
- name: mt_post_user
|
68
|
+
humanized_name: Username
|
61
69
|
label: Username (optional)
|
62
|
-
- name:
|
70
|
+
- name: mt_post_password
|
63
71
|
type: password
|
72
|
+
humanized_name: Password
|
64
73
|
label: Password (optional)
|
65
74
|
- name: cid
|
66
75
|
label: Connection ID (cid)
|
@@ -85,6 +94,9 @@ isms:
|
|
85
94
|
- name: protocol
|
86
95
|
value: sms
|
87
96
|
user: false
|
97
|
+
- name: address
|
98
|
+
humanized_name: From address
|
99
|
+
label: 'Address (this is usually the "from" number)'
|
88
100
|
- name: configuration
|
89
101
|
attributes:
|
90
102
|
- name: host
|
@@ -131,28 +143,6 @@ qst:
|
|
131
143
|
- name: password
|
132
144
|
type: password
|
133
145
|
|
134
|
-
smpp:
|
135
|
-
humanized_name: 'SMPP channel'
|
136
|
-
attributes:
|
137
|
-
- name: protocol
|
138
|
-
value: sms
|
139
|
-
user: false
|
140
|
-
- name: configuration
|
141
|
-
attributes:
|
142
|
-
- name: host
|
143
|
-
- name: port
|
144
|
-
type: integer
|
145
|
-
- name: user
|
146
|
-
- name: password
|
147
|
-
type: password
|
148
|
-
- name: system_type
|
149
|
-
default_value: vma
|
150
|
-
- name: source_ton
|
151
|
-
- name: source_npi
|
152
|
-
- name: destination_ton
|
153
|
-
- name: destination_npi
|
154
|
-
- name: service_type
|
155
|
-
|
156
146
|
smtp:
|
157
147
|
humanized_name: 'SMTP channel'
|
158
148
|
attributes:
|
@@ -0,0 +1,71 @@
|
|
1
|
+
smpp:
|
2
|
+
humanized_name: 'SMPP channel'
|
3
|
+
attributes:
|
4
|
+
- name: protocol
|
5
|
+
value: sms
|
6
|
+
user: false
|
7
|
+
- name: configuration
|
8
|
+
attributes:
|
9
|
+
- name: host
|
10
|
+
- name: port
|
11
|
+
type: integer
|
12
|
+
- name: user
|
13
|
+
- name: password
|
14
|
+
type: password
|
15
|
+
- name: system_type
|
16
|
+
default_value: vma
|
17
|
+
- name: source_ton
|
18
|
+
- name: source_npi
|
19
|
+
- name: destination_ton
|
20
|
+
- name: destination_npi
|
21
|
+
- name: service_type
|
22
|
+
- name: endianness_mo
|
23
|
+
type: boolean
|
24
|
+
label: 'Use little endian for UCS-2 MO messages'
|
25
|
+
- name: endianness_mt
|
26
|
+
type: boolean
|
27
|
+
label: 'Use little endian for UCS-2 MT messages'
|
28
|
+
- name: accept_mo_hex_string
|
29
|
+
type: boolean
|
30
|
+
humanized_name: 'Hex strings'
|
31
|
+
- name: default_mo_encoding
|
32
|
+
type: enum
|
33
|
+
options:
|
34
|
+
- value: 'ascii'
|
35
|
+
display: 'ASCII'
|
36
|
+
- value: 'latin1'
|
37
|
+
display: 'Latin1'
|
38
|
+
- value: 'ucs-2'
|
39
|
+
display: 'UCS-2'
|
40
|
+
- value: 'gsm'
|
41
|
+
display: 'GSM 03.38'
|
42
|
+
- name: mt_encodings
|
43
|
+
type: multi
|
44
|
+
options:
|
45
|
+
- value: 'ascii'
|
46
|
+
display: 'ASCII'
|
47
|
+
- value: 'latin1'
|
48
|
+
display: 'Latin1'
|
49
|
+
- value: 'ucs-2'
|
50
|
+
display: 'UCS-2'
|
51
|
+
- name: mt_max_length
|
52
|
+
type: enum
|
53
|
+
options:
|
54
|
+
- 140
|
55
|
+
- 160
|
56
|
+
- 254
|
57
|
+
- name: mt_csms_method
|
58
|
+
type: enum
|
59
|
+
options:
|
60
|
+
- value: 'udh'
|
61
|
+
display: 'UDH'
|
62
|
+
- value: 'optional_parameters'
|
63
|
+
display: 'Optional parameters'
|
64
|
+
- value: 'message_payload'
|
65
|
+
display: 'Message payload'
|
66
|
+
default_value: 'optional_parameters'
|
67
|
+
- name: suspension_codes
|
68
|
+
label: 'Suspension codes (comma separated)'
|
69
|
+
- name: rejection_codes
|
70
|
+
label: 'Rejection codes (comma separated)'
|
71
|
+
|
data/lib/pigeon.rb
CHANGED
@@ -9,6 +9,18 @@ module Pigeon
|
|
9
9
|
attr_accessor :verboice_default_call_flow
|
10
10
|
|
11
11
|
attr_accessor :twitter_consumer_key, :twitter_consumer_secret
|
12
|
+
|
13
|
+
def nuntium_configured?
|
14
|
+
nuntium_host.present? && nuntium_account.present? && nuntium_app.present? && nuntium_app_password.present?
|
15
|
+
end
|
16
|
+
|
17
|
+
def verboice_configured?
|
18
|
+
verboice_host.present? && verboice_account.present? && verboice_password.present?
|
19
|
+
end
|
20
|
+
|
21
|
+
def twitter_configured?
|
22
|
+
twitter_consumer_key.present? && twitter_consumer_secret.present?
|
23
|
+
end
|
12
24
|
end
|
13
25
|
|
14
26
|
def self.config
|
data/lib/pigeon/errors.rb
CHANGED
@@ -7,6 +7,8 @@ module Pigeon
|
|
7
7
|
|
8
8
|
def initialize(channel)
|
9
9
|
@channel = channel
|
10
|
+
errors = @channel.errors.full_messages.join(", ")
|
11
|
+
super(I18n.t(:"#{@channel.class.i18n_scope}.errors.messages.channel_invalid", :errors => errors, :default => :"errors.messages.channel_invalid"))
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
@@ -24,5 +26,21 @@ module Pigeon
|
|
24
26
|
})
|
25
27
|
end
|
26
28
|
end
|
29
|
+
|
30
|
+
class ApiException < PigeonError
|
31
|
+
attr_accessor :properties
|
32
|
+
|
33
|
+
def initialize(msg, properties = {})
|
34
|
+
super msg
|
35
|
+
@properties = properties
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class VerboiceException < ApiException
|
40
|
+
end
|
41
|
+
|
42
|
+
class NuntiumException < ApiException
|
43
|
+
end
|
44
|
+
|
27
45
|
end
|
28
46
|
|
data/lib/pigeon/nuntium.rb
CHANGED
@@ -1,10 +1,295 @@
|
|
1
|
-
|
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
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
|
5
|
+
require 'net/http'
|
6
|
+
require 'json'
|
7
|
+
require 'rest_client'
|
8
|
+
require 'cgi'
|
9
|
+
require 'pigeon/errors'
|
10
|
+
require 'pigeon/utils'
|
11
|
+
|
12
|
+
module Pigeon
|
13
|
+
class Nuntium
|
14
|
+
include Pigeon::Utils
|
15
|
+
|
16
|
+
def self.error_class
|
17
|
+
Pigeon::NuntiumException
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.from_config
|
21
|
+
config = Pigeon.config
|
22
|
+
|
23
|
+
Nuntium.new config.nuntium_host, config.nuntium_account, config.nuntium_app, config.nuntium_app_password
|
24
|
+
end
|
25
|
+
|
26
|
+
# Creates an application-authenticated Nuntium api access.
|
27
|
+
def initialize(url, account, application, password)
|
28
|
+
@url = url
|
29
|
+
@account = account
|
30
|
+
@application = application
|
31
|
+
@options = {
|
32
|
+
:user => "#{account}/#{application}",
|
33
|
+
:password => password,
|
34
|
+
:headers => {:content_type => 'application/json'},
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
# Gets the list of countries known to Nuntium as an array of hashes.
|
39
|
+
#
|
40
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
41
|
+
def countries
|
42
|
+
get_json "/api/countries.json"
|
43
|
+
end
|
44
|
+
|
45
|
+
# Gets a country as a hash given its iso2 or iso3 code, or nil if a country with that iso does not exist.
|
46
|
+
#
|
47
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
48
|
+
def country(iso)
|
49
|
+
get_json "/api/countries/#{iso}.json"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Gets the list of carriers known to Nuntium that belong to a country as an array of hashes, given its
|
53
|
+
# iso2 or iso3 code. Gets all carriers as an array of hashes if no country is specified.
|
54
|
+
#
|
55
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
56
|
+
def carriers(country_id = nil)
|
57
|
+
if country_id
|
58
|
+
get_json "/api/carriers.json?country_id=#{country_id}"
|
59
|
+
else
|
60
|
+
get_json "/api/carriers.json"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Gets a carrier as a hash given its guid, or nil if a carrier with that guid does not exist.
|
65
|
+
#
|
66
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
67
|
+
def carrier(guid)
|
68
|
+
get_json "/api/carriers/#{guid}.json"
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns the list of channels belonging to the application or that don't
|
72
|
+
# belong to any application, as an array of hashes.
|
73
|
+
#
|
74
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
75
|
+
def channels
|
76
|
+
get "/api/channels.json" do |response, error|
|
77
|
+
raise ::Pigeon::NuntiumException.new error.message if error
|
78
|
+
|
79
|
+
channels = JSON.parse response.body
|
80
|
+
channels.map! do |channel|
|
81
|
+
read_configuration channel
|
82
|
+
with_indifferent_access channel
|
83
|
+
end
|
84
|
+
channels
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns a channel given its name. Raises when the channel does not exist.
|
89
|
+
#
|
90
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
91
|
+
def channel(name)
|
92
|
+
get("/api/channels/#{name}.json") do |response, error|
|
93
|
+
raise ::Pigeon::NuntiumException.new error.message if error
|
94
|
+
|
95
|
+
channel = JSON.parse response.body
|
96
|
+
read_configuration channel
|
97
|
+
with_indifferent_access channel
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Creates a channel.
|
102
|
+
#
|
103
|
+
# create_channel :name => 'foo', :kind => 'qst_server', :protocol => 'sms', :configuration => {:password => 'bar'}
|
104
|
+
#
|
105
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong. You can access specific errors on properties via the properties
|
106
|
+
# accessor of the exception.
|
107
|
+
def create_channel(channel)
|
108
|
+
channel = channel.dup
|
109
|
+
|
110
|
+
write_configuration channel
|
111
|
+
post "/api/channels.json", channel.to_json do |response, error|
|
112
|
+
handle_channel_error error if error
|
113
|
+
|
114
|
+
channel = JSON.parse response.body
|
115
|
+
read_configuration channel
|
116
|
+
with_indifferent_access channel
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Updates a channel.
|
121
|
+
#
|
122
|
+
# update_channel :name => 'foo', :kind => 'qst_server', :protocol => 'sms', :configuration => {:password => 'bar'}
|
123
|
+
#
|
124
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong. You can access specific errors on properties via the properties
|
125
|
+
# accessor of the exception.
|
126
|
+
def update_channel(channel)
|
127
|
+
channel = channel.dup
|
128
|
+
|
129
|
+
write_configuration channel
|
130
|
+
channel_name = channel['name'] || channel[:name]
|
131
|
+
|
132
|
+
put "/api/channels/#{channel_name}.json", channel.to_json do |response, error|
|
133
|
+
handle_channel_error error if error
|
134
|
+
|
135
|
+
channel = JSON.parse response.body
|
136
|
+
read_configuration channel
|
137
|
+
with_indifferent_access channel
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Deletes a chnanel given its name.
|
142
|
+
#
|
143
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
144
|
+
def delete_channel(name)
|
145
|
+
delete "/api/channels/#{name}" do |response, error|
|
146
|
+
raise ::Pigeon::NuntiumException.new error.message if error
|
147
|
+
|
148
|
+
response
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Returns the list of candidate channels when simulating routing the given AO message.
|
153
|
+
#
|
154
|
+
# candidate_channels_for_ao :from => 'sms://1', :to => 'sms://2', :subject => 'hello', :body => 'hi!'
|
155
|
+
#
|
156
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
157
|
+
def candidate_channels_for_ao(message)
|
158
|
+
get_channels "/api/candidate/channels.json?#{to_query message}"
|
159
|
+
end
|
160
|
+
|
161
|
+
# Sends one or many AO messages.
|
162
|
+
#
|
163
|
+
# To send a token, just include it in the message as :token => 'my_token'
|
164
|
+
#
|
165
|
+
# send_ao :from => 'sms://1', :to => 'sms://2', :subject => 'hello', :body => 'hi!'
|
166
|
+
# send_ao [{:from => 'sms://1', :to => 'sms://2', :subject => 'hello', :body => 'hi!'}, {...}]
|
167
|
+
#
|
168
|
+
# Returns a hash with :id, :guid and :token keys if a single message was sent, otherwise
|
169
|
+
# returns a hash with a :token key.
|
170
|
+
#
|
171
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
172
|
+
def send_ao(messages)
|
173
|
+
if messages.is_a? Array
|
174
|
+
post "/#{@account}/#{@application}/send_ao.json", messages.to_json do |response, error|
|
175
|
+
raise ::Pigeon::NuntiumException.new error.message if error
|
176
|
+
|
177
|
+
with_indifferent_access({:token => response.headers[:x_nuntium_token]})
|
178
|
+
end
|
179
|
+
else
|
180
|
+
get "/#{@account}/#{@application}/send_ao?#{to_query messages}" do |response, error|
|
181
|
+
raise ::Pigeon::NuntiumException.new error.message if error
|
182
|
+
|
183
|
+
with_indifferent_access(
|
184
|
+
{
|
185
|
+
:id => response.headers[:x_nuntium_id],
|
186
|
+
:guid => response.headers[:x_nuntium_guid],
|
187
|
+
:token => response.headers[:x_nuntium_token],
|
188
|
+
}
|
189
|
+
)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# Gets AO messages that have the given token. The response is an array of hashes with the messages' attributes.
|
195
|
+
#
|
196
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
197
|
+
def get_ao(token)
|
198
|
+
get_json "/#{@account}/#{@application}/get_ao.json?token=#{token}"
|
199
|
+
end
|
200
|
+
|
201
|
+
# Gets the custom attributes specified for a given address. Returns a hash with the attributes
|
202
|
+
#
|
203
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
204
|
+
def get_custom_attributes(address)
|
205
|
+
get_json "/api/custom_attributes?address=#{address}"
|
206
|
+
end
|
207
|
+
|
208
|
+
# Sets custom attributes of a given address.
|
209
|
+
#
|
210
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
211
|
+
def set_custom_attributes(address, attributes)
|
212
|
+
post "/api/custom_attributes?address=#{address}", attributes.to_json do |response, error|
|
213
|
+
raise ::Pigeon::NuntiumException.new error.message if error
|
214
|
+
|
215
|
+
nil
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
# Creates a friendship between the channel's twitter account and the given user.
|
221
|
+
# Returns the response from twitter.
|
222
|
+
# Refer to Twitter's documentation: https://dev.twitter.com/docs/api/1/post/friendships/create
|
223
|
+
#
|
224
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
225
|
+
def twitter_friendship_create(channel_name, user, follow = true)
|
226
|
+
get("/api/channels/#{channel_name}/twitter/friendships/create?user=#{CGI.escape user}&follow=#{follow}") do |response, error|
|
227
|
+
raise ::Pigeon::NuntiumException.new error.message if error
|
228
|
+
|
229
|
+
response
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# Returns a URL to authorize the given twitter channel, which will eventually redirect
|
234
|
+
# to the given callback URL.
|
235
|
+
#
|
236
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
237
|
+
def twitter_authorize(channel_name, callback)
|
238
|
+
get_text("/api/channels/#{channel_name}/twitter/authorize?callback=#{CGI.escape callback}")
|
239
|
+
end
|
240
|
+
|
241
|
+
# Adds an xmpp conact to the xmpp account associated to the given channel.
|
242
|
+
#
|
243
|
+
# Raises ::Pigeon::NuntiumException if something goes wrong.
|
244
|
+
def xmpp_add_contact(channel_name, jid)
|
245
|
+
get("/api/channels/#{channel_name}/xmpp/add_contact?jid=#{CGI.escape jid}") do |response, error|
|
246
|
+
raise ::Pigeon::NuntiumException.new error.message if error
|
247
|
+
|
248
|
+
response
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
private
|
253
|
+
|
254
|
+
def write_configuration(channel)
|
255
|
+
return unless channel[:configuration] || channel['configuration']
|
256
|
+
|
257
|
+
configuration = []
|
258
|
+
(channel[:configuration] || channel['configuration']).each do |name, value|
|
259
|
+
configuration << {:name => name, :value => value}
|
260
|
+
end
|
261
|
+
if channel[:configuration]
|
262
|
+
channel[:configuration] = configuration
|
263
|
+
else
|
264
|
+
channel['configuration'] = configuration
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def read_configuration(channel)
|
269
|
+
channel['configuration'] = Hash[channel['configuration'].map { |e| [e['name'], e['value']] }]
|
270
|
+
end
|
271
|
+
|
272
|
+
def get_text(path)
|
273
|
+
get(path) do |response, error|
|
274
|
+
raise ::Pigeon::NuntiumException.new error.message if error
|
275
|
+
|
276
|
+
response.body
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def get_channels(path)
|
281
|
+
get(path) do |response, error|
|
282
|
+
raise ::Pigeon::NuntiumException.new error.message if error
|
283
|
+
|
284
|
+
channels = JSON.parse response.body
|
285
|
+
channels.map! do |channel|
|
286
|
+
read_configuration channel
|
287
|
+
with_indifferent_access channel
|
288
|
+
end
|
289
|
+
channels
|
290
|
+
end
|
291
|
+
end
|
6
292
|
|
7
|
-
Nuntium.new config.nuntium_host, config.nuntium_account, config.nuntium_app, config.nuntium_app_password
|
8
293
|
end
|
9
294
|
end
|
10
295
|
|