Skip to content

LoopMessage New gen API update;#20459

Merged
michelle0927 merged 12 commits intoPipedreamHQ:masterfrom
Deliany:loopmessage-new-gen-api
Apr 16, 2026
Merged

LoopMessage New gen API update;#20459
michelle0927 merged 12 commits intoPipedreamHQ:masterfrom
Deliany:loopmessage-new-gen-api

Conversation

@Deliany
Copy link
Copy Markdown
Contributor

@Deliany Deliany commented Apr 1, 2026

WHY

LoopMessage released a new generation API update that required significant changes.

Summary by CodeRabbit

  • New Features

    • Check Message Status action
    • Show Typing Indicator action
    • New Inbound Message source (webhook)
    • Send Voice Message action
  • Improvements

    • Expanded Send Outbound Message and Send Reaction capabilities
    • Authentication moved to secret API key and unified endpoints
    • Added WhatsApp and RCS channel support
    • Corrected reaction naming to "exclaim"
  • Chores

    • Removed unused stream helper
    • Updated package keywords (imessage, blue)
  • Documentation

    • README updated with omnichannel framing and AI assistant example

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 1, 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 Apr 16, 2026 6:15pm

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 Apr 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds multiple new LoopMessage actions and a new HTTP inbound source, refactors send actions to explicit run methods and props, changes app auth/endpoint/request logic and adds API methods, updates constants/utils, adjusts an existing source and package metadata.

Changes

Cohort / File(s) Summary
New Actions (status & typing)
components/loopmessage/actions/check_message_status/check_message_status.mjs, components/loopmessage/actions/typing-indicator/typing_indicator.mjs
Added "Check Message Status" and "Show Typing Indicator" actions. Both declare app and messageId props, implement getSummary(...), and async run({ $: step }) calling new app methods and exporting "$summary".
New Send Voice Action
components/loopmessage/actions/send-voice-message/send-voice-message.mjs
Added "Send Voice Message" action with props (contact, sender, mediaUrl, passthrough), getSummary(...), and async run() that calls app.sendMessage and exports "$summary".
Refactored Send Actions
components/loopmessage/actions/send-reaction/send-reaction.mjs, components/loopmessage/actions/send-text-message/send-text-message.mjs
Removed spread of shared common; now explicitly import/use app and utils. Updated metadata, bumped versions to 0.0.4, replaced props with explicit contact, sender, attachments, replyToId, passthrough, channel, etc., updated getSummary(...), and added async run() to call app methods and export "$summary".
App Module & API Methods
components/loopmessage/loopmessage.app.mjs
Switched to custom auth using api_key (Authorization header). Simplified URL/request logic (removed API placeholder), changed propDefinitions (recipientcontact, added sender, messageId, channel, mediaUrl, passthrough, etc.), refactored makeRequest, removed singleLookup, changed sendMessage endpoint, and added methods: delete, updatePipedreamWebhook, deactivatePipedreamWebhook, sendReaction, sendTyping, getMessageStatus.
Constants & Utilities
components/loopmessage/common/constants.mjs, components/loopmessage/common/utils.mjs
Set BASE_URL to "https://pipedream-api.loopmessage.com", added "whatsapp" and "rcs" to SERVICES, corrected REACTIONS entries (exlaimexclaim), removed API/API_PLACEHOLDER; removed streamIterator from utils default export, leaving keysToSnakeCase.
Sources & Metadata
components/loopmessage/sources/new-inbound-message/new-inbound-message.mjs, components/loopmessage/sources/new-alert-received/new-alert-received.mjs, components/loopmessage/package.json
Added new HTTP source new-inbound-message with webhook activate/deactivate hooks and HTTP respond behavior; updated new-alert-received to generic inbound semantics and removed db/alertType props and adjusted emitted id/summary/ts fallbacks; added imessage and blue keywords to package.json.
Docs
components/loopmessage/README.md
Updated overview wording to omnichannel framing and added a "Building AI Assistants" example use case.

Sequence Diagram(s)

sequenceDiagram
  participant Action as Action Runtime
  participant App as loopmessage.app
  participant API as External API
  participant Source as HTTP Source

  Note right of Action: send/sendReaction/sendTyping/checkStatus
  Action->>App: call sendMessage/sendReaction/sendTyping/getMessageStatus(step, data)
  App->>API: HTTP request to /integrations/pipedream/...
  API-->>App: HTTP response (status, message_id, ...)
  App-->>Action: return response
  Action->>Action: step.export("$summary", getSummary(response))
  Action-->>Caller: return response

  Note over Source,App: webhook registration flow
  Source->>App: updatePipedreamWebhook(endpoint) / deactivatePipedreamWebhook(endpoint)
  App->>API: POST/DELETE webhook endpoint
  API-->>App: confirmation
  App-->>Source: return
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'LoopMessage New gen API update' is vague and generic, using non-descriptive terms that don't convey specific details about the changeset. Provide a more specific title that highlights the primary change, such as 'Refactor LoopMessage integration for new generation API' or 'Update LoopMessage component to support new API endpoints'.
Description check ❓ Inconclusive The pull request description is minimal and only partially addresses the required template with a brief explanation under the WHY section. Expand the description to explain what changed, why it was necessary, and impact on the integration. The template requires more detail than currently provided.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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: 10

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

Inline comments:
In
`@components/loopmessage/actions/check_message_status/check_message_status.mjs`:
- Around line 10-14: The annotations object in check_message_status.mjs
incorrectly sets readOnlyHint to false; update the annotations block (the
annotations object that contains destructiveHint, openWorldHint, readOnlyHint)
so that readOnlyHint: true to accurately indicate this action is read-only (it
only performs a GET to retrieve message status).

In `@components/loopmessage/actions/send-reaction/send-reaction.mjs`:
- Around line 37-39: The getSummary function currently declares an unused
parameter `response`; remove the unused parameter by changing the signature to
getSummary() and update any local callers in this module that pass an argument
to call getSummary() without arguments (search for references to getSummary in
send-reaction.mjs); alternatively, if you prefer a more informative message, use
properties from the `response` object inside getSummary (e.g., response.status
or response.data) and include them in the returned string — but be sure to
update all call sites accordingly to pass the response when chosen.

In `@components/loopmessage/actions/send-text-message/send-text-message.mjs`:
- Around line 48-53: The attachments prop is defined inline in
send-text-message.mjs while other props use propDefinition from the app; move
the attachments definition into loopmessage.app.mjs as a reusable prop (e.g.,
export a propDefinition named attachments) and update send-text-message.mjs to
reference it via propDefinition: [app].attachments so other actions can reuse
the same schema and descriptions.

In `@components/loopmessage/actions/send-voice-message/send-voice-message.mjs`:
- Line 7: The description string in send-voice-message.mjs contains a typo:
update the exported description property (the "description" field in the
module/object for send-voice-message) from "Send s voice memo. Supports only in:
iMessage, RCS, WhatsApp." to "Send a voice memo. Supports only in: iMessage,
RCS, WhatsApp." so the wording is correct.

In `@components/loopmessage/actions/typing-indicator/typing_indicator.mjs`:
- Around line 4-43: The file uses 4-space indentation; update the export
object's formatting to use the project's 2-space style for consistency by
reformatting the default exported object (including keys: key, name,
description, type, version, annotations, props, methods, getSummary, and the
async run method) and nested blocks (the props.messageId.propDefinition,
methods.getSummary, and run destructuring and await call) to 2-space indentation
throughout so it matches other action files like send-reaction and
send-text-message.
- Around line 25-27: getSummary currently has no parameter but is invoked with a
response elsewhere and its returned string lacks the trailing period; update the
getSummary signature to accept the response parameter (e.g.,
getSummary(response)) and change the returned text to "Request accepted." so it
matches other actions like send-reaction.mjs and avoids a signature mismatch
when called with a response.

In `@components/loopmessage/loopmessage.app.mjs`:
- Line 71: The description string for the field named description contains a
stray Cyrillic "о" at the end; remove that trailing Cyrillic character so the
value ends with the intended punctuation/English text (update the description
property in loopmessage.app.mjs where the description string is defined).
- Line 58: The description string currently contains a duplicated "Optional.
Optional."; update the description for the relevant parameter/object in
loopmessage.app.mjs (the property named description) to remove the duplicate so
it reads e.g. "Optional. Add effect to your message. For iMessage only."
ensuring only a single "Optional." appears.
- Around line 107-115: The makeRequest method has inconsistent leading spaces;
reformat its declaration and body to use 2-space indentation like the rest of
the file: align the parameter destructuring (step = this, path, headers, ...args
= {}) and the return axios call so properties (headers:
this.getHeaders(headers), url: this.getUrl(path), ...args) are indented two
spaces per level; ensure references to makeRequest, axios, this.getHeaders and
this.getUrl remain unchanged but have consistent 2-space indentation.

In `@components/loopmessage/sources/new-alert-received/new-alert-received.mjs`:
- Around line 18-24: The fallback id using Date.now().toString() in the
this.$emit call (id: body.webhook_id || body.message_id ||
Date.now().toString()) is unsafe for dedupe="unique"; confirm whether
LoopMessage always supplies webhook_id or message_id, and if not replace the
Date.now() fallback with a robust deterministic fallback (e.g., compute a hash
of the entire body payload or JSON.stringify(body) to derive the id) so retries
and concurrent events produce stable, unique ids for deduplication.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a3739481-e1d1-4537-b37a-1271d6bf60fa

📥 Commits

Reviewing files that changed from the base of the PR and between bd6602f and e255a5c.

📒 Files selected for processing (10)
  • components/loopmessage/actions/check_message_status/check_message_status.mjs
  • components/loopmessage/actions/send-reaction/send-reaction.mjs
  • components/loopmessage/actions/send-text-message/send-text-message.mjs
  • components/loopmessage/actions/send-voice-message/send-voice-message.mjs
  • components/loopmessage/actions/typing-indicator/typing_indicator.mjs
  • components/loopmessage/common/constants.mjs
  • components/loopmessage/common/utils.mjs
  • components/loopmessage/loopmessage.app.mjs
  • components/loopmessage/package.json
  • components/loopmessage/sources/new-alert-received/new-alert-received.mjs
💤 Files with no reviewable changes (1)
  • components/loopmessage/common/utils.mjs

Comment thread components/loopmessage/actions/check_message_status/check_message_status.mjs Outdated
Comment thread components/loopmessage/actions/send-reaction/send-reaction.mjs
Comment thread components/loopmessage/actions/send-voice-message/send-voice-message.mjs Outdated
Comment thread components/loopmessage/actions/typing-indicator/typing_indicator.mjs Outdated
Comment thread components/loopmessage/actions/typing-indicator/typing_indicator.mjs Outdated
Comment thread components/loopmessage/loopmessage.app.mjs Outdated
Comment thread components/loopmessage/loopmessage.app.mjs Outdated
Comment thread components/loopmessage/loopmessage.app.mjs
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: 4

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

Inline comments:
In `@components/loopmessage/actions/send-reaction/send-reaction.mjs`:
- Around line 37-38: The getSummary(response) method currently returns a
template string that mistakenly includes a duplicated "ID" token; update
getSummary to return something like `Request accepted. Message ID:
\`${response.message_id}\`` (i.e., remove the extra "ID" before the backticked
message_id) so the step output reads "Message ID: <id>" instead of "Message ID:
ID <id>".

In `@components/loopmessage/actions/send-voice-message/send-voice-message.mjs`:
- Around line 23-28: The action currently defines a senderName prop that ends up
serialized (via utils.keysToSnakeCase) as sender_name and is sent in voice
requests, but the voice API ignores/renamed this field; remove the senderName
prop (and the duplicate occurrence at the later block) from the action's props
so it is not included in the request payload, or if you must keep it for UI
only, ensure it is not part of the object passed into utils.keysToSnakeCase/send
payload; update the send-voice-message action to reference no senderName
property (check the senderName prop definitions and any usages in
sendVoiceMessage/sendVoiceRequest) and remove those keys from the payload
construction.

In `@components/loopmessage/loopmessage.app.mjs`:
- Around line 68-72: The description for the passthrough config option
incorrectly says "store with the checkout" and is misleading; update the
passthrough property's description (property name: passthrough) to refer to
storing arbitrary metadata with the outbound message (or webhook payload)
instead of a checkout, e.g., "Optional. An arbitrary string of metadata to
attach to the outbound message; it will be included with all webhooks for this
message. Max length: 1000 characters." Make this change in the passthrough
object so the copy accurately reflects message metadata usage.
- Around line 7-21: The auth schema nests api_key under auth.props.auth.props,
but getHeaders() reads this.$auth.api_key; remove the extra nesting so the
config exposes api_key at auth.props.api_key (i.e., eliminate the inner "auth"
object) so that this.$auth.api_key resolves correctly; update the auth
declaration where api_key is defined and verify getHeaders() continues to
reference this.$auth.api_key.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5814de26-9021-4464-aa8f-0d6053b31ef5

📥 Commits

Reviewing files that changed from the base of the PR and between e255a5c and 20386ac.

📒 Files selected for processing (6)
  • components/loopmessage/actions/check_message_status/check_message_status.mjs
  • components/loopmessage/actions/send-reaction/send-reaction.mjs
  • components/loopmessage/actions/send-voice-message/send-voice-message.mjs
  • components/loopmessage/actions/typing-indicator/typing_indicator.mjs
  • components/loopmessage/loopmessage.app.mjs
  • components/loopmessage/sources/new-inbound-message/new-inbound-message.mjs

Comment thread components/loopmessage/actions/send-reaction/send-reaction.mjs Outdated
Comment thread components/loopmessage/actions/send-voice-message/send-voice-message.mjs Outdated
Comment thread components/loopmessage/loopmessage.app.mjs Outdated
Comment thread components/loopmessage/loopmessage.app.mjs Outdated
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: 1

♻️ Duplicate comments (3)
components/loopmessage/loopmessage.app.mjs (2)

69-73: ⚠️ Potential issue | 🟡 Minor

Fix the passthrough description copy.

The description still says “store with the checkout”, which misdescribes what this field does.

Suggested fix
     passthrough: {
       type: "string",
       label: "Passthrough",
-      description: "Optional. A string of metadata you wish to store with the checkout. Will be sent alongside all webhooks associated with the outbound message. Max length: 1000 characters.",
+      description: "Optional. A string of metadata you wish to store with the outbound message. It will be sent alongside all related webhooks. Max length: 1000 characters.",
       optional: true,
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/loopmessage/loopmessage.app.mjs` around lines 69 - 73, Update the
passthrough field description to remove the incorrect reference to "checkout"
and accurately describe its purpose: state that it's optional metadata stored
with the outbound message and sent with all webhooks for that message, and keep
the Max length: 1000 characters; modify the description string on the
passthrough property (the passthrough schema entry) accordingly.

7-21: ⚠️ Potential issue | 🔴 Critical

Flatten the custom auth schema or fix the access path.

Line 104 reads this.$auth.api_key, but the schema nests api_key under auth.props.auth.props. As written, the Authorization header will be undefined, so outbound requests will fail authentication.

Suggested fix
   auth: {
     type: "custom",
     props: {
-      auth: {
-        type: "custom",
-        props: {
-          api_key: {
-            type: "string",
-            label: "Authorization",
-            secret: true,
-          },
-        },
-      },
+      api_key: {
+        type: "string",
+        label: "Authorization",
+        secret: true,
+      },
     },
   },
#!/bin/bash
# Compare the declared auth shape with the runtime access path.
sed -n '7,21p' components/loopmessage/loopmessage.app.mjs
sed -n '101,105p' components/loopmessage/loopmessage.app.mjs

# Check whether any other app file nests a second custom-auth block under app auth.
rg -nUP --glob '*.app.mjs' 'auth:\s*\{\s*type:\s*"custom",\s*props:\s*\{\s*auth:\s*\{\s*type:\s*"custom"' components

Expected: the first two snippets show the mismatch directly, and the repo search should ideally only hit this file.

Also applies to: 101-105

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/loopmessage/loopmessage.app.mjs` around lines 7 - 21, The auth
schema currently nests api_key under auth.props.auth.props but the code reads
this.$auth.api_key; fix by flattening the declared auth schema to expose api_key
at this.$auth.api_key or update runtime access to match the nested shape (e.g.,
read this.$auth.auth.api_key); update the object under auth in the top-level app
definition (the block with type:"custom" and props:{ auth: { type:"custom",
props:{ api_key:... }}}) so api_key is directly under props, or change uses of
this.$auth.api_key in the file to the nested path (this.$auth.auth.api_key)
wherever referenced.
components/loopmessage/sources/new-inbound-message/new-inbound-message.mjs (1)

9-9: ⚠️ Potential issue | 🟠 Major

Make the emitted event metadata deterministic.

With dedupe: "unique", id becomes undefined when both webhook_id and message_id are absent, and Date.parse(body.created_at) returns NaN for malformed timestamps. That makes deduplication and event ordering unstable.

Suggested fix
+import { createHash } from "node:crypto";
 import app from "../../loopmessage.app.mjs";
@@
   async run({ body }) {
+    const parsedCreatedAt = body.created_at
+      ? Date.parse(body.created_at)
+      : NaN;
+    const eventId = body.webhook_id
+      ?? body.message_id
+      ?? createHash("sha256")
+        .update(JSON.stringify(body))
+        .digest("hex");
+
     this.$emit(body, {
-      id: body.webhook_id || body.message_id,
+      id: eventId,
       summary: body.contact
         ? `New inbound message from ${body.contact}`
         : "New inbound received",
-      ts: body.created_at
-        ? Date.parse(body.created_at)
-        : Date.now(),
+      ts: Number.isNaN(parsedCreatedAt)
+        ? Date.now()
+        : parsedCreatedAt,
     });

Also applies to: 25-33

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/loopmessage/sources/new-inbound-message/new-inbound-message.mjs`
at line 9, The emitted event metadata is non-deterministic: when dedupe is
"unique" the id can be undefined if webhook_id and message_id are missing and
Date.parse(body.created_at) can be NaN for malformed timestamps; update the
metadata construction (the places using dedupe: "unique", the id field and
Date.parse(body.created_at) — also adjust the same logic around the 25-33 range)
to produce deterministic values by: 1) setting id to a stable fallback when
webhook_id and message_id are absent (e.g., derive a deterministic hash from the
payload/headers or a canonical string of body fields), and 2) normalizing the
timestamp so Date.parse(body.created_at) is validated and falls back to a safe
numeric value (e.g., Date.now() or 0) when parsing fails; apply these fixes to
all occurrences that build the emitted event metadata.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/loopmessage/loopmessage.app.mjs`:
- Around line 165-168: The getMessageStatus function interpolates raw messageId
into the URL path, which can break the route if messageId contains characters
like /, ?, or #; fix by URL-encoding messageId before building the path (e.g.,
call encodeURIComponent on messageId) so the path passed to makeRequest remains
valid and safe when constructing
`/integrations/pipedream/message/status/{encodedId}/`; update getMessageStatus
to use the encoded variable when calling this.makeRequest.

---

Duplicate comments:
In `@components/loopmessage/loopmessage.app.mjs`:
- Around line 69-73: Update the passthrough field description to remove the
incorrect reference to "checkout" and accurately describe its purpose: state
that it's optional metadata stored with the outbound message and sent with all
webhooks for that message, and keep the Max length: 1000 characters; modify the
description string on the passthrough property (the passthrough schema entry)
accordingly.
- Around line 7-21: The auth schema currently nests api_key under
auth.props.auth.props but the code reads this.$auth.api_key; fix by flattening
the declared auth schema to expose api_key at this.$auth.api_key or update
runtime access to match the nested shape (e.g., read this.$auth.auth.api_key);
update the object under auth in the top-level app definition (the block with
type:"custom" and props:{ auth: { type:"custom", props:{ api_key:... }}}) so
api_key is directly under props, or change uses of this.$auth.api_key in the
file to the nested path (this.$auth.auth.api_key) wherever referenced.

In `@components/loopmessage/sources/new-inbound-message/new-inbound-message.mjs`:
- Line 9: The emitted event metadata is non-deterministic: when dedupe is
"unique" the id can be undefined if webhook_id and message_id are missing and
Date.parse(body.created_at) can be NaN for malformed timestamps; update the
metadata construction (the places using dedupe: "unique", the id field and
Date.parse(body.created_at) — also adjust the same logic around the 25-33 range)
to produce deterministic values by: 1) setting id to a stable fallback when
webhook_id and message_id are absent (e.g., derive a deterministic hash from the
payload/headers or a canonical string of body fields), and 2) normalizing the
timestamp so Date.parse(body.created_at) is validated and falls back to a safe
numeric value (e.g., Date.now() or 0) when parsing fails; apply these fixes to
all occurrences that build the emitted event metadata.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 851bd036-16b9-43e0-9b13-ea509b67e762

📥 Commits

Reviewing files that changed from the base of the PR and between 20386ac and fcdc485.

📒 Files selected for processing (2)
  • components/loopmessage/loopmessage.app.mjs
  • components/loopmessage/sources/new-inbound-message/new-inbound-message.mjs

Comment thread components/loopmessage/loopmessage.app.mjs
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: 1

♻️ Duplicate comments (1)
components/loopmessage/loopmessage.app.mjs (1)

160-164: ⚠️ Potential issue | 🟡 Minor

Encode messageId before building the status URL.

Line 163 still interpolates raw messageId into the path. If the ID contains /, ?, or #, the request can hit the wrong route or fail unexpectedly.

Suggested fix
     getMessageStatus(messageId, args = {}) {
+      const encodedMessageId = encodeURIComponent(messageId);
       return this.makeRequest({
         method: "get",
-        path: `/integrations/pipedream/message/status/${messageId}/`,
+        path: `/integrations/pipedream/message/status/${encodedMessageId}/`,
         ...args,
       });
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/loopmessage/loopmessage.app.mjs` around lines 160 - 164,
getMessageStatus currently interpolates raw messageId into the request path
which can break routes if the ID contains reserved characters; update the path
construction in getMessageStatus to encode the ID (use
encodeURIComponent(messageId)) before interpolation so the URL is safe, i.e.,
replace direct ${messageId} usage in the path argument of makeRequest with an
encoded version to ensure correct routing and avoid request failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/loopmessage/loopmessage.app.mjs`:
- Around line 71-75: The shared prop definition for mediaUrl wrongly marks the
audio URL optional; remove the `optional: true` property from the mediaUrl
shared prop in loopmessage.app.mjs so the field becomes required, and verify
that the action reusing this prop (send-voice-message.mjs) does not override it
back to optional (ensure send-voice-message uses the shared mediaUrl prop
as-is). This ensures send-voice-message.mjs cannot be configured without a media
URL.

---

Duplicate comments:
In `@components/loopmessage/loopmessage.app.mjs`:
- Around line 160-164: getMessageStatus currently interpolates raw messageId
into the request path which can break routes if the ID contains reserved
characters; update the path construction in getMessageStatus to encode the ID
(use encodeURIComponent(messageId)) before interpolation so the URL is safe,
i.e., replace direct ${messageId} usage in the path argument of makeRequest with
an encoded version to ensure correct routing and avoid request failures.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 548ae231-d851-496d-8b13-a6268e7b6469

📥 Commits

Reviewing files that changed from the base of the PR and between fcdc485 and 4777057.

📒 Files selected for processing (5)
  • components/loopmessage/actions/send-reaction/send-reaction.mjs
  • components/loopmessage/actions/send-text-message/send-text-message.mjs
  • components/loopmessage/actions/send-voice-message/send-voice-message.mjs
  • components/loopmessage/common/constants.mjs
  • components/loopmessage/loopmessage.app.mjs

Comment thread components/loopmessage/loopmessage.app.mjs Outdated
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: 1

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

Inline comments:
In `@components/loopmessage/README.md`:
- Line 3: Change the product name usage in the README from "The LoopMessage" to
"LoopMessage": locate the sentence that currently starts with "The LoopMessage
is an omnichannel..." and remove the leading article so it reads "LoopMessage is
an omnichannel..."; also scan the same README for any other occurrences of "The
LoopMessage" and replace them with "LoopMessage" for consistency.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2530b7b6-89b1-492b-af35-18cabb9a1259

📥 Commits

Reviewing files that changed from the base of the PR and between 4777057 and 7bc7ae8.

📒 Files selected for processing (1)
  • components/loopmessage/README.md

Comment thread components/loopmessage/README.md Outdated
Copy link
Copy Markdown
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

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

Thank you for your contribution! I left a few comments. Also, you'll need to update the package.json version to "0.3.0" and remove the blank line at the beginning of utils.mjs.

Comment thread components/loopmessage/actions/check_message_status/check_message_status.mjs Outdated
type: "string",
label: "Message ID",
description: "Outbound message ID.",
},
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Props should display a list of async options if possible. Could the message history endpoint be used to retrieve message IDs?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We plan to add it in a future update.

Comment thread components/loopmessage/loopmessage.app.mjs Outdated
label: "Recipient",
description: "The recipient of the message. This can be a phone number or email address.",
label: "Contact",
description: "Recipient phone number or email address.",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could async options for contact be retrieved through get audience list endpoint?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We plan to add it in a future update.

label: "Reply To ID",
description: "Optional. Reply to a message with a specific ID",
optional: true,
},
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could replyToId use async options?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We plan to add it in a future update.

@michelle0927 michelle0927 moved this from Ready for PR Review to Changes Required in Component (Source and Action) Backlog Apr 3, 2026
export default {
key: "loopmessage-check-message-status",
name: "Check Message Status",
description: "Action to get the current outbound message status. Possible values: processing, failed, delivered.",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Sorry, I missed this earlier. All actions should have doc links to the relevant documentation. Applies to all actions.

Suggested change
description: "Action to get the current outbound message status. Possible values: processing, failed, delivered.",
description: "Action to get the current outbound message status. Possible values: processing, failed, delivered. [See the documentation](<url here>)",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@michelle0927 The problem is that the documentation URLs may change over time. If we provide a link there and the page is moved, it could confuse users.

@michelle0927
Copy link
Copy Markdown
Collaborator

@Deliany, It sounds like perhaps this PR is premature? I'm getting 404 errors for endpoint that contain "/integrations/pipedream". If the API is still being developed, we should wait until it's ready before developing and releasing components for it.

@Deliany
Copy link
Copy Markdown
Contributor Author

Deliany commented Apr 11, 2026

@michelle0927 .../integrations/pipedream/... will only work if you use the HOST URL we specified for this project. We launched a separate instance with a subdomain to handle requests from Pipedream. If you try to send a request from the regular API endpoint a.loopmessage.com, it will return you a 404 error.

Copy link
Copy Markdown
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

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

These are the results I'm getting with the api key provided by the LoopMessage team.

For send-reaction, I'm getting undefined in the summary:


For send-voice-message, I'm getting undefined in the summary:

Image ---------------

For check-message-status, I'm geting a 404 error:

Image ---------------

For typing-indicator, I'm getting undefined in the summary:

Image ---------------

For send-text-message, I'm getting undefined in the summary:


For new-inbound-message, I'm unable to deploy the source:

Image

Comment thread components/loopmessage/sources/new-inbound-message/new-inbound-message.mjs Outdated
@Deliany
Copy link
Copy Markdown
Contributor Author

Deliany commented Apr 13, 2026

@michelle0927 we made some changes.
Now the code should handle unsuccessful statuses.
Also, we shared additional details with your team on how you can test it.

Copy link
Copy Markdown
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

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

Thanks @Deliany. I'm able to login and send & receive messages. Using the new api key, I'm still seeing the same results from the actions. I am able to deploy the source, new-inbound-message, but it's not receiveing any events and there's nothing under Webhooks history in the LoopMessage UI.

Image Image

@Deliany
Copy link
Copy Markdown
Contributor Author

Deliany commented Apr 13, 2026

@michelle0927 Thank you for the details!
We have already deployed the update for the Pipedream instance, and events should now register successfully for you.
Webhooks related to the Pipedream shouldn't be saved in the dashboard.

@Deliany Deliany requested a review from michelle0927 April 15, 2026 05:31
@michelle0927
Copy link
Copy Markdown
Collaborator

@Deliany Thanks, the webhook is working! However, I'm seeing a couple issues with these actions:

Check Message Status
Screenshot 2026-04-15 at 11 36 46 AM

Typing Indicator
Screenshot 2026-04-15 at 11 37 03 AM

@Deliany
Copy link
Copy Markdown
Contributor Author

Deliany commented Apr 15, 2026

@michelle0927 thank you for noticing. Our engineers have already made some changes, and now it should work for you.

Copy link
Copy Markdown
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

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

@Deliany Thank you for your work on this. This is ready for release!

@michelle0927 michelle0927 moved this from Changes Required to Ready for Release in Component (Source and Action) Backlog Apr 16, 2026
@michelle0927 michelle0927 merged commit 4dd8496 into PipedreamHQ:master Apr 16, 2026
9 checks passed
@github-project-automation github-project-automation Bot moved this from Ready for Release to Done in Component (Source and Action) Backlog Apr 16, 2026
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

Development

Successfully merging this pull request may close these issues.

6 participants