pubnub 5.3.4 → 5.4.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.
- checksums.yaml +4 -4
- data/.github/workflows/commands-handler.yml +7 -6
- data/.github/workflows/release.yml +9 -8
- data/.github/workflows/run-tests.yml +18 -13
- data/.github/workflows/run-validations.yml +11 -9
- data/.pubnub.yml +24 -4
- data/CHANGELOG.md +96 -79
- data/Gemfile +1 -0
- data/Gemfile.lock +90 -70
- data/VERSION +1 -1
- data/lib/pubnub/client/events.rb +10 -8
- data/lib/pubnub/client.rb +97 -96
- data/lib/pubnub/constants.rb +4 -1
- data/lib/pubnub/event.rb +28 -23
- data/lib/pubnub/events/fetch_messages.rb +128 -0
- data/lib/pubnub/events/publish.rb +1 -0
- data/lib/pubnub/events/signal.rb +4 -0
- data/lib/pubnub/subscribe_event/formatter.rb +29 -16
- data/lib/pubnub/validators/fetch_messages.rb +41 -0
- data/lib/pubnub/version.rb +1 -1
- data/pubnub.gemspec +2 -2
- metadata +8 -6
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pubnub
|
4
|
+
# Holds functionality to fetch:
|
5
|
+
# - batch messages (for multiple channels)
|
6
|
+
# - messages with message actions.
|
7
|
+
class FetchMessages < SingleEvent
|
8
|
+
include Concurrent::Async
|
9
|
+
include Pubnub::Validator::FetchMessages
|
10
|
+
|
11
|
+
def initialize(options, app)
|
12
|
+
@telemetry_name = :l_hist
|
13
|
+
@include_custom_message_type = options.fetch(:include_custom_message_type, false)
|
14
|
+
@include_message_actions = options.fetch(:include_message_actions, false)
|
15
|
+
@include_message_type = options.fetch(:include_message_type, true)
|
16
|
+
@include_uuid = options.fetch(:include_uuid, true)
|
17
|
+
@include_meta = options.fetch(:include_meta, false)
|
18
|
+
@start = options[:start] if options.key?(:start)
|
19
|
+
@end = options[:end] if options.key?(:end)
|
20
|
+
|
21
|
+
channel = options[:channel] if options.key?(:channel) && !options[:channel].empty?
|
22
|
+
@channels = options[:channels] if options.key?(:channels) && !options[:channels].empty?
|
23
|
+
if @include_message_actions
|
24
|
+
@channel = channel
|
25
|
+
elsif @channels.nil? && !channel.nil?
|
26
|
+
@channels = [channel]
|
27
|
+
@channel = nil
|
28
|
+
options.delete :channel
|
29
|
+
end
|
30
|
+
|
31
|
+
maximum = @include_message_actions || @channels&.size == 1 ? 100 : 25
|
32
|
+
@max = [options[:max], maximum].min unless options[:max].nil?
|
33
|
+
|
34
|
+
@event = current_operation
|
35
|
+
|
36
|
+
# Override crypto module if custom cipher key has been used.
|
37
|
+
random_iv = options.key?(:random_iv) ? options[:random_iv] : true
|
38
|
+
options[:crypto_module] = Crypto::CryptoModule.new_legacy(options[:cipher_key], random_iv) if options[:cipher_key]
|
39
|
+
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def current_operation
|
46
|
+
@include_message_actions ? Pubnub::Constants::OPERATION_FETCH_MESSAGES_WITH_ACTIONS : Pubnub::Constants::OPERATION_FETCH_MESSAGES
|
47
|
+
end
|
48
|
+
|
49
|
+
def parameters(signature: false)
|
50
|
+
parameters = super(signature)
|
51
|
+
parameters[:include_meta] = 'true' if @include_meta
|
52
|
+
parameters[:include_uuid] = 'true' if @include_uuid
|
53
|
+
parameters[:include_custom_message_type] = 'true' if @include_custom_message_type
|
54
|
+
parameters[:include_message_type] = 'true' if @include_message_type
|
55
|
+
parameters[:start] = @start unless @start.nil?
|
56
|
+
parameters[:end] = @end unless @end.nil?
|
57
|
+
parameters[:max] = @max unless @max.nil?
|
58
|
+
|
59
|
+
parameters
|
60
|
+
end
|
61
|
+
|
62
|
+
def path
|
63
|
+
storage_endpoint = @include_message_actions ? 'history-with-actions' : 'history'
|
64
|
+
"/v3/#{storage_endpoint}/sub-key/#{@subscribe_key}/channel/#{Pubnub::Formatter.channels_for_url((
|
65
|
+
unless @channel.nil?
|
66
|
+
[@channel]
|
67
|
+
end) || @channels)}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def enable_format_channels?
|
71
|
+
false
|
72
|
+
end
|
73
|
+
|
74
|
+
def decrypt_history(crypto, message)
|
75
|
+
encrypted_message = Base64.strict_decode64(message['message'])
|
76
|
+
message['message'] = JSON.parse(crypto.decrypt(encrypted_message), quirks_mode: true)
|
77
|
+
message
|
78
|
+
rescue StandardError => e
|
79
|
+
puts "Pubnub :: DECRYPTION ERROR: #{e}"
|
80
|
+
message['decrypt_error'] = true
|
81
|
+
message
|
82
|
+
end
|
83
|
+
|
84
|
+
def valid_envelope(parsed_response, req_res_objects)
|
85
|
+
channels = parsed_response['channels'] unless parsed_response['error']
|
86
|
+
more = parsed_response['more'].transform_keys(&:to_sym) if parsed_response.key?('more')
|
87
|
+
more&.delete :url
|
88
|
+
|
89
|
+
if crypto_module && channels
|
90
|
+
crypto = crypto_module
|
91
|
+
channels.transform_values! do |channel_messages|
|
92
|
+
channel_messages.map(&method(:decrypt_history).curry[crypto])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
Pubnub::Envelope.new(
|
97
|
+
event: @event,
|
98
|
+
event_options: @given_options,
|
99
|
+
timetoken: nil,
|
100
|
+
status: {
|
101
|
+
code: req_res_objects[:response].code,
|
102
|
+
client_request: req_res_objects[:request],
|
103
|
+
server_response: req_res_objects[:response],
|
104
|
+
|
105
|
+
category: Pubnub::Constants::STATUS_ACK,
|
106
|
+
error: false,
|
107
|
+
auto_retried: false,
|
108
|
+
|
109
|
+
data: nil,
|
110
|
+
current_timetoken: nil,
|
111
|
+
last_timetoken: nil,
|
112
|
+
subscribed_channels: nil,
|
113
|
+
subscribed_channel_groups: nil,
|
114
|
+
|
115
|
+
config: get_config
|
116
|
+
},
|
117
|
+
result: {
|
118
|
+
code: req_res_objects[:response].code,
|
119
|
+
operation: @event,
|
120
|
+
client_request: req_res_objects[:request],
|
121
|
+
server_response: req_res_objects[:response],
|
122
|
+
|
123
|
+
data: { channels: channels }.merge!(more.nil? ? {} : { more: more })
|
124
|
+
}
|
125
|
+
)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/lib/pubnub/events/signal.rb
CHANGED
@@ -26,6 +26,10 @@ module Pubnub
|
|
26
26
|
def parameters(*_args)
|
27
27
|
params = super
|
28
28
|
|
29
|
+
empty_if_blank = { custom_message_type: @custom_message_type }
|
30
|
+
empty_if_blank.delete_if { |_k, v| v.blank? }
|
31
|
+
|
32
|
+
params = params.merge(empty_if_blank)
|
29
33
|
params = params.merge(seqn: @sequence_number,
|
30
34
|
ortt: { t: @origination_time_token })
|
31
35
|
params
|
@@ -60,6 +60,7 @@ module Pubnub
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def plain_envelope(req_res_objects, timetoken)
|
63
|
+
operation = get_operation
|
63
64
|
Pubnub::Envelope.new(
|
64
65
|
event: @event,
|
65
66
|
event_options: @given_options,
|
@@ -82,7 +83,7 @@ module Pubnub
|
|
82
83
|
},
|
83
84
|
result: {
|
84
85
|
code: req_res_objects[:response].code,
|
85
|
-
operation:
|
86
|
+
operation: operation,
|
86
87
|
client_request: req_res_objects[:request],
|
87
88
|
server_response: req_res_objects[:response],
|
88
89
|
|
@@ -92,6 +93,20 @@ module Pubnub
|
|
92
93
|
end
|
93
94
|
|
94
95
|
def encrypted_envelope(req_res_objects, message, timetoken)
|
96
|
+
operation = get_operation(message)
|
97
|
+
data = {
|
98
|
+
message: decipher_payload(message),
|
99
|
+
subscribed_channel: message[:subscription_match] || message[:channel],
|
100
|
+
actual_channel: message[:channel],
|
101
|
+
publish_time_object: message[:publish_timetoken],
|
102
|
+
message_meta_data: message[:user_meta_data],
|
103
|
+
presence_event: get_presence_event(message),
|
104
|
+
presence: get_presence_data(message)
|
105
|
+
}
|
106
|
+
if !data[:actual_channel].end_with?('-pnpres') && (message[:type].nil? || [1, 4].include?(message[:type]))
|
107
|
+
data[:custom_message_type] = message[:custom_message_type]
|
108
|
+
end
|
109
|
+
|
95
110
|
Pubnub::Envelope.new(
|
96
111
|
event: @event,
|
97
112
|
event_options: @given_options,
|
@@ -114,19 +129,11 @@ module Pubnub
|
|
114
129
|
},
|
115
130
|
result: {
|
116
131
|
code: req_res_objects[:response].code,
|
117
|
-
operation:
|
132
|
+
operation: operation,
|
118
133
|
client_request: req_res_objects[:request],
|
119
134
|
server_response: req_res_objects[:response],
|
120
135
|
|
121
|
-
data:
|
122
|
-
message: decipher_payload(message),
|
123
|
-
subscribed_channel: message[:subscription_match] || message[:channel],
|
124
|
-
actual_channel: message[:channel],
|
125
|
-
publish_time_object: message[:publish_timetoken],
|
126
|
-
message_meta_data: message[:user_meta_data],
|
127
|
-
presence_event: get_presence_event(message),
|
128
|
-
presence: get_presence_data(message)
|
129
|
-
}
|
136
|
+
data: data
|
130
137
|
}
|
131
138
|
)
|
132
139
|
end
|
@@ -142,10 +149,10 @@ module Pubnub
|
|
142
149
|
Pubnub::Schemas::Envelope::StatusSchema.new.call status
|
143
150
|
end
|
144
151
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
152
|
+
return unless (results_validation + statuses_validation).map(&:failure?).index(true)
|
153
|
+
|
154
|
+
Pubnub.logger.error('Pubnub::SubscribeEvent::Formatter') { 'Invalid formatted envelope.' }
|
155
|
+
raise Exception, 'Invalid formatted envelope.'
|
149
156
|
end
|
150
157
|
|
151
158
|
def format_envelopes(response, request)
|
@@ -216,6 +223,7 @@ module Pubnub
|
|
216
223
|
|
217
224
|
def get_presence_data(message)
|
218
225
|
return nil unless get_operation(message) == Pubnub::Constants::OPERATION_PRESENCE
|
226
|
+
|
219
227
|
{
|
220
228
|
uuid: message[:payload]['uuid'],
|
221
229
|
timestamp: message[:payload]['timestamp'],
|
@@ -226,6 +234,7 @@ module Pubnub
|
|
226
234
|
|
227
235
|
def get_presence_event(message)
|
228
236
|
return nil unless get_operation(message) == Pubnub::Constants::OPERATION_PRESENCE
|
237
|
+
|
229
238
|
message[:payload]['action']
|
230
239
|
rescue StandardError
|
231
240
|
nil
|
@@ -233,7 +242,7 @@ module Pubnub
|
|
233
242
|
|
234
243
|
def expand_messages_keys(messages)
|
235
244
|
messages.map do |m|
|
236
|
-
{
|
245
|
+
envelope = {
|
237
246
|
shard: m['a'],
|
238
247
|
channel: m['c'],
|
239
248
|
subscription_match: m['b'],
|
@@ -250,11 +259,15 @@ module Pubnub
|
|
250
259
|
origination_time_token: expand_timetoken(m['o']),
|
251
260
|
publish_timetoken: expand_timetoken(m['p'])
|
252
261
|
}
|
262
|
+
envelope[:custom_message_type] = m['cmt'] if !m['c'].end_with?('-pnpres') && (envelope[:type].nil? || [1, 4].include?(envelope[:type]))
|
263
|
+
|
264
|
+
envelope
|
253
265
|
end
|
254
266
|
end
|
255
267
|
|
256
268
|
def expand_timetoken(timetoken)
|
257
269
|
return nil unless timetoken
|
270
|
+
|
258
271
|
{
|
259
272
|
timetoken: timetoken['t'],
|
260
273
|
region_code: timetoken['r']
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pubnub
|
4
|
+
# Validator module that holds all validators modules.
|
5
|
+
module Validator
|
6
|
+
# Validator for FetchMessages event.
|
7
|
+
module FetchMessages
|
8
|
+
include CommonValidator
|
9
|
+
|
10
|
+
def validate!
|
11
|
+
return if @skip_validate
|
12
|
+
|
13
|
+
validate_subscribe_key!
|
14
|
+
validate_channel_or_channels!
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def validate_subscribe_key!
|
20
|
+
return unless @subscribe_key.nil?
|
21
|
+
|
22
|
+
raise(
|
23
|
+
ArgumentError.new(object: self, message: ':subscribe_key is required for fetch messages event'),
|
24
|
+
':subscribe_key is required for fetch messages event'
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_channel_or_channels!
|
29
|
+
error_message = nil
|
30
|
+
if @include_message_actions
|
31
|
+
error_message = ":channels can't be used with :include_custom_message_type set to 'true'" unless @channels.nil?
|
32
|
+
error_message = ":channel is required with :include_custom_message_type set to 'true'" if @channel.nil?
|
33
|
+
elsif @channels.nil? || @channels.empty?
|
34
|
+
error_message = ':channels is required for fetch message event'
|
35
|
+
end
|
36
|
+
|
37
|
+
raise(ArgumentError.new(object: self, message: error_message), error_message) unless error_message.nil?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/pubnub/version.rb
CHANGED
data/pubnub.gemspec
CHANGED
@@ -19,8 +19,8 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.required_ruby_version = '>= 3.0.0'
|
20
20
|
|
21
21
|
spec.add_dependency 'addressable', '>= 2.0.0'
|
22
|
-
spec.add_dependency 'concurrent-ruby', '~> 1.
|
23
|
-
spec.add_dependency 'concurrent-ruby-edge', '~> 0.
|
22
|
+
spec.add_dependency 'concurrent-ruby', '~> 1.3.4'
|
23
|
+
spec.add_dependency 'concurrent-ruby-edge', '~> 0.7.1'
|
24
24
|
spec.add_dependency 'dry-validation', '~> 1.0'
|
25
25
|
spec.add_dependency 'httpclient', '~> 2.8', '>= 2.8.3'
|
26
26
|
spec.add_dependency 'json', '>= 2.2.0', '< 3'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pubnub
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- PubNub
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -30,28 +30,28 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.3.4
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.3.4
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: concurrent-ruby-edge
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.
|
47
|
+
version: 0.7.1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.
|
54
|
+
version: 0.7.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: dry-validation
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -184,6 +184,7 @@ files:
|
|
184
184
|
- lib/pubnub/events/audit.rb
|
185
185
|
- lib/pubnub/events/channel_registration.rb
|
186
186
|
- lib/pubnub/events/delete_messages.rb
|
187
|
+
- lib/pubnub/events/fetch_messages.rb
|
187
188
|
- lib/pubnub/events/get_all_channels_metadata.rb
|
188
189
|
- lib/pubnub/events/get_all_uuid_metadata.rb
|
189
190
|
- lib/pubnub/events/get_channel_members.rb
|
@@ -251,6 +252,7 @@ files:
|
|
251
252
|
- lib/pubnub/validators/client.rb
|
252
253
|
- lib/pubnub/validators/common_validator.rb
|
253
254
|
- lib/pubnub/validators/delete.rb
|
255
|
+
- lib/pubnub/validators/fetch_messages.rb
|
254
256
|
- lib/pubnub/validators/get_all_channels_metadata.rb
|
255
257
|
- lib/pubnub/validators/get_all_uuid_metadata.rb
|
256
258
|
- lib/pubnub/validators/get_channel_members.rb
|