Skip to content

feat(tiktok): add tiktok trigger, block#5504

Open
BillLeoutsakosvl346 wants to merge 13 commits into
stagingfrom
feature/tiktok-integration
Open

feat(tiktok): add tiktok trigger, block#5504
BillLeoutsakosvl346 wants to merge 13 commits into
stagingfrom
feature/tiktok-integration

Conversation

@BillLeoutsakosvl346

@BillLeoutsakosvl346 BillLeoutsakosvl346 commented Jul 8, 2026

Copy link
Copy Markdown

Adds TikTok as a full OAuth-based integration: provider registration (with TikTok's comma-separated scope and client_key requirements), 9 tools covering profile info, video listing/querying, creator info, direct video/photo posting (URL or file upload), inbox drafts, and post status polling, it also adds webhooks, plus the TikTok block, icon, and generated docs.

Summary

Brief description of what this PR does and why.

Fixes #(issue)

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: ___________

Testing

How has this been tested? What should reviewers focus on?

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Screenshots/Videos

Adds TikTok as a full OAuth-based integration: provider registration
(with TikTok's comma-separated scope and client_key requirements),
9 tools covering profile info, video listing/querying, creator info,
direct video/photo posting (URL or file upload), inbox drafts, and
post status polling, plus the TikTok block, icon, and generated docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Jul 8, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Jul 9, 2026 1:17am

Request Review

@cursor

cursor Bot commented Jul 8, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches OAuth/token refresh and a new signed webhook ingress that enqueues workflow runs; video file relay and third-party content publishing add operational and abuse surface, though scoped to new TikTok paths with tests for signature verification.

Overview
Adds a TikTok integration end-to-end: OAuth connect, workflow tools, a TikTok block, docs, and app-level webhooks.

OAuth & credentials — Registers TikTok with TIKTOK_CLIENT_ID / TIKTOK_CLIENT_SECRET, including TikTok-specific client_key on authorize/token and comma-separated scope. Token refresh uses client_key instead of client_id where required.

Workflow surface — Nine tools cover profile/stats, video list/query, creator posting constraints, direct video/photo publish (public URL or workflow file), inbox drafts, and publish status. A new /api/tools/tiktok/publish-video route handles FILE_UPLOAD by downloading the user file (capped at 250MB), initializing TikTok upload, and chunked PUTs to TikTok.

Webhooks & triggers — Fixed callback /api/webhooks/tiktok verifies TikTok-Signature (HMAC + timestamp skew), then fans out by user_openid to matching deployed workflows. Eight triggers map TikTok events (publish complete/failed, inbox, visibility, Video Kit, authorization removed). Proxy security filtering exempts this webhook path.

Product wiringTikTokBlock, tool/block/trigger registries, integration catalog, TikTokIcon, and generated integration docs; API contract baseline bumps to 921 routes.

Reviewed by Cursor Bugbot for commit cb1a766. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread apps/sim/app/api/tools/tiktok/publish-video/route.ts
Comment thread apps/sim/tools/tiktok/utils.ts
@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a full TikTok OAuth integration: provider registration, 9 tools (profile, videos, posting, drafts, status), 8 webhook triggers, a dedicated app-level fan-out webhook route at /api/webhooks/tiktok, an icon, a block, and generated docs. The webhook implementation is the primary focus of this review pass.

  • Webhook route (/api/webhooks/tiktok): verifies HMAC-SHA256 TikTok-Signature once per request, then fans out to all matching user workflows via user_openid → credential → webhook record lookup. Signature verification is timing-safe with a 5-minute timestamp skew window.
  • Fan-out query (tiktok-fanout.ts): resolves user_openid to account rows (via LIKE + in-memory UUID-suffix strip), looks up credentials, then fetches all active TikTok webhooks and filters in memory by providerConfig.credentialId — correct but worth noting for future scale.
  • OAuth quirks (TikTok-specific client_key param name and comma-separated scopes) are handled cleanly in auth.ts via authorizationUrlParams override and clientIdParamName on the refresh path.

Confidence Score: 5/5

The webhook integration is safe to merge — signature verification is timing-safe, timestamp replay protection is in place, and the fan-out correctly scopes each event to the authenticated user's workflows.

Signature verification (HMAC-SHA256 via safeCompare, 5-minute skew window), fan-out isolation by user_openid → credential, billing gate, and ack-always semantics are all correctly implemented. The two comments are about robustness and future scalability, neither of which affects correctness today.

No files require special attention — the webhook route, provider handler, and fan-out logic are all well-structured and covered by tests.

Important Files Changed

Filename Overview
apps/sim/app/api/webhooks/tiktok/route.ts App-level fan-out webhook route: verifies HMAC-SHA256 signature once, then iterates over matched webhooks. Proper ack-always behavior, size limits, billing check, and event-ID filtering are all in place.
apps/sim/lib/webhooks/providers/tiktok.ts WebhookProviderHandler implementation: signature parsing, HMAC verification with safeCompare, event matching, input formatting, and idempotency key extraction are all well-structured and tested.
apps/sim/lib/webhooks/tiktok-fanout.ts Fan-out logic: three-step DB lookup (account → credential → webhook). The final SQL query fetches ALL active TikTok webhooks then filters by credentialId in memory — correct but potentially expensive if there are many TikTok users.
apps/sim/lib/api/contracts/webhooks.ts Adds tiktokWebhookEnvelopeSchema with content as a required z.string(). TikTok always sends content, but events missing the field would be silently acked rather than raising an error.
apps/sim/lib/auth/auth.ts TikTok OAuth provider config handles the client_key and comma-separated scope quirks correctly via authorizationUrlParams override. getUserInfo builds an accountId as open_id + UUID suffix, which the fanout correctly strips.
apps/sim/lib/oauth/oauth.ts clientIdParamName field added to ProviderAuthConfig; buildAuthRequest correctly uses it so TikTok token-refresh sends client_key instead of client_id.
apps/sim/triggers/tiktok/utils.ts TIKTOK_TRIGGER_EVENT_MAP and isTikTokEventMatch correctly reflect documented TikTok event strings including the known typo in no_longer_publicaly_available.
apps/sim/proxy.ts Security filter updated to bypass bot-blocking for /api/webhooks/tiktok. Uses startsWith without a trailing slash (same pattern as the existing agentmail entry), which is correct for this fixed-path endpoint.
apps/sim/lib/webhooks/providers/tiktok.test.ts Comprehensive test suite covering signature parsing, verification (valid, invalid, stale, missing), content parsing, event matching, formatInput, and extractIdempotencyId.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant TikTok as TikTok Platform
    participant Route as /api/webhooks/tiktok
    participant Verify as verifyTikTokSignature
    participant Fanout as findTikTokWebhooksForOpenId
    participant DB as Database
    participant Queue as queueWebhookExecution

    TikTok->>Route: POST (TikTok-Signature header + JSON body)
    Route->>Route: readStreamToBufferWithLimit (size guard)
    Route->>Route: parse TikTok-Signature header (Zod)
    Route->>Verify: verifyTikTokSignature(rawBody, header)
    Verify->>Verify: parseTikTokSignatureHeader → t, s
    Verify->>Verify: check timestamp skew (±5 min)
    Verify->>Verify: HMAC-SHA256(t.rawBody, CLIENT_SECRET)
    Verify->>Verify: safeCompare(computed, s)
    Verify-->>Route: null (ok) or 401 Response
    Route->>Route: JSON.parse rawBody → envelope (Zod)
    Route->>Fanout: findTikTokWebhooksForOpenId(user_openid)
    Fanout->>DB: "SELECT accounts WHERE providerId='tiktok' LIKE 'openid-%'"
    DB-->>Fanout: matching account rows
    Fanout->>Fanout: in-memory UUID-suffix strip + exact match filter
    Fanout->>DB: SELECT credentials WHERE accountId IN (matched)
    DB-->>Fanout: credential IDs
    Fanout->>DB: SELECT webhook+workflow (active TikTok webhooks)
    DB-->>Fanout: all active TikTok webhooks
    Fanout->>Fanout: filter by providerConfig.credentialId in credentialIds
    Fanout-->>Route: "matched [{webhook, workflow}]"
    loop for each matched webhook
        Route->>Route: billing check (workspace entitlement)
        Route->>Route: checkWebhookPreprocessing
        Route->>Route: blockExistsInDeployment check
        Route->>Route: shouldSkipWebhookEvent
        Route->>Route: isTikTokEventMatch(triggerId, event)
        Route->>Queue: queueWebhookExecution(webhook, workflow, envelope)
        Queue-->>Route: "200 { message: 'Webhook processed' }"
    end
    Route-->>TikTok: "200 { ok: true, webhooksProcessed: N }"
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant TikTok as TikTok Platform
    participant Route as /api/webhooks/tiktok
    participant Verify as verifyTikTokSignature
    participant Fanout as findTikTokWebhooksForOpenId
    participant DB as Database
    participant Queue as queueWebhookExecution

    TikTok->>Route: POST (TikTok-Signature header + JSON body)
    Route->>Route: readStreamToBufferWithLimit (size guard)
    Route->>Route: parse TikTok-Signature header (Zod)
    Route->>Verify: verifyTikTokSignature(rawBody, header)
    Verify->>Verify: parseTikTokSignatureHeader → t, s
    Verify->>Verify: check timestamp skew (±5 min)
    Verify->>Verify: HMAC-SHA256(t.rawBody, CLIENT_SECRET)
    Verify->>Verify: safeCompare(computed, s)
    Verify-->>Route: null (ok) or 401 Response
    Route->>Route: JSON.parse rawBody → envelope (Zod)
    Route->>Fanout: findTikTokWebhooksForOpenId(user_openid)
    Fanout->>DB: "SELECT accounts WHERE providerId='tiktok' LIKE 'openid-%'"
    DB-->>Fanout: matching account rows
    Fanout->>Fanout: in-memory UUID-suffix strip + exact match filter
    Fanout->>DB: SELECT credentials WHERE accountId IN (matched)
    DB-->>Fanout: credential IDs
    Fanout->>DB: SELECT webhook+workflow (active TikTok webhooks)
    DB-->>Fanout: all active TikTok webhooks
    Fanout->>Fanout: filter by providerConfig.credentialId in credentialIds
    Fanout-->>Route: "matched [{webhook, workflow}]"
    loop for each matched webhook
        Route->>Route: billing check (workspace entitlement)
        Route->>Route: checkWebhookPreprocessing
        Route->>Route: blockExistsInDeployment check
        Route->>Route: shouldSkipWebhookEvent
        Route->>Route: isTikTokEventMatch(triggerId, event)
        Route->>Queue: queueWebhookExecution(webhook, workflow, envelope)
        Queue-->>Route: "200 { message: 'Webhook processed' }"
    end
    Route-->>TikTok: "200 { ok: true, webhooksProcessed: N }"
Loading

Reviews (3): Last reviewed commit: "Merge branch 'staging' into feature/tikt..." | Re-trigger Greptile

Comment thread apps/sim/app/api/tools/tiktok/publish-video/route.ts
@icecrasher321

Copy link
Copy Markdown
Collaborator

@BillLeoutsakosvl346

Few initial comments:

  • For tools that allow you to upload videos or files -- you should use our file upload subblock, and make sure it can take in a file or array of files in the advanced mode. We have a format called UserFiles (look at how the Gmail block accepts attachments for reference if needed). But the subblock should not take URLs, or other inputs -- only the file upload selector in basic mode or the User File references in advanced mode.

  • Read the AI code review comments. Our general practice is to finish all review cycles with the review bots and mark them as resolved or respond to them if they're inaccurate.

  • Please run the /memory-load-check skill to make sure we're never loading dangerously capped / uncapped media files into memory before processing them

  • All file based outputs -- should return user file objects. See other download tools or even the Gmail trigger (for the attachments output) to understand what I'm talking about. This allows file based variables to be passed between blocks. So for e.g. a file is fetched from TikTok and then attached to an email in a Gmail block.

Adds a file-typed avatarFile output (sourced from the largest available
avatar URL) alongside the existing string avatar fields, so the profile
picture can be materialized as a UserFile and chained into file-consuming
blocks (e.g. attached to an email), per PR review feedback.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/sim/tools/tiktok/list_videos.ts
@BillLeoutsakosvl346

Copy link
Copy Markdown
Author
  1. Reply to the Greptile bot comment (on computeChunkPlan / Math.floor)
    This is expected behavior, not a bug — it matches TikTok's documented chunking algorithm exactly. From TikTok's Media Transfer Guide:

"The value of total_chunk_count should be equal to video_size divided by chunk_size, rounded down to the nearest integer... Each chunk must be at least 5 MB but no greater than 64 MB, except for the final chunk, which can be greater than chunk_size (up to 128 MB) to accommodate any trailing bytes."

Their own example uses the identical numbers this comment flagged: video_size: 50000123, chunk_size: 10000000 → total_chunk_count: 5 (Math.floor(50000123/10000000)=5), with the last chunk absorbing the trailing 123 bytes as an oversized final chunk. Switching to Math.ceil would actually introduce a real bug: for files like 41MB, Math.ceil(41/10)=5 chunks produces a final chunk of only 1MB, violating TikTok's documented 5MB minimum chunk size. Keeping Math.floor as-is. Resolving.

  1. Explanation for "use the file upload subblock, no URLs" comment
    This is already implemented for video, and isn't applicable to photos:

Video (Direct Post Video / Upload Video Draft) already follows this exact pattern — a file-upload subblock in basic mode and a short-input block-reference subblock in advanced mode, both sharing canonicalParamId: 'file', normalized through the same normalizeFileInput() helper the Gmail attachment field uses. The URL input (videoUrl) is a structurally separate subblock only shown when the user picks the "Public URL" source — it's never mixed into the file subblock itself.
Photos (Direct Post Photo / Upload Photo Draft) can't support file upload — TikTok's Content Posting API only accepts PULL_FROM_URL for photo posts. There is no FILE_UPLOAD source option for photos in TikTok's API at all (confirmed in their Photo Post reference and Get Started guide). Adding a file-upload subblock there would have nothing to call.
3. Memory-load-check confirmation
Ran the memory-load-check pass. Findings:

The one large-file path — chunked video upload in publish-video/route.ts — downloads the workflow file into memory before forwarding it to TikTok. This is capped at TikTok's documented 4GB max video size (TIKTOK_MAX_VIDEO_BYTES), passed as maxBytes into downloadFileFromStorage, with a PayloadSizeLimitError caught and turned into a clean 413 response instead of letting an oversized file buffer unbounded.
The new avatar-file addition (see #4) reuses the platform's existing FileToolProcessor → downloadFileFromUrl pipeline, the same one used by slack_download, image_generate, and others — no new ad-hoc fetch/buffer code was added. Avatar images are small profile pictures, so the risk profile here is the same as the rest of the codebase's existing file-output tools.
4. Note on the avatarFile addition and photo cover images
Added a file-typed avatarFile output to Get User Info, sourced from the largest available avatar URL (avatar_large_url, falling back to avatar_url). It's additive — the existing avatarUrl/avatarUrl100/avatarLargeUrl string fields are unchanged — so this doesn't break anything for people already using the string outputs, but now the avatar can also be wired directly into a file-typed input on another block (e.g. a Gmail attachment), the same way slack_download and image_generate outputs work.

I intentionally left video/photo cover images (coverImageUrl in List/Query Videos) as plain URL strings rather than converting them too. Those are returned per-video inside an array of up to 20 videos per call, so converting them would mean silently downloading and storing up to 20 thumbnails into workflow storage on every List Videos call, most of which won't ever be used. Happy to add that too if there's a specific use case for it, but wanted to flag the cost tradeoff rather than do it by default.

@icecrasher321 icecrasher321 self-assigned this Jul 8, 2026
@icecrasher321

icecrasher321 commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

@BillLeoutsakosvl346

"The one large-file path — chunked video upload in publish-video/route.ts — downloads the workflow file into memory before forwarding it to TikTok. This is capped at TikTok's documented 4GB max video size (TIKTOK_MAX_VIDEO_BYTES), passed as maxBytes into downloadFileFromStorage, with a PayloadSizeLimitError caught and turned into a clean 413 response instead of letting an oversized file buffer unbounded." --> Can we make it so we have at most 250MB in memory for this instead of 4GB.

"I intentionally left video/photo cover images (coverImageUrl in List/Query Videos) as plain URL strings rather than converting them too. Those are returned per-video inside an array of up to 20 videos per call, so converting them would mean silently downloading and storing up to 20 thumbnails into workflow storage on every List Videos call, most of which won't ever be used. Happy to add that too if there's a specific use case for it, but wanted to flag the cost tradeoff rather than do it by default." --> are these publicly accesible URLs? If they are not, we should probably convert them too to be user files.

"Added a file-typed avatarFile output to Get User Info, sourced from the largest available avatar URL (avatar_large_url, falling back to avatar_url). It's additive — the existing avatarUrl/avatarUrl100/avatarLargeUrl string fields are unchanged — so this doesn't break anything for people already using the string outputs, but now the avatar can also be wired directly into a file-typed input on another block (e.g. a Gmail attachment), the same way slack_download and image_generate outputs work" --> this is an unreleased feature right now, so no need to maintain backwards compatibility. Only have the avatarFile output -- don't need the other string outputs. This applies in general. We need to make sure the outputs are lean and make sense.

…tputs

Cap the file-upload video buffer at 250MB instead of TikTok's 4GB ceiling —
relaying that much through this server's memory per request isn't safe
under concurrent load, and larger files can still go through the
PULL_FROM_URL path, which never buffers on our server. Also drop the
now-redundant avatarUrl/avatarUrl100/avatarLargeUrl string outputs from
Get User Info in favor of the file-typed avatarFile output alone, since
the feature is unreleased and the raw URL is still reachable via
avatarFile.url. Cover image URLs on List/Query Videos are confirmed to be
signed, expiring TikTok CDN links; left as strings (no file-output
conversion path exists for fields nested inside array items) but
documented the expiry behavior more clearly.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/sim/blocks/blocks/tiktok.ts Outdated
Comment thread apps/sim/tools/tiktok/utils.ts
@BillLeoutsakosvl346

Copy link
Copy Markdown
Author

Memory cap → 250MB. Done. TIKTOK_MAX_VIDEO_BYTES is now 250 * 1024 * 1024 instead of 4GB, with the 413 error message updated to match. This only affects the file-upload path (uploading from Sim storage) — the public-URL path is untouched since TikTok pulls those bytes directly and our server never buffers them, so larger files still work by using a URL instead.

Avatar outputs → lean. Done. Removed avatarUrl, avatarUrl100, and avatarLargeUrl from Get User Info, keeping only avatarFile. Since this hasn't shipped yet there's no back-compat need, and the raw URL is still reachable via avatarFile.url if anyone needs the string form.

Cover image URLs → left as strings. Confirmed they're signed, expiring TikTok CDN URLs (not permanent), so the instinct to convert them was right. But our file-output pipeline only auto-converts top-level outputs, not fields nested inside array items like videos[].coverImageUrl — doing it properly would mean a separate coverImageFiles[] array matched to videos by index, which is fragile (nothing but array position ties them together) and still downloads up to 20 thumbnails per call whether or not they're used. Given that cost/fragility tradeoff, I left it as a string but tightened the description to clearly say it's signed and time-limited, so it's used correctly rather than cached.

@greptile

Bill Leoutsakos and others added 2 commits July 8, 2026 11:34
…h-video route

The TikTok integration adds one new Zod-backed internal API route
(app/api/tools/tiktok/publish-video), which trips the route-count
ratchet in check-api-validation-contracts.ts. Bumping totalRoutes and
zodRoutes from 917 to 918 (nonZodRoutes stays 0) to acknowledge the
new route is properly validated.

Co-authored-by: Cursor <cursoragent@cursor.com>
After removing the avatar string outputs, avatar_url_100 was still
requested from TikTok's user info endpoint but never surfaced anywhere.
Removed it from the default field list and the field descriptions, and
noted that avatar_url/avatar_large_url feed the avatarFile output.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/sim/tools/tiktok/query_creator_info.ts
…onfig.params

The block's params function built a local `credential` variable from
params.oauthCredential and returned it under the key `credential` in
every switch case. That literal token is the raw subBlock id, which is
deleted after canonical transformation into `oauthCredential` — the
blocks.test.ts canonical-param-validation suite flags any params
function that still references it.

It was also redundant: oauthCredential is already part of the base
resolved inputs, which the executor merges into the tool call before
config.params overrides are applied, so the OAuth token resolution
(which reads contextParams.oauthCredential) worked regardless. Removed
the explicit credential plumbing, matching the convention already used
by other OAuth blocks like dropbox.ts.

Co-authored-by: Cursor <cursoragent@cursor.com>
query_creator_info had no request.body function, and
formatRequestParams() only attaches a body when tool.request.body is
defined at all — so despite sending Content-Type: application/json,
the request went out with no body whatsoever. Added body: () => ({}),
matching the convention already used by other parameterless-POST tools
in this codebase (Google Vault, Supabase, Square, Gmail, etc.).

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/sim/blocks/blocks/tiktok.ts Outdated
cursor, photoCoverIndex, and videoCoverTimestampMs all used a truthy
check (params.x && {...}) to decide whether to include an optional
numeric override, which drops a legitimate 0 (first page has no
cursor issue aside, photoCoverIndex 0 is TikTok's own default cover
photo, and timestamp 0 is a valid first-frame cover). Switched to
explicit undefined/empty-string checks, matching the !== undefined
convention the underlying tools already use.

In today's resolution pipeline these fields always arrive as strings
(even chained block references get stringified by the template
resolver), and a non-empty string like "0" is truthy, so this wasn't
actively broken end-to-end - but it was relying on that subtlety
rather than being correct by construction, and was inconsistent with
the tools' own undefined checks.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/sim/blocks/blocks/tiktok.ts
videoIds is a long-input (multiline textarea), the same widget used
for the newline-separated photoImages field on this block, but its
parser only split on commas. Entering one ID per line - the natural
pattern for a multiline field, and the one already used elsewhere on
this block - produced a single concatenated garbage string instead of
an array, so TikTok's query would fail or return nothing. Now splits
on commas or newlines, and updated the placeholder/description to
reflect both formats.

Co-authored-by: Cursor <cursoragent@cursor.com>
@BillLeoutsakosvl346

Copy link
Copy Markdown
Author
Screen.Recording.2026-07-08.at.2.06.34.PM.mov

Demo of the new feature!

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 83841a3. Configure here.

Comment thread apps/sim/app/api/webhooks/tiktok/route.ts Outdated
Co-authored-by: Cursor <cursoragent@cursor.com>
@BillLeoutsakosvl346

Copy link
Copy Markdown
Author

@greptile please do a final check of the new tiktok webhook code!

@BillLeoutsakosvl346

Copy link
Copy Markdown
Author

Demo of the tiktok webhook trigger!

Screen.Recording.2026-07-08.at.6.38.17.PM.mov

@icecrasher321 icecrasher321 changed the title feat(tiktok): add basic TikTok integration feat(tiktok): add tiktok trigger, block Jul 9, 2026
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.

2 participants