Skip to content

Add channel flag to push publish#184

Open
maratal wants to merge 6 commits intomainfrom
feature/push-publish-channel-name
Open

Add channel flag to push publish#184
maratal wants to merge 6 commits intomainfrom
feature/push-publish-channel-name

Conversation

@maratal
Copy link
Contributor

@maratal maratal commented Mar 23, 2026

Summary

  • Adds --channel flag to push publish command
  • When used without a direct recipient, publishes the push notification to the channel with the payload wrapped in extras.push, routing it to push-subscribed devices via the channel
  • If a direct recipient (--device-id, --client-id, --recipient) is also provided, --channel is silently ignored with a warning (emitted in both human-readable and JSON modes)

Summary by CodeRabbit

Release Notes

  • New Features

    • Added --channel flag to ably push publish for publishing push notifications to channels. When both recipient flags (e.g., --device-id) and --channel are provided, the channel flag is ignored with a warning.
  • Documentation

    • Updated ably push publish command documentation to expand targeting scope from "device or client" to "device, client, or channel".
    • Added example demonstrating ably channels presence update with --pretty-json formatting.

When --channel-name is provided without a direct recipient, the push
notification is published to the channel with the payload wrapped in
extras.push, routing it to push-subscribed devices via the channel.
If a direct recipient (--device-id, --client-id, --recipient) is also
present, --channel-name is ignored with a warning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@cursor
Copy link

cursor bot commented Mar 23, 2026

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@vercel
Copy link

vercel bot commented Mar 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cli-web-cli Ready Ready Preview, Comment Mar 26, 2026 4:32pm

Request Review

@coderabbitai
Copy link

coderabbitai bot commented Mar 23, 2026

Walkthrough

The changes add support for publishing push notifications via a channel in addition to device/client recipients. A new --channel-name flag was introduced, target validation logic was refactored to accept either direct recipients or a channel name, and publishing now routes to either the push admin API or the channel's publish method accordingly.

Changes

Cohort / File(s) Summary
Feature Implementation
src/commands/push/publish.ts
Added --channel-name flag with validation logic requiring either a direct recipient or channel name. Publishing routes to rest.push.admin.publish() for recipients or rest.channels.get().publish() with extras.push wrapper for channels. Includes new output helpers for formatting and warning messages.
Tests & Documentation
test/unit/commands/push/publish.test.ts, README.md
Expanded test coverage for --channel-name flag, channel publishing flow, recipient precedence, and error handling. Updated README documentation describing the new flag, channel-based publishing capability, and updated command examples.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI as CLI Command
    participant Validation
    participant Publisher
    participant PushAdmin as Push Admin API
    participant Channels as Channels API
    participant Output

    User->>CLI: ably push publish --channel-name=my-channel

    CLI->>Validation: Validate flags<br/>(has channel-name OR recipient?)
    Validation-->>CLI: ✓ Valid

    CLI->>Publisher: Route to publisher<br/>(hasDirectRecipient?)
    
    alt Channel-based Publishing
        Publisher->>Channels: Get channel instance
        Channels->>Channels: publish({<br/>extras: { push: payload }<br/>})
        Channels-->>Publisher: ✓ Published
        Publisher->>Output: Format response<br/>({ published: true, channel })
    else Recipient-based Publishing (if recipient provided)
        Publisher->>PushAdmin: publish(recipient, payload)
        PushAdmin-->>Publisher: ✓ Published
        Publisher->>Output: Format response<br/>(success message)
    end
    
    Output-->>User: Display result
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hoppy news! A channel path,
where push notifications can now bathe,
no longer just device and client calls,
the rabbit's CLI now conquers all channels!
With --channel-name set so bright,
notifications flow through extras.push tonight! 📢✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title directly reflects the main change: adding a --channel-name flag to the push publish command. It is concise, clear, and accurately summarizes the primary modification.
Description check ✅ Passed The pull request description clearly explains the new --channel-name flag functionality, its behavior with and without direct recipients, and includes release notes documenting the changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@maratal maratal changed the title feat(push): add --channel-name flag to push publish Add channel-name flag to push publish Mar 23, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/commands/push/publish.ts`:
- Line 236: The chained call rest.channels.get(channelName).publish({ extras: {
push: payload } }) is too long for Prettier; split the expression across
multiple lines to satisfy line-length rules. Specifically, break after getting
the channel (rest.channels.get(channelName)) and place the .publish( call on the
next line, with the object literal formatted over multiple lines (e.g., open
.publish( on its own line, then place extras and push on separate indented
lines) and close the call on a new line. Keep the same identifiers (rest,
channels, get, channelName, publish, payload) and behavior unchanged.
- Around line 99-105: The warning emitted when hasDirectRecipient and
flags["channel-name"] is true uses this.log(formatWarning(...)) and will corrupt
--json output; wrap that this.log call in a guard that checks
this.shouldOutputJson(flags) (i.e., only call this.log when
!this.shouldOutputJson(flags)) so the formatWarning message is emitted only for
human-readable runs; update the block around the this.log/formatWarning
invocation in publish (where hasDirectRecipient and flags["channel-name"] are
checked) to use the conditional before logging.

In `@test/unit/commands/push/publish.test.ts`:
- Around line 148-157: The test currently JSON.parses stdout directly which can
fail due to Prettier/whitespace formatting; update the test to trim the CLI
output before parsing by calling JSON.parse(stdout.trim()) so it tolerates
trailing newlines/formatting. Locate the test using runCommand in
publish.test.ts (the it block "should output JSON with channel when publishing
via channel") and change JSON.parse(stdout) to JSON.parse(stdout.trim()) to make
the assertion robust.
- Around line 173-183: Formatting in the "should handle channel publish errors"
test is inconsistent with project Prettier rules; reformat the test in
test/unit/commands/push/publish.test.ts (the it(...) block) so it matches the
code style: proper indentation, spacing around arrow functions, consistent
semicolons, and no stray blank/merged lines — specifically fix the block that
uses getMockAblyRest(),
mock.channels._getChannel("err-channel").publish.mockRejectedValue(new
Error("Channel error")), and the await runCommand([...], import.meta.url) call
so Prettier passes; you can run Prettier or your project's formatter to apply
the exact corrections.
- Around line 105-134: The tests "should publish via channel wrapping payload in
extras.push" and "should ignore --channel-name when --device-id is also
provided" have long single-line argument arrays and matcher chains that fail
Prettier; reformat the runCommand calls and expect(...) assertions into
multiline style so each argument or chained matcher is on its own line (e.g.,
break the runCommand argument array across multiple lines and break the
expect.objectContaining/expect.anything matcher chains into multiple indented
lines), keeping the same values and assertions for getMockAblyRest(),
runCommand(...), channel.publish expectations, and mock.push.admin.publish
checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e84d3f9a-95cf-4a66-bd46-ad5042445fcd

📥 Commits

Reviewing files that changed from the base of the PR and between c2c1d30 and b25c868.

📒 Files selected for processing (3)
  • README.md
  • src/commands/push/publish.ts
  • test/unit/commands/push/publish.test.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
description: "Raw recipient JSON for advanced targeting",
exclusive: ["device-id", "client-id"],
}),
"channel-name": Flags.string({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On other commands we use --channel so we should have the same here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — renamed to --channel.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should update PR summary about using --channel-name to --channel

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the PR description to reflect --channel throughout.

}

if (hasDirectRecipient && flags["channel-name"]) {
this.log(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per coderabbit, this would break json mode

Copy link
Contributor Author

@maratal maratal Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

…-json

- Rename flag to --channel for consistency with other commands (per Andy)
- Wrap --channel-ignored warning in !shouldOutputJson() guard to avoid
  polluting machine-readable output (per CodeRabbit/Andy)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

if (hasDirectRecipient && flags.channel && !this.shouldOutputJson(flags)) {
this.log(
formatWarning(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel this warning should also be available in JSON mode.
You can check ephemeralSpaceWarning at https://github.com/ably/ably-cli/pull/185/changes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — now emits logJsonStatus("warning", ...) when --json is active, following the same pattern as ephemeralSpaceWarning in #185.

if (!hasDirectRecipient && !flags.channel) {
this.fail(
"A recipient is required: --device-id, --client-id, or --recipient",
"A target is required: --device-id, --client-id, --recipient, or --channel-name",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"A target is required: --device-id, --client-id, --recipient, or --channel-name",
"A target is required: --device-id, --client-id, --recipient, or --channel",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks.

@maratal maratal changed the title Add channel-name flag to push publish Add channel flag to push publish Mar 26, 2026
…emit channel-ignored warning in JSON mode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@maratal
Copy link
Contributor Author

maratal commented Mar 26, 2026

Manual testing — --channel flag

The following commands were tested manually with the new --channel flag:

./bin/run.js push publish --channel exampleChannel1 --title "Hello" --body "World 001"
./bin/run.js push publish --channel exampleChannel1 --title "Hello" --body "World 002" --data '{"key":"value"}'
./bin/run.js push publish --channel exampleChannel1 --payload '{"notification":{"title":"Hello","body":"World 003"},"data":{"key":"value"}}'
./bin/run.js push publish --channel exampleChannel1 --payload ./notification.json
./bin/run.js push batch-publish --payload ./notifications.json
./bin/run.js push batch-publish --payload '[{"channel": "exampleChannel1","payload": {"notification": {"title": "Hello","body": "World 007"},"data":{"key":"value"}}}]'

All commands completed successfully. ✅

}
} else {
this.log(formatSuccess("Push notification published."));
const channelName = flags.channel!;
Copy link
Contributor

@sacOO7 sacOO7 Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw I feel, if possible we should also introduce confirmation dialogue saying

Push notification will be sent to all users subscribed to this channel or channels, do you want to publish to all users present on the channel

using promptForConfirmation in the code.

Generally devs tend to test push notifications, if there are lots of users present on the channel in prod environment, all of them will receive test notifications. So, we can make it explicit in the prompt.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, goes for batch-publish on given set of channels

Copy link
Contributor Author

@maratal maratal Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Added promptForConfirmation before the channel publish in push publish and batch-publish — it warns that the notification will go to all devices subscribed to the channel, and is skipped in --json mode or with the new --force/-f flag for scripted use.

…mpts

- batch-publish now accepts items with a "channel" field as an alternative
  to "recipient"; channel items are published via extras.push on the channel
  (the /push/batch/publish API only accepts recipient-based items)
- If both "channel" and "recipient" are present in a batch item, "channel"
  is ignored with a warning (consistent with push publish behaviour)
- Added promptForConfirmation before publishing to channels in both
  push publish and push batch-publish, as channel publishes reach all
  subscribed devices — skipped in --json mode and with new --force/-f flag
- Added --force flag to push publish and push batch-publish to skip the
  confirmation prompt in scripts/CI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants