urbanairship 3.0.2 → 3.1.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.
@@ -1,6 +1,6 @@
1
1
  require 'unirest'
2
- require 'urbanairship/common'
3
- require 'urbanairship/loggable'
2
+ require 'urbanairship'
3
+
4
4
 
5
5
  module Urbanairship
6
6
  class Client
@@ -28,10 +28,9 @@ module Urbanairship
28
28
  # @param [Object] url Request URL
29
29
  # @param [Object] content_type Content-Type
30
30
  # @param [Object] version API Version
31
- # @param [Object] params Parameters
32
31
  # @return [Object] Push Response
33
- def send_request(method: required('method'), body: required('body'), url: required('url'),
34
- content_type: nil, version: nil, params: nil)
32
+ def send_request(method: required('method'), url: required('url'), body: nil,
33
+ content_type: nil)
35
34
  req_type = case method
36
35
  when 'GET'
37
36
  :get
@@ -45,26 +44,30 @@ module Urbanairship
45
44
  fail 'Method was not "GET" "POST" "PUT" or "DELETE"'
46
45
  end
47
46
 
48
- logger.debug("Making #{method} request to #{url}. \n\tHeaders:\n\tcontent-type: #{content_type}\n\tversion=#{version.to_s}\nBody:\n\t#{body}")
47
+ headers = {'User-agent' => 'UARubyLib/' + UA::VERSION}
48
+ headers['Accept'] = 'application/vnd.urbanairship+json; version=3'
49
+
50
+ if content_type
51
+ headers['Content-type'] = content_type
52
+ end
53
+
54
+ logger.debug("Making #{method} request to #{url}. \n\tHeaders:\n\tcontent-type: #{content_type}\n\tversion=3\nBody:\n\t#{body}")
49
55
 
50
56
  response = Unirest.method(req_type).call(
51
- url,
52
- headers:{
53
- "Content-type" => content_type,
54
- "Accept" => "application/vnd.urbanairship+json; version=" + version.to_s
55
- },
56
- auth:{
57
- :user=>@key,
58
- :password=>@secret
59
- },
60
- parameters: body
57
+ url,
58
+ headers: headers,
59
+ auth:{
60
+ :user=>@key,
61
+ :password=>@secret
62
+ },
63
+ parameters: body
61
64
  )
62
65
 
63
66
  logger.debug("Received #{response.code} response. Headers:\n\t#{response.headers}\nBody:\n\t#{response.body}")
64
67
 
65
68
  Response.check_code(response.code, response)
66
69
 
67
- {'body'=>response.body, 'code'=>response.code}
70
+ {'body'=>response.body, 'code'=>response.code, 'headers'=>response.headers}
68
71
  end
69
72
 
70
73
  # Create a Push Object
@@ -1,5 +1,6 @@
1
1
  require 'urbanairship/loggable'
2
2
 
3
+
3
4
  module Urbanairship
4
5
  # Features mixed in to all classes
5
6
  module Common
@@ -13,8 +14,9 @@ module Urbanairship
13
14
  DT_FEEDBACK_URL = BASE_URL + '/device_tokens/feedback/'
14
15
  APID_FEEDBACK_URL = BASE_URL + '/apids/feedback/'
15
16
  SCHEDULES_URL = BASE_URL + '/schedules/'
16
- TAGS_URL = BASE_URL + '/tags/'
17
17
  SEGMENTS_URL = BASE_URL + '/segments/'
18
+ NAMED_USER_URL = BASE_URL + '/named_users/'
19
+ REPORTS_URL = BASE_URL + '/reports/'
18
20
 
19
21
  # Helper method for required keyword args in Ruby 2.0 that is compatible with 2.1+
20
22
  # @example
@@ -92,14 +94,56 @@ module Urbanairship
92
94
  # Parse Response Codes and trigger appropriate actions.
93
95
  def self.check_code(response_code, response)
94
96
  if response_code == 401
95
- raise Unauthorized, "Client is not authorized to make this request. The authorization credentials are incorrect or missing."
97
+ raise Unauthorized, 'Client is not authorized to make this request. The authorization credentials are incorrect or missing.'
96
98
  elsif response_code == 403
97
- raise Forbidden, "Client is not forbidden from making this request. The application does not have the proper entitlement to access this feature."
99
+ raise Forbidden, 'Client is forbidden from making this request. The application does not have the proper entitlement to access this feature.'
98
100
  elsif !((200...300).include?(response_code))
99
101
  raise AirshipFailure.new.from_response(response)
100
102
  end
101
103
  end
102
104
  end
103
105
 
106
+ class PageIterator
107
+ include Urbanairship::Common
108
+ include Urbanairship::Loggable
109
+ include Enumerable
110
+ attr_accessor :data_attribute
111
+
112
+ def initialize(client: required('client'))
113
+ @client = client
114
+ @next_page = nil
115
+ @data_list = nil
116
+ @data_attribute = nil
117
+ end
118
+
119
+ def load_page
120
+ return false unless @next_page
121
+ response = @client.send_request(
122
+ method: 'GET',
123
+ url: @next_page
124
+ )
125
+ logger.info("Retrieving data from: #{@next_page}")
126
+ check_next_page = response['body']['next_page']
127
+ if check_next_page != @next_page
128
+ @next_page = check_next_page
129
+ elsif check_next_page
130
+ # if check_page = next_page, we have repeats in the response.
131
+ # and we don't want to load them
132
+ return false
133
+ else
134
+ @next_page = nil
135
+ end
136
+ @data_list = response['body'][@data_attribute]
137
+ true
138
+ end
139
+
140
+ def each
141
+ while load_page
142
+ @data_list.each do | value |
143
+ yield value
144
+ end
145
+ end
146
+ end
147
+ end
104
148
  end
105
149
  end
@@ -0,0 +1,73 @@
1
+ require 'urbanairship'
2
+
3
+
4
+ module Urbanairship
5
+ module Devices
6
+ class ChannelTags
7
+ include Urbanairship::Common
8
+ include Urbanairship::Loggable
9
+ attr_writer :client
10
+ attr_reader :audience, :add_group, :remove_group, :set_group
11
+
12
+ def initialize(client: required('client'))
13
+ @client = client
14
+ @audience = {}
15
+ @add_group = {}
16
+ @remove_group = {}
17
+ @set_group = {}
18
+ @url = CHANNEL_URL + 'tags/'
19
+ end
20
+
21
+ def set_audience(ios: nil, android: nil, amazon: nil)
22
+ if ios
23
+ @audience['ios_channel'] = ios
24
+ end
25
+ if android
26
+ @audience['android_channel'] = android
27
+ end
28
+ if amazon
29
+ @audience['amazon_channel'] = amazon
30
+ end
31
+ end
32
+
33
+ def add(group_name: required('group_name'), tags: required('tags'))
34
+ @add_group[group_name] = tags
35
+ end
36
+
37
+ def remove(group_name: required('group_name'), tags: required('tags'))
38
+ @remove_group[group_name] = tags
39
+ end
40
+
41
+ def set(group_name: required('group_name'), tags: required('tags'))
42
+ @set_group[group_name] = tags
43
+ end
44
+
45
+ def send_request
46
+ payload = {}
47
+
48
+ fail ArgumentError,
49
+ 'An audience is required for modifying tags' if @audience.empty?
50
+ fail ArgumentError,
51
+ 'A tag request cannot both add and set tags' if !@add_group.empty? and !@set_group.empty?
52
+ fail ArgumentError,
53
+ 'A tag request cannot both remove and set tags' if !@remove_group.empty? and !@set_group.empty?
54
+ fail ArgumentError,
55
+ 'A tag request must add, remove, or set a tag' if @remove_group.empty? and @add_group.empty? and @set_group.empty?
56
+
57
+ payload['audience'] = @audience
58
+ payload['add'] = @add_group unless @add_group.empty?
59
+ payload['remove'] = @remove_group unless @remove_group.empty?
60
+ payload['set'] = @set_group unless @set_group.empty?
61
+
62
+ response = @client.send_request(
63
+ method: 'POST',
64
+ body: JSON.dump(payload),
65
+ url: @url,
66
+ content_type: 'application/json'
67
+ )
68
+ logger.info("Set tags for audience: #{@audience}")
69
+ response
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,35 @@
1
+ require 'json'
2
+ require 'urbanairship'
3
+
4
+ module Urbanairship
5
+ module Devices
6
+ class ChannelUninstall
7
+ include Urbanairship::Common
8
+ include Urbanairship::Loggable
9
+ attr_reader :client
10
+
11
+ # Initialize a ChannelUninstall Object
12
+ #
13
+ # @param [Object] client
14
+ def initialize(client: required('client'))
15
+ @client = client
16
+ end
17
+
18
+ def uninstall(channels: required('channels'))
19
+ chan_num = channels.length
20
+ fail ArgumentError,
21
+ 'Maximum of 200 channel uninstalls exceeded.' if chan_num > 200
22
+
23
+ response = @client.send_request(
24
+ method: 'POST',
25
+ body: JSON.dump(channels),
26
+ url: CHANNEL_URL + 'uninstall/',
27
+ content_type: 'application/json'
28
+ )
29
+
30
+ logger.info { "Successfully uninstalled #{chan_num} channels." }
31
+ response
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,61 @@
1
+ require 'urbanairship'
2
+
3
+
4
+ module Urbanairship
5
+ module Devices
6
+ class ChannelInfo
7
+ include Urbanairship::Common
8
+ include Urbanairship::Loggable
9
+ attr_writer :client
10
+
11
+ def initialize(client: required('client'))
12
+ @client = client
13
+ end
14
+
15
+ def lookup(uuid: required('uuid'))
16
+ response = @client.send_request(
17
+ method: 'GET',
18
+ url: CHANNEL_URL + uuid
19
+ )
20
+ logger.info("Retrieved channel information for #{uuid}")
21
+ response['body']['channel']
22
+ end
23
+ end
24
+
25
+ class ChannelList < Urbanairship::Common::PageIterator
26
+ def initialize(client: required('client'))
27
+ super(client: client)
28
+ @next_page = CHANNEL_URL
29
+ @data_attribute = 'channels'
30
+ end
31
+ end
32
+
33
+ class Feedback
34
+ include Urbanairship::Common
35
+ include Urbanairship::Loggable
36
+
37
+ def initialize(client: required('client'))
38
+ @client = client
39
+ end
40
+
41
+ def device_token(since: required('device token'))
42
+ url = DT_FEEDBACK_URL + '?since=' + since
43
+ get_feedback(url: url)
44
+ end
45
+
46
+ def apid(since: required('since'))
47
+ url = APID_FEEDBACK_URL + '?since=' + since
48
+ get_feedback(url: url)
49
+ end
50
+
51
+ def get_feedback(url: required('url'))
52
+ response = @client.send_request(
53
+ method: 'GET',
54
+ url: url
55
+ )
56
+ logger.info("Requested feedback at url #{url}")
57
+ response
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,87 @@
1
+ require 'urbanairship'
2
+
3
+
4
+ module Urbanairship
5
+ module Devices
6
+ class NamedUser
7
+ include Urbanairship::Common
8
+ include Urbanairship::Loggable
9
+ attr_accessor :named_user_id
10
+
11
+ def initialize(client: required('client'))
12
+ @client = client
13
+ @named_user_id = nil
14
+ end
15
+
16
+ def associate(channel_id: required('channel_id'), device_type: required('device_type'))
17
+ fail ArgumentError,
18
+ 'named_user_id is required for association' if @named_user_id.nil?
19
+
20
+ payload = {}
21
+ payload['channel_id'] = channel_id
22
+ payload['device_type'] = device_type
23
+ payload['named_user_id'] = @named_user_id
24
+
25
+ response = @client.send_request(
26
+ method: 'POST',
27
+ body: JSON.dump(payload),
28
+ url: NAMED_USER_URL + '/associate',
29
+ content_type: 'application/json'
30
+ )
31
+ logger.info { "Associated channel_id #{channel_id} with named_user #{@named_user_id}" }
32
+ response
33
+ end
34
+
35
+ def disassociate(channel_id: required('channel_id'), device_type: required('device_type'))
36
+ payload = {}
37
+ payload['channel_id'] = channel_id
38
+ payload['device_type'] = device_type
39
+ payload['named_user_id'] = @named_user_id unless @named_user_id.nil?
40
+ response = @client.send_request(
41
+ method: 'POST',
42
+ body: JSON.dump(payload),
43
+ url: NAMED_USER_URL + '/disassociate',
44
+ content_type: 'application/json'
45
+ )
46
+ logger.info { "Dissociated channel_id #{channel_id}" }
47
+ response
48
+ end
49
+
50
+ def lookup
51
+ fail ArgumentError,
52
+ 'named_user_id is required for lookup' if @named_user_id.nil?
53
+ response = @client.send_request(
54
+ method: 'GET',
55
+ url: NAMED_USER_URL + '?id=' + @named_user_id,
56
+ )
57
+ logger.info { "Retrieved information on named_user_id #{@named_user_id}" }
58
+ response
59
+ end
60
+ end
61
+
62
+
63
+ class NamedUserTags < ChannelTags
64
+ include Urbanairship::Common
65
+
66
+ def initialize(client: required('client'))
67
+ super(client: client)
68
+ @url = NAMED_USER_URL + 'tags/'
69
+ end
70
+
71
+ def set_audience(user_ids: required('user_ids'))
72
+ @audience['named_user_id'] = user_ids
73
+ end
74
+ end
75
+
76
+
77
+ class NamedUserList < Urbanairship::Common::PageIterator
78
+ include Urbanairship::Common
79
+
80
+ def initialize(client: required('client'))
81
+ super(client: client)
82
+ @next_page = NAMED_USER_URL
83
+ @data_attribute = 'named_users'
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,109 @@
1
+ require 'json'
2
+ require 'urbanairship'
3
+
4
+
5
+ module Urbanairship
6
+ module Devices
7
+ class Segment
8
+ include Urbanairship::Common
9
+ include Urbanairship::Loggable
10
+ attr_accessor :display_name, :criteria
11
+ attr_reader :id
12
+
13
+ def initialize(client: required('client'))
14
+ @client = client
15
+ @display_name = nil
16
+ @criteria = nil
17
+ @id = nil
18
+ end
19
+
20
+ # Build a Segment from the display_name and criteria attributes
21
+ #
22
+ # @param [Object] client The Client
23
+ # @return [Object] response HTTP response
24
+ def create
25
+ fail ArgumentError,
26
+ 'Both display_name and criteria must be set to a value' if display_name.nil? or criteria.nil?
27
+ payload = {
28
+ :display_name => @display_name,
29
+ :criteria => @criteria
30
+ }
31
+ response = @client.send_request(
32
+ method: 'POST',
33
+ body: JSON.dump(payload),
34
+ url: SEGMENTS_URL,
35
+ content_type: 'application/json'
36
+ )
37
+ logger.info { "Successful segment creation: #{@display_name}" }
38
+ seg_url = response['headers'][:location]
39
+ @id = seg_url.split('/')[-1]
40
+ response
41
+ end
42
+
43
+ # Build a Segment from the display_name and criteria attributes
44
+ #
45
+ # @param [Object] id The id of the segment being looked up
46
+ def from_id(id: required('id'))
47
+ fail ArgumentError,
48
+ 'id must be set to a valid string' if id.nil?
49
+ response = @client.send_request(
50
+ method: 'GET',
51
+ url: SEGMENTS_URL + id
52
+ )
53
+ logger.info("Retrieved segment information for #{id}")
54
+ @id = id
55
+ @criteria = response['body']['criteria']
56
+ @display_name = response['body']['display_name']
57
+ response
58
+ end
59
+
60
+ # Update a segment with new criteria/display_name
61
+ #
62
+ # @ returns [Object] response HTTP response
63
+ def update
64
+ fail ArgumentError,
65
+ 'id cannot be nil' if @id.nil?
66
+ fail ArgumentError,
67
+ 'Either display_name or criteria must be set to a value' if display_name.nil? and criteria.nil?
68
+
69
+ data = {}
70
+ data['display_name'] = @display_name
71
+ data['criteria'] = @criteria
72
+ response = @client.send_request(
73
+ method: 'PUT',
74
+ body: JSON.dump(data),
75
+ url: SEGMENTS_URL + @id,
76
+ content_type: 'application/json'
77
+ )
78
+ logger.info { "Successful segment update: #{@display_name}" }
79
+ response
80
+ end
81
+
82
+ # Delete a segment
83
+ #
84
+ # @ returns [Object] response HTTP response
85
+ def delete
86
+ fail ArgumentError,
87
+ 'id cannot be nil' if @id.nil?
88
+
89
+ url = SEGMENTS_URL + @id
90
+ response = @client.send_request(
91
+ method: 'DELETE',
92
+ url: url
93
+ )
94
+ logger.info { "Successful segment deletion: #{@display_name}" }
95
+ response
96
+ end
97
+ end
98
+
99
+ class SegmentList < Urbanairship::Common::PageIterator
100
+ include Urbanairship::Common
101
+
102
+ def initialize(client: required('client'))
103
+ super(client: client)
104
+ @next_page = SEGMENTS_URL
105
+ @data_attribute = 'segments'
106
+ end
107
+ end
108
+ end
109
+ end