# Channels
## Channels
The `Channels` object, accessed from the [rest library client constructor](https://ably.com/docs/api/rest-sdk#channels), is used to create and destroy `Channel` objects. It exposes the following public methods:
### Channels Methods
#### getGet
`Channel get(String channelName, ChannelOptions channelOptions)`
`Channel Get(String channelName, ChannelOptions channelOptions)`
`ARTRealtimeChannel get(String channelName, ARTChannelOptions channelOptions)`
Creates a new [Channel](#properties) object if none for the channel exists, or returns the existing channel object.
#### releaseRelease
`release(String channelName)`
`void release(String channelName)`
`bool Release(string channelName)`
Releases a [Channel](#properties) object, deleting it from the local SDK client instance and enabling it to be garbage collected.
This method only affects the local client-side representation of the channel. The channel itself on the Ably platform is not deleted or changed, and other client instances (in the same or different processes) are unaffected.
After releasing a channel, calling `channels.get(channelName)` will create a fresh channel object. If using a singleton REST client pattern with multiple execution contexts, be cautious when calling `release` as it will affect all parts of your application using that client instance. Subsequent publish operations on the same channel name will require obtaining a new channel object.
## Channel
The Channel object, created via the [Channels](#channels-object) object, is used to interact with a specific channel.
### Channel PropertiesChannel AttributesAbly\Channel PropertiesARTRestChannel PropertiesAbly::Rest::Channel Attributesio.ably.lib.rest.Channel MembersIO.Ably.Rest.RestChannel MembersChannel Methods
The `Channel` object exposes the following public propertiesattributesmembers:
#### nameName
The name `String` unique to this channel.
#### presencePresence
Provides access to the [REST Presence](https://ably.com/docs/presence-occupancy/presence) object for this channel which can be used to get members present on the channel, or retrieve presence event history.
#### push
Provides access to the [PushChannel](https://ably.com/docs/api/realtime-sdk/push#push-channel) object for this channel which can be used to access members present on the channel, or participate in presence.
### Channel Methods
#### publishPublish
There are two overloaded versions of this method:
`publish(String name, Object data, PublishOptions options?) Promise`
`publish(String name, Object data)`
`publish(name=Unicode, data=Object)`
`void publish(String name, Object data)`
`Task PublishAsync(string name, object data, string clientId = null)`
`publish(name: String?, data: AnyObject?, callback: ((ARTErrorInfo?) -> Void)?)`
`(c *RestChannel) Publish(name string, data interface{}) (error ErrorInfo)`
`Future publish({String name, Object data})`
Publish a single message on this channel based on a given event name and payload. A callback may optionally be passed in to this call to be notified of success or failure of the operation.A listener may optionally be passed in to this call to be notified of success or failure of the operation.A callback may optionally be passed in to this call to be notified of success of the operation.
It is also possible to publish a message to multiple channels at once using our [batch publish feature](https://ably.com/docs/messages/batch#batch-publish).
`publish(Message message, PublishOptions options?): Promise`
Publish a single message on this channel.
`publish(Message[] messages, PublishOptions options?): Promise`
`publish(Message[] messages)`
`publish(messages=List)`
`void publish(Message[] messages)`
`Task PublishAsync(IEnumerable messages)`
`publish(messages: [ARTMessage], callback: ((ARTErrorInfo?) -> Void)?)`
`(c *RestChannel) PublishAll(messages []*proto.Message) (error ErrorInfo)`
`Future publish({List messages})`
Publish several messages on this channel. A callback may optionally be passed in to this call to be notified of success or failure of the operation.A listener may optionally be passed in to this call to be notified of success or failure of the operation.A callback may optionally be passed in to this call to be notified of success of the operation.
The entire `messages` array is published atomically. This means that:
* Either they will all be successfully published or none of them will
* The [max message size](https://ably.com/docs/platform/pricing/limits#message) limit applies to the total size of all messages in the array
* The publish will only count as a single message for the purpose of [per-channel rate limit](https://ably.com/docs/platform/pricing/limits#message)
* If you are using client-specified message IDs for publish idempotency, [they must conform to certain restrictions](https://faqs.ably.com/client-specified-message-id-restrictions-for-multiple-messages-published-atomically)
#### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| data | Data payload for the message. The supported payload types are Strings, objects or arrays capable of JSON representation, buffers containing arbitrary binary data, and null. (Note that if sending a binary, that binary should be the entire payload; an object with a binary field within it may not be correctly encoded) | `Object` |
| messages | An array of message objects to publish | [`Message []`](#message) |
| options | Optional parameters to provide to the publish operation | [`PublishOptions`](#publish-options) |
| Parameter | Description | Type |
|-----------|-------------|------|
| name | Event name for the published message | `String``Unicode` for Python 2, `String` for Python 3 |
| data | Data payload for the message. The supported payload types are strings, plain .NET objects, binary data as byte arrays, and nullunicode Strings, Dict, or List objects that can be serialized to JSON using `json.dumps`, binary data as `bytearray` (in Python 3, `bytes` also works), and None | `Object` |
| messages | An array of message objects to publish | [`Message []`](#message) |
| Parameter | Description | Type |
|-----------|-------------|------|
| data | Data payload for the message. The supported payload types are strings, objects that can be serialized to JSON, binary data as byte arrays, and nil | `interface` |
| messages | An array of message objects to publish | [`Message []`](#message) |
| Parameter | Description | Type |
|-----------|-------------|------|
| data | Data payload for the message. The supported payload types are Strings, Hash or Array objects that can be serialized to JSON using `to_json`, binary data as `ASCII-8BIT` byte arrays, and null. (Note that if sending a byte array, it should be the entire payload; a hash or array with a bytearray field within it may not be correctly encoded) | `Object` |
| messages | An array of message objects to publish | [`Message []`](#message) |
| Parameter | Description | Type |
|-----------|-------------|------|
| data | Data payload for the message. The supported payload types are Strings, Associative Array or Array objects that can be serialized to JSON, binary data as byte arrays, and null | `Object` |
| messages | An array of message objects to publish | [`Message []`](#message) |
| Parameter | Description | Type |
|-----------|-------------|------|
| data | Data payload for the message. The supported payload types are Strings, JsonObject, binary data as byte arrays, and null | `Object` |
| messages | An array of message objects to publish | [`Message []`](#message) |
| Parameter | Description | Type |
|-----------|-------------|------|
| name | Event name for the published message | `String` |
| data | Data payload for the message. The supported payload types are String, Map, List, and null | `Object` |
| message | Payload for the message as a [`Message`](#message) object | [`Message`](#message) |
| messages | An array of message objects to publish | [`Message []`](#message) |
| Parameter | Description | Type |
|-----------|-------------|------|
| data | Data payload for the message. The supported payload types are `NS``String`, `NS``Dictionary` or `NS``Array` objects that can be serialized to JSON, binary data as `NSData`, and `nil` | `Object` |
| messages | An array of message objects to publish | [`Message []`](#message) |
| callback | Called upon publishing the message, or with an error | |
#### Returns
Returns a promise. On success, the promise resolves. On failure, the promise is rejected with an [`ErrorInfo`](#error-info) object that details the reason why it was rejected.
#### Callback result
On successful publish of the message, `err` is null. On failure to publish the message, `err` contains an [`ErrorInfo`](#error-info) object describing the failure reason.
#### Failure
On failure to publish the message, an [`AblyException`](https://ably.com/docs/api/rest-sdk/types#ably-exception) will be raised.
#### Returns
The method is asynchronous and returns a Task that can be awaited.
On failure to publish the message, an [`AblyException`](https://ably.com/docs/api/rest-sdk/types#ably-exception) will be raised.
#### Returns
The function returns [`ErrorInfo`](#error-info) if an error has occurred, otherwise it returns `nil`.
#### Returns
The function throws `ably.AblyException` if an error has occurred.
### history
### History
`history(Object params?): Promise>`
`PaginatedResult history(Hash options)`
`PaginatedResult history(kwargs_options)`
`PaginatedResult history(Array options)`
`PaginatedResult history(Param[] options)`
`Task> HistoryAsync(PaginatedRequestParams dataQuery)`
`history(query: ARTRealtimeHistoryQuery?, callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void) throws`
`(c *RestChannel) History(options *PaginateParams) (*PaginatedResult, error)`
Gets a [paginated](#paginated-result) set of historical messages for this channel. If the [channel is configured to persist messages to disk](https://faqs.ably.com/how-long-are-messages-stored-for), then message history will [typically be available for 24 - 72 hours](https://faqs.ably.com/how-long-are-messages-stored-for). If not, messages are only retained in memory by the Ably service for two minutes.
#### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| paramsquery[`Param[]`](#param) optionsparams | An optional object containing the query parametersOptional keyword arguments containing the query parametersAn optional set of key value pairs containing the query parametersAn optional Associative Array containing the query parameters, as specified in the [message history API documentation](https://ably.com/docs/api/rest-sdk/history#channel-history) | Object |
| Parameter | Description | Type |
|-----------|-------------|------|
| query | An optional object containing the query parameters, as specified in the [message history API documentation](https://ably.com/docs/api/rest-sdk/history#channel-history) | Object |
| callback | Called with a [`ARTPaginatedResult`](#paginated-result)\<[`ARTMessage`](#message)> object or an error | Callback |
#### Returns
Returns a promise. On success, the promise is fulfilled with a [`PaginatedResult`](#paginated-result) object containing an array of messages. On failure, the promise is rejected with an [`ErrorInfo`](#error-info) object that details the reason why it was rejected.
#### Callback result
On success, `resultPage` contains a [`PaginatedResult`](#paginated-result) encapsulating an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next()`](#paginated-result) and [`first()`](#paginated-result) methods.
On failure to retrieve message history, `err` contains an [`ErrorInfo`](#error-info) object with the failure reason.
#### Returns
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next`](#paginated-result) and [`first`](#paginated-result) methods.
Failure to retrieve the message history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception)
#### Returns
The method is asynchronous and return a Task that has to be awaited to get the result.
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`NextAsync`](#paginated-result) and [`FirstAsync`](#paginated-result) methods.
Failure to retrieve the message history will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception)
#### Returns
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next`](#paginated-result) and [`first`](#paginated-result) methods. `error` will be nil.
On failure to retrieve message history, the `error` contains an [`ErrorInfo`](#error-info) object with the failure reason.
#### getMessage
`getMessage(serialOrMessage: string | Message): Promise`
`Message getMessage(String serial)`
`Message get_message(serial_or_message)`
Retrieves the latest version of a specific message by its serial identifier. Requires the **history** [capability](https://ably.com/docs/auth/capabilities).
See [updating and deleting messages: retrieving the latest version](https://ably.com/docs/messages/updates-deletes#get) for more information.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| serialOrMessage | Either the serial identifier string of the message to retrieve, or a [`Message`](https://ably.com/docs/api/realtime-sdk/messages) object containing a populated `serial` field | `string` or [`Message`](https://ably.com/docs/api/realtime-sdk/messages) |
##### Returns
Returns a promise which, upon success, will be fulfilled with a [`Message`](https://ably.com/docs/api/realtime-sdk/messages) object representing the latest version of the message. Upon failure, the promise will be rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object which explains the error.
| Parameter | Description | Type |
|-----------|-------------|------|
| serial | Serial identifier string of the message to retrieve | `String` |
##### Returns
Returns a [`Message`](https://ably.com/docs/api/realtime-sdk/messages) object representing the latest version of the message.
| Parameter | Description | Type |
|-----------|-------------|------|
| serial_or_message | Either the serial identifier string of the message to retrieve, or a `Message` object containing a populated `serial` field | `str` or `Message` |
##### Returns
Returns a [`Message`](https://ably.com/docs/api/realtime-sdk/messages) object representing the latest version of the message.
On failure, raises an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception).
#### updateMessage
`updateMessage(message: Message, operation?: MessageOperation, params?: Record): Promise`
`UpdateDeleteResult updateMessage(Message message, MessageOperation operation)`
`UpdateDeleteResult update_message(message, operation=None, params=dict())`
Publishes an update to an existing message with shallow mixin semantics. Non-null `name`, `data`, and `extras` fields in the provided message will replace the corresponding fields in the existing message, while null fields will be left unchanged. Requires the **message-update-own** or **message-update-any** [capability](https://ably.com/docs/auth/capabilities).
See [updating and deleting messages: updates](https://ably.com/docs/messages/updates-deletes#update) for more information.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| message | A [`Message`](https://ably.com/docs/api/realtime-sdk/messages) object containing a populated `serial` field and the fields to update | [`Message`](https://ably.com/docs/api/realtime-sdk/messages) |
| operation | An optional `MessageOperation` object containing metadata about the update operation. Can include `clientId`, `description`, and `metadata` fields | `MessageOperation` (optional) |
| params | Optional parameters sent as part of the query string | `Record` (optional) |
##### Returns
Returns a promise which, upon success, will be fulfilled with an [`UpdateDeleteResult`](https://ably.com/docs/api/realtime-sdk/types#update-delete-result) object containing the new version of the message. Upon failure, the promise will be rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object which explains the error.
##### Returns
Returns an [`UpdateDeleteResult`](https://ably.com/docs/api/realtime-sdk/types#update-delete-result) object containing the new version of the message.
#### deleteMessage
`deleteMessage(message: Message, operation?: MessageOperation, params?: Record): Promise`
`UpdateDeleteResult deleteMessage(Message message, MessageOperation operation)`
`UpdateDeleteResult delete_message(message, operation=None, params=dict())`
Marks a message as deleted by publishing an update with an action of `MESSAGE_DELETE`. This does not remove the message from the server, and the full message history remains accessible. Uses shallow mixin semantics: non-null `name`, `data`, and `extras` fields in the provided message will replace the corresponding fields in the existing message, while null fields will be left unchanged. Requires the **message-delete-own** or **message-delete-any** [capability](https://ably.com/docs/auth/capabilities).
See [updating and deleting messages: deletes](https://ably.com/docs/messages/updates-deletes#delete) for more information.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| message | A [`Message`](https://ably.com/docs/api/realtime-sdk/messages) object containing a populated `serial` field | [`Message`](https://ably.com/docs/api/realtime-sdk/messages) |
| operation | An optional `MessageOperation` object containing metadata about the delete operation. Can include `clientId`, `description`, and `metadata` fields | `MessageOperation` (optional) |
| params | Optional parameters sent as part of the query string | `Record` (optional) |
##### Returns
Returns a promise which, upon success, will be fulfilled with an [`UpdateDeleteResult`](https://ably.com/docs/api/realtime-sdk/types#update-delete-result) object containing the new version of the message. Upon failure, the promise will be rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object which explains the error.
##### Returns
Returns an [`UpdateDeleteResult`](https://ably.com/docs/api/realtime-sdk/types#update-delete-result) object containing the new version of the message.
#### appendMessage
`appendMessage(message: Message, operation?: MessageOperation, params?: Record): Promise`
`UpdateDeleteResult appendMessage(Message message, MessageOperation operation)`
`UpdateDeleteResult append_message(message, operation=None, params=dict())`
Appends data to an existing message. The supplied `data` field is appended to the previous message's data, while all other fields (`name`, `extras`) replace the previous values if provided. Requires the **message-update-own** or **message-update-any** [capability](https://ably.com/docs/auth/capabilities).
For publishing a high rate of appends, you typically want to use a realtime client, not a REST client, in order to have message order preservation. See [append ordering](https://ably.com/docs/messages/updates-deletes#append-ordering).
See [updating and deleting messages: appends](https://ably.com/docs/messages/updates-deletes#append) for more information.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| message | A [`Message`](https://ably.com/docs/api/realtime-sdk/messages) object containing a populated `serial` field and the data to append | [`Message`](https://ably.com/docs/api/realtime-sdk/messages) |
| operation | An optional `MessageOperation` object containing metadata about the append operation. Can include `clientId`, `description`, and `metadata` fields | `MessageOperation` (optional) |
| params | Optional parameters sent as part of the query string | `Record` (optional) |
##### Returns
Returns a promise which, upon success, will be fulfilled with an [`UpdateDeleteResult`](https://ably.com/docs/api/realtime-sdk/types#update-delete-result) object containing the new version of the message. Upon failure, the promise will be rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object which explains the error.
##### Returns
Returns an [`UpdateDeleteResult`](https://ably.com/docs/api/realtime-sdk/types#update-delete-result) object containing the new version of the message.
#### getMessageVersions
`getMessageVersions(serialOrMessage: string | Message, params?: Record): Promise>`
`PaginatedResult getMessageVersions(String serial, Param[] params)`
`PaginatedResult get_message_versions(serial_or_message, **params)`
Retrieves all historical versions of a specific message, ordered by version. This includes the original message and all subsequent updates or delete operations. Requires the **history** [capability](https://ably.com/docs/auth/capabilities).
See [updating and deleting messages: versions](https://ably.com/docs/messages/updates-deletes#versions) for more information.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| serialOrMessage | Either the serial identifier string of the message whose versions are to be retrieved, or a [`Message`](https://ably.com/docs/api/realtime-sdk/messages) object containing a populated `serial` field | `string` or [`Message`](https://ably.com/docs/api/realtime-sdk/messages) |
| params | Optional parameters sent as part of the query string | `Record` (optional) |
##### Returns
Returns a promise which, upon success, will be fulfilled with a [`PaginatedResult`](#paginated-result) object containing an array of [`Message`](https://ably.com/docs/api/realtime-sdk/messages) objects representing all versions of the message. Upon failure, the promise will be rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object which explains the error.
##### Returns
On success, the returned [`PaginatedResult`](#paginated-result) encapsulates an array of [`Message`](#message) objects corresponding to the current page of results. [`PaginatedResult`](#paginated-result) supports pagination using [`next`](#paginated-result) and [`first`](#paginated-result) methods.
Failure to retrieve the message versions will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception)
## Related types
### MessageARTMessageAbly::Models::MessageAbly\Models\Messageio.ably.lib.types.MessageIO.Ably.Message
A `Message` represents an individual message that is sent to or received from Ably.
#### nameName
The event name, if provided.
_Type: `String`_
#### dataData
The message payload, if provided.
_Type: `String`, `StringBuffer`, `JSON Object``String`, `ByteArray`, `JSONObject`, `JSONArray``String`, `byte[]`, `plain C# object that can be serialized to JSON``String`, `Binary` (ASCII-8BIT String), `Hash`, `Array``String`, `Bytearray`, `Dict`, `List``String`, `Binary String`, `Associative Array`, `Array``NSString *`, `NSData *`, `NSDictionary *`, `NSArray *``String`, `NSData`, `Dictionary`, `Array``String`, `Map`, `List`_
#### extrasExtras
Metadata and/or ancillary payloads, if provided. Valid payloads include [`push`](https://ably.com/docs/push/publish#payload), [`headers`](https://ably.com/docs/pub-sub/advanced#headers) (a map of strings to strings for arbitrary customer-supplied metadata), [`ephemeral`](https://ably.com/docs/pub-sub/advanced#ephemeral), and [`privileged`](https://ably.com/docs/platform/integrations/webhooks#skipping) objects.
_Type: `JSONObject`, `JSONArray`plain C# object that can be converted to JSON`JSON Object``Hash`, `Array``Dict`, `List``Dictionary`, `Array``NSDictionary *`, `NSArray *``Associative Array`, `Array`_
#### idId
A Unique ID assigned by Ably to this message.
_Type: `String`_
#### clientIdClientIdclient_id
The client ID of the publisher of this message.
_Type: `String`_
#### connectionIdConnectionIdconnection_id
The connection ID of the publisher of this message.
_Type: `String`_
#### connectionKeyConnectionKeyconnection_key
A connection key, which can optionally be included for a REST publish as part of the [publishing on behalf of a realtime client functionality](https://ably.com/docs/pub-sub/advanced#publish-on-behalf).
_Type: `String`_
#### timestampTimestamp
Timestamp when the message was first received by the Ably, as milliseconds since the epocha `Time` object.
_Type: `Integer``Long Integer``DateTimeOffset``Time``NSDate`_
#### encodingEncoding
This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the `data` payload.
_Type: `String`_
### action
The action type of the message, one of the [`MessageAction`](https://ably.com/docs/api/realtime-sdk/types#message-action) enum values.
_Type: `enum { MESSAGE_CREATE, MESSAGE_UPDATE, MESSAGE_DELETE, MESSAGE_APPEND, META, MESSAGE_SUMMARY }`_
### serial
A server-assigned identifier that will be the same in all future updates of this message. It can be used to add [annotations](https://ably.com/docs/messages/annotations) to a message or to [update or delete](https://ably.com/docs/messages/updates-deletes) it. Serial will only be set if you enable annotations, updates, deletes, and appends in [channel rules](https://ably.com/docs/channels#rules).
_Type: `String`_
### annotations
An object containing information about annotations that have been made to the object.
_Type: [`MessageAnnotations`](https://ably.com/docs/api/realtime-sdk/types#message-annotations)_
### version
An object containing version metadata for messages that have been updated or deleted. See [updating and deleting messages](https://ably.com/docs/messages/updates-deletes) for more information.
_Type: [`MessageVersion`](#message-version)_
### Message constructors
#### Message.fromEncoded
`Message.fromEncoded(Object encodedMsg, ChannelOptions channelOptions?) -> Message`
A static factory method to create a [`Message`](https://ably.com/docs/api/realtime-sdk/types#message) from a deserialized `Message`-like object encoded using Ably's wire protocol.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| encodedMsg | A `Message`-like deserialized object | `Object` |
| channelOptions | An optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data | `Object` |
##### Returns
A [`Message`](https://ably.com/docs/api/realtime-sdk/types#message) object
#### Message.fromEncodedArray
`Message.fromEncodedArray(Object[] encodedMsgs, ChannelOptions channelOptions?) -> Message[]`
A static factory method to create an array of [`Messages`](https://ably.com/docs/api/realtime-sdk/types#message) from an array of deserialized `Message`-like object encoded using Ably's wire protocol.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| encodedMsgs | An array of `Message`-like deserialized objects | `Array` |
| channelOptions | An optional [`ChannelOptions`](https://ably.com/docs/api/realtime-sdk/types#channel-options). If you have an encrypted channel, use this to allow the library to decrypt the data | `Object` |
##### Returns
An `Array` of [`Message`](https://ably.com/docs/api/realtime-sdk/types#message) objects
### ChannelOptions ObjectARTChannelOptionsChannelOptions HashChannelOptions keyword argumentsChannelOptions Arrayio.ably.lib.types.ChannelOptionsIO.Ably.ChannelOptions
Channel options are used for setting [channel parameters](https://ably.com/docs/channels/options) and [configuring encryption](https://ably.com/docs/channels/options/encryption).
`ChannelOptions`, a plain JavaScript object, may optionally be specified when instancing a [`Channel`](https://ably.com/docs/channels), and this may be used to specify channel-specific options. The following attributes can be defined on the object:
`ChannelOptions`, a Hash object, may optionally be specified when instancing a [`Channel`](https://ably.com/docs/channels), and this may be used to specify channel-specific options. The following key symbol values can be added to the Hash:
`ChannelOptions`, an Associative Array, may optionally be specified when instancing a [`Channel`](https://ably.com/docs/channels), and this may be used to specify channel-specific options. The following named keys and values can be added to the Associated Array:
`ART``io.ably.lib.types.``ChannelOptions` may optionally be specified when instancing a [`Channel`](https://ably.com/docs/channels), and this may be used to specify channel-specific options.
`IO.Ably.ChannelOptions` may optionally be specified when instancing a [`Channel`](https://ably.com/docs/channels), and this may be used to specify channel-specific options.
#### PropertiesMembersAttributes
| Parameter | Description | Type |
|-----------|-------------|------|
| :cipherCipherParamscipher | Requests encryption for this channel when not null, and specifies encryption-related parameters (such as algorithm, chaining mode, key length and key). See [an example](https://ably.com/docs/channels/options/encryption) | [`CipherParams`](https://ably.com/docs/api/realtime-sdk/encryption#cipher-params) or an options object containing at a minimum a `key` or a `Param[]` list containing at a minimum a `key` or an options hash containing at a minimum a `key` or an Associative Array containing at a minimum a `key` |
| Parameter | Description | Type |
|-----------|-------------|------|
| paramsParams | Optional [parameters](https://ably.com/docs/channels/options) which specify behaviour of the channel | `Map``JSON Object` |
| cipherCipherParams | Requests encryption for this channel when not null, and specifies encryption-related parameters (such as algorithm, chaining mode, key length and key). See [an example](https://ably.com/docs/api/realtime-sdk/encryption#getting-started) | [`CipherParams`](https://ably.com/docs/api/realtime-sdk/encryption#cipher-params) or an options object containing at a minimum a `key` or a `Param[]` list containing at a minimum a `key` or an options hash containing at a minimum a `key` or an Associative Array containing at a minimum a `key` |
### Static methods
#### withCipherKey
`static ChannelOptions.withCipherKey(Byte[] or String key)`
A helper method to generate a `ChannelOptions` for the simple case where you only specify a key.
##### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| key | A binary `Byte[]` array or a base64-encoded `String` | `Byte[]` or `String` |
##### Returns
On success, the method returns a complete `ChannelOptions` object. Failure will raise an [`AblyException`](https://ably.com/docs/api/realtime-sdk/types#ably-exception).
### PublishOptions
Options passed to a [`publish()`](#publish) operation to customize its behavior.
#### Parameters
| Parameter | Description | Type |
|-----------|-------------|------|
| quickAck | Reduces the latency of REST publishes, though provides a [slightly lower quality of service](https://faqs.ably.com/why-are-some-rest-publishes-on-a-channel-slow-and-then-typically-faster-on-subsequent-publishes) | `Boolean` |
### PaginatedRequestParams
`PaginatedRequestParams` is a type that encapsulates the parameters for a history queries. For example usage see [`Channel#History`](https://ably.com/docs/api/realtime-sdk/history#channel-history).
#### Members
| Parameter | Description | Type |
|-----------|-------------|------|
| Start | The start of the queried interval. _default: null_ | `DateTimeOffset` |
| End | The end of the queried interval. _default: null_ | `DateTimeOffset` |
| Limit | Limits the number of items returned by history or stats. _default: null_ | `Integer` |
| Direction | Enum which is either `Forwards` or `Backwards`. _default: Backwards_ | `Direction` enum |
| ExtraParameters | Optionally any extra query parameters that may be passed to the query. This is mainly used internally by the library to manage paging. | `Dictionary` |
### PaginatedResultARTPaginatedResultAbly::Models::PaginatedResultAbly\Models\PaginatedResultio.ably.lib.types.PaginatedResultIO.Ably.PaginatedResult
A `PaginatedResult` is a type that represents a page of results for all message and presence history, stats and REST presence requests. The response from a [Ably REST API paginated query](https://ably.com/docs/api/rest-api/#pagination) is accompanied by metadata that indicates the relative queries available to the `PaginatedResult` object.
#### PropertiesMembersAttributes
| Property | Description | Type |
|----------|-------------|------|
| itemsItems | contains the current page of results (for example an Array of [`Message`](#message) or [`PresenceMessage`](#presence-message) objects for a channel history request) | `Array ``List ` |
#### Methods
##### firstFirst
`first(): Promise`
`PaginatedResult first`
`PaginatedResult first()`
`PaginatedResult first()`
`Task> FirstAsync()`
`PaginatedResult first()`
`first(callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
`First() (PaginatedResult, error)`
Returns a new `PaginatedResult` for the first page of results. When using the Realtime library, the `first` method returns a [Deferrable](https://ably.com/docs/api/realtime-sdk/types#deferrable) and yields a [`PaginatedResult`](#paginated-result).The method is asynchronous and returns a Task which needs to be awaited to get the [`PaginatedResult`](#paginated-result).
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` for the first page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
##### hasNextHasNexthas_next?has_next
`Boolean hasNext()`
`Boolean has_next?`
`Boolean HasNext()`
`HasNext() (bool)`
Returns `true` if there are more pages available by calling `next``Next` and returns `false` if this page is the last page available.
##### isLastIsLastlast?is_last
`Boolean isLast()`
`Boolean last?`
`Boolean IsLast()`
`IsLast() (bool)`
Returns `true` if this page is the last page and returns `false` if there are more pages available by calling `next``Next` available.
##### nextNext
`next(): Promise`
`PaginatedResult next`
`PaginatedResult next()`
`PaginatedResult next()`
`Task> NextAsync()`
`PaginatedResult next()`
`next(callback: (ARTPaginatedResult?, ARTErrorInfo?) -> Void)`
`Next() (PaginatedResult, error)`
Returns a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `null`a blank PaginatedResult will be returned`Null``None``nil` is returned. The method is asynchronous and return a Task which needs to be awaited to get the `PaginatedResult`When using the Realtime library, the `first` method returns a [Deferrable](https://ably.com/docs/api/realtime-sdk/types#deferrable) and yields a [`PaginatedResult`](#paginated-result).
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` loaded with the next page of results. If there are no further pages, then `null` is returned. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
##### current
`current(): Promise`
Returns a promise. On success, the promise is fulfilled with a new `PaginatedResult` loaded with the current page of results. On failure, the promise is rejected with an [`ErrorInfo`](https://ably.com/docs/api/realtime-sdk/types#error-info) object that details the reason why it was rejected.
##### Example
```javascript
const paginatedResult = await channel.history();
console.log('Page 0 item 0:' + paginatedResult.items[0].data);
const nextPage = await paginatedResult.next();
console.log('Page 1 item 1: ' + nextPage.items[1].data);
console.log('Last page?: ' + nextPage.isLast());
```
```nodejs
const paginatedResult = await channel.history();
console.log('Page 0 item 0:' + paginatedResult.items[0].data);
const nextPage = await paginatedResult.next();
console.log('Page 1 item 1: ' + nextPage.items[1].data);
console.log('Last page?: ' + nextPage.isLast());
```
```java
PaginatedResult firstPage = channel.history();
System.out.println("Page 0 item 0:" + firstPage.items[0].data);
if (firstPage.hasNext) {
PaginatedResult nextPage = firstPage.next();
System.out.println("Page 1 item 1:" + nextPage.items[1].data);
System.out.println("More pages?:" + Strong.valueOf(nextPage.hasNext()));
};
```
```csharp
PaginatedResult firstPage = await channel.HistoryAsync(null);
Message firstMessage = firstPage.Items[0];
Console.WriteLine("Page 0 item 0: " + firstMessage.data);
if (firstPage.HasNext)
{
var nextPage = await firstPage.NextAsync();
Console.WriteLine("Page 1 item 1:" + nextPage.Items[1].data);
Console.WriteLine("More pages?: " + nextPage.HasNext());
}
```
```ruby
# When using the REST sync library
first_page = channel.history
puts "Page 0 item 0: #{first_page.items[0].data}"
if first_page.has_next?
next_page = first_page.next
puts "Page 1 item 1: #{next_page.items[1].data}"
puts "Last page?: #{next_page.is_last?}"
end
# When using the Realtime EventMachine library
channel.history do |first_page|
puts "Page 0 item 0: #{first_page.items[0].data}"
if first_page.has_next?
first_page.next do |next_page|
puts "Page 1 item 1: #{next_page.items[1].data}"
puts "Last page?: #{next_page.is_last?}"
end
end
end
```
```python
result_page = channel.history()
print 'Page 0 item 0: ' + str(result_page.items[0].data)
if result_page.has_next():
next_page = result_page.next()
print 'Page 1 item 1: ' + str(next_page.items[1].data)
print 'Last page?: ' + str(next_page.is_last())
```
```php
$firstPage = $channel.history();
echo("Page 0 item 0: " . $firstPage->items[0]->data);
if ($firstPage->hasNext()) {
$nextPage = $firstPage->next();
echo("Page 1 item 1: " . $nextPage->items[1]->data);
echo("Last page?: " . $nextPage->isLast());
}
```
```objc
[channel history:^(ARTPaginatedResult *paginatedResult, ARTErrorInfo *error) {
NSLog(@"Page 0 item 0: %@", paginatedResult.items[0].data);
[paginatedResult next:^(ARTPaginatedResult *nextPage, ARTErrorInfo *error) {
NSLog(@"Page 1 item 1: %@", nextPage.items[1].data);
NSLog(@"Last page?: %d", nextPage.isLast());
}];
}];
```
```swift
channel.history { paginatedResult, error in
guard let paginatedResult = paginatedResult else {
print("No results available")
return
}
print("Page 0 item 0: \((paginatedResult.items[0] as! ARTMessage).data)")
paginatedResult.next { nextPage, error in
guard let nextPage = nextPage else {
print("No next page available")
return
}
print("Page 1 item 1: \((nextPage.items[1] as! ARTMessage).data)")
print("Last page? \(nextPage.isLast())")
}
}
```
```go
page0, err := channel.History(nil)
fmt.Println("Page. 0 item 0: %s\n", page0.Messages[0].Data)
page1, err := page0.Next()
fmt.Println("Page. 1 item 1: %s\n", page1.Messages[1].Data)
fmt.Println("Last page? %s\n", page1.IsLast())
```
### io.ably.lib.types.Param
`Param` is a type encapsulating a key/value pair. This type is used frequently in method parameters allowing key/value pairs to be used more flexible, see [`Channel#history`](https://ably.com/docs/api/realtime-sdk/history#channel-history) for an example.
Please note that `key` and `value` attributes are always strings. If an `Integer` or other value type is expected, then you must coerce that type into a `String`.
#### Members
| Parameter | Description | Type |
|-----------|-------------|------|
| key | The key value | `String` |
| value | The value associated with the `key` | `String` |