Skip to content
380 changes: 327 additions & 53 deletions src/commands/integrations/create.ts

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion src/commands/integrations/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,16 @@ export default class IntegrationsDeleteCommand extends ControlBaseCommand {
this.log(`\nYou are about to delete the following integration:`);
this.log(`${formatLabel("Integration ID")} ${integration.id}`);
this.log(`${formatLabel("Type")} ${integration.ruleType}`);
this.log(`${formatLabel("Request Mode")} ${integration.requestMode}`);
if (integration.requestMode) {
this.log(`${formatLabel("Request Mode")} ${integration.requestMode}`);
}

if (integration.invocationMode) {
this.log(
`${formatLabel("Invocation Mode")} ${integration.invocationMode}`,
);
}

this.log(`${formatLabel("Source Type")} ${integration.source.type}`);
if (integration.source.channelFilter) {
this.log(
Expand Down
12 changes: 11 additions & 1 deletion src/commands/integrations/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,22 @@ export default class IntegrationsGetCommand extends ControlBaseCommand {
this.log(`${formatLabel("ID")} ${rule.id}`);
this.log(`${formatLabel("App ID")} ${rule.appId}`);
this.log(`${formatLabel("Rule Type")} ${rule.ruleType}`);
this.log(`${formatLabel("Request Mode")} ${rule.requestMode}`);
if (rule.requestMode) {
this.log(`${formatLabel("Request Mode")} ${rule.requestMode}`);
}

if (rule.invocationMode) {
this.log(`${formatLabel("Invocation Mode")} ${rule.invocationMode}`);
}

if (rule.source.channelFilter) {
this.log(
`${formatLabel("Source Channel Filter")} ${rule.source.channelFilter}`,
);
}
if (rule.chatRoomFilter) {
this.log(`${formatLabel("Chat Room Filter")} ${rule.chatRoomFilter}`);
}
this.log(`${formatLabel("Source Type")} ${rule.source.type}`);
this.log(
`${formatLabel("Target")} ${this.formatJsonOutput(structuredClone(rule.target) as Record<string, unknown>, flags).replaceAll("\n", "\n ")}`,
Expand Down
16 changes: 14 additions & 2 deletions src/commands/integrations/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ export default class IntegrationsListCommand extends ControlBaseCommand {
hasMore,
integrations: integrations.map((integration) => ({
appId: integration.appId,
chatRoomFilter: integration.chatRoomFilter || null,
created: new Date(integration.created).toISOString(),
id: integration.id,
invocationMode: integration.invocationMode || null,
modified: new Date(integration.modified).toISOString(),
requestMode: integration.requestMode,
requestMode: integration.requestMode || null,
source: {
channelFilter: integration.source.channelFilter || null,
type: integration.source.type,
Expand All @@ -75,11 +77,21 @@ export default class IntegrationsListCommand extends ControlBaseCommand {
this.log(formatHeading(`Integration ID: ${integration.id}`));
this.log(` App ID: ${integration.appId}`);
this.log(` Type: ${integration.ruleType}`);
this.log(` Request Mode: ${integration.requestMode}`);
if (integration.requestMode) {
this.log(` Request Mode: ${integration.requestMode}`);
}

if (integration.invocationMode) {
this.log(` Invocation Mode: ${integration.invocationMode}`);
}

this.log(` Source Type: ${integration.source.type}`);
if (integration.source.channelFilter) {
this.log(` Channel Filter: ${integration.source.channelFilter}`);
}
if (integration.chatRoomFilter) {
this.log(` Chat Room Filter: ${integration.chatRoomFilter}`);
}
this.log(
` Target: ${JSON.stringify(integration.target, null, 2).replaceAll("\n", "\n ")}`,
);
Expand Down
24 changes: 22 additions & 2 deletions src/commands/integrations/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Args, Flags } from "@oclif/core";
import { ControlBaseCommand } from "../../control-base-command.js";
// Interface for rule update data structure (most fields optional)
interface PartialRuleData {
chatRoomFilter?: string;
requestMode?: string;
ruleType?: string; // Usually shouldn't be updated, but kept for structure
source?: {
Expand All @@ -24,7 +25,8 @@ export default class IntegrationsUpdateCommand extends ControlBaseCommand {

static examples = [
"$ ably integrations update rule123 --status disabled",
'$ ably integrations update rule123 --channel-filter "chat:*"',
'$ ably integrations update rule123 --channel-filter "chat:.*"',
'$ ably integrations update rule123 --chat-room-filter "room:.*"',
'$ ably integrations update rule123 --target-url "https://new-example.com/webhook"',
"$ ably integrations update rule123 --status disabled --json",
];
Expand All @@ -39,6 +41,10 @@ export default class IntegrationsUpdateCommand extends ControlBaseCommand {
description: "Channel filter pattern",
required: false,
}),
"chat-room-filter": Flags.string({
description: "Chat room filter pattern",
required: false,
}),
status: Flags.string({
description: "Status of the rule",
options: ["enabled", "disabled"],
Expand Down Expand Up @@ -96,6 +102,10 @@ export default class IntegrationsUpdateCommand extends ControlBaseCommand {
updatePayload.source.channelFilter = flags["channel-filter"];
}

if (flags["chat-room-filter"]) {
updatePayload.chatRoomFilter = flags["chat-room-filter"];
}

// Update target if it's an HTTP rule and target-url is provided
if (existingRule.ruleType === "http" && flags["target-url"]) {
// Ensure target exists before assigning to url
Expand Down Expand Up @@ -124,12 +134,22 @@ export default class IntegrationsUpdateCommand extends ControlBaseCommand {
this.log(`ID: ${updatedRule.id}`);
this.log(`App ID: ${updatedRule.appId}`);
this.log(`Rule Type: ${updatedRule.ruleType}`);
this.log(`Request Mode: ${updatedRule.requestMode}`);
if (updatedRule.requestMode) {
this.log(`Request Mode: ${updatedRule.requestMode}`);
}

if (updatedRule.invocationMode) {
this.log(`Invocation Mode: ${updatedRule.invocationMode}`);
}

if (updatedRule.source.channelFilter) {
this.log(
`Source Channel Filter: ${updatedRule.source.channelFilter}`,
);
}
if (updatedRule.chatRoomFilter) {
this.log(`Chat Room Filter: ${updatedRule.chatRoomFilter}`);
}
this.log(`Source Type: ${updatedRule.source.type}`);
if (
typeof updatedRule.target === "object" &&
Expand Down
23 changes: 19 additions & 4 deletions src/services/control-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,30 +81,45 @@ export interface Namespace {
tlsOnly?: boolean;
}

// Retry/failure policy for rule types invoked with invocationMode
// "BEFORE_PUBLISH" (chat moderation and before-publish webhook rule types).
export interface BeforePublishConfig {
failedAction: string;
maxRetries: number;
retryTimeout: number;
tooManyRequestsAction: string;
}

export interface Rule {
_links?: {
self: string;
};
appId: string;
beforePublishConfig?: BeforePublishConfig;
created: number;
id: string;
invocationMode?: string;
modified: number;
requestMode: string;
requestMode?: string;
ruleType: string;
source: {
channelFilter: string;
channelFilter?: string;
type: string;
};
chatRoomFilter?: string;
target: unknown;
version: string;
}

// Define RuleData interface for rule creation and updates
export interface RuleData {
requestMode: string;
beforePublishConfig?: BeforePublishConfig;
chatRoomFilter?: string;
invocationMode?: string;
requestMode?: string;
ruleType: string;
source: {
channelFilter: string;
channelFilter?: string;
type: string;
};
status?: "disabled" | "enabled";
Expand Down
Loading
Loading