feat: scaffold Next.js 15 project with TypeScript and Tailwind
This commit is contained in:
@@ -0,0 +1,578 @@
|
||||
# Platform Specs & Integration Guide: Instagram, TikTok, Nextdoor
|
||||
|
||||
**Target platforms for your pipeline.** This document replaces the generic platform coverage in the original analysis with specific specs, API details, and implementation guidance for your three platforms.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Platform Comparison Matrix](#1-platform-comparison-matrix)
|
||||
2. [Instagram — Full Spec](#2-instagram--full-spec)
|
||||
3. [TikTok — Full Spec](#3-tiktok--full-spec)
|
||||
4. [Nextdoor — Full Spec](#4-nextdoor--full-spec)
|
||||
5. [Updated Knowledge File: platform_guidelines.md](#5-updated-knowledge-file-platform_guidelinesmd)
|
||||
6. [Updated Agent Modifications](#6-updated-agent-modifications)
|
||||
7. [Updated Environment Variables](#7-updated-environment-variables)
|
||||
8. [Publishing Flow Per Platform](#8-publishing-flow-per-platform)
|
||||
9. [Key Differences from Original System](#9-key-differences-from-original-system)
|
||||
|
||||
---
|
||||
|
||||
## 1. Platform Comparison Matrix
|
||||
|
||||
| Dimension | Instagram | TikTok | Nextdoor |
|
||||
|-----------|-----------|--------|----------|
|
||||
| **Primary format** | Feed (1:1), Reels (9:16), Stories (9:16) | Vertical video (9:16) | Feed image (1:1), Display (16:9) |
|
||||
| **Video max length** | Reels: 15 min (ads: keep ≤30s) | 10 min (ads: keep 15-30s) | 2-120s (keep ≤30s) |
|
||||
| **Image dimensions** | Feed: 1080x1080, Portrait: 1080x1350 | N/A (video-first) | 1200x1200 (spotlight), 1200x628 (display) |
|
||||
| **Video dimensions** | 1080x1920 (9:16) | 1080x1920 (9:16) | 1080x1920 (9:16) or 1920x1080 (16:9) |
|
||||
| **API type** | Instagram Graph API (REST) | Content Posting API (REST) | Ads API (GraphQL) |
|
||||
| **Auth** | OAuth via Meta Business Login | OAuth 2.0 + PKCE | OAuth2 / Bearer / Basic |
|
||||
| **Publishing flow** | Create container → wait → publish | Init upload → upload video → direct post | Create campaign → ad group → ad → creative |
|
||||
| **Token expiry** | 60 days (long-lived) | 24 hours (refreshable) | Varies |
|
||||
| **Organic posting** | Yes (via Graph API) | Yes (Content Posting API) | Limited (2 free/month for business) |
|
||||
| **Tone** | Aspirational, polished, punchy | Raw, authentic, trend-driven | Neighborly, local, trustworthy |
|
||||
| **Audience** | Broad consumer, visual-first | Gen Z / Millennials, entertainment-first | Homeowners, local community, 25-65 |
|
||||
|
||||
---
|
||||
|
||||
## 2. Instagram — Full Spec
|
||||
|
||||
### Ad Formats & Dimensions
|
||||
|
||||
| Format | Dimensions | Aspect Ratio | Max File Size | Duration |
|
||||
|--------|-----------|--------------|---------------|----------|
|
||||
| **Feed Post** | 1080 x 1080 px | 1:1 (square) | 30 MB (image) | — |
|
||||
| **Feed Portrait** | 1080 x 1350 px | 4:5 | 30 MB | — |
|
||||
| **Feed Landscape** | 1080 x 566 px | 1.91:1 | 30 MB | — |
|
||||
| **Stories** | 1080 x 1920 px | 9:16 | 4 GB (video) | ≤15s per clip |
|
||||
| **Reels** | 1080 x 1920 px | 9:16 | 4 GB | ≤90s (API), rec ≤30s for ads |
|
||||
| **Carousel** | 1080 x 1080 px | 1:1 | 30 MB per card | Up to 10 cards |
|
||||
|
||||
### Safe Zones
|
||||
- **Stories/Reels top:** Leave 14% (250px) clear for username/camera icons
|
||||
- **Stories/Reels bottom:** Leave 20% (340px) clear for CTA/swipe-up UI
|
||||
- **Key content:** Center of frame
|
||||
|
||||
### Video Specs
|
||||
- **Format:** MP4 (H.264 codec preferred)
|
||||
- **Frame rate:** 24-30 fps (30 recommended)
|
||||
- **Audio:** AAC, 128kbps+
|
||||
- **Captions:** Recommended (80% of users watch with sound off)
|
||||
|
||||
### Caption Guidelines
|
||||
- **Length:** ≤125 chars for ads (2 lines visible), up to 2200 chars for organic
|
||||
- **Structure:** Hook → Value/Vibe → CTA → line break → Hashtags (3-5)
|
||||
- **Emojis:** 1-2 max
|
||||
|
||||
### API Integration
|
||||
|
||||
**Permissions needed:**
|
||||
- `instagram_business_basic`
|
||||
- `instagram_business_content_publish`
|
||||
|
||||
**Publishing flow (Node.js):**
|
||||
```javascript
|
||||
// Step 1: Create media container
|
||||
const container = await fetch(
|
||||
`https://graph.facebook.com/v20.0/${IG_USER_ID}/media`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
image_url: supabasePublicUrl, // Must be publicly accessible
|
||||
caption: captionText,
|
||||
access_token: INSTAGRAM_ACCESS_TOKEN
|
||||
// For Reels: add media_type: 'REELS', video_url: videoPublicUrl
|
||||
})
|
||||
}
|
||||
);
|
||||
const { id: containerId } = await container.json();
|
||||
|
||||
// Step 2: Check container status (for video)
|
||||
// Poll GET /{containerId}?fields=status_code until status_code === 'FINISHED'
|
||||
|
||||
// Step 3: Publish
|
||||
const publish = await fetch(
|
||||
`https://graph.facebook.com/v20.0/${IG_USER_ID}/media_publish`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
creation_id: containerId,
|
||||
access_token: INSTAGRAM_ACCESS_TOKEN
|
||||
})
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
**Rate limit:** 200 requests/hour/account
|
||||
|
||||
**Token management:**
|
||||
- Long-lived tokens expire after **60 days**
|
||||
- Exchange short-lived → long-lived via `/oauth/access_token`
|
||||
- Set calendar reminder or automated refresh before expiry
|
||||
|
||||
### Sources
|
||||
- [Instagram Graph API Complete Guide 2026](https://elfsight.com/blog/instagram-graph-api-complete-developer-guide-for-2026/)
|
||||
- [Instagram Content Publishing Docs](https://developers.facebook.com/docs/instagram-platform/content-publishing/)
|
||||
- [Instagram Reels API Guide](https://www.getphyllo.com/post/a-complete-guide-to-the-instagram-reels-api)
|
||||
- [Instagram Ad Dimensions 2026](https://admanage.ai/blog/instagram-ad-dimensions)
|
||||
|
||||
---
|
||||
|
||||
## 3. TikTok — Full Spec
|
||||
|
||||
### Ad Formats & Dimensions
|
||||
|
||||
| Format | Dimensions | Aspect Ratio | Max File Size | Duration |
|
||||
|--------|-----------|--------------|---------------|----------|
|
||||
| **In-Feed Video** | 1080 x 1920 px | 9:16 (required) | 500 MB | 9-60s (ads), up to 10 min (organic) |
|
||||
| **Square** | 1080 x 1080 px | 1:1 | 500 MB | Same |
|
||||
| **Landscape** | 1920 x 1080 px | 16:9 | 500 MB | Same |
|
||||
|
||||
**9:16 vertical is mandatory for best performance** — square and landscape are technically supported but consistently underperform.
|
||||
|
||||
### Video Specs
|
||||
- **Format:** MP4, MOV, MPEG, 3GP, AVI
|
||||
- **Min resolution:** 540 x 960 (9:16) / 640 x 640 (1:1)
|
||||
- **Bitrate:** ≥516 kbps
|
||||
- **Frame rate:** 24-30 fps
|
||||
- **Audio:** Required (TikTok is sound-on by default)
|
||||
|
||||
### Creative Best Practices
|
||||
- **Hook in first 3 seconds** (not 5 — TikTok scrolls fast)
|
||||
- **On-screen text:** Large, central, ≤6 words per frame
|
||||
- **Keep key elements centered** — description/logo overlay crops edges
|
||||
- **Optimal length:** 15-30s for ads, 21-34s per TikTok's own data
|
||||
- **Style:** Raw/authentic outperforms polished — "made on TikTok, not for TikTok"
|
||||
- **Sound:** Essential — 93% of top-performing TikToks use audio
|
||||
- **Subtitles:** Always include (accessibility + sound-off viewing)
|
||||
|
||||
### Caption Guidelines
|
||||
- **Length:** Up to 4000 chars (but shorter = better for engagement)
|
||||
- **Hashtags:** 3-5 relevant hashtags, mix trending + niche
|
||||
- **Tone:** Casual, conversational, trend-aware, slightly irreverent
|
||||
- **No hard-sell CTAs** — soft CTAs work better ("link in bio", "check this out")
|
||||
|
||||
### API Integration
|
||||
|
||||
**TikTok Content Posting API — OAuth 2.0 + PKCE flow:**
|
||||
|
||||
```javascript
|
||||
// Step 1: Redirect user to TikTok authorization
|
||||
const authUrl = `https://www.tiktok.com/v2/auth/authorize/?` +
|
||||
`client_key=${CLIENT_KEY}&scope=user.info.basic,video.publish` +
|
||||
`&response_type=code&redirect_uri=${REDIRECT_URI}&state=${csrfState}`;
|
||||
|
||||
// Step 2: Exchange code for access token
|
||||
const tokenRes = await fetch('https://open.tiktokapis.com/v2/oauth/token/', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: new URLSearchParams({
|
||||
client_key: CLIENT_KEY,
|
||||
client_secret: CLIENT_SECRET,
|
||||
code: authCode,
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: REDIRECT_URI
|
||||
})
|
||||
});
|
||||
const { access_token, refresh_token } = await tokenRes.json();
|
||||
|
||||
// Step 3: Init video upload
|
||||
const initRes = await fetch('https://open.tiktokapis.com/v2/post/publish/video/init/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${access_token}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
post_info: {
|
||||
title: 'Your caption here #hashtag',
|
||||
privacy_level: 'PUBLIC_TO_EVERYONE',
|
||||
disable_duet: false,
|
||||
disable_comment: false,
|
||||
disable_stitch: false
|
||||
},
|
||||
source_info: {
|
||||
source: 'FILE_UPLOAD',
|
||||
video_size: fileSize,
|
||||
chunk_size: fileSize,
|
||||
total_chunk_count: 1
|
||||
}
|
||||
})
|
||||
});
|
||||
const { data: { publish_id, upload_url } } = await initRes.json();
|
||||
|
||||
// Step 4: Upload video binary to upload_url
|
||||
await fetch(upload_url, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Range': `bytes 0-${fileSize - 1}/${fileSize}`,
|
||||
'Content-Type': 'video/mp4'
|
||||
},
|
||||
body: videoBuffer
|
||||
});
|
||||
```
|
||||
|
||||
**Token management:**
|
||||
- Access tokens expire in **24 hours**
|
||||
- Refresh tokens last **365 days**
|
||||
- **Must implement auto-refresh** — unlike Instagram's 60-day window, TikTok tokens expire daily
|
||||
|
||||
**Two posting modes:**
|
||||
1. **Direct Post** — content goes live immediately (use for automation)
|
||||
2. **Upload to Inbox** — queues in creator's drafts for manual review
|
||||
|
||||
**No native scheduling** — implement your own via cron/BullMQ/Redis
|
||||
|
||||
### Sources
|
||||
- [TikTok Content Posting API Docs](https://developers.tiktok.com/products/content-posting-api/)
|
||||
- [TikTok Direct Post Reference](https://developers.tiktok.com/doc/content-posting-api-reference-direct-post)
|
||||
- [TikTok OAuth Token Management](https://developers.tiktok.com/doc/oauth-user-access-token-management)
|
||||
- [TikTok Ad Specs 2026](https://admanage.ai/blog/tiktok-ad-specs)
|
||||
- [TikTok Content Posting Developer Guide 2026](https://www.tokportal.com/learn/tiktok-content-posting-api-developer-guide)
|
||||
|
||||
---
|
||||
|
||||
## 4. Nextdoor — Full Spec
|
||||
|
||||
### Important: Nextdoor is Different
|
||||
|
||||
Nextdoor operates fundamentally differently from Instagram/TikTok:
|
||||
- **Audience:** Hyperlocal — homeowners, families, local businesses in verified neighborhoods
|
||||
- **Tone:** Neighborly, trustworthy, community-first (NOT flashy marketing speak)
|
||||
- **API access:** Ads API requires partnership application; organic posting limited to 2 free business posts/month
|
||||
- **Ad format:** Primarily static image ads; video supported but not the primary format
|
||||
- **Targeting:** Geographic (neighborhood-level), demographic, interest-based — leverages 14 years of verified neighbor data
|
||||
|
||||
### Ad Formats & Dimensions
|
||||
|
||||
| Format | Dimensions | Aspect Ratio | Max File Size | Notes |
|
||||
|--------|-----------|--------------|---------------|-------|
|
||||
| **Spotlight Ad** | 1200 x 1200 px | 1:1 | 1 MB | JPG/PNG, premium placement |
|
||||
| **Display Ad** | 1200 x 628 px | ~1.91:1 | 150 MB | JPG/PNG/GIF |
|
||||
| **Multi-destination (Carousel)** | 1200 x 1200 px min | 1:1 | 150 MB | 2-10 images, JPG/PNG |
|
||||
| **Video Ad** | Variable | 16:9 or 1:1 | 500 MB | MP4/MOV, 2-120s, rec ≤30s |
|
||||
| **Video Thumbnail** | 1200 x 628 px | ~16:9 | — | Auto-generated or custom |
|
||||
| **Lead Gen (Image)** | 1200 x 628 px | 1.91:1 | 150 MB | JPG/PNG |
|
||||
| **Lead Gen (Video)** | Variable | 16:9 or 1:1 | 500 MB | MP4/MOV |
|
||||
|
||||
### Creative Best Practices
|
||||
- **Subtitles on video** — always (many users browse silently)
|
||||
- **Keep video ≤30 seconds** for best engagement
|
||||
- **Local feel** — avoid stock-photo-corporate look; authentic, neighborhood imagery performs best
|
||||
- **CTA clarity** — "Learn More", "Get a Quote", "Visit Us" (direct, local-action oriented)
|
||||
- **No aggressive sales language** — Nextdoor's community first-ethos; "hard sell" gets reported
|
||||
|
||||
### Tone Guidelines (Critical for Nextdoor)
|
||||
- **DO:** Sound like a helpful neighbor, reference local context, use warm/genuine language
|
||||
- **DON'T:** Sound like a national brand blast, use hype/urgency tactics, be salesy
|
||||
- **Think:** "Hey neighbors, we just launched..." NOT "LIMITED TIME OFFER! ACT NOW!"
|
||||
|
||||
### API Integration
|
||||
|
||||
**Nextdoor Ads API — GraphQL-based:**
|
||||
|
||||
The Ads API is a single GraphQL endpoint supporting queries and mutations across 7 resources: profile, advertiser, campaign, ad group, ad, creative, media, reports.
|
||||
|
||||
**Access:** Requires application through [developer.nextdoor.com](https://developer.nextdoor.com/). Not self-service — you need partnership approval.
|
||||
|
||||
**Auth options:** Basic Auth, Bearer Token, or OAuth2
|
||||
|
||||
**Campaign creation flow:**
|
||||
```
|
||||
1. Create Advertiser account (or use existing)
|
||||
2. Create Campaign (objective, budget, schedule)
|
||||
3. Create Ad Group (targeting, bid strategy)
|
||||
4. Upload Media (image/video creative)
|
||||
5. Create Ad (links creative to ad group)
|
||||
6. Campaign goes into review → approved → live
|
||||
```
|
||||
|
||||
**What must be done in Nextdoor Ads Manager (not API):**
|
||||
- Initial signup
|
||||
- Payment method setup
|
||||
- Custom audience creation
|
||||
- Media archiving
|
||||
|
||||
**Organic posting alternative:**
|
||||
- Nextdoor Publish API allows programmatic organic posts
|
||||
- **Limit:** 2 free business posts/month
|
||||
- Partners like Orlo and ZenCity can schedule and geo-target posts
|
||||
- Best for: local news, community updates, soft-sell brand presence
|
||||
|
||||
### Env Variables Needed
|
||||
|
||||
```bash
|
||||
# Nextdoor Ads API
|
||||
NEXTDOOR_API_TOKEN=YOUR_BEARER_TOKEN # Or use OAuth2 credentials
|
||||
NEXTDOOR_ADVERTISER_ID=YOUR_ADVERTISER_ID # From Ads Manager
|
||||
|
||||
# Nextdoor Publish API (organic)
|
||||
NEXTDOOR_PUBLISH_API_KEY=YOUR_KEY # If using organic posting
|
||||
```
|
||||
|
||||
### Sources
|
||||
- [Nextdoor Ads API Overview](https://developer.nextdoor.com/docs/advertising-overview)
|
||||
- [Nextdoor Developer Portal](https://developer.nextdoor.com/)
|
||||
- [Nextdoor Creative Specs](https://business.nextdoor.com/en-us/nam/nextdoor-ads-manager/creative-specs)
|
||||
- [Nextdoor Ad Specs 2025 (PDF)](https://coegipartners.com/wp-content/uploads/2025/01/NextDoor-Specs-2025.pdf)
|
||||
- [Nextdoor Ads API Launch Announcement](https://about.nextdoor.com/press-releases/nextdoor-launches-ads-api-program-offering-advertisers-an-easier-way-to-extend-their-campaigns-to-nextdoor)
|
||||
|
||||
---
|
||||
|
||||
## 5. Updated Knowledge File: platform_guidelines.md
|
||||
|
||||
Replace the original 3-platform file with this structure:
|
||||
|
||||
```markdown
|
||||
# Platform Guidelines: [Your Brand]
|
||||
|
||||
**Purpose:** Ensures all content is correctly formatted and styled per platform
|
||||
before publishing. Reference before finalizing any post, video, or caption.
|
||||
|
||||
---
|
||||
|
||||
## 1. Platform Overview
|
||||
|
||||
| Platform | Content Types | Primary Tone | Hashtags |
|
||||
|----------|--------------|--------------|----------|
|
||||
| **Instagram** | Feed (1:1), Reels (9:16), Stories (9:16), Carousel | Aspirational, polished, punchy | Required (3-5) |
|
||||
| **TikTok** | Vertical video (9:16) only | Raw, authentic, trend-driven | Required (3-5) |
|
||||
| **Nextdoor** | Feed image (1:1), Display (16:9), Video | Neighborly, local, trustworthy | Not used |
|
||||
|
||||
---
|
||||
|
||||
## 2. Instagram
|
||||
|
||||
### Image Specs
|
||||
| Format | Dimensions | Ratio |
|
||||
|--------|-----------|-------|
|
||||
| Feed Post | 1080 x 1080 px | 1:1 |
|
||||
| Feed Portrait | 1080 x 1350 px | 4:5 |
|
||||
| Story/Reel | 1080 x 1920 px | 9:16 |
|
||||
|
||||
### Caption Rules
|
||||
- Length: 1-3 sentences before hashtags
|
||||
- Structure: Hook + Value + CTA + line break + Hashtags
|
||||
- Emojis: 1-2 from approved set
|
||||
- CTA: Always include, place before hashtags
|
||||
|
||||
### Safe Zones (Stories/Reels)
|
||||
- Top 14% (250px) — keep clear
|
||||
- Bottom 20% (340px) — keep clear
|
||||
|
||||
---
|
||||
|
||||
## 3. TikTok
|
||||
|
||||
### Video Specs
|
||||
| Property | Requirement |
|
||||
|----------|------------|
|
||||
| Dimensions | 1080 x 1920 px (9:16 mandatory) |
|
||||
| Length | 15-30s optimal for ads |
|
||||
| Format | MP4, ≥516 kbps |
|
||||
| Audio | Required (sound-on platform) |
|
||||
| Subtitles | Always include |
|
||||
|
||||
### Caption Rules
|
||||
- Tone: Casual, conversational, trend-aware
|
||||
- Hashtags: 3-5 (mix trending + niche)
|
||||
- No hard-sell CTAs — use "link in bio", "check this out"
|
||||
- Hook in first 3 seconds
|
||||
- On-screen text: ≤6 words per frame, large, centered
|
||||
|
||||
### Key Difference from Instagram
|
||||
TikTok rewards authenticity over polish. Content should feel
|
||||
"made on TikTok" — raw, energetic, personality-driven.
|
||||
Overproduced content underperforms.
|
||||
|
||||
---
|
||||
|
||||
## 4. Nextdoor
|
||||
|
||||
### Image Specs
|
||||
| Format | Dimensions | Ratio |
|
||||
|--------|-----------|-------|
|
||||
| Spotlight Ad | 1200 x 1200 px | 1:1 |
|
||||
| Display Ad | 1200 x 628 px | ~1.91:1 |
|
||||
| Video | MP4/MOV | 16:9 or 1:1 |
|
||||
|
||||
### Tone Rules (CRITICAL)
|
||||
- Sound like a helpful neighbor, NOT a national brand
|
||||
- Reference local context when possible
|
||||
- Warm, genuine, community-first language
|
||||
- NO hype, urgency tactics, or aggressive sales language
|
||||
- CTA style: "Learn More", "Get a Quote", "Visit Us"
|
||||
|
||||
### Caption Rules
|
||||
- Keep it conversational and local
|
||||
- No hashtags (Nextdoor doesn't use them)
|
||||
- Focus on community value, not product pushing
|
||||
- Video: ≤30 seconds with subtitles
|
||||
|
||||
### Posting Limits
|
||||
- Organic: 2 free business posts/month
|
||||
- Ads: Via Ads Manager or Ads API (requires partnership)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Updated Agent Modifications
|
||||
|
||||
### Ad Creative Designer — Changes
|
||||
|
||||
The original system only generated 1080x1080 Instagram square ads. For your three platforms, the agent needs to produce **multiple format variants per campaign:**
|
||||
|
||||
| Platform | Static Ad Size | Video Size |
|
||||
|----------|---------------|------------|
|
||||
| Instagram Feed | 1080 x 1080 px | 1080 x 1920 px (Reels) |
|
||||
| Instagram Stories | 1080 x 1920 px | 1080 x 1920 px |
|
||||
| TikTok | N/A (video only) | 1080 x 1920 px |
|
||||
| Nextdoor Spotlight | 1200 x 1200 px | — |
|
||||
| Nextdoor Display | 1200 x 628 px | 1920 x 1080 or 1080 x 1080 |
|
||||
|
||||
**Playwright screenshot configs needed:**
|
||||
```javascript
|
||||
const PLATFORM_CONFIGS = {
|
||||
instagram_feed: { width: 1080, height: 1080 },
|
||||
instagram_stories: { width: 1080, height: 1920 },
|
||||
nextdoor_spotlight: { width: 1200, height: 1200 },
|
||||
nextdoor_display: { width: 1200, height: 628 },
|
||||
};
|
||||
```
|
||||
|
||||
### Video Ad Specialist — Changes
|
||||
|
||||
Must now produce **two video variants:**
|
||||
|
||||
| Platform | Dimensions | Aspect | Length | Style |
|
||||
|----------|-----------|--------|--------|-------|
|
||||
| Instagram Reels | 1080 x 1920 | 9:16 | ≤30s | Polished, branded |
|
||||
| TikTok | 1080 x 1920 | 9:16 | 15-30s | Raw, authentic, trend-driven |
|
||||
| Nextdoor (optional) | 1080 x 1080 or 1920 x 1080 | 1:1 or 16:9 | ≤30s | Local, warm, community feel |
|
||||
|
||||
**Key insight:** Instagram and TikTok share the same 9:16 dimensions but the **creative style should differ significantly.** The Remotion composition should accept a `style` parameter:
|
||||
- `style: "polished"` → clean motion graphics, brand colors, professional typography (Instagram)
|
||||
- `style: "authentic"` → rougher transitions, text overlays, trend-aware pacing (TikTok)
|
||||
- `style: "local"` → warm, simple, community-focused (Nextdoor)
|
||||
|
||||
### Copywriter Agent — Changes
|
||||
|
||||
Must now produce **3 platform-specific copy files** instead of the original 3:
|
||||
|
||||
```
|
||||
outputs/{task_name}_{date}/copy/
|
||||
├── instagram_caption.txt # Hook + Value + CTA + hashtags
|
||||
├── tiktok_caption.txt # Casual, trend-aware, soft CTA + hashtags
|
||||
├── nextdoor_post.txt # Neighborly, local, no hashtags
|
||||
└── copy_output.json # Consolidated structured data
|
||||
```
|
||||
|
||||
### Distribution Agent — Changes
|
||||
|
||||
Now handles **3 different API integrations:**
|
||||
|
||||
| Platform | API | Auth | Publishing Flow |
|
||||
|----------|-----|------|----------------|
|
||||
| Instagram | Graph API (REST) | OAuth, 60-day tokens | Create container → wait FINISHED → publish |
|
||||
| TikTok | Content Posting API (REST) | OAuth 2.0 + PKCE, 24-hour tokens | Init upload → PUT video binary → direct post |
|
||||
| Nextdoor | Ads API (GraphQL) | Bearer/OAuth2, requires partnership | Campaign → Ad Group → Creative → Ad |
|
||||
|
||||
**Token refresh automation is critical:**
|
||||
- Instagram: refresh before 60-day expiry
|
||||
- TikTok: **auto-refresh daily** (24-hour expiry)
|
||||
- Nextdoor: depends on auth method
|
||||
|
||||
---
|
||||
|
||||
## 7. Updated Environment Variables
|
||||
|
||||
```bash
|
||||
# .env.example
|
||||
|
||||
# === Research ===
|
||||
TAVILY_API_KEY=tvly-YOUR_API_KEY
|
||||
|
||||
# === Media Storage ===
|
||||
SUPABASE_URL=YOUR_SUPABASE_PROJECT_URL
|
||||
SUPABASE_SERVICE_ROLE_KEY=YOUR_SUPABASE_SERVICE_ROLE_KEY
|
||||
|
||||
# === Instagram Graph API ===
|
||||
INSTAGRAM_ACCOUNT_ID=YOUR_INSTAGRAM_PROFESSIONAL_ACCOUNT_ID
|
||||
INSTAGRAM_ACCESS_TOKEN=YOUR_INSTAGRAM_USER_ACCESS_TOKEN
|
||||
# Permissions: instagram_business_basic, instagram_business_content_publish
|
||||
# Token expires: 60 days — implement refresh
|
||||
|
||||
# === TikTok Content Posting API ===
|
||||
TIKTOK_CLIENT_KEY=YOUR_TIKTOK_APP_CLIENT_KEY
|
||||
TIKTOK_CLIENT_SECRET=YOUR_TIKTOK_APP_CLIENT_SECRET
|
||||
TIKTOK_ACCESS_TOKEN=YOUR_TIKTOK_USER_ACCESS_TOKEN
|
||||
TIKTOK_REFRESH_TOKEN=YOUR_TIKTOK_REFRESH_TOKEN
|
||||
# Token expires: 24 hours — MUST auto-refresh daily
|
||||
# Refresh token expires: 365 days
|
||||
|
||||
# === Nextdoor Ads API ===
|
||||
NEXTDOOR_API_TOKEN=YOUR_NEXTDOOR_BEARER_TOKEN
|
||||
NEXTDOOR_ADVERTISER_ID=YOUR_NEXTDOOR_ADVERTISER_ID
|
||||
# Requires partnership application at developer.nextdoor.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Publishing Flow Per Platform
|
||||
|
||||
### Instagram
|
||||
```
|
||||
Media generated locally
|
||||
→ Upload to Supabase (public URL required)
|
||||
→ POST /{ig-user-id}/media (create container with public URL)
|
||||
→ Poll container status until FINISHED
|
||||
→ POST /{ig-user-id}/media_publish (publish)
|
||||
→ Return post ID
|
||||
```
|
||||
|
||||
### TikTok
|
||||
```
|
||||
Video generated locally
|
||||
→ POST /v2/post/publish/video/init/ (get upload_url)
|
||||
→ PUT video binary to upload_url
|
||||
→ TikTok processes and publishes
|
||||
→ Return publish_id
|
||||
```
|
||||
Note: TikTok accepts direct file upload — **no Supabase intermediary needed** for TikTok (unlike Instagram). However, keeping Supabase as the central store is still good practice for archival.
|
||||
|
||||
### Nextdoor
|
||||
```
|
||||
For Ads (via Ads API):
|
||||
→ Upload media asset via API
|
||||
→ Create Campaign (objective, budget)
|
||||
→ Create Ad Group (targeting, schedule)
|
||||
→ Create Ad (link creative + copy)
|
||||
→ Submit for review → auto-approved → live
|
||||
|
||||
For Organic (via Publish API):
|
||||
→ POST content via Publish API
|
||||
→ Limited to 2 free posts/month
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Key Differences from Original System
|
||||
|
||||
| Aspect | Original (Andy's System) | Your System |
|
||||
|--------|-------------------------|-------------|
|
||||
| **Platforms** | Instagram, YouTube, Threads | Instagram, TikTok, Nextdoor |
|
||||
| **Video style** | Single polished style | Multiple styles (polished, authentic, local) |
|
||||
| **Static ad sizes** | 1080x1080 only | 1080x1080, 1080x1920, 1200x1200, 1200x628 |
|
||||
| **API complexity** | 3 simple REST APIs | REST + REST + GraphQL (Nextdoor) |
|
||||
| **Token management** | Instagram 60-day only | Instagram 60-day + TikTok daily refresh |
|
||||
| **Tone variation** | Single brand voice | 3 platform-adapted voices from same brand identity |
|
||||
| **Nextdoor** | Not included | Requires partnership application + community-first creative |
|
||||
| **Supabase role** | Required for Instagram | Required for Instagram, optional for TikTok, required for Nextdoor ads |
|
||||
| **YouTube** | Included | Dropped (can add back) |
|
||||
| **Threads** | Included | Dropped (can add back) |
|
||||
| **Scheduling** | Basic advisory | Need custom scheduler for TikTok (no native scheduling API) |
|
||||
|
||||
---
|
||||
|
||||
*Compiled March 2026. Verify API versions and access requirements before implementation.*
|
||||
Reference in New Issue
Block a user