Class: RingCentralSdk::REST::Subscription

Inherits:
Object
  • Object
show all
Includes:
Observable
Defined in:
lib/ringcentral_sdk/rest/subscription.rb

Overview

Subscription class is an observerable class that represents one RingCentral subscription using the PubNub transport via the Subscription API

Constant Summary collapse

RENEW_HANDICAP =
60

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client) ⇒ Subscription

Returns a new instance of Subscription.



20
21
22
23
24
25
26
27
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 20

def initialize(client)
  @client = client
  @event_filters = []
  @_timeout = nil
  @_subscription = nil_subscription
  @_pubnub = nil
  @_logger_prefix = " -- #{self.class.name}: "
end

Instance Attribute Details

#event_filtersObject (readonly)

Returns the value of attribute event_filters.



18
19
20
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 18

def event_filters
  @event_filters
end

Instance Method Details

#_clear_timeoutObject



271
272
273
274
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 271

def _clear_timeout
  @_timeout.exit if @_timeout.is_a?(Thread) && @_timeout.status == 'sleep'
  @_timeout = nil
end

#_decrypt(message) ⇒ Object



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 220

def _decrypt(message)
  unless alive?
    raise 'Subscription is not alive'
  end

  if _encrypted?
    delivery_mode = @_subscription['deliveryMode']

    cipher = OpenSSL::Cipher::AES.new(128, :ECB)
    cipher.decrypt
    cipher.key = Base64.decode64(delivery_mode['encryptionKey'].to_s)

    ciphertext = Base64.decode64(message)
    plaintext = cipher.update(ciphertext) + cipher.final

    message = MultiJson.decode(plaintext, symbolize_keys: false)
  end

  message
end

#_encrypted?Boolean

Returns:

  • (Boolean)


241
242
243
244
245
246
247
248
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 241

def _encrypted?
  delivery_mode = @_subscription['deliveryMode']
  is_encrypted  = delivery_mode.key?('encryption') \
    && delivery_mode['encryption'] \
    && delivery_mode.key?('encryptionKey') \
    && delivery_mode['encryptionKey']
  is_encrypted
end

#_notify(message) ⇒ Object



211
212
213
214
215
216
217
218
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 211

def _notify(message)
  count = count_observers
  @client.config.logger.debug("RingCentralSdk::REST::Subscription NOTIFYING '#{count}' observers")

  message = _decrypt message
  changed
  notify_observers message
end

#_set_timeoutObject



258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 258

def _set_timeout
  _clear_timeout

  if @_subscription && !@_subscription.empty? && @_subscription.key?('expiresIn')
    time_to_expiration = (@_subscription['expiresIn'] - RENEW_HANDICAP)
  end

  @_timeout = Thread.new do
    sleep time_to_expiration
    renew
  end
end

#_subscribe_at_pubnubObject



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 177

def 
  raise 'Subscription is not alive' unless alive?

  s_key = @_subscription['deliveryMode']['subscriberKey']

  @_pubnub = new_pubnub(s_key, false, '')

  callback = Pubnub::SubscribeCallback.new(
    message: ->(envelope) {
      @client.config.logger.debug "MESSAGE: #{envelope.result[:data]}"
      _notify envelope.result[:data][:message]
      changed
    },
    presence: ->(envelope) {
      @client.config.logger.info "PRESENCE: #{envelope.result[:data]}"
    },
    status: lambda do |envelope|
      @client.config.logger.info "\n\n\n#{envelope.status}\n\n\n"
      if envelope.error?
        @client.config.logger.info "ERROR! #{envelope.status[:category]}"
      elsif envelope.status[:last_timetoken] == 0 # Connected!
        @client.config.logger.info('CONNECTED!')
      end
    end
  )

  @_pubnub.add_listener callback: callback, name: :ringcentral

  @_pubnub.subscribe(
    channels: @_subscription['deliveryMode']['address']
  )
  @client.config.logger.debug('SUBSCRIBED')
end

#_unsubscribe_at_pubnubObject



250
251
252
253
254
255
256
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 250

def _unsubscribe_at_pubnub
  if @_pubnub && alive?
    @_pubnub.unsubscribe(channel: @_subscription['deliveryMode']['address']) do |envelope|
      puts envelope.status
    end
  end
end

#add_events(events) ⇒ Object



56
57
58
59
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 56

def add_events(events)
  raise 'Events is not an array.' unless events.is_a? Array
  @event_filters.push(events) unless events.empty?
end

#alive?Boolean

Returns:

  • (Boolean)


142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 142

def alive?
  s = @_subscription
  if
    (s.key?('deliveryMode') && s['deliveryMode']) \
    && (s['deliveryMode'].key?('subscriberKey') && s['deliveryMode']['subscriberKey']) \
    && (
      s['deliveryMode'].key?('address') \
      && !s['deliveryMode']['address'].nil? \
      && !s['deliveryMode']['address'].empty?
    )
    return true
  end
  false
end

#destroyObject



173
174
175
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 173

def destroy
  reset
end

#new_pubnub(subscribe_key = '', ssl_on = false, publish_key = '', my_logger = nil) ⇒ Object



281
282
283
284
285
286
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 281

def new_pubnub(subscribe_key = '', ssl_on = false, publish_key = '', my_logger = nil)
  Pubnub.new(
    subscribe_key: subscribe_key.to_s,
    publish_key: publish_key.to_s
  )
end

#nil_subscriptionObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 29

def nil_subscription
  {
    'eventFilters'    => [],
    'expirationTime'  => '', # 2014-03-12T19:54:35.613Z
    'expiresIn'       => 0,
    'deliveryMode'    => {
      'transportType' => 'PubNub',
      'encryption'    => false,
      'address'       => '',
      'subscriberKey' => '',
      'secretKey'     => ''
    },
    'id'              => '',
    'creationTime'    => '', # 2014-03-12T19:54:35.613Z
    'status'          => '', # Active
    'uri'             => ''
  }
end

#pubnubObject



48
49
50
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 48

def pubnub
  @_pubnub
end

#register(events = nil) ⇒ Object



52
53
54
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 52

def register(events = nil)
  alive? ? renew(events) : subscribe(events)
end

#removeObject



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 124

def remove
  raise 'Subscription is not alive' unless alive?

  begin
    response = @client.http.delete do |req|
      req.url 'subscription/' + @_subscription['id'].to_s
    end
    reset
    changed
    notify_observers response.body
    return response
  rescue StandardError => e
    reset
    changed
    notify_observers e
  end
end

#renew(events = nil) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 97

def renew(events = nil)
  set_events(events) if events.is_a? Array

  raise 'Subscription is not alive' unless alive?
  raise 'Events are undefined' if @event_filters.empty?
  _clear_timeout

  begin
    response = @client.http.post do |req|
      req.url uri_join(@_subscription['uri'], 'renew')
      req.headers['Content-Type'] = 'application/json'
    end

    set_subscription response.body
    changed
    notify_observers response

    return response
  rescue StandardError => e
    @client.config.logger.warn "RingCentralSdk::REST::Subscription: RENEW_ERROR #{e}"
    reset
    changed
    notify_observers e
    raise 'Renew HTTP Request Error'
  end
end

#resetObject



167
168
169
170
171
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 167

def reset
  _clear_timeout
  _unsubscribe_at_pubnub
  @_subscription = nil_subscription
end

#set_events(events) ⇒ Object



61
62
63
64
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 61

def set_events(events)
  raise 'Events is not an array.' unless events.is_a? Array
  @event_filters = events
end

#set_subscription(data) ⇒ Object



161
162
163
164
165
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 161

def set_subscription(data)
  _clear_timeout
  @_subscription = data
  _set_timeout
end

#subscribe(events = nil) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 66

def subscribe(events = nil)
  set_events(events) if events.is_a? Array

  raise 'Events are undefined' unless @event_filters.is_a?(Array) && !@event_filters.empty?
  
  begin
    response = @client.http.post do |req|
      req.url 'subscription'
      req.headers['Content-Type'] = 'application/json'
      req.body = {
        eventFilters: @event_filters,
        deliveryMode: {
          transportType: 'PubNub',
          encryption: 'true'
        }
      }
    end
    puts response.body
    set_subscription response.body
    
    changed
    notify_observers response
    return response
  rescue StandardError => e
    reset
    changed
    notify_observers(e)
    raise 'Subscribe HTTP Request Error: ' + e.to_s
  end
end

#subscriptionObject



157
158
159
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 157

def subscription
  @_subscription
end

#uri_join(*args) ⇒ Object



276
277
278
279
# File 'lib/ringcentral_sdk/rest/subscription.rb', line 276

def uri_join(*args)
  url = args.join('/').gsub(%r{/+}, '/')
  url.gsub(%r{^(https?:/)}i, '\1/')
end