Skip to content

feat(instant_reply): Add Instant Reply app — WhatsApp, Instagram & Messenger AI inbox#21089

Open
suleimandoescsec wants to merge 2 commits into
PipedreamHQ:masterfrom
suleimandoescsec:feat/instant-reply-app
Open

feat(instant_reply): Add Instant Reply app — WhatsApp, Instagram & Messenger AI inbox#21089
suleimandoescsec wants to merge 2 commits into
PipedreamHQ:masterfrom
suleimandoescsec:feat/instant-reply-app

Conversation

@suleimandoescsec
Copy link
Copy Markdown

@suleimandoescsec suleimandoescsec commented Jun 6, 2026

What is Instant Reply?

Instant Reply is a shared AI inbox for WhatsApp Business, Instagram DMs, and Facebook Messenger. Teams use it to qualify leads, automate replies with AI, send broadcasts, and sync conversations to HubSpot or Pipedrive.

What this PR adds

Actions

Key Name Description
instant_reply-send-message Send Message Send free-form or template messages via WhatsApp, Instagram, or Messenger
instant_reply-create-contact Create Contact Add a new contact to the Instant Reply inbox
instant_reply-update-contact Update Contact Update contact fields, tags, and custom data
instant_reply-add-note Add Note to Conversation Attach internal notes to a conversation thread

Sources (Triggers)

Key Name Description
instant_reply-new-message New Inbound Message Emit when a new message arrives (WhatsApp / Instagram / Messenger)
instant_reply-new-lead New Qualified Lead Emit when a conversation is marked as a qualified lead

Authentication

API key — users generate their key at instantreply.co/dashboard/settings/api. Connects via Authorization: Bearer header.

Example use cases

  • Form → WhatsApp: Typeform submission → Create Contact → Send Message
  • New lead → CRM: New Qualified Lead → Create Deal in HubSpot / Pipedrive
  • New message → Slack: New Inbound Message → Post to Slack channel
  • WhatsApp → Sheet: New Inbound Message → Append Row to Google Sheets

Checklist

  • New app with type: "app" and propDefinitions
  • Actions use $.export("$summary", ...)
  • Sources use dedupe: "unique" and poll via $.service.db
  • package.json matches Pipedream conventions (@pipedream/platform ^1.6.8)
  • No hardcoded secrets — all auth via $auth.api_key
  • README included

Summary by CodeRabbit

  • New Features

    • Instant Reply integration: send messages, create/update contacts, add notes, list/get conversations.
    • New actions: send campaigns, trigger WhatsApp journeys, update lead stage.
    • New event sources/triggers: inbound messages, qualified leads, campaign completed, Instagram/Facebook comments.
  • Documentation

    • Comprehensive Instant Reply docs covering channels, actions, triggers, authentication, and example workflows.

Adds community integration for Instant Reply — a shared AI inbox for
WhatsApp Business, Instagram DMs, and Facebook Messenger.

Actions:
- instant_reply-send-message: send free-form or template messages
- instant_reply-create-contact: add a new contact to the inbox
- instant_reply-update-contact: update contact fields and tags
- instant_reply-add-note: attach internal notes to conversations

Sources (triggers):
- instant_reply-new-message: emit on every inbound message (60s poll)
- instant_reply-new-lead: emit when a conversation is marked qualified (5m poll)

Auth: API key (Bearer token via $auth.api_key)

Fixes: #new-app
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 6, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
pipedream-docs-redirect-do-not-edit Ignored Ignored Jun 7, 2026 9:39am

Request Review

@pipedream-component-development
Copy link
Copy Markdown
Collaborator

Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified.

@pipedream-component-development
Copy link
Copy Markdown
Collaborator

Thanks for submitting this PR! When we review PRs, we follow the Pipedream component guidelines. If you're not familiar, here's a quick checklist:

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 6, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new Instant Reply component: an authenticated app wrapper, multiple actions (messaging, contact management, campaigns, notes, journey trigger, lead-stage), four polling sources for webhook events, package manifest, and README documentation.

Changes

Instant Reply Integration

Layer / File(s) Summary
App foundation and authentication
components/instant_reply/instant_reply.app.mjs, components/instant_reply/package.json
Defines the Instant Reply app with Bearer API auth, request helpers, endpoint wrapper methods (contacts, conversations, templates, messages, campaigns, pipeline, trigger), propDefinitions for dynamic options, and package manifest.
Contact create & update actions
components/instant_reply/actions/create-contact/create-contact.mjs, components/instant_reply/actions/update-contact/update-contact.mjs
Actions to create and update contacts; map props to API payloads, call app methods, export summaries, and return responses.
Messaging, conversation, campaign, and journey actions
components/instant_reply/actions/send-message/send-message.mjs, components/instant_reply/actions/get-conversation/get-conversation.mjs, components/instant_reply/actions/list-conversations/list-conversations.mjs, components/instant_reply/actions/send-campaign/send-campaign.mjs, components/instant_reply/actions/trigger-journey/trigger-journey.mjs
Send message action with conditional props by messageType; actions to get/list conversations, create/send campaigns, and trigger WhatsApp journeys; each calls the app endpoints and returns API responses with exported summaries.
Add note & update lead stage actions
components/instant_reply/actions/add-note/add-note.mjs, components/instant_reply/actions/update-lead-stage/update-lead-stage.mjs
Action to add internal conversation notes and action to update pipeline lead stage; both invoke app endpoints, export human-readable summaries, and return responses.
New inbound message source
components/instant_reply/sources/new-message/new-message.mjs
Polls message.inbound webhook events since persisted lastTs, optionally filters by channel, emits events with metadata, and updates checkpoint.
New qualified lead source
components/instant_reply/sources/new-lead/new-lead.mjs
Polls lead.qualified webhook events (limit 100), emits events newer than lastTs with metadata including contact/channel, and persists updated checkpoint.
Campaign completed & new comment sources
components/instant_reply/sources/campaign-completed/campaign-completed.mjs, components/instant_reply/sources/new-comment/new-comment.mjs
Polls campaign.completed and comment.received webhook events, emits matching events with metadata, and persists lastTs checkpoints.
Integration documentation
components/instant_reply/README.md
README describing supported channels, available actions and triggers, API-key authentication, and example workflow scenarios.

Sequence Diagram(s)

sequenceDiagram
  participant Action as SendMessageAction
  participant App as InstantReplyApp
  participant API as Instant Reply API
  Action->>App: this.instantReply.sendMessage(payload)
  App->>API: POST /messages (Authorization: Bearer api_key)
  API-->>App: response
  App-->>Action: response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • ashwins01
  • mariano-pd
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: introducing a new Instant Reply app for WhatsApp, Instagram, and Messenger integration.
Description check ✅ Passed The description covers the app purpose, all major actions and sources added, authentication method, use cases, and a complete checklist with all items marked complete.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown
Contributor

@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: 14

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/instant_reply/actions/add-note/add-note.mjs`:
- Around line 3-8: The exported action object (key "instant_reply-add-note") is
missing the required annotations object; add an annotations property to the
default export with readOnlyHint: false, destructiveHint: false, and
openWorldHint: true so the action correctly declares it creates data and makes
external API calls—update the object literal in the add-note module (the default
export) to include this annotations object.

In `@components/instant_reply/actions/create-contact/create-contact.mjs`:
- Around line 3-8: The exported action object (default export) is missing the
required annotations object; add an annotations property to the root exported
object with keys readOnlyHint: false, destructiveHint: false, and openWorldHint:
true so the "instant_reply-create-contact" action correctly declares it's a
writing action that makes external API calls; update the default export in
create-contact.mjs (the object containing key/name/description/version/type) to
include this annotations object.

In `@components/instant_reply/actions/send-message/send-message.mjs`:
- Around line 3-8: The exported action object (default export with key
"instant_reply-send-message" / name "Send Message") is missing the required
annotations object; add an annotations property to the exported object
containing { readOnlyHint: false, destructiveHint: false, openWorldHint: true }
so the runtime knows this action performs external API calls and mutates/sends
data.
- Around line 33-52: Remove the redundant hidden static prop declarations for
body, templateId, and templateVariables from the static props object and rely
only on the conditional definitions in additionalProps(); specifically delete
the entries named "body", "templateId", and "templateVariables" in the static
props block so that additionalProps() is the single source of truth for those
conditional props (leave additionalProps() and its definitions unchanged).

In `@components/instant_reply/actions/update-contact/update-contact.mjs`:
- Around line 3-8: The exported action object (key
"instant_reply-update-contact") is missing the required annotations object; add
an annotations property to the default export containing readOnlyHint: false,
destructiveHint: false, and openWorldHint: true so the action metadata correctly
reflects that it modifies data and makes external API calls.

In `@components/instant_reply/instant_reply.app.mjs`:
- Around line 144-149: Update getWebhookEvents to accept a $ parameter and
forward it into the internal request so the platform can attach request context
for logging and error propagation: modify the getWebhookEvents(signature) to
include ($ = {}) or ($, args = {}) and pass $ into the call to
this._makeRequest({ path: "/webhook-events", ...args, $ }) so callers (e.g.,
new-message.mjs/new-lead.mjs) can supply the $ request context; ensure the
change matches the pattern used by other app methods that call
this._makeRequest.

In `@components/instant_reply/package.json`:
- Line 3: The package.json "version" field in the instant_reply component is
incorrectly set to "0.1.0"; change it to "0.0.1" and ensure the same "version"
value is used in each action/source module file (update the version key in
create-contact.mjs, update-contact.mjs, send-message.mjs, and add-note.mjs) so
all new component files start at 0.0.1 per the component versioning guidelines.

In `@components/instant_reply/sources/new-lead/new-lead.mjs`:
- Line 7: The component's initial version is set incorrectly to "0.1.0"; update
the version field in the module metadata (the "version" entry in new-lead.mjs)
to "0.0.1" so the new component starts at the required initial version; locate
the literal version: "0.1.0" and replace it with "0.0.1".
- Line 6: The component description string in new-lead.mjs is missing the
required documentation link; update the description value (the description
property in the exported component object) to end with the markdown link "[See
the documentation](https://...)" pointing to the component docs (replace
https://... with the actual docs URL), ensuring the link is appended to the
existing sentence and preserves punctuation and spacing.
- Around line 39-45: The call to this.instantReply.getWebhookEvents currently
requests only the first page (limit: 100) and can drop older events if more than
100 leads appear between polls; update the logic around getWebhookEvents to
iterate through all pages in a single poll cycle (using the API's pagination
mechanism: page/cursor/offset) starting from since: new
Date(lastTs).toISOString() and aggregating results until the API indicates no
more pages, emitting all collected "lead.qualified" events; ensure you
propagate/advance the pagination token (or increment page/offset) from the
response and keep params.limit (or configurable page size) while preserving
lastTs usage for the poll boundary.

In `@components/instant_reply/sources/new-message/new-message.mjs`:
- Line 7: Change the component initial version from "0.1.0" to "0.0.1" by
updating the version field in the new-message component (the version: "0.1.0"
entry in new-message.mjs) so the component starts at the required initial
version "0.0.1".
- Line 51: Remove the redundant "|| undefined" fallback when building the
request payload: replace the property assignment that uses "channel:
this.channel || undefined" with simply "channel: this.channel" (locate the
object literal where channel is set in new-message.mjs). This relies on
`@pipedream/platform`'s axios behavior that strips undefined values and keeps the
payload cleaner; no other logic changes are required.
- Line 6: The component's description string (the description field in
new-message component) is missing the required documentation link; update the
description value so it ends with a markdown documentation link like "[See the
documentation](https://...)" (replace the ... with the correct docs URL)
ensuring the link is appended to the existing sentence and stays within the same
string literal.
- Around line 47-54: The current call to this.instantReply.getWebhookEvents with
params { type: "message.inbound", since: new Date(lastTs).toISOString(),
channel: this.channel || undefined, limit: 100 } only retrieves one page; change
the logic in the method that calls this.instantReply.getWebhookEvents (the
polling handler using lastTs and channel) to iterate and fetch all pages in a
loop: call getWebhookEvents repeatedly using the API's pagination mechanism
(e.g., nextCursor/nextPage token or page/offset param returned by
getWebhookEvents) until no more pages, accumulate all events before
processing/emitting them, and update lastTs based on the latest event timestamp
after all pages are fetched; ensure you handle empty pages, respect the existing
limit param, and surface or propagate any pagination token field returned by
getWebhookEvents.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3ed8fa3e-0ee9-4082-be7d-85502fc6c447

📥 Commits

Reviewing files that changed from the base of the PR and between 6d12c92 and f426174.

📒 Files selected for processing (9)
  • components/instant_reply/README.md
  • components/instant_reply/actions/add-note/add-note.mjs
  • components/instant_reply/actions/create-contact/create-contact.mjs
  • components/instant_reply/actions/send-message/send-message.mjs
  • components/instant_reply/actions/update-contact/update-contact.mjs
  • components/instant_reply/instant_reply.app.mjs
  • components/instant_reply/package.json
  • components/instant_reply/sources/new-lead/new-lead.mjs
  • components/instant_reply/sources/new-message/new-message.mjs

Comment on lines +3 to +8
export default {
key: "instant_reply-add-note",
name: "Add Note to Conversation",
description: "Add an internal note to an Instant Reply conversation. Useful for logging external context (form submission data, payment status, CRM updates) alongside the conversation thread. [See the docs](https://www.instantreply.co/developers)",
version: "0.1.0",
type: "action",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Add required annotations object.

Action components must include an annotations object. This action adds internal notes to conversations via POST /conversations/{id}/notes, so:

  • readOnlyHint: false (creates data)
  • destructiveHint: false (adds a note; does not delete or irreversibly overwrite)
  • openWorldHint: true (makes external API calls)
✅ Suggested fix
 export default {
   key: "instant_reply-add-note",
   name: "Add Note to Conversation",
   description: "Add an internal note to an Instant Reply conversation. Useful for logging external context (form submission data, payment status, CRM updates) alongside the conversation thread. [See the docs](https://www.instantreply.co/developers)",
   version: "0.1.0",
   type: "action",
+  annotations: {
+    readOnlyHint: false,
+    destructiveHint: false,
+    openWorldHint: true,
+  },
   props: {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/actions/add-note/add-note.mjs` around lines 3 - 8,
The exported action object (key "instant_reply-add-note") is missing the
required annotations object; add an annotations property to the default export
with readOnlyHint: false, destructiveHint: false, and openWorldHint: true so the
action correctly declares it creates data and makes external API calls—update
the object literal in the add-note module (the default export) to include this
annotations object.

Source: Coding guidelines

Comment on lines +3 to +8
export default {
key: "instant_reply-create-contact",
name: "Create Contact",
description: "Create a new contact in your Instant Reply inbox. Use this to sync leads from forms, CRMs, or any trigger into Instant Reply. [See the docs](https://www.instantreply.co/developers)",
version: "0.1.0",
type: "action",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Add required annotations object.

Action components must include an annotations object with readOnlyHint, destructiveHint, and openWorldHint fields. This action creates a new contact via an external API call, so:

  • readOnlyHint: false (writes data)
  • destructiveHint: false (creates, does not delete or irreversibly overwrite)
  • openWorldHint: true (makes external API calls)
✅ Suggested fix
 export default {
   key: "instant_reply-create-contact",
   name: "Create Contact",
   description: "Create a new contact in your Instant Reply inbox. Use this to sync leads from forms, CRMs, or any trigger into Instant Reply. [See the docs](https://www.instantreply.co/developers)",
   version: "0.1.0",
   type: "action",
+  annotations: {
+    readOnlyHint: false,
+    destructiveHint: false,
+    openWorldHint: true,
+  },
   props: {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/actions/create-contact/create-contact.mjs` around
lines 3 - 8, The exported action object (default export) is missing the required
annotations object; add an annotations property to the root exported object with
keys readOnlyHint: false, destructiveHint: false, and openWorldHint: true so the
"instant_reply-create-contact" action correctly declares it's a writing action
that makes external API calls; update the default export in create-contact.mjs
(the object containing key/name/description/version/type) to include this
annotations object.

Source: Coding guidelines

Comment on lines +3 to +8
export default {
key: "instant_reply-send-message",
name: "Send Message",
description: "Send a WhatsApp, Instagram DM, or Messenger message to a contact. Use a free-form body within a 24-hour customer window, or pick a pre-approved template for outbound outreach. [See the docs](https://www.instantreply.co/developers)",
version: "0.1.0",
type: "action",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Add required annotations object.

Action components must include an annotations object. This action sends messages via external messaging APIs (WhatsApp/Instagram/Messenger), so:

  • readOnlyHint: false (sends data)
  • destructiveHint: false (sends messages; does not delete or irreversibly destroy data)
  • openWorldHint: true (makes external API calls)
✅ Suggested fix
 export default {
   key: "instant_reply-send-message",
   name: "Send Message",
   description: "Send a WhatsApp, Instagram DM, or Messenger message to a contact. Use a free-form body within a 24-hour customer window, or pick a pre-approved template for outbound outreach. [See the docs](https://www.instantreply.co/developers)",
   version: "0.1.0",
   type: "action",
+  annotations: {
+    readOnlyHint: false,
+    destructiveHint: false,
+    openWorldHint: true,
+  },
   props: {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/actions/send-message/send-message.mjs` around lines
3 - 8, The exported action object (default export with key
"instant_reply-send-message" / name "Send Message") is missing the required
annotations object; add an annotations property to the exported object
containing { readOnlyHint: false, destructiveHint: false, openWorldHint: true }
so the runtime knows this action performs external API calls and mutates/sends
data.

Source: Coding guidelines

Comment on lines +33 to +52
body: {
type: "string",
label: "Message Body",
description: "The text content of the message.",
hidden: true,
},
templateId: {
propDefinition: [
instantReply,
"templateId",
],
hidden: true,
},
templateVariables: {
type: "object",
label: "Template Variables",
description: "Key-value pairs for the template placeholders, e.g. `{ \"1\": \"Alice\", \"2\": \"order #123\" }`.",
optional: true,
hidden: true,
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Remove redundant hidden props.

Props body, templateId, and templateVariables are declared in the static props object with hidden: true (lines 33-52) and then completely redefined in additionalProps() (lines 54-78). The static declarations serve no purpose here — additionalProps() alone should define these conditional props.

Simplify by removing the static hidden prop definitions.

♻️ Suggested fix
     messageType: {
       type: "string",
       label: "Message Type",
       description: "Send a free-form text message (only valid within 24 hours of the customer's last message) or a pre-approved template.",
       options: [
         { label: "Free-form text", value: "text" },
         { label: "Template", value: "template" },
       ],
       reloadProps: true,
     },
-    body: {
-      type: "string",
-      label: "Message Body",
-      description: "The text content of the message.",
-      hidden: true,
-    },
-    templateId: {
-      propDefinition: [
-        instantReply,
-        "templateId",
-      ],
-      hidden: true,
-    },
-    templateVariables: {
-      type: "object",
-      label: "Template Variables",
-      description: "Key-value pairs for the template placeholders, e.g. `{ \"1\": \"Alice\", \"2\": \"order `#123`\" }`.",
-      optional: true,
-      hidden: true,
-    },
   },
   async additionalProps() {
📝 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
body: {
type: "string",
label: "Message Body",
description: "The text content of the message.",
hidden: true,
},
templateId: {
propDefinition: [
instantReply,
"templateId",
],
hidden: true,
},
templateVariables: {
type: "object",
label: "Template Variables",
description: "Key-value pairs for the template placeholders, e.g. `{ \"1\": \"Alice\", \"2\": \"order #123\" }`.",
optional: true,
hidden: true,
},
messageType: {
type: "string",
label: "Message Type",
description: "Send a free-form text message (only valid within 24 hours of the customer's last message) or a pre-approved template.",
options: [
{ label: "Free-form text", value: "text" },
{ label: "Template", value: "template" },
],
reloadProps: true,
},
},
async additionalProps() {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/actions/send-message/send-message.mjs` around lines
33 - 52, Remove the redundant hidden static prop declarations for body,
templateId, and templateVariables from the static props object and rely only on
the conditional definitions in additionalProps(); specifically delete the
entries named "body", "templateId", and "templateVariables" in the static props
block so that additionalProps() is the single source of truth for those
conditional props (leave additionalProps() and its definitions unchanged).

Comment on lines +3 to +8
export default {
key: "instant_reply-update-contact",
name: "Update Contact",
description: "Update an existing contact's fields in Instant Reply. Use this to sync CRM updates, tag changes, or enriched data back into your inbox. [See the docs](https://www.instantreply.co/developers)",
version: "0.1.0",
type: "action",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Add required annotations object.

Action components must include an annotations object. This action updates contact fields via PATCH /contacts/{id}, so:

  • readOnlyHint: false (modifies data)
  • destructiveHint: false (updates are reversible; another update can restore previous values)
  • openWorldHint: true (makes external API calls)
✅ Suggested fix
 export default {
   key: "instant_reply-update-contact",
   name: "Update Contact",
   description: "Update an existing contact's fields in Instant Reply. Use this to sync CRM updates, tag changes, or enriched data back into your inbox. [See the docs](https://www.instantreply.co/developers)",
   version: "0.1.0",
   type: "action",
+  annotations: {
+    readOnlyHint: false,
+    destructiveHint: false,
+    openWorldHint: true,
+  },
   props: {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/actions/update-contact/update-contact.mjs` around
lines 3 - 8, The exported action object (key "instant_reply-update-contact") is
missing the required annotations object; add an annotations property to the
default export containing readOnlyHint: false, destructiveHint: false, and
openWorldHint: true so the action metadata correctly reflects that it modifies
data and makes external API calls.

Source: Coding guidelines

Comment on lines +39 to +45
const response = await this.instantReply.getWebhookEvents({
params: {
type: "lead.qualified",
since: new Date(lastTs).toISOString(),
limit: 100,
},
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Implement pagination to fetch all new qualified leads.

The current implementation only fetches up to 100 events per poll (line 43) and does not handle pagination. If more than 100 leads are qualified between poll intervals, older events will be permanently skipped. As per coding guidelines: "For APIs that paginate, fetch/emit all pages of new items in a single poll cycle (don't stop after the first page)."

🔄 Recommended pagination pattern
  async run() {
    const lastTs = this._getLastTs();
    let newLastTs = lastTs;

-    const response = await this.instantReply.getWebhookEvents({
-      params: {
-        type: "lead.qualified",
-        since: new Date(lastTs).toISOString(),
-        limit: 100,
-      },
-    });
-
-    const events = response?.data ?? [];
+    let page = 1;
+    let hasMore = true;
+
+    while (hasMore) {
+      const response = await this.instantReply.getWebhookEvents({
+        params: {
+          type: "lead.qualified",
+          since: new Date(lastTs).toISOString(),
+          limit: 100,
+          page,
+        },
+      });
+
+      const events = response?.data ?? [];
+      hasMore = events.length === 100;
+      page++;

-    for (const event of events) {
-      const ts = Date.parse(event.created_at);
-      if (ts > lastTs) {
-        this.$emit(event, this.generateMeta(event));
-        if (ts > newLastTs) newLastTs = ts;
+      for (const event of events) {
+        const ts = Date.parse(event.created_at);
+        if (ts > lastTs) {
+          this.$emit(event, this.generateMeta(event));
+          if (ts > newLastTs) newLastTs = ts;
+        }
      }
    }

    this._setLastTs(newLastTs);
  },

Note: Verify the Instant Reply API's pagination mechanism (page-based, cursor-based, or offset-based) and adjust accordingly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/sources/new-lead/new-lead.mjs` around lines 39 - 45,
The call to this.instantReply.getWebhookEvents currently requests only the first
page (limit: 100) and can drop older events if more than 100 leads appear
between polls; update the logic around getWebhookEvents to iterate through all
pages in a single poll cycle (using the API's pagination mechanism:
page/cursor/offset) starting from since: new Date(lastTs).toISOString() and
aggregating results until the API indicates no more pages, emitting all
collected "lead.qualified" events; ensure you propagate/advance the pagination
token (or increment page/offset) from the response and keep params.limit (or
configurable page size) while preserving lastTs usage for the poll boundary.

Source: Coding guidelines

export default {
key: "instant_reply-new-message",
name: "New Inbound Message",
description: "Emit an event each time a new inbound message arrives in your Instant Reply inbox — from WhatsApp, Instagram DM, or Messenger. Use this to trigger CRM updates, Slack notifications, or any downstream workflow.",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add required documentation link to component description.

As per coding guidelines, component description fields must end with [See the documentation](https://...). This link is required for all components.

📝 Suggested addition
-  description: "Emit an event each time a new inbound message arrives in your Instant Reply inbox — from WhatsApp, Instagram DM, or Messenger. Use this to trigger CRM updates, Slack notifications, or any downstream workflow.",
+  description: "Emit an event each time a new inbound message arrives in your Instant Reply inbox — from WhatsApp, Instagram DM, or Messenger. Use this to trigger CRM updates, Slack notifications, or any downstream workflow. [See the documentation](https://www.instantreply.co/docs/api)",
📝 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
description: "Emit an event each time a new inbound message arrives in your Instant Reply inbox — from WhatsApp, Instagram DM, or Messenger. Use this to trigger CRM updates, Slack notifications, or any downstream workflow.",
description: "Emit an event each time a new inbound message arrives in your Instant Reply inbox — from WhatsApp, Instagram DM, or Messenger. Use this to trigger CRM updates, Slack notifications, or any downstream workflow. [See the documentation](https://www.instantreply.co/docs/api)",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/sources/new-message/new-message.mjs` at line 6, The
component's description string (the description field in new-message component)
is missing the required documentation link; update the description value so it
ends with a markdown documentation link like "[See the
documentation](https://...)" (replace the ... with the correct docs URL)
ensuring the link is appended to the existing sentence and stays within the same
string literal.

Source: Coding guidelines

key: "instant_reply-new-message",
name: "New Inbound Message",
description: "Emit an event each time a new inbound message arrives in your Instant Reply inbox — from WhatsApp, Instagram DM, or Messenger. Use this to trigger CRM updates, Slack notifications, or any downstream workflow.",
version: "0.1.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Correct initial version to 0.0.1.

New components must start at version 0.0.1, not 0.1.0. As per coding guidelines: "new components start at 0.0.1".

🔧 Proposed fix
-  version: "0.1.0",
+  version: "0.0.1",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/sources/new-message/new-message.mjs` at line 7,
Change the component initial version from "0.1.0" to "0.0.1" by updating the
version field in the new-message component (the version: "0.1.0" entry in
new-message.mjs) so the component starts at the required initial version
"0.0.1".

Source: Coding guidelines

Comment on lines +47 to +54
const response = await this.instantReply.getWebhookEvents({
params: {
type: "message.inbound",
since: new Date(lastTs).toISOString(),
channel: this.channel || undefined,
limit: 100,
},
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Implement pagination to fetch all new events.

The current implementation only fetches up to 100 events per poll (line 52) and does not handle pagination. If more than 100 inbound messages arrive between poll intervals, older events will be permanently skipped. As per coding guidelines: "For APIs that paginate, fetch/emit all pages of new items in a single poll cycle (don't stop after the first page)."

🔄 Recommended pagination pattern
  async run() {
    const lastTs = this._getLastTs();
    let newLastTs = lastTs;

-    const response = await this.instantReply.getWebhookEvents({
-      params: {
-        type: "message.inbound",
-        since: new Date(lastTs).toISOString(),
-        channel: this.channel || undefined,
-        limit: 100,
-      },
-    });
-
-    const events = response?.data ?? [];
+    let page = 1;
+    let hasMore = true;
+
+    while (hasMore) {
+      const response = await this.instantReply.getWebhookEvents({
+        params: {
+          type: "message.inbound",
+          since: new Date(lastTs).toISOString(),
+          channel: this.channel || undefined,
+          limit: 100,
+          page,
+        },
+      });
+
+      const events = response?.data ?? [];
+      hasMore = events.length === 100;
+      page++;

-    for (const event of events) {
-      const ts = Date.parse(event.created_at);
-      if (ts > lastTs) {
-        this.$emit(event, this.generateMeta(event));
-        if (ts > newLastTs) newLastTs = ts;
+      for (const event of events) {
+        const ts = Date.parse(event.created_at);
+        if (ts > lastTs) {
+          this.$emit(event, this.generateMeta(event));
+          if (ts > newLastTs) newLastTs = ts;
+        }
      }
    }

    this._setLastTs(newLastTs);
  },

Note: Verify the Instant Reply API's pagination mechanism (page-based, cursor-based, or offset-based) and adjust accordingly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/sources/new-message/new-message.mjs` around lines 47
- 54, The current call to this.instantReply.getWebhookEvents with params { type:
"message.inbound", since: new Date(lastTs).toISOString(), channel: this.channel
|| undefined, limit: 100 } only retrieves one page; change the logic in the
method that calls this.instantReply.getWebhookEvents (the polling handler using
lastTs and channel) to iterate and fetch all pages in a loop: call
getWebhookEvents repeatedly using the API's pagination mechanism (e.g.,
nextCursor/nextPage token or page/offset param returned by getWebhookEvents)
until no more pages, accumulate all events before processing/emitting them, and
update lastTs based on the latest event timestamp after all pages are fetched;
ensure you handle empty pages, respect the existing limit param, and surface or
propagate any pagination token field returned by getWebhookEvents.

Source: Coding guidelines

params: {
type: "message.inbound",
since: new Date(lastTs).toISOString(),
channel: this.channel || undefined,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Remove redundant || undefined fallback.

The @pipedream/platform axios implementation automatically strips undefined values from request parameters, so this.channel || undefined is equivalent to just this.channel. The explicit fallback adds no value.

♻️ Simplification
-        channel: this.channel || undefined,
+        channel: this.channel,
📝 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
channel: this.channel || undefined,
channel: this.channel,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/sources/new-message/new-message.mjs` at line 51,
Remove the redundant "|| undefined" fallback when building the request payload:
replace the property assignment that uses "channel: this.channel || undefined"
with simply "channel: this.channel" (locate the object literal where channel is
set in new-message.mjs). This relies on `@pipedream/platform`'s axios behavior
that strips undefined values and keeps the payload cleaner; no other logic
changes are required.

…tform features

Actions added: list-conversations, get-conversation, send-campaign,
update-lead-stage, trigger-journey

Sources added: new-comment (Instagram/FB posts), campaign-completed

app.mjs: fixed events endpoint path, added listCampaigns,
listPipelineLeads, triggerJourney methods

README updated with full feature coverage.

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

@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: 12

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/instant_reply/actions/get-conversation/get-conversation.mjs`:
- Around line 7-10: Update the action header: set version to "0.0.1" (it should
start at 0.0.1 for a new component) and add a required annotations block next to
the existing props block; for example add an annotations object with semantic
boolean keys such as public, system, and user (e.g., annotations: { public:
true, system: false, user: true }) so the action (referenced by the existing
props/instantReply and the get-conversation action) declares the semantic hints
expected by the component guidelines.

In `@components/instant_reply/actions/list-conversations/list-conversations.mjs`:
- Around line 7-10: Update the action metadata: change the version string from
"0.1.0" to "0.0.1" and add a top-level annotations object (next to
version/type/props) with the required boolean flags for this action (e.g.,
annotations: { /* semantic booleans */ }). Modify the file's header where the
symbols version and props (and the action definition in
components/instant_reply/actions/list-conversations/list-conversations.mjs) are
declared so the new annotations block is present and populated with semantically
correct boolean values.

In `@components/instant_reply/actions/send-campaign/send-campaign.mjs`:
- Around line 7-10: The action's metadata uses version "0.1.0" and is missing
the required annotations block; change the version field in this module to
"0.0.1" and add an annotations property next to props (near the instantReply
prop) containing the required boolean flags (use the semantically correct
booleans for this action per project conventions) so the action follows the
components/*/actions/** metadata conventions.

In `@components/instant_reply/actions/trigger-journey/trigger-journey.mjs`:
- Around line 7-10: The component's metadata must be initialized as a new
action: change the version from "0.1.0" to "0.0.1" and add an annotations object
alongside props (near the block containing props: { instantReply, }) that
includes the required semantic boolean flags (e.g., public, ui, or other
project-standard booleans) to declare this action's semantics; update the
top-level object where version/type/props are defined (the same block in
trigger-journey.mjs) to include annotations with correct booleans and the
downgraded version.
- Around line 16-27: Add a pre-call guard that validates the action inputs so
either triggerName or journeyId is provided (and non-empty) before calling the
downstream API: locate where the action reads props triggerName and journeyId
(the handler that performs the API call around the section using these
variables) and add a check that throws/returns a clear configuration error like
"Either triggerName or journeyId must be provided" if both are missing; apply
the same guard before the other API call block referenced in the comment (the
second block around lines 41–53) so invalid input fails fast with a descriptive
error instead of letting the request proceed.

In `@components/instant_reply/actions/update-lead-stage/update-lead-stage.mjs`:
- Around line 7-10: The component uses version: "0.1.0" and lacks the required
action metadata block; change the version to "0.0.1" and add an annotations
object for the action (e.g., a top-level annotations property near the existing
version/type/props) initializing the required boolean flags per action metadata
rules so the action is valid; update the file's version string and add the
annotations block alongside the existing version/type/props entries (referencing
the version and annotations symbols in the file).

In `@components/instant_reply/sources/campaign-completed/campaign-completed.mjs`:
- Line 7: This component's manifest sets the version field to "0.1.0" but new
source components must start at "0.0.1"; update the version key (version:
"0.1.0") in campaign-completed.mjs to version: "0.0.1" so the initial release
follows the project guideline for new components.
- Line 6: The component's description property (the "description" field in
campaign-completed.mjs) must be updated to append the required documentation
link; modify the description string so it ends with a docs link in the exact
format "[See the documentation](https://...)" (for example: description: "Emit
an event... [See the documentation](https://your-docs-link)"), preserving the
existing text and punctuation and ensuring there is a single space before the
bracketed link.

In `@components/instant_reply/sources/new-comment/new-comment.mjs`:
- Line 7: The version field currently reads "0.1.0" for the new source; update
the initial version string to "0.0.1" so the new component complies with the
guideline; locate the version property (version: "0.1.0") in new-comment.mjs and
change its value to "0.0.1" ensuring the quotes and syntax remain unchanged.
- Line 6: The component description string (the description property in
new-comment.mjs) must be updated to append the required docs link; modify the
description value so it ends with a space followed by "[See the
documentation](https://...)" (preserve the existing sentence and punctuation),
e.g., update the description property in the module to include that exact
markdown link at the end.
- Around line 64-70: The loop currently short-circuits on sentiment
(this.sentiment) before handling timestamps so filtered events never advance
newLastTs; move the timestamp parsing/ts logic ahead of the sentiment check and
always update newLastTs when ts > lastTs (e.g. newLastTs = Math.max(newLastTs,
ts)), then conditionally call this.$emit(event, this.generateMeta(event)) only
if the sentiment matches; reference the for (const event of events) loop,
this.sentiment, event.sentiment, ts, newLastTs, lastTs, this.$emit and
generateMeta when making the change.
- Around line 15-23: The property descriptions for the enum props platform and
sentiment are too generic; update the description text for the platform property
and the sentiment property so they include inline concrete examples matching
their options (e.g., platform: "Which platform to monitor for comments, e.g.
'instagram' or 'messenger'." and sentiment: "Only emit events for comments with
this sentiment, e.g. 'positive', 'neutral', or 'negative' — leave blank for
all."). Edit the description strings for the platform and sentiment fields in
the configuration object so the examples are explicit and match the options
arrays.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a8f02add-1fb6-47a9-9bac-54c2a941d15a

📥 Commits

Reviewing files that changed from the base of the PR and between f426174 and f5e5ca9.

📒 Files selected for processing (9)
  • components/instant_reply/README.md
  • components/instant_reply/actions/get-conversation/get-conversation.mjs
  • components/instant_reply/actions/list-conversations/list-conversations.mjs
  • components/instant_reply/actions/send-campaign/send-campaign.mjs
  • components/instant_reply/actions/trigger-journey/trigger-journey.mjs
  • components/instant_reply/actions/update-lead-stage/update-lead-stage.mjs
  • components/instant_reply/instant_reply.app.mjs
  • components/instant_reply/sources/campaign-completed/campaign-completed.mjs
  • components/instant_reply/sources/new-comment/new-comment.mjs

Comment on lines +7 to +10
version: "0.1.0",
type: "action",
props: {
instantReply,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add required action annotations and initialize this new action at 0.0.1.

Line 7 uses version: "0.1.0" for a brand-new component, and there is no annotations block near Lines 8-10. Per the action/component guidelines, new components should start at 0.0.1 and actions should declare semantic hints.

Suggested patch
-  version: "0.1.0",
+  version: "0.0.1",
   type: "action",
+  annotations: {
+    openWorldHint: true,
+    readOnlyHint: true,
+    destructiveHint: false,
+  },

As per coding guidelines, new components start at 0.0.1, and components/*/actions/**/*.mjs actions must include annotations with semantically correct booleans.

📝 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
version: "0.1.0",
type: "action",
props: {
instantReply,
version: "0.0.1",
type: "action",
annotations: {
openWorldHint: true,
readOnlyHint: true,
destructiveHint: false,
},
props: {
instantReply,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/actions/get-conversation/get-conversation.mjs`
around lines 7 - 10, Update the action header: set version to "0.0.1" (it should
start at 0.0.1 for a new component) and add a required annotations block next to
the existing props block; for example add an annotations object with semantic
boolean keys such as public, system, and user (e.g., annotations: { public:
true, system: false, user: true }) so the action (referenced by the existing
props/instantReply and the get-conversation action) declares the semantic hints
expected by the component guidelines.

Source: Coding guidelines

Comment on lines +7 to +10
version: "0.1.0",
type: "action",
props: {
instantReply,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add required action annotations and initialize this new action at 0.0.1.

Line 7 sets version: "0.1.0" for a new action, and there is no annotations block near Lines 8-10. This should be corrected to match the action/component standards.

Suggested patch
-  version: "0.1.0",
+  version: "0.0.1",
   type: "action",
+  annotations: {
+    openWorldHint: true,
+    readOnlyHint: true,
+    destructiveHint: false,
+  },

As per coding guidelines, new components start at 0.0.1, and components/*/actions/**/*.mjs actions must include annotations with semantically correct booleans.

📝 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
version: "0.1.0",
type: "action",
props: {
instantReply,
version: "0.0.1",
type: "action",
annotations: {
openWorldHint: true,
readOnlyHint: true,
destructiveHint: false,
},
props: {
instantReply,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/actions/list-conversations/list-conversations.mjs`
around lines 7 - 10, Update the action metadata: change the version string from
"0.1.0" to "0.0.1" and add a top-level annotations object (next to
version/type/props) with the required boolean flags for this action (e.g.,
annotations: { /* semantic booleans */ }). Modify the file's header where the
symbols version and props (and the action definition in
components/instant_reply/actions/list-conversations/list-conversations.mjs) are
declared so the new annotations block is present and populated with semantically
correct boolean values.

Source: Coding guidelines

Comment on lines +7 to +10
version: "0.1.0",
type: "action",
props: {
instantReply,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add required action annotations and initialize this new action at 0.0.1.

Line 7 currently starts this new action at 0.1.0, and there is no annotations block near Lines 8-10. Both should be updated to align with required action metadata/versioning conventions.

Suggested patch
-  version: "0.1.0",
+  version: "0.0.1",
   type: "action",
+  annotations: {
+    openWorldHint: true,
+    readOnlyHint: false,
+    destructiveHint: false,
+  },

As per coding guidelines, new components start at 0.0.1, and components/*/actions/**/*.mjs actions must include annotations with semantically correct booleans.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/actions/send-campaign/send-campaign.mjs` around
lines 7 - 10, The action's metadata uses version "0.1.0" and is missing the
required annotations block; change the version field in this module to "0.0.1"
and add an annotations property next to props (near the instantReply prop)
containing the required boolean flags (use the semantically correct booleans for
this action per project conventions) so the action follows the
components/*/actions/** metadata conventions.

Source: Coding guidelines

Comment on lines +7 to +10
version: "0.1.0",
type: "action",
props: {
instantReply,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add required action annotations and initialize this new action at 0.0.1.

Line 7 sets 0.1.0 for a new component, and annotations are missing near Lines 8-10. This action should include semantic hint annotations and start at 0.0.1.

Suggested patch
-  version: "0.1.0",
+  version: "0.0.1",
   type: "action",
+  annotations: {
+    openWorldHint: true,
+    readOnlyHint: false,
+    destructiveHint: false,
+  },

As per coding guidelines, new components start at 0.0.1, and components/*/actions/**/*.mjs actions must include annotations with semantically correct booleans.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/actions/trigger-journey/trigger-journey.mjs` around
lines 7 - 10, The component's metadata must be initialized as a new action:
change the version from "0.1.0" to "0.0.1" and add an annotations object
alongside props (near the block containing props: { instantReply, }) that
includes the required semantic boolean flags (e.g., public, ui, or other
project-standard booleans) to declare this action's semantics; update the
top-level object where version/type/props are defined (the same block in
trigger-journey.mjs) to include annotations with correct booleans and the
downgraded version.

Source: Coding guidelines

Comment on lines +16 to +27
triggerName: {
type: "string",
label: "Journey Trigger Name",
description: "The stable slug you configured on the journey (e.g. 'new_signup', 'trial_expired'). Either this or Journey ID is required.",
optional: true,
},
journeyId: {
type: "string",
label: "Journey ID",
description: "UUID of the WhatsApp journey. Use Trigger Name instead if you want a stable identifier that doesn't change when you recreate journeys.",
optional: true,
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate triggerName/journeyId before the API call.

Both props are optional, but Line 19 says one is required. Add a pre-call guard so invalid input fails fast with a clear configuration error instead of an opaque downstream API failure.

Suggested patch
   async run({ $ }) {
+    if (!this.triggerName && !this.journeyId) {
+      throw new Error("Provide either Journey Trigger Name or Journey ID.");
+    }
+
     const response = await this.instantReply._makeRequest({
       $,
       method: "POST",

As per coding guidelines, pre-call validation is the right place to handle user configuration mistakes for actions.

Also applies to: 41-53

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/actions/trigger-journey/trigger-journey.mjs` around
lines 16 - 27, Add a pre-call guard that validates the action inputs so either
triggerName or journeyId is provided (and non-empty) before calling the
downstream API: locate where the action reads props triggerName and journeyId
(the handler that performs the API call around the section using these
variables) and add a check that throws/returns a clear configuration error like
"Either triggerName or journeyId must be provided" if both are missing; apply
the same guard before the other API call block referenced in the comment (the
second block around lines 41–53) so invalid input fails fast with a descriptive
error instead of letting the request proceed.

Source: Coding guidelines

key: "instant_reply-campaign-completed",
name: "Campaign Completed",
description: "Emit an event each time a broadcast campaign finishes sending. Use this to trigger post-campaign reports, CRM updates, or follow-up sequences.",
version: "0.1.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Set the initial version to 0.0.1 for a new source component.

Line 7 uses 0.1.0, but this is a newly added component and should start at 0.0.1.

Suggested fix
-  version: "0.1.0",
+  version: "0.0.1",

As per coding guidelines, “new components start at 0.0.1.”

📝 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
version: "0.1.0",
version: "0.0.1",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/sources/campaign-completed/campaign-completed.mjs`
at line 7, This component's manifest sets the version field to "0.1.0" but new
source components must start at "0.0.1"; update the version key (version:
"0.1.0") in campaign-completed.mjs to version: "0.0.1" so the initial release
follows the project guideline for new components.

Source: Coding guidelines

export default {
key: "instant_reply-new-comment",
name: "New Comment Received",
description: "Emit an event each time a new comment is received on one of your Instagram or Facebook posts. Use this to trigger auto-replies, sentiment alerts, or CRM tagging workflows.",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Append the required docs link to the component description.

Line 6 needs to end with [See the documentation](https://...).

Suggested fix
-  description: "Emit an event each time a new comment is received on one of your Instagram or Facebook posts. Use this to trigger auto-replies, sentiment alerts, or CRM tagging workflows.",
+  description: "Emit an event each time a new comment is received on one of your Instagram or Facebook posts. Use this to trigger auto-replies, sentiment alerts, or CRM tagging workflows. [See the documentation](https://www.instantreply.co/docs)",

As per coding guidelines, component description must end with [See the documentation](https://...).

📝 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
description: "Emit an event each time a new comment is received on one of your Instagram or Facebook posts. Use this to trigger auto-replies, sentiment alerts, or CRM tagging workflows.",
description: "Emit an event each time a new comment is received on one of your Instagram or Facebook posts. Use this to trigger auto-replies, sentiment alerts, or CRM tagging workflows. [See the documentation](https://www.instantreply.co/docs)",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/sources/new-comment/new-comment.mjs` at line 6, The
component description string (the description property in new-comment.mjs) must
be updated to append the required docs link; modify the description value so it
ends with a space followed by "[See the documentation](https://...)" (preserve
the existing sentence and punctuation), e.g., update the description property in
the module to include that exact markdown link at the end.

Source: Coding guidelines

key: "instant_reply-new-comment",
name: "New Comment Received",
description: "Emit an event each time a new comment is received on one of your Instagram or Facebook posts. Use this to trigger auto-replies, sentiment alerts, or CRM tagging workflows.",
version: "0.1.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Set the initial version to 0.0.1 for this new source.

Line 7 should start at 0.0.1 since this component is newly introduced.

Suggested fix
-  version: "0.1.0",
+  version: "0.0.1",

As per coding guidelines, “new components start at 0.0.1.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/sources/new-comment/new-comment.mjs` at line 7, The
version field currently reads "0.1.0" for the new source; update the initial
version string to "0.0.1" so the new component complies with the guideline;
locate the version property (version: "0.1.0") in new-comment.mjs and change its
value to "0.0.1" ensuring the quotes and syntax remain unchanged.

Source: Coding guidelines

Comment on lines +15 to +23
description: "Which platform to monitor for comments",
options: ["instagram", "messenger"],
optional: true,
},
sentiment: {
type: "string",
label: "Sentiment Filter",
description: "Only emit events for comments with this sentiment. Leave blank for all.",
options: ["positive", "neutral", "negative"],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Make enum prop descriptions explicit with inline examples for agent use.

Lines 15 and 22 are generic; include concrete enum examples directly in each description to improve agent reliability.

Suggested fix
-      description: "Which platform to monitor for comments",
+      description: "Platform to monitor for comment events. Example: `instagram` or `messenger`.",
@@
-      description: "Only emit events for comments with this sentiment. Leave blank for all.",
+      description: "Only emit comments matching this sentiment. Example: `positive`, `neutral`, or `negative`. Leave blank to emit all sentiments.",

As per coding guidelines, prop descriptions should be agent-friendly and include concrete inline examples for enums.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/sources/new-comment/new-comment.mjs` around lines 15
- 23, The property descriptions for the enum props platform and sentiment are
too generic; update the description text for the platform property and the
sentiment property so they include inline concrete examples matching their
options (e.g., platform: "Which platform to monitor for comments, e.g.
'instagram' or 'messenger'." and sentiment: "Only emit events for comments with
this sentiment, e.g. 'positive', 'neutral', or 'negative' — leave blank for
all."). Edit the description strings for the platform and sentiment fields in
the configuration object so the examples are explicit and match the options
arrays.

Source: Coding guidelines

Comment on lines +64 to +70
for (const event of events) {
if (this.sentiment && event.sentiment !== this.sentiment) continue;
const ts = Date.parse(event.created_at);
if (ts > lastTs) {
this.$emit(event, this.generateMeta(event));
if (ts > newLastTs) newLastTs = ts;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Advance checkpoint even for sentiment-filtered events.

Line 65 short-circuits before timestamp handling, so skipped events don’t move newLastTs. This can cause repeated polling of the same events and starvation of older matching events behind the limit window.

Suggested fix
     for (const event of events) {
-      if (this.sentiment && event.sentiment !== this.sentiment) continue;
       const ts = Date.parse(event.created_at);
-      if (ts > lastTs) {
-        this.$emit(event, this.generateMeta(event));
-        if (ts > newLastTs) newLastTs = ts;
-      }
+      if (ts > newLastTs) newLastTs = ts;
+      if (ts <= lastTs) continue;
+      if (this.sentiment && event.sentiment !== this.sentiment) continue;
+      this.$emit(event, this.generateMeta(event));
     }

Based on learnings, checkpoint/cursor state should be updated for both emitted and non-emitted items to avoid replay; as per coding guidelines, polling sources should store cursor state to prevent re-emitting old events.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@components/instant_reply/sources/new-comment/new-comment.mjs` around lines 64
- 70, The loop currently short-circuits on sentiment (this.sentiment) before
handling timestamps so filtered events never advance newLastTs; move the
timestamp parsing/ts logic ahead of the sentiment check and always update
newLastTs when ts > lastTs (e.g. newLastTs = Math.max(newLastTs, ts)), then
conditionally call this.$emit(event, this.generateMeta(event)) only if the
sentiment matches; reference the for (const event of events) loop,
this.sentiment, event.sentiment, ts, newLastTs, lastTs, this.$emit and
generateMeta when making the change.

Sources: Coding guidelines, Learnings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

User submitted Submitted by a user

Projects

Status: Ready for PR Review

Development

Successfully merging this pull request may close these issues.

4 participants