instedd-pigeon 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|