ably 1.0.7 → 1.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.
- checksums.yaml +4 -4
- data/.editorconfig +14 -0
- data/.travis.yml +4 -4
- data/CHANGELOG.md +26 -3
- data/Rakefile +32 -0
- data/SPEC.md +920 -565
- data/ably.gemspec +9 -4
- data/lib/ably/auth.rb +28 -2
- data/lib/ably/exceptions.rb +8 -2
- data/lib/ably/models/channel_state_change.rb +1 -1
- data/lib/ably/models/connection_state_change.rb +1 -1
- data/lib/ably/models/device_details.rb +87 -0
- data/lib/ably/models/device_push_details.rb +86 -0
- data/lib/ably/models/error_info.rb +23 -2
- data/lib/ably/models/idiomatic_ruby_wrapper.rb +4 -4
- data/lib/ably/models/protocol_message.rb +32 -2
- data/lib/ably/models/push_channel_subscription.rb +89 -0
- data/lib/ably/modules/conversions.rb +1 -1
- data/lib/ably/modules/encodeable.rb +1 -1
- data/lib/ably/modules/exception_codes.rb +128 -0
- data/lib/ably/modules/model_common.rb +15 -2
- data/lib/ably/modules/state_machine.rb +1 -1
- data/lib/ably/realtime.rb +1 -0
- data/lib/ably/realtime/auth.rb +1 -1
- data/lib/ably/realtime/channel.rb +24 -102
- data/lib/ably/realtime/channel/channel_manager.rb +2 -6
- data/lib/ably/realtime/channel/channel_state_machine.rb +2 -2
- data/lib/ably/realtime/channel/publisher.rb +74 -0
- data/lib/ably/realtime/channel/push_channel.rb +62 -0
- data/lib/ably/realtime/client.rb +87 -0
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +6 -2
- data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +1 -1
- data/lib/ably/realtime/connection.rb +8 -5
- data/lib/ably/realtime/connection/connection_manager.rb +7 -7
- data/lib/ably/realtime/connection/websocket_transport.rb +1 -1
- data/lib/ably/realtime/presence.rb +4 -4
- data/lib/ably/realtime/presence/members_map.rb +3 -3
- data/lib/ably/realtime/push.rb +40 -0
- data/lib/ably/realtime/push/admin.rb +61 -0
- data/lib/ably/realtime/push/channel_subscriptions.rb +108 -0
- data/lib/ably/realtime/push/device_registrations.rb +105 -0
- data/lib/ably/rest.rb +1 -0
- data/lib/ably/rest/channel.rb +33 -5
- data/lib/ably/rest/channel/push_channel.rb +62 -0
- data/lib/ably/rest/client.rb +137 -28
- data/lib/ably/rest/middleware/parse_message_pack.rb +17 -1
- data/lib/ably/rest/presence.rb +1 -0
- data/lib/ably/rest/push.rb +42 -0
- data/lib/ably/rest/push/admin.rb +54 -0
- data/lib/ably/rest/push/channel_subscriptions.rb +121 -0
- data/lib/ably/rest/push/device_registrations.rb +103 -0
- data/lib/ably/version.rb +7 -2
- data/spec/acceptance/realtime/auth_spec.rb +6 -8
- data/spec/acceptance/realtime/channel_spec.rb +166 -51
- data/spec/acceptance/realtime/client_spec.rb +149 -0
- data/spec/acceptance/realtime/connection_failures_spec.rb +1 -1
- data/spec/acceptance/realtime/connection_spec.rb +4 -4
- data/spec/acceptance/realtime/message_spec.rb +19 -17
- data/spec/acceptance/realtime/presence_spec.rb +5 -5
- data/spec/acceptance/realtime/push_admin_spec.rb +696 -0
- data/spec/acceptance/realtime/push_spec.rb +27 -0
- data/spec/acceptance/rest/auth_spec.rb +4 -3
- data/spec/acceptance/rest/base_spec.rb +2 -2
- data/spec/acceptance/rest/client_spec.rb +129 -10
- data/spec/acceptance/rest/message_spec.rb +175 -4
- data/spec/acceptance/rest/push_admin_spec.rb +896 -0
- data/spec/acceptance/rest/push_spec.rb +25 -0
- data/spec/acceptance/rest/time_spec.rb +1 -1
- data/spec/run_parallel_tests +33 -0
- data/spec/unit/logger_spec.rb +10 -3
- data/spec/unit/models/device_details_spec.rb +102 -0
- data/spec/unit/models/device_push_details_spec.rb +101 -0
- data/spec/unit/models/error_info_spec.rb +51 -3
- data/spec/unit/models/message_spec.rb +17 -2
- data/spec/unit/models/presence_message_spec.rb +1 -1
- data/spec/unit/models/push_channel_subscription_spec.rb +86 -0
- data/spec/unit/realtime/client_spec.rb +12 -0
- data/spec/unit/realtime/push_channel_spec.rb +36 -0
- data/spec/unit/rest/channel_spec.rb +8 -1
- data/spec/unit/rest/client_spec.rb +30 -0
- data/spec/unit/rest/push_channel_spec.rb +36 -0
- metadata +71 -8
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'ably/realtime/push/admin'
|
2
|
+
|
3
|
+
module Ably
|
4
|
+
module Realtime
|
5
|
+
# Class providing push notification functionality
|
6
|
+
class Push
|
7
|
+
# @private
|
8
|
+
attr_reader :client
|
9
|
+
|
10
|
+
def initialize(client)
|
11
|
+
@client = client
|
12
|
+
end
|
13
|
+
|
14
|
+
# Admin features for push notifications like managing devices and channel subscriptions
|
15
|
+
# @return [Ably::Realtime::Push::Admin]
|
16
|
+
def admin
|
17
|
+
@admin ||= Admin.new(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Activate this device for push notifications by registering with the push transport such as GCM/APNS
|
21
|
+
#
|
22
|
+
# @note This is unsupported in the Ruby library
|
23
|
+
def activate(*arg)
|
24
|
+
raise_unsupported
|
25
|
+
end
|
26
|
+
|
27
|
+
# Deactivate this device for push notifications by removing the registration with the push transport such as GCM/APNS
|
28
|
+
#
|
29
|
+
# @note This is unsupported in the Ruby library
|
30
|
+
def deactivate(*arg)
|
31
|
+
raise_unsupported
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def raise_unsupported
|
36
|
+
raise Ably::Exceptions::PushNotificationsNotSupported, 'This device does not support receiving or subscribing to push notifications. All PushChannel methods are unavailable'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'ably/realtime/push/device_registrations'
|
2
|
+
require 'ably/realtime/push/channel_subscriptions'
|
3
|
+
|
4
|
+
module Ably::Realtime
|
5
|
+
class Push
|
6
|
+
# Class providing push notification administrative functionality
|
7
|
+
# for registering devices and attaching to channels etc.
|
8
|
+
class Admin
|
9
|
+
include Ably::Modules::AsyncWrapper
|
10
|
+
include Ably::Modules::Conversions
|
11
|
+
|
12
|
+
# @api private
|
13
|
+
attr_reader :client
|
14
|
+
|
15
|
+
# @api private
|
16
|
+
attr_reader :push
|
17
|
+
|
18
|
+
def initialize(push)
|
19
|
+
@push = push
|
20
|
+
@client = push.client
|
21
|
+
end
|
22
|
+
|
23
|
+
# (see Ably::Rest::Push#publish)
|
24
|
+
#
|
25
|
+
# @yield Block is invoked upon successful publish of the message
|
26
|
+
# @return [Ably::Util::SafeDeferrable]
|
27
|
+
#
|
28
|
+
def publish(recipient, data, &callback)
|
29
|
+
raise ArgumentError, "Expecting a Hash object for recipient, got #{recipient.class}" unless recipient.kind_of?(Hash)
|
30
|
+
raise ArgumentError, "Recipient data is empty. You must provide recipient details" if recipient.empty?
|
31
|
+
raise ArgumentError, "Expecting a Hash object for data, got #{data.class}" unless data.kind_of?(Hash)
|
32
|
+
raise ArgumentError, "Push data field is empty. You must provide attributes for the push notification" if data.empty?
|
33
|
+
|
34
|
+
async_wrap(callback) do
|
35
|
+
rest_push_admin.publish(recipient, data)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Manage device registrations
|
40
|
+
# @return [Ably::Realtime::Push::DeviceRegistrations]
|
41
|
+
def device_registrations
|
42
|
+
@device_registrations ||= DeviceRegistrations.new(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Manage channel subscriptions for devices or clients
|
46
|
+
# @return [Ably::Realtime::Push::ChannelSubscriptions]
|
47
|
+
def channel_subscriptions
|
48
|
+
@channel_subscriptions ||= ChannelSubscriptions.new(self)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
def rest_push_admin
|
53
|
+
client.rest_client.push.admin
|
54
|
+
end
|
55
|
+
|
56
|
+
def logger
|
57
|
+
client.logger
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Ably::Realtime
|
2
|
+
class Push
|
3
|
+
# Manage push notification channel subscriptions for devices or clients
|
4
|
+
class ChannelSubscriptions
|
5
|
+
include Ably::Modules::Conversions
|
6
|
+
include Ably::Modules::AsyncWrapper
|
7
|
+
|
8
|
+
# @api private
|
9
|
+
attr_reader :client
|
10
|
+
|
11
|
+
# @api private
|
12
|
+
attr_reader :admin
|
13
|
+
|
14
|
+
def initialize(admin)
|
15
|
+
@admin = admin
|
16
|
+
@client = admin.client
|
17
|
+
end
|
18
|
+
|
19
|
+
# (see Ably::Rest::Push::ChannelSubscriptions#list)
|
20
|
+
#
|
21
|
+
# @yield Block is invoked when request succeeds
|
22
|
+
# @return [Ably::Util::SafeDeferrable]
|
23
|
+
#
|
24
|
+
def list(params, &callback)
|
25
|
+
raise ArgumentError, "params must be a Hash" unless params.kind_of?(Hash)
|
26
|
+
|
27
|
+
if (IdiomaticRubyWrapper(params).keys & [:channel, :client_id, :device_id]).length == 0
|
28
|
+
raise ArgumentError, "at least one channel, client_id or device_id filter param must be provided"
|
29
|
+
end
|
30
|
+
|
31
|
+
async_wrap(callback) do
|
32
|
+
rest_channel_subscriptions.list(params.merge(async_blocking_operations: true))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# (see Ably::Rest::Push::ChannelSubscriptions#list_channels)
|
37
|
+
#
|
38
|
+
# @yield Block is invoked when request succeeds
|
39
|
+
# @return [Ably::Util::SafeDeferrable]
|
40
|
+
#
|
41
|
+
def list_channels(params = {}, &callback)
|
42
|
+
params = {} if params.nil?
|
43
|
+
raise ArgumentError, "params must be a Hash" unless params.kind_of?(Hash)
|
44
|
+
|
45
|
+
async_wrap(callback) do
|
46
|
+
rest_channel_subscriptions.list_channels(params.merge(async_blocking_operations: true))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# (see Ably::Rest::Push::ChannelSubscriptions#save)
|
51
|
+
#
|
52
|
+
# @yield Block is invoked when request succeeds
|
53
|
+
# @return [Ably::Util::SafeDeferrable]
|
54
|
+
#
|
55
|
+
def save(push_channel_subscription, &callback)
|
56
|
+
push_channel_subscription_object = PushChannelSubscription(push_channel_subscription)
|
57
|
+
raise ArgumentError, "Channel is required yet is empty" if push_channel_subscription_object.channel.to_s.empty?
|
58
|
+
|
59
|
+
async_wrap(callback) do
|
60
|
+
rest_channel_subscriptions.save(push_channel_subscription)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# (see Ably::Rest::Push::ChannelSubscriptions#remove)
|
65
|
+
#
|
66
|
+
# @yield Block is invoked when request succeeds
|
67
|
+
# @return [Ably::Util::SafeDeferrable]
|
68
|
+
#
|
69
|
+
def remove(push_channel_subscription, &callback)
|
70
|
+
push_channel_subscription_object = PushChannelSubscription(push_channel_subscription)
|
71
|
+
raise ArgumentError, "Channel is required yet is empty" if push_channel_subscription_object.channel.to_s.empty?
|
72
|
+
if push_channel_subscription_object.client_id.to_s.empty? && push_channel_subscription_object.device_id.to_s.empty?
|
73
|
+
raise ArgumentError, "Either client_id or device_id must be present"
|
74
|
+
end
|
75
|
+
|
76
|
+
async_wrap(callback) do
|
77
|
+
rest_channel_subscriptions.remove(push_channel_subscription)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# (see Ably::Rest::Push::ChannelSubscriptions#remove_where)
|
82
|
+
#
|
83
|
+
# @yield Block is invoked when request succeeds
|
84
|
+
# @return [Ably::Util::SafeDeferrable]
|
85
|
+
#
|
86
|
+
def remove_where(params, &callback)
|
87
|
+
raise ArgumentError, "params must be a Hash" unless params.kind_of?(Hash)
|
88
|
+
|
89
|
+
if (IdiomaticRubyWrapper(params).keys & [:channel, :client_id, :device_id]).length == 0
|
90
|
+
raise ArgumentError, "at least one channel, client_id or device_id filter param must be provided"
|
91
|
+
end
|
92
|
+
|
93
|
+
async_wrap(callback) do
|
94
|
+
rest_channel_subscriptions.remove_where(params)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
def rest_channel_subscriptions
|
100
|
+
client.rest_client.push.admin.channel_subscriptions
|
101
|
+
end
|
102
|
+
|
103
|
+
def logger
|
104
|
+
client.logger
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Ably::Realtime
|
2
|
+
class Push
|
3
|
+
# Manage device registrations for push notifications
|
4
|
+
class DeviceRegistrations
|
5
|
+
include Ably::Modules::Conversions
|
6
|
+
include Ably::Modules::AsyncWrapper
|
7
|
+
|
8
|
+
# @api private
|
9
|
+
attr_reader :client
|
10
|
+
|
11
|
+
# @api private
|
12
|
+
attr_reader :admin
|
13
|
+
|
14
|
+
def initialize(admin)
|
15
|
+
@admin = admin
|
16
|
+
@client = admin.client
|
17
|
+
end
|
18
|
+
|
19
|
+
# (see Ably::Rest::Push::DeviceRegistrations#get)
|
20
|
+
#
|
21
|
+
# @yield Block is invoked when request succeeds
|
22
|
+
# @return [Ably::Util::SafeDeferrable]
|
23
|
+
#
|
24
|
+
def get(device_id, &callback)
|
25
|
+
device_id = device_id.id if device_id.kind_of?(Ably::Models::DeviceDetails)
|
26
|
+
raise ArgumentError, "device_id must be a string or DeviceDetails object" unless device_id.kind_of?(String)
|
27
|
+
|
28
|
+
async_wrap(callback) do
|
29
|
+
rest_device_registrations.get(device_id)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# (see Ably::Rest::Push::DeviceRegistrations#list)
|
34
|
+
#
|
35
|
+
# @yield Block is invoked when request succeeds
|
36
|
+
# @return [Ably::Util::SafeDeferrable]
|
37
|
+
#
|
38
|
+
def list(params = {}, &callback)
|
39
|
+
params = {} if params.nil?
|
40
|
+
raise ArgumentError, "params must be a Hash" unless params.kind_of?(Hash)
|
41
|
+
raise ArgumentError, "device_id filter cannot be specified alongside a client_id filter. Use one or the other" if params[:client_id] && params[:device_id]
|
42
|
+
|
43
|
+
async_wrap(callback) do
|
44
|
+
rest_device_registrations.list(params.merge(async_blocking_operations: true))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# (see Ably::Rest::Push::DeviceRegistrations#save)
|
49
|
+
#
|
50
|
+
# @yield Block is invoked when request succeeds
|
51
|
+
# @return [Ably::Util::SafeDeferrable]
|
52
|
+
#
|
53
|
+
def save(device, &callback)
|
54
|
+
device_details = DeviceDetails(device)
|
55
|
+
raise ArgumentError, "Device ID is required yet is empty" if device_details.id.nil? || device_details == ''
|
56
|
+
|
57
|
+
async_wrap(callback) do
|
58
|
+
rest_device_registrations.save(device_details)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# (see Ably::Rest::Push::DeviceRegistrations#remove)
|
63
|
+
#
|
64
|
+
# @yield Block is invoked when request succeeds
|
65
|
+
# @return [Ably::Util::SafeDeferrable]
|
66
|
+
#
|
67
|
+
def remove(device_id, &callback)
|
68
|
+
device_id = device_id.id if device_id.kind_of?(Ably::Models::DeviceDetails)
|
69
|
+
raise ArgumentError, "device_id must be a string or DeviceDetails object" unless device_id.kind_of?(String)
|
70
|
+
|
71
|
+
async_wrap(callback) do
|
72
|
+
rest_device_registrations.remove(device_id)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# (see Ably::Rest::Push::DeviceRegistrations#remove_where)
|
77
|
+
#
|
78
|
+
# @yield Block is invoked when request succeeds
|
79
|
+
# @return [Ably::Util::SafeDeferrable]
|
80
|
+
#
|
81
|
+
def remove_where(params = {}, &callback)
|
82
|
+
filter = if params.kind_of?(Ably::Models::DeviceDetails)
|
83
|
+
{ 'deviceId' => params.id }
|
84
|
+
else
|
85
|
+
raise ArgumentError, "params must be a Hash" unless params.kind_of?(Hash)
|
86
|
+
raise ArgumentError, "device_id filter cannot be specified alongside a client_id filter. Use one or the other" if params[:client_id] && params[:device_id]
|
87
|
+
IdiomaticRubyWrapper(params).as_json
|
88
|
+
end
|
89
|
+
|
90
|
+
async_wrap(callback) do
|
91
|
+
rest_device_registrations.remove_where(filter)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
def rest_device_registrations
|
97
|
+
client.rest_client.push.admin.device_registrations
|
98
|
+
end
|
99
|
+
|
100
|
+
def logger
|
101
|
+
client.logger
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/ably/rest.rb
CHANGED
data/lib/ably/rest/channel.rb
CHANGED
@@ -3,8 +3,6 @@ module Ably
|
|
3
3
|
# The Ably Realtime service organises the traffic within any application into named channels.
|
4
4
|
# Channels are the "unit" of message distribution; clients attach to channels to subscribe to messages, and every message broadcast by the service is associated with a unique channel.
|
5
5
|
#
|
6
|
-
# @!attribute [r] client
|
7
|
-
# @return {Ably::Realtime::Client} Ably client associated with this channel
|
8
6
|
# @!attribute [r] name
|
9
7
|
# @return {String} channel name
|
10
8
|
# @!attribute [r] options
|
@@ -12,7 +10,19 @@ module Ably
|
|
12
10
|
class Channel
|
13
11
|
include Ably::Modules::Conversions
|
14
12
|
|
15
|
-
|
13
|
+
# Ably client associated with this channel
|
14
|
+
# @return [Ably::Realtime::Client]
|
15
|
+
# @api private
|
16
|
+
attr_reader :client
|
17
|
+
|
18
|
+
attr_reader :name, :options
|
19
|
+
|
20
|
+
# Push channel used for push notification (client-side)
|
21
|
+
# @return [Ably::Rest::Channel::PushChannel]
|
22
|
+
# @api private
|
23
|
+
attr_reader :push
|
24
|
+
|
25
|
+
IDEMPOTENT_LIBRARY_GENERATED_ID_LENGTH = 9 # See spec RSL1k1
|
16
26
|
|
17
27
|
# Initialize a new Channel object
|
18
28
|
#
|
@@ -27,13 +37,14 @@ module Ably
|
|
27
37
|
update_options channel_options
|
28
38
|
@client = client
|
29
39
|
@name = name
|
40
|
+
@push = PushChannel.new(self)
|
30
41
|
end
|
31
42
|
|
32
43
|
# Publish one or more messages to the channel.
|
33
44
|
#
|
34
45
|
# @param name [String, Array<Ably::Models::Message|Hash>, nil] The event name of the message to publish, or an Array of [Ably::Model::Message] objects or [Hash] objects with +:name+ and +:data+ pairs
|
35
46
|
# @param data [String, ByteArray, nil] The message payload unless an Array of [Ably::Model::Message] objects passed in the first argument
|
36
|
-
# @param attributes [Hash, nil] Optional additional message attributes such as :client_id or :connection_id, applied when name attribute is nil or a string
|
47
|
+
# @param attributes [Hash, nil] Optional additional message attributes such as :extras, :id, :client_id or :connection_id, applied when name attribute is nil or a string
|
37
48
|
# @return [Boolean] true if the message was published, otherwise false
|
38
49
|
#
|
39
50
|
# @example
|
@@ -58,12 +69,16 @@ module Ably
|
|
58
69
|
messages = if name.kind_of?(Enumerable)
|
59
70
|
name
|
60
71
|
else
|
72
|
+
if name.kind_of?(Ably::Models::Message)
|
73
|
+
raise ArgumentError, "name argument does not support single Message objects, only arrays of Message objects"
|
74
|
+
end
|
75
|
+
|
61
76
|
name = ensure_utf_8(:name, name, allow_nil: true)
|
62
77
|
ensure_supported_payload data
|
63
78
|
[{ name: name, data: data }.merge(attributes)]
|
64
79
|
end
|
65
80
|
|
66
|
-
payload = messages.map do |message|
|
81
|
+
payload = messages.each_with_index.map do |message, index|
|
67
82
|
Ably::Models::Message(message.dup).tap do |msg|
|
68
83
|
msg.encode client.encoders, options
|
69
84
|
|
@@ -75,6 +90,17 @@ module Ably
|
|
75
90
|
raise Ably::Exceptions::IncompatibleClientId.new("Cannot publish with client_id '#{msg.client_id}' as it is incompatible with the current configured client_id '#{client.client_id}'")
|
76
91
|
end
|
77
92
|
end.as_json
|
93
|
+
end.tap do |payload|
|
94
|
+
if client.idempotent_rest_publishing
|
95
|
+
# We cannot mutate for idempotent publishing if one or more messages already has an ID
|
96
|
+
if payload.all? { |msg| !msg['id'] }
|
97
|
+
# Mutate the JSON to support idempotent publishing where a Message.id does not exist
|
98
|
+
idempotent_publish_id = SecureRandom.base64(IDEMPOTENT_LIBRARY_GENERATED_ID_LENGTH)
|
99
|
+
payload.each_with_index do |msg, idx|
|
100
|
+
msg['id'] = "#{idempotent_publish_id}:#{idx}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
78
104
|
end
|
79
105
|
|
80
106
|
response = client.post("#{base_path}/publish", payload.length == 1 ? payload.first : payload)
|
@@ -141,3 +167,5 @@ module Ably
|
|
141
167
|
end
|
142
168
|
end
|
143
169
|
end
|
170
|
+
|
171
|
+
require 'ably/rest/channel/push_channel'
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Ably::Rest
|
2
|
+
class Channel
|
3
|
+
# A push channel used for push notifications
|
4
|
+
# Each PushChannel maps to exactly one Rest Channel
|
5
|
+
#
|
6
|
+
# @!attribute [r] channel
|
7
|
+
# @return [Ably::Rest::Channel] Underlying channel object
|
8
|
+
#
|
9
|
+
class PushChannel
|
10
|
+
attr_reader :channel
|
11
|
+
|
12
|
+
def initialize(channel)
|
13
|
+
raise ArgumentError, "Unsupported channel type '#{channel.class}'" unless channel.kind_of?(Ably::Rest::Channel)
|
14
|
+
@channel = channel
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"<PushChannel: name=#{channel.name}>"
|
19
|
+
end
|
20
|
+
|
21
|
+
# Subscribe local device for push notifications on this channel
|
22
|
+
#
|
23
|
+
# @note This is unsupported in the Ruby library
|
24
|
+
def subscribe_device(*args)
|
25
|
+
raise_unsupported
|
26
|
+
end
|
27
|
+
|
28
|
+
# Subscribe all devices registered to this client's authenticated client_id for push notifications on this channel
|
29
|
+
#
|
30
|
+
# @note This is unsupported in the Ruby library
|
31
|
+
def subscribe_client_id(*args)
|
32
|
+
raise_unsupported
|
33
|
+
end
|
34
|
+
|
35
|
+
# Unsubscribe local device for push notifications on this channel
|
36
|
+
#
|
37
|
+
# @note This is unsupported in the Ruby library
|
38
|
+
def unsubscribe_device(*args)
|
39
|
+
raise_unsupported
|
40
|
+
end
|
41
|
+
|
42
|
+
# Unsubscribe all devices registered to this client's authenticated client_id for push notifications on this channel
|
43
|
+
#
|
44
|
+
# @note This is unsupported in the Ruby library
|
45
|
+
def unsubscribe_client_id(*args)
|
46
|
+
raise_unsupported
|
47
|
+
end
|
48
|
+
|
49
|
+
# Get list of subscriptions on this channel for this device or authenticate client_id
|
50
|
+
#
|
51
|
+
# @note This is unsupported in the Ruby library
|
52
|
+
def get_subscriptions(*args)
|
53
|
+
raise_unsupported
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
def raise_unsupported
|
58
|
+
raise Ably::Exceptions::PushNotificationsNotSupported, 'This device does not support receiving or subscribing to push notifications. All PushChannel methods are unavailable'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|