Skip to content

Shortcut - new source#19128

Merged
michelle0927 merged 4 commits intomasterfrom
issue-18593
Nov 23, 2025
Merged

Shortcut - new source#19128
michelle0927 merged 4 commits intomasterfrom
issue-18593

Conversation

@michelle0927
Copy link
Copy Markdown
Collaborator

@michelle0927 michelle0927 commented Nov 18, 2025

Resolves #18593

Summary by CodeRabbit

  • New Features

    • Webhook-based event source for real-time Shortcut notifications with filtering; test event and sample emit for onboarding.
    • Reusable Shortcut integration base and new async selectors for workflow states, labels, and stories.
    • Story creation improvements: select related stories, provide tasks as simple list, and supply comments as plain text; success summary exported after creation.
  • Bug Fixes

    • Standardized field labels and clearer, consistent field descriptions.
  • Chores

    • Bumped component/action/package versions and platform dependency.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Copy Markdown

vercel bot commented Nov 18, 2025

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

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
pipedream-docs Ignored Ignored Nov 20, 2025 5:29pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Nov 20, 2025 5:29pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 18, 2025

Walkthrough

Adds webhook-based Shortcut sources with a shared base for webhook lifecycle, a new "New Event Received" trigger with filtering and sample event, introduces async propDefinitions (workflowStateId, labelIds, storyIds), refactors create-story action to use propDefinitions and simplify props/payload, and bumps package versions/dependencies.

Changes

Cohort / File(s) Summary
App prop definitions
components/shortcut/shortcut.app.mjs
Added propDefinitions exposing three async props: workflowStateId, labelIds, and storyIds — each populates options via Shortcut API calls (workflows→states, labels, and paginated story search).
Create-story action
components/shortcut/actions/create-story/create-story.mjs
Version bumped 1.0.11.0.2. Replaced inline async workflowStateId options with propDefinition: [shortcut, "workflowStateId"]. comment changed from object→string (mapped to { text }). Added storyIds prop (propDefinition) and tasks as string[]; payload now maps storyIdsstory_links and taskstasks. run signature updated to async run({ $ }) and adds $.export("$summary", ...). Multiple prop descriptions/capitalization standardized.
Search-stories action
components/shortcut/actions/search-stories/search-stories.mjs
Version bumped 1.0.11.0.2. No functional changes.
Package metadata
components/shortcut/package.json
Package version bumped 1.0.01.1.0. Added dependency @pipedream/platform: "^3.1.1".
Source base module
components/shortcut/sources/common/base.mjs
New reusable base source exporting props (shortcut, db, http), lifecycle hooks activate/deactivate to create/delete webhooks and persist hookId, helpers for base URL/headers, createWebhook/deleteWebhook, processEvent() placeholder (throws), and run() that validates webhook body, responds 200, then calls processEvent.
New event source
components/shortcut/sources/new-event-received/new-event-received.mjs
New source extending base: defines key/name/version/type/dedupe, props for filtering (issueType, name, workflowStateIds, labelIds), generateMeta() to build summary, processEvent() to filter incoming events, resolve issues via searchStories/searchEpics, apply workflow/label filters, and emit events. Includes sampleEmit.
Test event payload
components/shortcut/sources/new-event-received/test-event.mjs
New sample event module exporting a representative Shortcut webhook payload and related issue data for testing/emulation.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Pipedream
    participant DB as Database
    participant Shortcut as Shortcut API

    rect rgba(200,220,240,0.5)
    Note over Pipedream,DB: Source Activation
    User->>Pipedream: Activate source
    Pipedream->>Shortcut: POST /integrations/webhook (webhook_url)
    Shortcut-->>Pipedream: { hookId }
    Pipedream->>DB: Store hookId
    end

    rect rgba(240,240,200,0.5)
    Note over Shortcut,Pipedream: Event Delivery & Processing
    Shortcut->>Pipedream: POST webhook (event body)
    activate Pipedream
    Pipedream->>Pipedream: Validate body → respond 200
    Pipedream->>Pipedream: processEvent(body) — filter by issueType/name
    Pipedream->>Shortcut: GET searchStories or searchEpics (resolve issue)
    Shortcut-->>Pipedream: Return issue
    Pipedream->>Pipedream: Apply workflow/label filters
    Pipedream->>Pipedream: Emit event (body + resolved issue)
    deactivate Pipedream
    end

    rect rgba(240,200,220,0.5)
    Note over Pipedream,DB: Source Deactivation
    User->>Pipedream: Deactivate source
    Pipedream->>DB: Retrieve hookId
    Pipedream->>Shortcut: DELETE /integrations/webhook/{hookId}
    Shortcut-->>Pipedream: Success
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay special attention to:
    • components/shortcut/sources/common/base.mjs: webhook creation/deletion, DB persistence, headers/auth, error handling around processEvent and run().
    • components/shortcut/sources/new-event-received/new-event-received.mjs: filtering logic, correct choice between stories vs epics API, and emitted event shape.
    • components/shortcut/shortcut.app.mjs: correctness of async options pagination and filtering (workflows → states).
    • components/shortcut/actions/create-story/create-story.mjs: mapping changes for comment{ text }, storyIdsstory_links, taskstasks, and run({ $ }) plus the new summary export.

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR implements triggers with filtering by issue type, name, workflow state IDs, and label IDs; however, 'Status' filtering is missing from the implementation. Add status/workflow state filtering as a public prop for users to filter events by status, aligning with issue #18593 requirements.
Out of Scope Changes check ⚠️ Warning The PR includes version bumps and refactoring of the create-story action alongside the new source implementation, potentially introducing unrelated scope creep. Consider separating the create-story action updates into a separate PR to keep this PR focused on adding the new Shortcut source.
Description check ❓ Inconclusive The PR description is minimal and only contains 'Resolves #18593' without substantive details matching the template structure. Add a 'WHY' section explaining the rationale for these changes and how they address the linked issue's requirements.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Shortcut - new source' directly describes the main change in the PR, which adds a new event source for Shortcut.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch issue-18593

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: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b616f42 and 9081095.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • components/shortcut/actions/create-story/create-story.mjs (11 hunks)
  • components/shortcut/actions/search-stories/search-stories.mjs (1 hunks)
  • components/shortcut/package.json (2 hunks)
  • components/shortcut/shortcut.app.mjs (1 hunks)
  • components/shortcut/sources/common/base.mjs (1 hunks)
  • components/shortcut/sources/new-event-received/new-event-received.mjs (1 hunks)
  • components/shortcut/sources/new-event-received/test-event.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-10-20T01:01:02.970Z
Learnt from: js07
Repo: PipedreamHQ/pipedream PR: 18744
File: components/slack_v2/actions/send-large-message/send-large-message.mjs:49-64
Timestamp: 2025-10-20T01:01:02.970Z
Learning: In components/slack_v2/actions/send-large-message/send-large-message.mjs, the metadata_event_payload prop is typed as string, so the code only needs to handle string-to-JSON parsing and does not need to handle object inputs.

Applied to files:

  • components/shortcut/sources/new-event-received/test-event.mjs
📚 Learning: 2024-10-08T15:33:38.240Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12697
File: components/salesforce_rest_api/sources/common-webhook-methods.mjs:1-71
Timestamp: 2024-10-08T15:33:38.240Z
Learning: The `common-webhook-methods.mjs` object is designed to be extended, similar to an abstract class, and intentionally does not implement certain methods like `generateWebhookMeta` and `getEventType` to enforce implementation in subclasses.

Applied to files:

  • components/shortcut/sources/common/base.mjs
  • components/shortcut/sources/new-event-received/new-event-received.mjs
📚 Learning: 2025-01-23T03:55:15.166Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 15376
File: components/monday/sources/name-updated/name-updated.mjs:6-6
Timestamp: 2025-01-23T03:55:15.166Z
Learning: Source names in Monday.com components don't need to start with "New" if they emit events for updated items (e.g., "Name Updated", "Column Value Updated") rather than new items. This follows the component guidelines exception where the "New" prefix is only required when emits are limited to new items.

Applied to files:

  • components/shortcut/sources/new-event-received/new-event-received.mjs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
  • GitHub Check: pnpm publish
  • GitHub Check: Lint Code Base
🔇 Additional comments (7)
components/shortcut/package.json (1)

3-18: Version bump and new platform dependency look consistent

The 1.1.0 version and the addition of @pipedream/platform align with the new shared base source that relies on platform utilities, so this metadata change looks correct.

Please confirm ^3.1.1 matches the version used by other newer components in this repo to avoid subtle runtime differences.

components/shortcut/sources/new-event-received/test-event.mjs (1)

1-99: Sample event payload aligns with source expectations

The exported { body, issue } shape and fields (e.g., body.actions[0].entity_type, body.actions[0].id, body.changed_at, issue.workflow_state_id, issue.label_ids) line up with how the source processes and emits events, so this is a good representative test payload.

components/shortcut/sources/common/base.mjs (1)

6-79: Webhook lifecycle + run pattern look solid for an abstract base

The base source cleanly encapsulates webhook create/delete using the stored hookId, and run correctly responds 200 before delegating to processEvent, which child sources are expected to implement. This aligns well with the abstract “common webhook methods” pattern used in other integrations.

Based on learnings

components/shortcut/actions/search-stories/search-stories.mjs (1)

7-7: Version bump is consistent with surrounding Shortcut updates

Updating the action version to 1.0.2 to accompany the broader Shortcut integration changes looks appropriate; behavior is unchanged and metadata stays in sync with the package.

components/shortcut/shortcut.app.mjs (1)

44-52: LGTM!

The labelIds implementation is clean and handles empty data gracefully with destructuring defaults.

components/shortcut/actions/create-story/create-story.mjs (2)

20-24: Excellent refactor to eliminate duplication.

Moving workflowStateId to a shared propDefinition improves maintainability and consistency across actions.


29-244: LGTM! Text improvements enhance consistency.

The label and description updates improve consistency (e.g., "Id" → "ID", "Ids" → "IDs") and polish the user-facing text.

GTFalcao
GTFalcao previously approved these changes Nov 18, 2025
Copy link
Copy Markdown
Collaborator

@GTFalcao GTFalcao left a comment

Choose a reason for hiding this comment

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

LGTM!

@vunguyenhung
Copy link
Copy Markdown
Contributor

@vunguyenhung
Copy link
Copy Markdown
Contributor

Hello everyone, I have tested this PR and there're some test cases failed or needed improvement.

Please check test reports below for more information:

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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/shortcut/actions/create-story/create-story.mjs (1)

245-337: Fix validation typo so linkedFileIds is actually validated

In the validation constraints you have:

const constraints = {
  // ...
  externalLinks: utils.validateArrayWhenPresent,
  fileIds: utils.validateArrayWhenPresent,
  followerIds: utils.validateArrayWhenPresent,
  inkedFileIds: utils.validateArrayWhenPresent,
  ownerIds: utils.validateArrayWhenPresent,
};

but the attributes you validate are:

{
  // ...
  linkedFileIds: this.linkedFileIds,
  ownerIds: this.ownerIds,
}

Because of the inkedFileIds typo, linkedFileIds is not checked at all. Suggest aligning the key:

-      followerIds: utils.validateArrayWhenPresent,
-      inkedFileIds: utils.validateArrayWhenPresent,
-      ownerIds: utils.validateArrayWhenPresent,
+      followerIds: utils.validateArrayWhenPresent,
+      linkedFileIds: utils.validateArrayWhenPresent,
+      ownerIds: utils.validateArrayWhenPresent,

This restores array validation for linkedFileIds while keeping the rest of the refactor intact.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b6af872 and aaa54ff.

📒 Files selected for processing (3)
  • components/shortcut/actions/create-story/create-story.mjs (10 hunks)
  • components/shortcut/shortcut.app.mjs (1 hunks)
  • components/shortcut/sources/new-event-received/new-event-received.mjs (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-09-12T07:49:36.125Z
Learnt from: matyascimbulka
Repo: PipedreamHQ/pipedream PR: 18308
File: components/apify/actions/run-task-synchronously/run-task-synchronously.mjs:70-0
Timestamp: 2025-09-12T07:49:36.125Z
Learning: The Apify Task object always contains the `options` field according to the official API documentation, making nested destructuring like `options: { build }` safe to use without additional checks.

Applied to files:

  • components/shortcut/shortcut.app.mjs
📚 Learning: 2025-10-20T01:01:02.970Z
Learnt from: js07
Repo: PipedreamHQ/pipedream PR: 18744
File: components/slack_v2/actions/send-large-message/send-large-message.mjs:49-64
Timestamp: 2025-10-20T01:01:02.970Z
Learning: In components/slack_v2/actions/send-large-message/send-large-message.mjs, the metadata_event_payload prop is typed as string, so the code only needs to handle string-to-JSON parsing and does not need to handle object inputs.

Applied to files:

  • components/shortcut/sources/new-event-received/new-event-received.mjs
📚 Learning: 2025-01-23T03:55:15.166Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 15376
File: components/monday/sources/name-updated/name-updated.mjs:6-6
Timestamp: 2025-01-23T03:55:15.166Z
Learning: Source names in Monday.com components don't need to start with "New" if they emit events for updated items (e.g., "Name Updated", "Column Value Updated") rather than new items. This follows the component guidelines exception where the "New" prefix is only required when emits are limited to new items.

Applied to files:

  • components/shortcut/sources/new-event-received/new-event-received.mjs
📚 Learning: 2024-10-10T19:18:27.998Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 14265
File: components/the_magic_drip/sources/common.mjs:35-43
Timestamp: 2024-10-10T19:18:27.998Z
Learning: In `components/the_magic_drip/sources/common.mjs`, when processing items in `getAndProcessData`, `savedIds` is intentionally updated with IDs of both emitted and non-emitted items to avoid emitting retroactive events upon first deployment and ensure only new events are emitted as they occur.

Applied to files:

  • components/shortcut/sources/new-event-received/new-event-received.mjs
📚 Learning: 2024-10-08T15:33:38.240Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 12697
File: components/salesforce_rest_api/sources/common-webhook-methods.mjs:1-71
Timestamp: 2024-10-08T15:33:38.240Z
Learning: The `common-webhook-methods.mjs` object is designed to be extended, similar to an abstract class, and intentionally does not implement certain methods like `generateWebhookMeta` and `getEventType` to enforce implementation in subclasses.

Applied to files:

  • components/shortcut/sources/new-event-received/new-event-received.mjs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: pnpm publish
  • GitHub Check: Ensure component commits modify component versions
  • GitHub Check: Lint Code Base
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components

@vunguyenhung
Copy link
Copy Markdown
Contributor

Hello everyone, I have tested this PR and there're some test cases failed or needed improvement.

Please check test reports below for more information:

@michelle0927
Copy link
Copy Markdown
Collaborator Author

@vunguyenhung The screenshot in the report shows "nov21" entered in the name prop, but the story created has name "21nov". Can you try creating a story where the name contains the string in the name prop? Otherwise, the source will filter it out as expected.

@vunguyenhung
Copy link
Copy Markdown
Contributor

Hi everyone, all test cases are passed! Ready for release!

Test reports

@michelle0927
Copy link
Copy Markdown
Collaborator Author

/approve

@michelle0927 michelle0927 merged commit 76d24db into master Nov 23, 2025
10 checks passed
@michelle0927 michelle0927 deleted the issue-18593 branch November 23, 2025 21:15
@vunguyenhung
Copy link
Copy Markdown
Contributor

Hi @michelle0927, my bad on this.

Thank you for clarifying!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[APP] Need Triggers from Shortcut

3 participants