gupshup-rb 0.1.7.1 → 0.1.8

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +17 -0
  3. data/.rubocop.yml +59 -0
  4. data/CHANGELOG.md +9 -0
  5. data/CODE_OF_CONDUCT.md +62 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +21 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +1 -1
  10. data/Rakefile +10 -0
  11. data/bin/console +9 -0
  12. data/bin/setup +5 -0
  13. data/gupshup-rb-0.1.0.gem +0 -0
  14. data/gupshup-rb-0.1.1.gem +0 -0
  15. data/gupshup-rb-0.1.2.gem +0 -0
  16. data/gupshup-rb-0.1.3.gem +0 -0
  17. data/gupshup-rb-0.1.4.gem +0 -0
  18. data/gupshup-rb-0.1.5.gem +0 -0
  19. data/gupshup-rb-0.1.6.gem +0 -0
  20. data/gupshup-rb.gemspec +39 -0
  21. data/lib/gupshup-rb/framework/gupshup_response.rb +19 -0
  22. data/lib/gupshup-rb/framework/request.rb +41 -0
  23. data/lib/gupshup-rb/framework/response.rb +18 -0
  24. data/lib/gupshup-rb/framework/rest/domain.rb +36 -0
  25. data/lib/gupshup-rb/framework/rest/error.rb +51 -0
  26. data/lib/gupshup-rb/framework/rest/helper.rb +11 -0
  27. data/lib/gupshup-rb/framework/rest/obsolete_client.rb +12 -0
  28. data/lib/gupshup-rb/framework/rest/page.rb +103 -0
  29. data/lib/gupshup-rb/framework/rest/resource.rb +23 -0
  30. data/lib/gupshup-rb/framework/rest/version.rb +153 -0
  31. data/lib/gupshup-rb/framework/serialize.rb +81 -0
  32. data/lib/gupshup-rb/framework/values.rb +9 -0
  33. data/lib/gupshup-rb/http/http_client.rb +53 -0
  34. data/lib/gupshup-rb/http.rb +5 -0
  35. data/lib/gupshup-rb/rest/api/v1/message.rb +59 -0
  36. data/lib/gupshup-rb/rest/api/v1.rb +29 -0
  37. data/lib/gupshup-rb/rest/api.rb +245 -0
  38. data/lib/gupshup-rb/rest/client.rb +581 -0
  39. data/lib/gupshup-rb/rest.rb +13 -0
  40. data/lib/gupshup-rb/util/configuration.rb +33 -0
  41. data/lib/gupshup-rb/version.rb +3 -0
  42. data/lib/gupshup-rb.rb +47 -0
  43. metadata +50 -7
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gupshup
4
+ module REST
5
+ class Version
6
+ attr_accessor :domain
7
+
8
+ class RecordStream
9
+ include Enumerable
10
+
11
+ def initialize(page, limit: nil, page_limit: nil)
12
+ @page = page
13
+ @limit = limit
14
+ @page_limit = page_limit
15
+ end
16
+
17
+ def each
18
+ current_record = 0
19
+ current_page = 1
20
+
21
+ while @page
22
+ @page.each do |record|
23
+ yield record
24
+ current_record += 1
25
+ return nil if @limit && @limit <= current_record
26
+ end
27
+
28
+ return nil if @page_limit && @page_limit <= current_page
29
+
30
+ @page = @page.next_page
31
+ current_page += 1
32
+ end
33
+ end
34
+ end
35
+
36
+ def initialize(domain)
37
+ @domain = domain
38
+ @version = nil
39
+ end
40
+
41
+ def absolute_url(uri)
42
+ @domain.absolute_url(relative_uri(uri))
43
+ end
44
+
45
+ def relative_uri(uri)
46
+ "#{@version.chomp('/').gsub(/^\//, '')}/#{uri.chomp('/').gsub(/^\//, '')}"
47
+ end
48
+
49
+ def request(method, uri, params = {}, data = {}, headers = {}, auth = nil, timeout = nil)
50
+ url = relative_uri(uri)
51
+ params = params.delete_if { |_k, v| v.nil? }
52
+ data = data
53
+ @domain.request(method, url, params, data, headers, auth, timeout)
54
+ end
55
+
56
+ def exception(response, header)
57
+ Gupshup::REST::RestError.new(header, response)
58
+ end
59
+
60
+ def fetch(method, uri, params: {}, data: {}, headers: {}, auth: nil, timeout: nil)
61
+ response = request(
62
+ method,
63
+ uri,
64
+ params,
65
+ data,
66
+ headers,
67
+ auth,
68
+ timeout
69
+ )
70
+
71
+ # Note that 3XX response codes are allowed for fetches.
72
+ if response.status_code < 200 || response.status_code >= 400
73
+ raise exception(response, 'Unable to fetch record')
74
+ end
75
+
76
+ response.body
77
+ end
78
+
79
+ def update(method, uri, params: {}, data: {}, headers: {}, auth: nil, timeout: nil)
80
+ response = request(
81
+ method,
82
+ uri,
83
+ params,
84
+ data,
85
+ headers,
86
+ auth,
87
+ timeout
88
+ )
89
+
90
+ if response.status_code < 200 || response.status_code >= 300
91
+ raise exception(response, 'Unable to update record')
92
+ end
93
+
94
+ response.body
95
+ end
96
+
97
+ def delete(method, uri, params: {}, data: {}, headers: {}, auth: nil, timeout: nil)
98
+ response = request(
99
+ method,
100
+ uri,
101
+ params,
102
+ data,
103
+ headers,
104
+ auth,
105
+ timeout
106
+ )
107
+
108
+ if response.status_code < 200 || response.status_code >= 300
109
+ raise exception(response, 'Unable to delete record')
110
+ end
111
+
112
+ response.status_code == 204
113
+ end
114
+
115
+ def read_limits(limit = nil, page_size = nil)
116
+ unless limit.nil? || page_size
117
+ page_size = limit
118
+ end
119
+
120
+ {
121
+ limit: limit || nil,
122
+ page_size: page_size || nil
123
+ }
124
+ end
125
+
126
+ def page(method, uri, params: {}, data: {}, headers: {}, auth: nil, timeout: nil)
127
+ request(
128
+ method,
129
+ uri,
130
+ params,
131
+ data,
132
+ headers,
133
+ auth,
134
+ timeout
135
+ )
136
+ end
137
+
138
+ def stream(page, limit: nil, page_limit: nil)
139
+ RecordStream.new(page, limit: limit, page_limit: page_limit)
140
+ end
141
+
142
+ def create(method, uri, params: {}, data: {}, headers: {}, auth: nil, timeout: nil)
143
+ response = request(method, uri, params, data, headers, auth, timeout)
144
+
145
+ if response.status_code < 200 || response.status_code >= 300
146
+ raise exception(response, 'Unable to create record')
147
+ end
148
+
149
+ response.body
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gupshup
4
+ def self.serialize_iso8601_date(date)
5
+ if date.eql?(:unset)
6
+ date
7
+ elsif date.is_a?(Date)
8
+ date.iso8601
9
+ elsif date.is_a?(Time)
10
+ date.strftime('%Y-%m-%d')
11
+ elsif date.is_a?(String)
12
+ date
13
+ end
14
+ end
15
+
16
+ def self.serialize_iso8601_datetime(date)
17
+ if date.eql?(:unset)
18
+ date
19
+ elsif date.is_a?(Date)
20
+ Time.new(date.year, date.month, date.day).utc.iso8601
21
+ elsif date.is_a?(Time)
22
+ date.utc.iso8601
23
+ elsif date.is_a?(String)
24
+ date
25
+ end
26
+ end
27
+
28
+ def self.deserialize_rfc2822(date)
29
+ Time.rfc2822(date) unless date.nil?
30
+ end
31
+
32
+ def self.deserialize_iso8601_date(date)
33
+ Date.parse(date) unless date.nil?
34
+ end
35
+
36
+ def self.deserialize_iso8601_datetime(date)
37
+ Time.parse(date) unless date.nil?
38
+ end
39
+
40
+ def self.serialize_object(object)
41
+ if object.is_a?(Hash) || object.is_a?(Array)
42
+ JSON.generate(object)
43
+ else
44
+ object
45
+ end
46
+ end
47
+
48
+ def self.flatten(map, result = {}, previous = [])
49
+ map.each do |key, value|
50
+ if value.is_a? Hash
51
+ self.flatten(value, result, previous + [key])
52
+ else
53
+ result[(previous + [key]).join('.')] = value
54
+ end
55
+ end
56
+
57
+ result
58
+ end
59
+
60
+ def self.prefixed_collapsible_map(map, prefix)
61
+ result = {}
62
+ if map.is_a? Hash
63
+ flattened = self.flatten(map)
64
+ result = {}
65
+ flattened.each do |key, value|
66
+ result[prefix + '.' + key] = value
67
+ end
68
+ end
69
+
70
+ result
71
+ end
72
+
73
+ def self.serialize_list(input_list)
74
+ return input_list unless input_list.is_a? Array
75
+ result = []
76
+ input_list.each do |e|
77
+ result.push yield e
78
+ end
79
+ result
80
+ end
81
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gupshup
4
+ class Values
5
+ def self.of(hash)
6
+ hash.delete_if { |_, v| v.eql?(:unset) }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,53 @@
1
+
2
+ require 'faraday'
3
+
4
+ module Gupshup
5
+ module HTTP
6
+ class Client
7
+ attr_accessor :adapter
8
+ attr_reader :last_response, :last_request
9
+ def initialize
10
+ @adapter = Faraday.default_adapter
11
+ end
12
+
13
+ def _request(request)
14
+ @connection = Faraday.new(url: "#{request.host}:#{request.port.to_s}", ssl: { verify: true }) do |f|
15
+ f.request :url_encoded
16
+ f.adapter @adapter
17
+ f.headers = request.headers
18
+ end
19
+ @last_request = request
20
+ @last_response = nil
21
+ response = send(request)
22
+ if response.status == 504
23
+ object = { message: 'Request timeout', code: 504 }.to_json
24
+ elsif response.body && !response.body.empty?
25
+ object = response.body
26
+ elsif response.status == 400
27
+ object = { message: 'Bad request', code: 400 }.to_json
28
+ end
29
+
30
+ gupshup_response = Gupshup::Response.new(response.status, object, headers: response.headers)
31
+ @last_response = gupshup_response
32
+
33
+ gupshup_response
34
+ end
35
+
36
+ def send(request)
37
+ @connection.send(request.method.downcase.to_sym,
38
+ request.url,
39
+ request.method == 'GET' ? request.params : request.data)
40
+ rescue Faraday::Error => e
41
+ raise Gupshup::REST::GupshupError, e
42
+ end
43
+
44
+ def request(host, port, method, url, data = {}, headers = {}, params = {}, auth = nil, timeout = nil)
45
+ request = Gupshup::Request.new(host, port, method, url, params, data, headers)
46
+ _request(request)
47
+
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir[File.join(__dir__, 'http/**/*.rb')].sort.each do |file|
4
+ require file
5
+ end
@@ -0,0 +1,59 @@
1
+ module Gupshup
2
+ module REST
3
+ class Api < Domain
4
+ class V1 < Version
5
+ class MessageList < ListResource
6
+ ##
7
+ # Initialize the MessageList
8
+ # @param [Version] version Version that contains the resource
9
+ # @param [String] src_name The SID
10
+ # @return [MessageList] MessageList
11
+ # def initialize(version, src_name: nil, content_type, from, apikey)
12
+ def initialize(version, src_name: nil)
13
+ super(version)
14
+
15
+ # Path Solution
16
+ @solution = {src_name: src_name}
17
+ @uri = "https://api.gupshup.io/sm/api/v1/msg"
18
+ @base_url = 'https://api.gupshup.io'
19
+ @path = '/sm/api/v1/msg'
20
+
21
+ @channel = 'whatsapp'
22
+
23
+ end
24
+ def create(to: nil, from: :unset, body: :unset, media_url: :unset, content_type: :unset, src_name: :unset, api_key: :unset)
25
+ headers = { 'apikey' => api_key}
26
+ binding.local_variables.each do |var_name|
27
+ var_value = binding.local_variable_get(var_name)
28
+ puts "#{var_name}: #{var_value}"
29
+ end
30
+
31
+ #case message_params[:type]
32
+ #when 'text'
33
+ #else
34
+ send_text_message(headers, from, to, body, src_name)
35
+ #end
36
+ #end
37
+
38
+
39
+ end
40
+
41
+ # @param [Object] destination
42
+ def send_text_message(headers, from, to, body, src_name)
43
+ payload = {'type' => 'text',
44
+ 'text' => body }.to_json
45
+ data = { 'channel' => @channel,
46
+ 'destination' => to,
47
+ 'source' => from,
48
+ 'src.name' => src_name,
49
+ 'message' => payload }
50
+ r = Gupshup::HTTP::Client.new
51
+ r.request(host = @base_url, port = 443, method = 'POST', url = @path, data = data, headers = headers)
52
+
53
+ end
54
+
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,29 @@
1
+
2
+ module Gupshup
3
+ module REST
4
+ class Api
5
+ class V1 < Version
6
+ ##
7
+ # Initialize the V1 version of Api
8
+ def initialize(domain)
9
+ super
10
+ @version = 'v1'
11
+ @solution = {}
12
+ end
13
+
14
+ def messages(sid=:unset)
15
+ raise ArgumentError, 'sid cannot be nil' if sid.nil?
16
+
17
+ @messages = V1::MessageList.new(@version, src_name: @solution[:sid], )
18
+
19
+ @messages
20
+ end
21
+ ##
22
+ # Provide a user friendly representation
23
+ def to_s
24
+ '<Gupshup::REST::Api::V1>'
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,245 @@
1
+ ##
2
+ # This code was generated by
3
+ # \ / _ _ _| _ _
4
+ # | (_)\/(_)(_|\/| |(/_ v1.0.0
5
+ # / /
6
+ #
7
+ # frozen_string_literal: true
8
+
9
+ module Gupshup
10
+ module REST
11
+ class Api < Domain
12
+ ##
13
+ # Initialize the Api Domain
14
+ def initialize(gupshup)
15
+ super
16
+
17
+ @uri = "https://api.gupshup.io/sm/api/v1/msg"
18
+
19
+ # Versions
20
+ @v2010 = nil
21
+ end
22
+
23
+ ##
24
+ # Version v2010 of api
25
+ def v2010
26
+ @v2010 ||= V2010.new self
27
+ end
28
+
29
+ ##
30
+ # Account provided as the authenticating account
31
+ def account
32
+ self.v2010.account
33
+ end
34
+
35
+ ##
36
+ # @param [String] sid A 34 character string that uniquely identifies this
37
+ # resource.
38
+ # @return [Gupshup::REST::Api::V2010::AccountInstance] if sid was passed.
39
+ # @return [Gupshup::REST::Api::V2010::AccountList]
40
+ def accounts(sid=:unset)
41
+ self.v2010.accounts(sid)
42
+ end
43
+
44
+ ##
45
+ # @param [String] sid The unique string that that we created to identify the
46
+ # Address resource.
47
+ # @return [Gupshup::REST::Api::V2010::AccountContext::AddressInstance] if sid was passed.
48
+ # @return [Gupshup::REST::Api::V2010::AccountContext::AddressList]
49
+ def addresses(sid=:unset)
50
+ self.account.addresses(sid)
51
+ end
52
+
53
+ ##
54
+ # @param [String] sid The unique string that that we created to identify the
55
+ # Application resource.
56
+ # @return [Gupshup::REST::Api::V2010::AccountContext::ApplicationInstance] if sid was passed.
57
+ # @return [Gupshup::REST::Api::V2010::AccountContext::ApplicationList]
58
+ def applications(sid=:unset)
59
+ self.account.applications(sid)
60
+ end
61
+
62
+ ##
63
+ # @param [String] connect_app_sid The SID that we assigned to the Connect App.
64
+ # @return [Gupshup::REST::Api::V2010::AccountContext::AuthorizedConnectAppInstance] if connect_app_sid was passed.
65
+ # @return [Gupshup::REST::Api::V2010::AccountContext::AuthorizedConnectAppList]
66
+ def authorized_connect_apps(connect_app_sid=:unset)
67
+ self.account.authorized_connect_apps(connect_app_sid)
68
+ end
69
+
70
+ ##
71
+ # @param [String] country_code The
72
+ # {ISO-3166-1}[https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2] country code of
73
+ # the country.
74
+ # @return [Gupshup::REST::Api::V2010::AccountContext::AvailablePhoneNumberCountryInstance] if country_code was passed.
75
+ # @return [Gupshup::REST::Api::V2010::AccountContext::AvailablePhoneNumberCountryList]
76
+ def available_phone_numbers(country_code=:unset)
77
+ self.account.available_phone_numbers(country_code)
78
+ end
79
+
80
+ ##
81
+ # @return [Gupshup::REST::Api::V2010::AccountContext::BalanceInstance]
82
+ def balance
83
+ self.account.balance()
84
+ end
85
+
86
+ ##
87
+ # @param [String] sid The unique string that we created to identify this Call
88
+ # resource.
89
+ # @return [Gupshup::REST::Api::V2010::AccountContext::CallInstance] if sid was passed.
90
+ # @return [Gupshup::REST::Api::V2010::AccountContext::CallList]
91
+ def calls(sid=:unset)
92
+ self.account.calls(sid)
93
+ end
94
+
95
+ ##
96
+ # @param [String] sid The unique string that that we created to identify this
97
+ # Conference resource.
98
+ # @return [Gupshup::REST::Api::V2010::AccountContext::ConferenceInstance] if sid was passed.
99
+ # @return [Gupshup::REST::Api::V2010::AccountContext::ConferenceList]
100
+ def conferences(sid=:unset)
101
+ self.account.conferences(sid)
102
+ end
103
+
104
+ ##
105
+ # @param [String] sid The unique string that that we created to identify the
106
+ # ConnectApp resource.
107
+ # @return [Gupshup::REST::Api::V2010::AccountContext::ConnectAppInstance] if sid was passed.
108
+ # @return [Gupshup::REST::Api::V2010::AccountContext::ConnectAppList]
109
+ def connect_apps(sid=:unset)
110
+ self.account.connect_apps(sid)
111
+ end
112
+
113
+ ##
114
+ # @param [String] sid The unique string that that we created to identify this
115
+ # IncomingPhoneNumber resource.
116
+ # @return [Gupshup::REST::Api::V2010::AccountContext::IncomingPhoneNumberInstance] if sid was passed.
117
+ # @return [Gupshup::REST::Api::V2010::AccountContext::IncomingPhoneNumberList]
118
+ def incoming_phone_numbers(sid=:unset)
119
+ self.account.incoming_phone_numbers(sid)
120
+ end
121
+
122
+ ##
123
+ # @param [String] sid The unique string that that we created to identify the Key
124
+ # resource.
125
+ # @return [Gupshup::REST::Api::V2010::AccountContext::KeyInstance] if sid was passed.
126
+ # @return [Gupshup::REST::Api::V2010::AccountContext::KeyList]
127
+ def keys(sid=:unset)
128
+ self.account.keys(sid)
129
+ end
130
+
131
+ ##
132
+ # @param [String] sid The unique string that that we created to identify the
133
+ # Message resource.
134
+ # @return [Gupshup::REST::Api::V2010::AccountContext::MessageInstance] if sid was passed.
135
+ # @return [Gupshup::REST::Api::V2010::AccountContext::MessageList]
136
+ def messages(sid=:unset)
137
+ self.account.messages(sid)
138
+ end
139
+
140
+ ##
141
+ # @return [Gupshup::REST::Api::V2010::AccountContext::NewKeyInstance]
142
+ def new_keys
143
+ self.account.new_keys()
144
+ end
145
+
146
+ ##
147
+ # @return [Gupshup::REST::Api::V2010::AccountContext::NewSigningKeyInstance]
148
+ def new_signing_keys
149
+ self.account.new_signing_keys()
150
+ end
151
+
152
+ ##
153
+ # @param [String] sid The unique string that that we created to identify the
154
+ # Notification resource.
155
+ # @return [Gupshup::REST::Api::V2010::AccountContext::NotificationInstance] if sid was passed.
156
+ # @return [Gupshup::REST::Api::V2010::AccountContext::NotificationList]
157
+ def notifications(sid=:unset)
158
+ self.account.notifications(sid)
159
+ end
160
+
161
+ ##
162
+ # @param [String] sid The unique string that that we created to identify the
163
+ # OutgoingCallerId resource.
164
+ # @return [Gupshup::REST::Api::V2010::AccountContext::OutgoingCallerIdInstance] if sid was passed.
165
+ # @return [Gupshup::REST::Api::V2010::AccountContext::OutgoingCallerIdList]
166
+ def outgoing_caller_ids(sid=:unset)
167
+ self.account.outgoing_caller_ids(sid)
168
+ end
169
+
170
+ ##
171
+ # @param [String] sid The unique string that that we created to identify this
172
+ # Queue resource.
173
+ # @return [Gupshup::REST::Api::V2010::AccountContext::QueueInstance] if sid was passed.
174
+ # @return [Gupshup::REST::Api::V2010::AccountContext::QueueList]
175
+ def queues(sid=:unset)
176
+ self.account.queues(sid)
177
+ end
178
+
179
+ ##
180
+ # @param [String] sid The unique string that that we created to identify the
181
+ # Recording resource.
182
+ # @return [Gupshup::REST::Api::V2010::AccountContext::RecordingInstance] if sid was passed.
183
+ # @return [Gupshup::REST::Api::V2010::AccountContext::RecordingList]
184
+ def recordings(sid=:unset)
185
+ self.account.recordings(sid)
186
+ end
187
+
188
+ ##
189
+ # @param [String] sid The sid
190
+ # @return [Gupshup::REST::Api::V2010::AccountContext::SigningKeyInstance] if sid was passed.
191
+ # @return [Gupshup::REST::Api::V2010::AccountContext::SigningKeyList]
192
+ def signing_keys(sid=:unset)
193
+ self.account.signing_keys(sid)
194
+ end
195
+
196
+ ##
197
+ # @return [Gupshup::REST::Api::V2010::AccountContext::SipInstance]
198
+ def sip
199
+ self.account.sip()
200
+ end
201
+
202
+ ##
203
+ # @param [String] sid The unique string that that we created to identify this
204
+ # ShortCode resource.
205
+ # @return [Gupshup::REST::Api::V2010::AccountContext::ShortCodeInstance] if sid was passed.
206
+ # @return [Gupshup::REST::Api::V2010::AccountContext::ShortCodeList]
207
+ def short_codes(sid=:unset)
208
+ self.account.short_codes(sid)
209
+ end
210
+
211
+ ##
212
+ # @return [Gupshup::REST::Api::V2010::AccountContext::TokenInstance]
213
+ def tokens
214
+ self.account.tokens()
215
+ end
216
+
217
+ ##
218
+ # @param [String] sid The unique string that that we created to identify the
219
+ # Transcription resource.
220
+ # @return [Gupshup::REST::Api::V2010::AccountContext::TranscriptionInstance] if sid was passed.
221
+ # @return [Gupshup::REST::Api::V2010::AccountContext::TranscriptionList]
222
+ def transcriptions(sid=:unset)
223
+ self.account.transcriptions(sid)
224
+ end
225
+
226
+ ##
227
+ # @return [Gupshup::REST::Api::V2010::AccountContext::UsageInstance]
228
+ def usage
229
+ self.account.usage()
230
+ end
231
+
232
+ ##
233
+ # @return [Gupshup::REST::Api::V2010::AccountContext::ValidationRequestInstance]
234
+ def validation_requests
235
+ self.account.validation_requests()
236
+ end
237
+
238
+ ##
239
+ # Provide a user friendly representation
240
+ def to_s
241
+ '#<Gupshup::REST::Api>'
242
+ end
243
+ end
244
+ end
245
+ end