Skip to content

New Components - social_fetch#21091

Open
Lukem121 wants to merge 5 commits into
PipedreamHQ:masterfrom
social-freak-ltd:social-fetch-components
Open

New Components - social_fetch#21091
Lukem121 wants to merge 5 commits into
PipedreamHQ:masterfrom
social-freak-ltd:social-fetch-components

Conversation

@Lukem121
Copy link
Copy Markdown

@Lukem121 Lukem121 commented Jun 7, 2026

Summary

Adds Social Fetch workflow components for the registered social_fetch app:

  • Source: New Profile Update (timer polling + profile diff)
  • Actions: Get Profile, Get Post, List Profile Posts, Get Transcript, Get Credit Balance

Replaces the stub social_fetch.app.mjs with the full app runtime (API key auth via x-api-key, route helpers, error formatting).

Relates to #21083

Test plan

  • npx eslint components/social_fetch
  • Connect Social Fetch account with sfk_… API key; verify connection test (GET /v1/whoami)
  • Run Get Profile action (e.g. TikTok handle)
  • Run Get Credit Balance action
  • Deploy New Profile Update source on a timer; confirm polling + diff emit

Auth

  • Header: x-api-key
  • Prop: api_key
  • Connection test: GET https://api.socialfetch.dev/v1/whoami

Summary by CodeRabbit

  • New Features

    • Added Social Fetch integration to retrieve public social media/web data.
    • New actions to fetch profiles, posts, transcripts, list profile posts, and check credit balance.
    • New source that detects profile changes and emits structured diffs for automations.
  • Documentation

    • Added setup and usage guide with API key steps, connection test, input guidance, and troubleshooting.

Replace stub social_fetch.app.mjs with full runtime, route helpers, and workflow components. Relates to PipedreamHQ#21083
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 7, 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 7:38pm

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

Review Change Stack

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 a Social Fetch integration: constants/utilities, routing, app HTTP plumbing with error formatting and auth, five Pipedream actions, a scheduled profile-change source that diffs and emits events, package metadata, and a README.

Changes

Social Fetch Integration

Layer / File(s) Summary
Configuration and utilities foundation
components/social_fetch/common/constants.mjs, components/social_fetch/common/utils.mjs, components/social_fetch/package.json
Platform and content-type allowlists, getObjectDiff recursive diff utility, and updated package metadata with @pipedream/platform dependency and version bump to 0.1.0.
Routing helpers and profile labeling
components/social_fetch/common/routing.mjs
Cursor helper, platform-aware route resolvers for profile/post/list/transcript endpoints, input validation, and profileLabel for human-friendly labels.
App core and HTTP request plumbing
components/social_fetch/social_fetch.app.mjs
Prop definitions, formatApiError, _headers, _makeRequest (axios to API_BASE_URL with x-api-key), and public methods: getCreditBalance, getProfile, getPost, listProfilePosts, getTranscript, plus profileSummaryLabel.
Action implementations
components/social_fetch/actions/*
Generated Pipedream action definitions (Get Credit Balance, Get Post, Get Profile, Get Transcript, List Profile Posts) that call the app methods, set $summary, and return API responses.
Profile Change Detection Source
components/social_fetch/sources/new-profile-update/*
Scheduled source that polls a profile, computes structural diffs with getObjectDiff, persists lastProfile, emits events when changes are detected, and includes a test event payload and sampleEmit.
User Documentation
components/social_fetch/README.md
Overview, API key setup, connection test (GET /v1/whoami with x-api-key), and troubleshooting for insufficient credits and input type selection (Handle vs Profile URL).

Sequence Diagrams

sequenceDiagram
  participant Action as Action Module
  participant App as social_fetch.app
  participant Routing as routing.mjs
  participant API as Social Fetch API
  Action->>App: call getProfile/getPost/listProfilePosts/getTranscript/getCreditBalance
  App->>Routing: resolve route (platform, inputs)
  Routing-->>App: return {path, params}
  App->>App: _makeRequest(path, params) with x-api-key
  App->>API: HTTP GET to API_BASE_URL + path
  API-->>App: JSON response or HTTP error
  App-->>Action: return data or throw formatted Error
Loading
sequenceDiagram
  participant Timer as Scheduled Timer
  participant Source as new-profile-update
  participant App as social_fetch.app
  participant DB as persistent DB
  participant Stream as Event Stream
  Timer->>Source: deploy/run triggered
  Source->>DB: _getLastProfile()
  DB-->>Source: lastProfile or undefined
  Source->>App: getProfile(platform, handle, profileUrl)
  App-->>Source: current profile
  Source->>Source: getObjectDiff(lastProfile, profile)
  alt diff is non-empty
    Source->>DB: _setLastProfile(profile)
    Source->>Source: profileSummaryLabel()
    Source->>Stream: $emit({profile, diff, metadata})
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • michelle0927
  • mariano-pd
  • GTFalcao
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description covers the summary, test plan, and auth details. However, it does not include the required versioning checklist section confirming that component versions were updated or that package.json version was bumped. Complete the description template by filling out the Checklist section, particularly confirming versioning updates and app integration status, rather than leaving the template checkboxes blank.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'New Components - social_fetch' directly summarizes the main addition: new workflow components for the social_fetch app, including a source and multiple actions.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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: 1

🤖 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/social_fetch/sources/new-profile-update/new-profile-update.mjs`:
- Around line 73-75: The emitted metadata currently uses runtime clock values
for id and ts (id: Date.now(), ts: Date.parse(new Date())), which breaks dedupe
and timestamp guarantees; replace those with a stable, event-derived id (use the
source event's unique id field or a deterministic hash of event properties such
as profile identifier + event timestamp) and set ts from the API event timestamp
(e.g., parse event.published/event.updated/event.timestamp) instead of
Date.now()/new Date(); keep summary using label unchanged. Target the id and ts
assignments in the object that builds the emission (the id, ts, summary entries)
and ensure the new id is deterministic across restarts/polls.
🪄 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: f671ee01-72e3-4174-a84a-ad50c8ace693

📥 Commits

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

⛔ Files ignored due to path filters (1)
  • components/social_fetch/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • components/social_fetch/README.md
  • components/social_fetch/actions/get-credit-balance/get-credit-balance.mjs
  • components/social_fetch/actions/get-post/get-post.mjs
  • components/social_fetch/actions/get-profile/get-profile.mjs
  • components/social_fetch/actions/get-transcript/get-transcript.mjs
  • components/social_fetch/actions/list-profile-posts/list-profile-posts.mjs
  • components/social_fetch/common/constants.mjs
  • components/social_fetch/common/routing.mjs
  • components/social_fetch/common/utils.mjs
  • components/social_fetch/package.json
  • components/social_fetch/social_fetch.app.mjs
  • components/social_fetch/sources/new-profile-update/new-profile-update.mjs
  • components/social_fetch/sources/new-profile-update/test-event.mjs

Comment thread components/social_fetch/sources/new-profile-update/new-profile-update.mjs Outdated
Lukem121 and others added 2 commits June 8, 2026 02:15
…entation clarity

- Cleaned up error message formatting in formatApiError function.
- Enhanced descriptions for various properties in social_fetch.app.mjs to improve clarity for users.
- Updated pnpm-lock.yaml to reflect changes in dependencies and versions.
Co-authored-by: Cursor <cursoragent@cursor.com>
@Lukem121
Copy link
Copy Markdown
Author

Lukem121 commented Jun 7, 2026

Thanks for the review!

Addressed the CodeRabbit feedback on emit metadata in New Profile Update (commit 5a4481e):

  • id — deterministic hash from platform + profile identity + diff content (dedupe-safe across restarts/polls with dedupe: "unique")
  • ts — detection time at poll (Date.now()); our API does not return a profile updatedAt field
  • Source version bumped to 0.0.2
  • Added JSDoc on app methods to improve docstring coverage

All 5 actions and auth were tested locally via pd publish before this PR. Happy to make any other changes during review.

@Lukem121 Lukem121 mentioned this pull request Jun 7, 2026
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/social_fetch/social_fetch.app.mjs (1)

108-118: ⚠️ Potential issue | 🟡 Minor

Merge caller-supplied headers with auth headers in _makeRequest() (avoid clobbering x-api-key)

_makeRequest() sets headers: this._headers(), but then spreads ...opts, so any opts.headers from the caller will replace the auth headers. Destructure headers and merge it with _headers(), and switch to baseURL + url.

🔧 Suggested refactor
     async _makeRequest({
-      $ = this, path, params, ...opts
+      $ = this,
+      path,
+      params,
+      headers = {},
+      ...opts
     } = {}) {
       let response;
       try {
         response = await axios($, {
-          url: `${API_BASE_URL}${path}`,
-          headers: this._headers(),
+          baseURL: API_BASE_URL,
+          url: path,
+          headers: {
+            ...this._headers(),
+            ...headers,
+          },
           params,
           ...opts,
         });
       } catch (error) {
🤖 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/social_fetch/social_fetch.app.mjs` around lines 108 - 118, In
_makeRequest(), callers' opts.headers currently overwrite the auth headers from
this._headers(); fix by destructuring headers from opts (e.g., { headers:
callerHeaders, ...restOpts } = opts), merge them with this._headers()
(callerHeaders taking precedence or vice versa per desired behavior) and pass
the merged headers into axios; also change the axios call to use baseURL:
API_BASE_URL and url: path (instead of concatenating) and spread restOpts into
the request so all other options remain intact (refer to _makeRequest and
this._headers()).
🤖 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/social_fetch/social_fetch.app.mjs`:
- Around line 41-42: The prop description strings in
components/social_fetch/social_fetch.app.mjs (the description fields for the
social platform and the related input props in the same block) are written as UI
instructions; replace them with input-contract style descriptions that specify
the expected value, type, and conditional requirements — e.g., for the platform
prop state the allowed values (e.g., "twitter", "instagram", "facebook",
"linkedin"), for the handle input state "a username without @ (string) required
when platform is a handle-based service", and for the profileUrl input state "a
full profile URL (string, starting with http/https) required when platform is
facebook or linkedin"; ensure each description is concise, agent-focused, and
mentions validation/format expectations rather than telling a human how to
select fields.
- Around line 66-67: Update the prop description strings in
components/social_fetch/social_fetch.app.mjs for the properties handle,
profileUrl, postUrl, and contentType to include concrete inline examples and
remove UI-centric phrasing; e.g., change the handle description to "Username or
handle (without @), e.g. 'nasa'", profileUrl to "Full profile URL, e.g.
'https://www.linkedin.com/in/janedoe/'", postUrl to "Full post/video URL, e.g.
'https://www.tiktok.com/@nasa/video/1234567890'", and contentType to "Type of
content, e.g. 'videos'"; apply the same example-style updates where similar
descriptions appear on the other indicated lines (73-74, 80-81, 91-92).

---

Outside diff comments:
In `@components/social_fetch/social_fetch.app.mjs`:
- Around line 108-118: In _makeRequest(), callers' opts.headers currently
overwrite the auth headers from this._headers(); fix by destructuring headers
from opts (e.g., { headers: callerHeaders, ...restOpts } = opts), merge them
with this._headers() (callerHeaders taking precedence or vice versa per desired
behavior) and pass the merged headers into axios; also change the axios call to
use baseURL: API_BASE_URL and url: path (instead of concatenating) and spread
restOpts into the request so all other options remain intact (refer to
_makeRequest and this._headers()).
🪄 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: 993695f9-4dd2-404f-a006-2ce050ca55b3

📥 Commits

Reviewing files that changed from the base of the PR and between 2a63f12 and 249e00b.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • components/social_fetch/social_fetch.app.mjs

Comment thread components/social_fetch/social_fetch.app.mjs Outdated
Comment thread components/social_fetch/social_fetch.app.mjs Outdated
Co-authored-by: Cursor <cursoragent@cursor.com>
@Lukem121
Copy link
Copy Markdown
Author

Lukem121 commented Jun 7, 2026

Follow-up on the latest CodeRabbit review — addressed in commit 9cf0505:

  • Rewrote prop description fields as input contracts with inline examples (no UI-centric Select phrasing)
  • Fixed _makeRequest() to merge caller headers with auth headers and use baseURL + url
  • Added remaining method JSDoc for docstring coverage

The earlier dedupe fix (5a4481e) remains in place for the polling source.

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/social_fetch/social_fetch.app.mjs (1)

164-175: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Add JSDoc to public methods for consistency.

getPost, listProfilePosts, and getTranscript lack JSDoc annotations, while similar methods (getCreditBalance, getProfile, profileSummaryLabel) include them. Consistent documentation improves maintainability and helps agents understand method contracts.

📝 Suggested JSDoc additions
+   /**
+    * `@param` {{ platform?: string; postUrl?: string; [key: string]: unknown }} [args]
+    */
    getPost({
      platform, postUrl, ...opts
    } = {}) {
+   /**
+    * `@param` {{ platform?: string; contentType?: string; handle?: string;
+    *   profileUrl?: string; cursor?: string; [key: string]: unknown }} [args]
+    */
    listProfilePosts({
      platform,
      contentType,
+   /**
+    * `@param` {{ platform?: string; mediaUrl?: string; [key: string]: unknown }} [args]
+    */
    getTranscript({
      platform, mediaUrl, ...opts
    } = {}) {

Also applies to: 176-194, 195-206

🤖 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/social_fetch/social_fetch.app.mjs` around lines 164 - 175, Add
JSDoc comments to the public methods getPost, listProfilePosts, and
getTranscript to match the style used for
getCreditBalance/getProfile/profileSummaryLabel: include a short description,
`@param` annotations for each parameter (platform, postUrl or other options
object, and any spread/opts), types and whether optional, and an `@returns`
annotation describing the returned Promise/response shape; place the JSDoc
immediately above each function definition (getPost, listProfilePosts,
getTranscript) so documentation and editors can surface the method contract
consistently.
♻️ Duplicate comments (1)
components/social_fetch/social_fetch.app.mjs (1)

47-47: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Rewrite prop descriptions to be agent-focused and include concrete examples.

These descriptions still contain UI-centric phrasing ("Select the platform", "Paste the URL from the browser address bar") and lack inline examples for non-obvious formats.

As per coding guidelines, prop description fields must be written for AI agent consumption, avoid UI-centric language, and include concrete inline examples for non-obvious inputs.

✏️ Example rewrites
     platform: {
       type: "string",
       label: "Platform",
       description:
-        "Select the social platform. Handle-based platforms need a username; Facebook and LinkedIn need a full profile URL.",
+        "Social media platform. Use a username (handle) for TikTok, Instagram, Twitter/X, or Threads; use a full profile URL for Facebook or LinkedIn. Example: `tiktok`, `instagram`, `facebook`, `linkedin`.",
       options: PROFILE_PLATFORMS,
     },
     handle: {
       type: "string",
       label: "Handle",
       description:
-        "Username or handle (without @) for TikTok, Instagram, Twitter/X, or Threads.",
+        "Username without the leading @ symbol. Example: `nasa`.",
       optional: true,
     },
     profileUrl: {
       type: "string",
       label: "Profile URL",
       description:
-        "Full profile page URL for Facebook or LinkedIn. Paste the URL from the browser address bar.",
+        "Full Facebook or LinkedIn profile URL. Example: `https://www.linkedin.com/in/janedoe/`.",
       optional: true,
     },
     postUrl: {
       type: "string",
       label: "Post URL",
       description:
-        "Full URL of the post, video, or tweet. Paste the link from your browser address bar.",
+        "Full URL of the post, video, or tweet. Example: `https://www.tiktok.com/@nasa/video/1234567890`.",
     },
     contentType: {
       type: "string",
       label: "Content Type",
       description:
-        "Videos for TikTok; Posts or Reels for Instagram; Tweets for Twitter / X; Posts for Threads and Facebook.",
+        "Type of content to list. Use `videos` for TikTok, `posts` or `reels` for Instagram, `tweets` for Twitter/X, `posts` for Threads or Facebook.",
       options: CONTENT_TYPE_OPTIONS,
     },

Also applies to: 72-72, 79-79, 86-86, 97-97

🤖 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/social_fetch/social_fetch.app.mjs` at line 47, Update the prop
"description" strings in components/social_fetch/social_fetch.app.mjs to be
agent-focused (address the AI directly), remove UI-centric phrasing, and include
concrete inline examples for non-obvious formats: for the platform selector
description explain what each platform expects (e.g., "use handle for
Twitter/Instagram: 'elonmusk'; use full profile URL for Facebook/LinkedIn:
'https://www.facebook.com/zuck'"), for the username/handle prop give example
handles and clarifying format (e.g., "no leading @, e.g. 'jack' or 'spotify'"),
and for URL props show exact example URLs and any required components (e.g.,
"include https:// and full path, e.g. 'https://www.linkedin.com/in/janedoe/'").
Apply this style to all description fields in the file (the other occurrences
noted in the review) so every description is written to the agent and includes
at least one concrete example.

Source: Coding guidelines

🤖 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/social_fetch/sources/new-profile-update/new-profile-update.mjs`:
- Around line 50-66: The generated id in _buildEmitMetadata can exceed 64 chars
when identity (e.g., profileUrl) is long; replace the raw identity in the id
with a short cryptographic hash of the identity (e.g., sha256 and take a 16-char
hex slice) and then build the id as platform + separator + identityHash +
separator + diffHash, and finally enforce a max length of 64 characters (slice
or truncate the composed string) so emitted ids always remain <=64 chars.
- Around line 57-60: The emitted metadata `id` built from
`${this.platform}:${identity}:${diffHash}` exceeds the 64-char dedupe-id limit
and will break deduplication; change the `id` construction in
new-profile-update.mjs (where `createHash("sha256")` produces `diffHash`) to
produce a <=64-char deterministic id by folding/hashing the full identifying
payload into a short fingerprint (e.g., hash the concatenation of platform,
identity and diffHash and slice to 64 chars as in
components/linkly/sources/new-link-clicked/new-link-clicked.mjs) and, if you
must allow repeated identical diffs to emit, incorporate a persisted monotonic
counter or the API-provided update/event timestamp into the input used to derive
the id (do not use Date.now() if an API timestamp is available).

---

Outside diff comments:
In `@components/social_fetch/social_fetch.app.mjs`:
- Around line 164-175: Add JSDoc comments to the public methods getPost,
listProfilePosts, and getTranscript to match the style used for
getCreditBalance/getProfile/profileSummaryLabel: include a short description,
`@param` annotations for each parameter (platform, postUrl or other options
object, and any spread/opts), types and whether optional, and an `@returns`
annotation describing the returned Promise/response shape; place the JSDoc
immediately above each function definition (getPost, listProfilePosts,
getTranscript) so documentation and editors can surface the method contract
consistently.

---

Duplicate comments:
In `@components/social_fetch/social_fetch.app.mjs`:
- Line 47: Update the prop "description" strings in
components/social_fetch/social_fetch.app.mjs to be agent-focused (address the AI
directly), remove UI-centric phrasing, and include concrete inline examples for
non-obvious formats: for the platform selector description explain what each
platform expects (e.g., "use handle for Twitter/Instagram: 'elonmusk'; use full
profile URL for Facebook/LinkedIn: 'https://www.facebook.com/zuck'"), for the
username/handle prop give example handles and clarifying format (e.g., "no
leading @, e.g. 'jack' or 'spotify'"), and for URL props show exact example URLs
and any required components (e.g., "include https:// and full path, e.g.
'https://www.linkedin.com/in/janedoe/'"). Apply this style to all description
fields in the file (the other occurrences noted in the review) so every
description is written to the agent and includes at least one concrete example.
🪄 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: 9fb39dcc-e6fb-44e1-8769-aa46d58e7771

📥 Commits

Reviewing files that changed from the base of the PR and between 249e00b and 5a4481e.

📒 Files selected for processing (3)
  • components/social_fetch/common/utils.mjs
  • components/social_fetch/social_fetch.app.mjs
  • components/social_fetch/sources/new-profile-update/new-profile-update.mjs

Co-authored-by: Cursor <cursoragent@cursor.com>
@Lukem121
Copy link
Copy Markdown
Author

Lukem121 commented Jun 7, 2026

Addressed the latest CodeRabbit emit-id feedback in fddec70:

  • Hash profile identity (sha256, 16-char hex) instead of embedding raw profileUrl/handle in the id
  • Composed id is now platform:identityHash:diffHash (~44 chars, under the 64-char dedupe limit)
  • Source bumped to 0.0.3

Re: repeated identical diffs (A->B->A->B) being suppressed — intentional with dedupe unique for now; our API has no update timestamp to disambiguate. Happy to add a persisted emit counter if reviewers want every re-occurrence to fire.

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.

Caution

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

⚠️ Outside diff range comments (1)
components/social_fetch/sources/new-profile-update/new-profile-update.mjs (1)

82-103: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Move state update after emit to prevent skipped events on partial failure.

The call to _setLastProfile(profile) on line 83 happens before $emit() on line 92. If the emit fails, the state is already updated, causing the event to be permanently skipped on retry.

Proposed fix
     if (Object.keys(diff).length > 0) {
-      this._setLastProfile(profile);
       const label = this.app.profileSummaryLabel(
         this.platform,
         this.handle,
         this.profileUrl,
       );
       const {
         id, ts,
       } = this._buildEmitMetadata(profile, diff);
       this.$emit(
         {
           profile,
           diff,
         },
         {
           id,
           summary: `Profile update for ${label}`,
           ts,
         },
       );
+      this._setLastProfile(profile);
     }

As per coding guidelines: "Update stored state AFTER emitting (so partial failures don't cause skipped events on the next run)."

🤖 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/social_fetch/sources/new-profile-update/new-profile-update.mjs`
around lines 82 - 103, The state update is happening before the emit which can
cause events to be skipped if the emit fails; move the call to
_setLastProfile(profile) so it runs only after $emit(...) completes
successfully. Keep building the label and metadata as-is using
app.profileSummaryLabel(...) and _buildEmitMetadata(profile, diff), call
this.$emit(...) first with the constructed payload and metadata (id, summary,
ts), and then call this._setLastProfile(profile) immediately after the emit
returns to ensure state is only advanced on successful emit.

Source: Coding guidelines

🤖 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.

Outside diff comments:
In `@components/social_fetch/sources/new-profile-update/new-profile-update.mjs`:
- Around line 82-103: The state update is happening before the emit which can
cause events to be skipped if the emit fails; move the call to
_setLastProfile(profile) so it runs only after $emit(...) completes
successfully. Keep building the label and metadata as-is using
app.profileSummaryLabel(...) and _buildEmitMetadata(profile, diff), call
this.$emit(...) first with the constructed payload and metadata (id, summary,
ts), and then call this._setLastProfile(profile) immediately after the emit
returns to ensure state is only advanced on successful emit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9308c21b-1f37-4d75-8c10-d34b3f40b225

📥 Commits

Reviewing files that changed from the base of the PR and between 9cf0505 and fddec70.

📒 Files selected for processing (1)
  • components/social_fetch/sources/new-profile-update/new-profile-update.mjs

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