Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default {
name: "Add Subscriber",
description: "Add subscribers to the specified account and list. [See the docs here](https://api.aweber.com/#tag/Subscribers/paths/~1accounts~1{accountId}~1lists~1{listId}~1subscribers/post).",
type: "action",
version: "0.0.4",
version: "0.0.5",
annotations: {
destructiveHint: false,
openWorldHint: true,
Expand Down
163 changes: 163 additions & 0 deletions components/aweber/actions/create-broadcast/create-broadcast.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import aweberApp from "../../aweber.app.mjs";

export default {
key: "aweber-create-broadcast",
name: "Create Broadcast",
description: "Create a broadcast under the specified account and list. [See the docs here](https://api.aweber.com/#tag/Broadcasts/paths/~1accounts~1%7BaccountId%7D~1lists~1%7BlistId%7D~1broadcasts/post).",
type: "action",
version: "0.0.1",
annotations: {
destructiveHint: false,
openWorldHint: true,
readOnlyHint: false,
},
props: {
aweberApp,
accountId: {
propDefinition: [
aweberApp,
"accountId",
],
},
listId: {
propDefinition: [
aweberApp,
"listId",
({ accountId }) => ({
accountId,
}),
],
},
bodyHTML: {
type: "string",
label: "Body HTML",
description: "The content of the message in HTML format. If `Body Text` is not provided, it will be auto-generated. If `Body Text` is not provided, `Body HTML` must be provided.",
},
bodyText: {
type: "string",
label: "Body Text",
description: "The content of the message in plain text, used when HTML is not supported. If `Body HTML` is not provided, the broadcast will be sent using only the `Body Text`. If `Body Text` is not provided, `Body HTML` must be provided.",
},
Comment on lines +31 to +40
Copy link
Contributor

@coderabbitai coderabbitai bot Oct 13, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Prop requirements contradict descriptions.

Both bodyHTML and bodyText are required fields (no optional: true), but their descriptions indicate that at least one should be provided, not both. This prevents users from creating HTML-only or text-only broadcasts as described in the prop documentation.

Apply this diff to make both props optional while enforcing that at least one must be provided:

     bodyHTML: {
       type: "string",
       label: "Body HTML",
       description: "The content of the message in HTML format. If `Body Text` is not provided, it will be auto-generated. If `Body Text` is not provided, `Body HTML` must be provided.",
+      optional: true,
     },
     bodyText: {
       type: "string",
       label: "Body Text",
       description: "The content of the message in plain text, used when HTML is not supported. If `Body HTML` is not provided, the broadcast will be sent using only the `Body Text`. If `Body Text` is not provided, `Body HTML` must be provided.",
+      optional: true,
     },

Then add validation in the run method before the API call:

   async run({ $ }) {
+    if (!this.bodyHTML && !this.bodyText) {
+      throw new Error("At least one of 'Body HTML' or 'Body Text' must be provided.");
+    }
+
     const response = await this.aweberApp.createBroadcast({
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
bodyHTML: {
type: "string",
label: "Body HTML",
description: "The content of the message in HTML format. If `Body Text` is not provided, it will be auto-generated. If `Body Text` is not provided, `Body HTML` must be provided.",
},
bodyText: {
type: "string",
label: "Body Text",
description: "The content of the message in plain text, used when HTML is not supported. If `Body HTML` is not provided, the broadcast will be sent using only the `Body Text`. If `Body Text` is not provided, `Body HTML` must be provided.",
},
// In the props definitions (around lines 31–40):
bodyHTML: {
type: "string",
label: "Body HTML",
description: "The content of the message in HTML format. If `Body Text` is not provided, it will be auto-generated. If `Body Text` is not provided, `Body HTML` must be provided.",
optional: true,
},
bodyText: {
type: "string",
label: "Body Text",
description: "The content of the message in plain text, used when HTML is not supported. If `Body HTML` is not provided, the broadcast will be sent using only the `Body Text`. If `Body Text` is not provided, `Body HTML` must be provided.",
optional: true,
},
// In the run method (before the API call):
async run({ $ }) {
if (!this.bodyHTML && !this.bodyText) {
throw new Error("At least one of 'Body HTML' or 'Body Text' must be provided.");
}
const response = await this.aweberApp.createBroadcast({
// …rest of the parameters
});
// …
}
🤖 Prompt for AI Agents
In components/aweber/actions/create-broadcast/create-broadcast.mjs around lines
31-40, change both bodyHTML and bodyText prop definitions to include optional:
true (making them optional), and in the run method add a pre-API-call validation
that reads the input props and throws a clear error if neither bodyHTML nor
bodyText is provided (e.g., if (!bodyHTML && !bodyText) throw new Error("Provide
at least one of bodyHTML or bodyText")). Ensure the validation runs before
constructing the request so HTML-only or text-only broadcasts are allowed but
both being empty is rejected.

Copy link
Collaborator

Choose a reason for hiding this comment

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

CodeRabbit's comment makes sense here. bodyHTML and bodyText are both required, but their descriptions somewhat contradict this.

Copy link
Contributor

Choose a reason for hiding this comment

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

@GTFalcao, thank you for confirming! Yes, the current implementation creates a conflict between the required fields and their descriptions. Making both bodyHTML and bodyText optional while adding runtime validation to ensure at least one is provided is the correct approach. This will allow users to create:

  • HTML-only broadcasts (with auto-generated plain text)
  • Text-only broadcasts
  • Mixed HTML and text broadcasts

while preventing the error case where neither is provided. The suggested fix aligns with the AWeber API behavior described in the prop documentation.

bodyAmp: {
type: "string",
label: "Body AMP",
description: "The content of the message in AMP format. [Read Aweber KB article before using this field](https://help.aweber.com/hc/en-us/articles/360025741194)",
optional: true,
},
clickTrackingEnabled: {
type: "boolean",
label: "Click Tracking Enabled",
description: "Enables links in the email message to be tracked.",
optional: true,
},
excludeLists: {
propDefinition: [
aweberApp,
"listSelfLink",
({ accountId }) => ({
accountId,
}),
],
type: "string[]",
label: "Exclude Lists",
description: "List of [Lists](https://api.aweber.com/#tag/Lists) URLs to exclude in the delivery of this broadcast. **e.g. `https://api.aweber.com/1.0/accounts/<account_id>/lists/<list_id>`**",
optional: true,
},
includeLists: {
propDefinition: [
aweberApp,
"listSelfLink",
({ accountId }) => ({
accountId,
}),
],
type: "string[]",
label: "Include Lists",
description: "List of [Lists](https://api.aweber.com/#tag/Lists) URLs to include in the delivery of this broadcast. **e.g. `https://api.aweber.com/1.0/accounts/<account_id>/lists/<list_id>`**",
optional: true,
},
facebookIntegration: {
propDefinition: [
aweberApp,
"integrations",
({ accountId }) => ({
accountId,
serviceName: "facebook",
}),
],
label: "Facebook Integration",
description: "URL to the [Facebook broadcast integration](https://api.aweber.com/#tag/Integrations) to use for this broadcast. When the broadcast is sent, the subject of the broadcast will be posted to this Facebook integration - **e.g. `https://api.aweber.com/1.0/accounts/<account_id>/integrations/<integration_id>`**.",
optional: true,
},
isArchived: {
type: "boolean",
label: "Is Archived",
description: "Whether the broadcast enabled sharing via an archive URL.",
optional: true,
},
notifyOnSend: {
type: "boolean",
label: "Notify on Send",
description: "If true, notify when stats are available on a sent broadcast message.",
optional: true,
},
segmentLink: {
propDefinition: [
aweberApp,
"segmentSelfLink",
({
accountId, listId,
}) => ({
accountId,
listId,
}),
],
optional: true,
},
subject: {
type: "string",
label: "Subject",
description: "The broadcast subject line. Subject must not be empty nor contain only whitespace.",
},
twitterIntegration: {
propDefinition: [
aweberApp,
"integrations",
({ accountId }) => ({
accountId,
serviceName: "twitter",
}),
],
label: "Twitter Integration",
description: "URL to the [Twitter broadcast integration](https://api.aweber.com/#tag/Integrations) to use for this broadcast. When the broadcast is sent, the subject of the broadcast will be tweeted - **e.g. `https://api.aweber.com/1.0/accounts/<account_id>/integrations/<integration_id>`**.",
optional: true,
},
},
async run({ $ }) {
const response = await this.aweberApp.createBroadcast({
$,
accountId: this.accountId,
listId: this.listId,
data: {
body_html: this.bodyHTML,
body_text: this.bodyText,
body_amp: this.bodyAmp,
click_tracking_enabled: this.clickTrackingEnabled,
exclude_lists: this.excludeLists,
include_lists: this.includeLists,
facebook_integration: this.facebookIntegration,
is_archived: this.isArchived,
notify_on_send: this.notifyOnSend,
segment_link: this.segmentLink,
subject: this.subject,
twitter_integration: this.twitterIntegration,
},
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});

$.export("$summary", `Successfully created broadcast with **UUID: ${response.uuid}**.`);
return response;
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export default {
name: "Create Or Update Subscriber",
description: "Create subscriber if the subscriber email is not existing or update the information for the specified subscriber by email. [See the docs here](https://api.aweber.com/#tag/Subscribers/paths/~1accounts~1{accountId}~1lists~1{listId}~1subscribers/patch).",
type: "action",
version: "0.0.2",
version: "0.0.3",
annotations: {
destructiveHint: true,
openWorldHint: true,
Expand Down
2 changes: 1 addition & 1 deletion components/aweber/actions/get-accounts/get-accounts.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default {
name: "Get Accounts",
description: "Get a paginated collection of accounts. [See the docs here](https://api.aweber.com/#tag/Accounts/paths/~1accounts/get).",
type: "action",
version: "0.0.4",
version: "0.0.5",
annotations: {
destructiveHint: false,
openWorldHint: true,
Expand Down
2 changes: 1 addition & 1 deletion components/aweber/actions/get-lists/get-lists.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default {
name: "Get Lists",
description: "Get a paginated collection of subscriber lists. [See the docs here](https://api.aweber.com/#tag/Lists/paths/~1accounts~1{accountId}~1lists/get).",
type: "action",
version: "0.0.4",
version: "0.0.5",
annotations: {
destructiveHint: false,
openWorldHint: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default {
name: "Get Subscribers",
description: "Get a paginated collection of subscribers under the specified account and list. [See the docs here](https://api.aweber.com/#tag/Subscribers/paths/~1accounts~1{accountId}~1lists~1{listId}~1subscribers/get).",
type: "action",
version: "0.0.4",
version: "0.0.5",
annotations: {
destructiveHint: false,
openWorldHint: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default {
name: "Update Subscriber",
description: "Update the information for the specified subscriber by email. [See the docs here](https://api.aweber.com/#tag/Subscribers/paths/~1accounts~1{accountId}~1lists~1{listId}~1subscribers/patch).",
type: "action",
version: "0.0.3",
version: "0.0.4",
annotations: {
destructiveHint: true,
openWorldHint: true,
Expand Down
Loading
Loading