Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ $ ably-interactive
* [`ably bench publisher CHANNEL`](#ably-bench-publisher-channel)
* [`ably bench subscriber CHANNEL`](#ably-bench-subscriber-channel)
* [`ably channels`](#ably-channels)
* [`ably channels annotations`](#ably-channels-annotations)
* [`ably channels annotations delete CHANNEL SERIAL TYPE`](#ably-channels-annotations-delete-channel-serial-type)
* [`ably channels annotations get CHANNEL SERIAL`](#ably-channels-annotations-get-channel-serial)
* [`ably channels annotations publish CHANNEL SERIAL TYPE`](#ably-channels-annotations-publish-channel-serial-type)
* [`ably channels annotations subscribe CHANNEL`](#ably-channels-annotations-subscribe-channel)
* [`ably channels append CHANNEL SERIAL MESSAGE`](#ably-channels-append-channel-serial-message)
* [`ably channels batch-publish [MESSAGE]`](#ably-channels-batch-publish-message)
* [`ably channels delete CHANNEL SERIAL`](#ably-channels-delete-channel-serial)
Expand Down Expand Up @@ -1373,6 +1378,7 @@ EXAMPLES
$ ably channels list

COMMANDS
ably channels annotations Manage annotations on Ably Pub/Sub channel messages
ably channels append Append data to a message on an Ably channel
ably channels batch-publish Publish messages to multiple Ably channels with a single request
ably channels delete Delete a message on an Ably channel
Expand All @@ -1388,6 +1394,179 @@ COMMANDS

_See code: [src/commands/channels/index.ts](https://github.com/ably/ably-cli/blob/v0.17.0/src/commands/channels/index.ts)_

## `ably channels annotations`

Manage annotations on Ably Pub/Sub channel messages

```
USAGE
$ ably channels annotations

DESCRIPTION
Manage annotations on Ably Pub/Sub channel messages

EXAMPLES
$ ably channels annotations publish my-channel "01234567890:0" "reactions:flag.v1" --name thumbsup

$ ably channels annotations subscribe my-channel

$ ably channels annotations get my-channel "01234567890:0"
```

_See code: [src/commands/channels/annotations/index.ts](https://github.com/ably/ably-cli/blob/v0.17.0/src/commands/channels/annotations/index.ts)_

## `ably channels annotations delete CHANNEL SERIAL TYPE`

Delete an annotation from a channel message

```
USAGE
$ ably channels annotations delete CHANNEL SERIAL TYPE [-v] [--json | --pretty-json] [--client-id <value>] [--count <value>]
[-n <value>]

ARGUMENTS
CHANNEL The channel name
SERIAL The serial of the message to remove annotation from
TYPE The annotation type (e.g., reactions:flag.v1, reactions:multiple.v1)

FLAGS
-n, --name=<value> The annotation name (e.g., emoji name for reactions)
-v, --verbose Output verbose logs
--client-id=<value> Overrides any default client ID when using API authentication. Use "none" to explicitly set
no client ID. Not applicable when using token authentication.
--count=<value> The annotation count (for multiple.v1 types)
--json Output in JSON format
--pretty-json Output in colorized JSON format

DESCRIPTION
Delete an annotation from a channel message

EXAMPLES
$ ably channels annotations delete my-channel "01234567890:0" "reactions:flag.v1" --name thumbsup

$ ably channels annotations delete my-channel "01234567890:0" "reactions:multiple.v1" --name thumbsup --count 2

$ ably channels annotations delete my-channel "01234567890:0" "reactions:flag.v1" --json

$ ably channels annotations delete my-channel "01234567890:0" "reactions:flag.v1" --pretty-json
```

_See code: [src/commands/channels/annotations/delete.ts](https://github.com/ably/ably-cli/blob/v0.17.0/src/commands/channels/annotations/delete.ts)_

## `ably channels annotations get CHANNEL SERIAL`

Get annotations for a channel message

```
USAGE
$ ably channels annotations get CHANNEL SERIAL [-v] [--json | --pretty-json] [--limit <value>]

ARGUMENTS
CHANNEL The channel name
SERIAL The serial of the message to get annotations for

FLAGS
-v, --verbose Output verbose logs
--json Output in JSON format
--limit=<value> [default: 50] Maximum number of results to return (default: 50)
--pretty-json Output in colorized JSON format

DESCRIPTION
Get annotations for a channel message

EXAMPLES
$ ably channels annotations get my-channel "01234567890:0"

$ ably channels annotations get my-channel "01234567890:0" --limit 100

$ ably channels annotations get my-channel "01234567890:0" --json

$ ably channels annotations get my-channel "01234567890:0" --pretty-json
```

_See code: [src/commands/channels/annotations/get.ts](https://github.com/ably/ably-cli/blob/v0.17.0/src/commands/channels/annotations/get.ts)_

## `ably channels annotations publish CHANNEL SERIAL TYPE`

Publish an annotation on a channel message

```
USAGE
$ ably channels annotations publish CHANNEL SERIAL TYPE [-v] [--json | --pretty-json] [--client-id <value>] [--count <value>]
[--data <value>] [-e <value>] [-n <value>]

ARGUMENTS
CHANNEL The channel name
SERIAL The serial of the message to annotate
TYPE The annotation type (e.g., reactions:flag.v1, reactions:multiple.v1)

FLAGS
-e, --encoding=<value> The encoding for the annotation data
-n, --name=<value> The annotation name (e.g., emoji name for reactions)
-v, --verbose Output verbose logs
--client-id=<value> Overrides any default client ID when using API authentication. Use "none" to explicitly set
no client ID. Not applicable when using token authentication.
--count=<value> The annotation count (for multiple.v1 types)
--data=<value> Arbitrary annotation payload (JSON string or plain text)
--json Output in JSON format
--pretty-json Output in colorized JSON format

DESCRIPTION
Publish an annotation on a channel message

EXAMPLES
$ ably channels annotations publish my-channel "01234567890:0" "reactions:flag.v1" --name thumbsup

$ ably channels annotations publish my-channel "01234567890:0" "reactions:multiple.v1" --name thumbsup --count 3

$ ably channels annotations publish my-channel "01234567890:0" "reactions:flag.v1" --data '{"key":"value"}'

$ ably channels annotations publish my-channel "01234567890:0" "reactions:flag.v1" --json

$ ably channels annotations publish my-channel "01234567890:0" "reactions:flag.v1" --pretty-json
```

_See code: [src/commands/channels/annotations/publish.ts](https://github.com/ably/ably-cli/blob/v0.17.0/src/commands/channels/annotations/publish.ts)_

## `ably channels annotations subscribe CHANNEL`

Subscribe to annotations on an Ably channel

```
USAGE
$ ably channels annotations subscribe CHANNEL [-v] [--json | --pretty-json] [--client-id <value>] [-D <value>] [--rewind <value>]
[--type <value>]

ARGUMENTS
CHANNEL The channel name to subscribe to annotations on

FLAGS
-D, --duration=<value> Automatically exit after N seconds
-v, --verbose Output verbose logs
--client-id=<value> Overrides any default client ID when using API authentication. Use "none" to explicitly set
no client ID. Not applicable when using token authentication.
--json Output in JSON format
--pretty-json Output in colorized JSON format
--rewind=<value> Number of messages to rewind when subscribing (default: 0)
--type=<value> Filter annotations by type

DESCRIPTION
Subscribe to annotations on an Ably channel

EXAMPLES
$ ably channels annotations subscribe my-channel

$ ably channels annotations subscribe my-channel --type "reactions:flag.v1"

$ ably channels annotations subscribe my-channel --json

$ ably channels annotations subscribe my-channel --pretty-json

$ ably channels annotations subscribe my-channel --duration 30
```

_See code: [src/commands/channels/annotations/subscribe.ts](https://github.com/ably/ably-cli/blob/v0.17.0/src/commands/channels/annotations/subscribe.ts)_

## `ably channels append CHANNEL SERIAL MESSAGE`

Append data to a message on an Ably channel
Expand Down
2 changes: 1 addition & 1 deletion docs/Project-Structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ This document outlines the directory structure of the Ably CLI project.
│ │ ├── auth/ # Authentication (keys, tokens)
│ │ ├── bench/ # Benchmarking (publisher, subscriber)
│ │ ├── channel-rule/ # Hidden alias → apps/rules/
│ │ ├── channels/ # Pub/Sub channels (publish, subscribe, presence, history, etc.)
│ │ ├── channels/ # Pub/Sub channels (publish, subscribe, presence, history, annotations, etc.)
│ │ ├── config/ # CLI config management (show, path)
│ │ ├── connections/ # Client connections (test)
│ │ ├── integrations/ # Integration rules
Expand Down
127 changes: 127 additions & 0 deletions src/commands/channels/annotations/delete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { Args, Flags } from "@oclif/core";
import * as Ably from "ably";

import { AblyBaseCommand } from "../../../base-command.js";
import { clientIdFlag, productApiFlags } from "../../../flags.js";
import {
extractSummarizationType,
validateAnnotationParams,
} from "../../../utils/annotations.js";
import {
formatProgress,
formatResource,
formatSuccess,
} from "../../../utils/output.js";

export default class ChannelsAnnotationsDelete extends AblyBaseCommand {
static override args = {
channel: Args.string({
description: "The channel name",
required: true,
}),
serial: Args.string({
description: "The serial of the message to remove annotation from",
required: true,
}),
type: Args.string({
description:
"The annotation type (e.g., reactions:flag.v1, reactions:multiple.v1)",
required: true,
}),
};

static override description = "Delete an annotation from a channel message";

static override examples = [
'$ ably channels annotations delete my-channel "01234567890:0" "reactions:flag.v1" --name thumbsup',
'$ ably channels annotations delete my-channel "01234567890:0" "reactions:multiple.v1" --name thumbsup',
'$ ably channels annotations delete my-channel "01234567890:0" "reactions:flag.v1" --json',
'$ ably channels annotations delete my-channel "01234567890:0" "reactions:flag.v1" --pretty-json',
];

static override flags = {
...productApiFlags,
...clientIdFlag,
name: Flags.string({
char: "n",
description: "The annotation name (e.g., emoji name for reactions)",
}),
};

async run(): Promise<void> {
const { args, flags } = await this.parse(ChannelsAnnotationsDelete);
const channelName = args.channel;
const serial = args.serial;
const type = args.type;

let client: Ably.Realtime | null = null;

try {
const summarization = extractSummarizationType(type);
const validationErrors = validateAnnotationParams(summarization, {
name: flags.name,
});
if (validationErrors.length > 0) {
this.fail(validationErrors.join("\n"), flags, "annotationDelete");
}

// Uses Realtime client because RestAnnotations.delete is not exposed in SDK types
client = await this.createAblyRealtimeClient(flags);
if (!client) return;

const channel = client.channels.get(channelName);

if (!this.shouldOutputJson(flags)) {
this.log(
formatProgress(
`Deleting annotation on message ${formatResource(serial)} in channel ${formatResource(channelName)}`,
),
);
}

const annotation: Ably.OutboundAnnotation = { type };
if (flags.name !== undefined) annotation.name = flags.name;

await channel.annotations.delete(serial, annotation);

this.logCliEvent(
flags,
"annotationDelete",
"annotationDeleted",
`Deleted annotation on message ${serial} in channel ${channelName}`,
{
channel: channelName,
serial,
type,
name: flags.name,
},
);

if (this.shouldOutputJson(flags)) {
this.logJsonResult(
{
channel: channelName,
serial,
type,
name: flags.name,
},
flags,
);
} else {
this.log(
formatSuccess(
`Annotation deleted on message ${formatResource(serial)} in channel ${formatResource(channelName)}.`,
),
);
}
} catch (error) {
this.fail(error, flags, "annotationDelete", {
channel: channelName,
serial,
type,
});
} finally {
client?.close();
}
}
}
Loading
Loading