Skip to main content

threads-auto-post

Threads affiliate auto-post: v19 — Browserless HTTP primary + Shopee buyer-review 5★+media HD + Pinterest fallback + 1-post=1-link forever. Content CERITA/TIPS Viewbait v5: post_1 first line ALL CAPS + total ≥210 chars. Cron no_agent=true, script_timeout≥900, THREADS_ALLOW_UI_FALLBACK=0. See references/viewbait-v5-and-cron-timeout-fix.md. Triggers: post threads, review image, caption/hook, provider timeout threads post.

Jump to install

Source facts

Repository
Sekolah76/syadagentic
Last source activity
August 26, 2026 at 15:28
Detected SKILL.md language
English
Stars
24
Forks
9

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
76 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
threads-auto-post
description
Threads affiliate auto-post: v19 — Browserless HTTP primary + Shopee buyer-review 5★+media HD + Pinterest fallback + 1-post=1-link forever. Content CERITA/TIPS Viewbait v5: post_1 first line ALL CAPS + total ≥210 chars. Cron no_agent=true, script_timeout≥900, THREADS_ALLOW_UI_FALLBACK=0. See references/viewbait-v5-and-cron-timeout-fix.md. Triggers: post threads, review image, caption/hook, provider timeout threads post.
tags
["threads","affiliate","shopee","auto-post","browserless","http","image-upload","hook-engine","playwright","sso","dedup","camoufox"]
related_skills
["threads-auto-reply"]
# Threads Affiliate Auto-Post (v18.0) ## CRITICAL RULES - **Refs**: `references/shopee-review-image-and-dedup-v18.md` (product-only 5★+media HD scrape + permanent link dedup). - **Pool/batch**: skill `affiliate-pool-isolation-and-batch` + `~/.hermes/scripts/affiliate_batch_manager.py` (auto-advance batch N→N+1 saat unused=0; pool 100 unique terverifikasi 2026-07-13). - **Refs**: `references/affiliate-pool-batch-and-count.md` — auto-advance batch N→N+1 when UNUSED=0; isolated pools per channel; **always count unique `s.shopee.co.id` URLs** (header "100" can lie — was 97 until 3 missing links injected 2026-07-13). - **1 Post = 1 Link Affiliate Forever**: Tidak boleh ada daur ulang (recycle) dari `USED` ke `UNUSED`. Permanent: `threads_used_links.json`. Simpan log di `~/.hermes/scripts/threads_used_links.json`. - **Review Gambar Produk Real (Bukan Katalog)**: - Wajib ambil ulasan pembeli bintang 5 dengan media (`5 bintang` + `dengan media`). - Tolak URL non-produk (halaman toko/shop homepage). - Ekstrak menggunakan `i.src` original (bukan `currentSrc` thumbnail `@resize_w144`). ## CRITICAL DISTINCTIONS - **"Postingan"** = POST BARU (original content). Skill ini. - **"Reply"** / **"Komentar"** = Balasan di postingan orang lain. Pakai `threads-auto-reply`. - **JANGAN CAMPUR ADUK.** ## Shopee Review Image (MUST) - **Product-link only.** Resolve affiliate shortlink → `/product/{shop_id}/{item_id}`. Reject shop/store URLs. - **5★ + Dengan Media only.** Never product gallery / catalog / avatar. - **HD original path:** use `img.getAttribute('src')` (or cleaned original). Do **not** prefer `currentSrc` — Shopee injects `@resize_w144_nl.webp` thumbs (~5KB). - **Module:** `~/.hermes/scripts/shopee_scraper.py` → `scrape_review_image()`. - **Cron wire:** `run_threads_post.sh` (`no_agent=true`) → `cron_post.py` → `get_real_review_photo()` **must** call `scrape_review_image` (do not re-inline old camoufox scraper). - Full procedure + pitfalls: `references/shopee-review-scraper.md` - **Shopee Review Image**: WAJIB link produk (bukan toko) + filter 5 Bintang + HD. Lihat `references/shopee-review-image-scraper.md`. ## Publish path (2026-07-13) Engine order in `cron_post.py`: 1. **`threads_post_http.py`** — Browserless HTTP v2 (Image Upload + GraphQL/Rupload, 0 RAM, super-fast) - Image Upload: `POST /rupload_igphoto/fb_uploader_{upload_id}` (image/jpeg) - Configure Feed: `POST /api/v1/media/configure_text_post_app_feed/` (image root) - Chaining/Text replies: `POST /api/v1/media/configure_text_only_post/` - Speed: 0 RAM, ~1.2s per post, pure `urllib`/`requests`. 2. **`threads_post_applescript.py`** — Chrome Profile 16 live window - Fill: **System Events paste** (`pbcopy` + cmd+v) — trusted input - Send: score Kirim **y>300 x>700 first**, Quartz/OS mouse + Meta+Enter fallback - Hook fetch/XHR for Create/Publish names - Hard verify profile or mutation 3. **`threads_post_p16_playwright.py`** — clone minimal P16 → `/tmp/chrome_threads_p16_ud` - Non-default user-data so Chrome allows automation - Playwright keyboard.type + mouse.click (trusted-ish) - Clone Cookies/Network/Local Storage only; clear Singleton* locks 4. **`threads_post_v6.py`** — legacy cookie inject (last resort) Env override: `THREADS_FORCE_PLAYWRIGHT=1` → skip HTTP & AS, use cookie PW path only (debug). ## Browserless HTTP Engine Specification (configure_text_only_post) - **URL**: `POST https://www.threads.net/api/v1/media/configure_text_only_post/` - **Headers**: - `X-IG-App-ID`: `238260118697367` (Native Threads app ID) - `X-ASBD-ID`: `129477` - `Cookie`: MUST contain valid `sessionid`, `csrftoken`, `ds_user_id` - `X-CSRFToken`: value from `csrftoken` cookie - **Payload Schema (urlencoded)**: - `publish_mode`: `text_post` - `timezone_offset`: `25200` - `caption`: post text content - `client_context`: `<epoch_ms>-<rand_5_digits>` - `text_post_app_info`: JSON string containing: - Root post: `{"reply_control": 0}` - Child thread reply: `{"reply_control": 0, "reply_id": "<parent_pk>", "is_reply": true, "reply_to_author": "<uid>"}` - `replied_to_media_id` (only for child replies): parent post `pk` (not code) - **Success Criteria**: Response JSON status == `ok` AND `media.pk` (e.g. `3939965155132008399`) and `media.code` (e.g. `DatkW8LD2fP`) exist. Use `media.pk` as `replied_to_media_id` and `text_post_app_info.reply_id` for the next reply in the chain. ## Hard gate (same for all engines) ## Browserless / pure HTTP (research 2026-07-13) Target: GraphQL `POST /api/graphql` tanpa browser. **Belum production.** - IG cookie alone ≠ Threads session (pure HTTP SSO belum auto). - Wajib: `lsd` + `fb_dtsg` + Threads session + mutation Create/Publish/Barcelona*Create*. - Build order: hybrid network capture → `scripts/threads_post_http.py`. - Full blueprint: `references/browserless-graphql-post.md`, `references/auth-preflight-jagonya.md`. ## 🔥 STORY MODE / JUAL CERITA > **Publish hard-verify + anti-false-success:** `references/story-mode-publish-hard-verify.md` > History canonical: `~/.hermes/scripts/threads_post_history.json` only (never skill-dir). > **Kirim click ≠ success.** Write history / mark USED only after GraphQL Create/Publish mutation **or** strict profile `inner_text` unique snip (hook≥24 / product≥8 / link tail). See `references/kirim-publish-hard-verify.md`. > **Send order:** bottom-right Kirim first (`y>300`, `x>700`, score≥100) → `has-text("Kirim").last force=True` → never prefer `has-text("Post").last` (false feed matches). > **False soft-verify:** HTML-only / soft profile match without mutation caused false success 2026-07-12 — independent re-check; revert history if not live. > Cookie: Chrome Profile 16 → `jagonya_shopee`; multi-domain inject IG + Threads. > Pre-unpause: dry-run `threads_story_dry_run.py 12` + live post hard-verify; cron stays paused until SYADAGENTIC says unpause. (2026-07-12) — ACTIVE DEFAULT **SYADAGENTIC redesign: posting = jual cerita, bukan review/value tip polos.** Engine: `~/.hermes/scripts/threads_story_engine.py` · wired di `cron_post.py` v5. ### 3-beat formula (HARD) | Post | Isi | Larangan | |---|---|---| | **1** | Scene + konflik (curhat) | ❌ produk, brand, CTA, link | | **2** | Twist / insight cerita | ❌ hard CTA / link; product soft max ~40% | | **3** | Resolusi + soft CTA + save + `s.shopee.co.id` | ✅ link HANYA di sini | ### 6 story types (rotasi, no repeat 4 last) `keresahan_malam` · `malu_sosial` · `salah_beli` · `teman_bukti` · `open_loop` · `regret` Mapped per kategori: skincare / parfum / haircare / makeup. ### Soft CTA bank - "yang mau coba, link ada di bawah 🫶" - "yang penasaran, gw taro link-nya 👇" - "save dulu aja, nanti kalo butuh tinggal klik 📌" - "buat yang mau coba, cek di bawah ya 🤍" History fields: `hook_category` = story_type · `content_mode=story_v1` · `story_type`. ### Story ops (2026-07-12) - **Dry-run:** `~/.hermes/scripts/threads_story_dry_run.py 12` (no browser) — must pass unique link/hook + no adjacent same story before unpause. - **Dedup stack + USED mark:** `references/story-mode-dedup-no-agent.md` - **Auth preflight (blocks live post):** `references/auth-preflight-jagonya.md` — verify session **is** `@jagonya_shopee` (`ds_user_id=3310347890`), not just `web_profile_info` 200. P16 can be logged in as another IG account (e.g. olivia.vanesso). - History path **canonical only:** `~/.hermes/scripts/threads_post_history.json` (not skill dir). - `cron_post.py` must use `if __name__ == "__main__"` guard (import-safe for dry-run). - `mark_link_used` + DB sync **only after** publisher success. ## 🔥 SOFT SELLING RULE (2026-06-23) — still applies under story mode **SYADAGENTIC explicitly wants SOFT SELLING.** Story mode is the implementation. - **Thread 1–2: Pure story.** No hard product dump, no CTA. - **Thread terakhir: Minimal CTA.** Soft line + link — NO "cek sekarang", NO "beli di sini". - **Never brand-dump in hook.** Build curiosity first. - **Tone: friend sharing, NOT seller.** - Pattern: scene → twist → soft close + link ### Soft CTA examples (USE these): - "yang mau coba, link ada di bawah 🫶" - "yang penasaran, gw taro link-nya 👇" - "save dulu aja, nanti kalo butuh tinggal klik 📌" - "buat yang mau coba, cek di bawah ya 🤍" ### Hard CTA examples (DON'T use): - ❌ "CEK SEKARANG SEBELUM KEHABISAN" - ❌ "BELI DI SINI 👇👇👇" - ❌ "Jangan sampai ketinggalan!" - ❌ "FLASH SALE!!!" ## ⚠️ HARD RULE: WAJIB AFFILIATE LINK - **POST TERAKHIR (3/5/6/7) HARUS contain `s.shopee.co.id/XXXX`** — no exceptions - Jangan pernah posting thread tanpa link di post terakhir - Kalau link database kosong → JANGAN POST, report to user instead - User explicitly warned: "jangan postingan doang" — always verify POST TERAKHIR has link before Kirim - **LINK INSERTION (v8)**: Use `navigator.clipboard.writeText()` + `Meta+v` paste. `keyboard.type()` does NOT trigger Threads' URL detection. Clipboard paste is the ONLY method that works (verified 2026-06-11). - **PRE-SEND VERIFY**: check `editors.nth(N).inner_text()` contains link before clicking Send. If missing → retry with paste, then keyboard.type fallback. ## 📸 IMAGE STRATEGY — MANDATORY REAL USER REVIEW PHOTOS (v15 — 2026-06-27 CORRECTION) **⚠️ CRITICAL 2026-06-27: Threads posts MUST use Shopee review images ONLY via Camoufox. NO Pinterest fallback. NO AI images. NO product thumbnails. NO random images. If Shopee returns no valid review image → SKIP IMAGE entirely.** **⚠️ CRITICAL 2026-06-27 v2 — `/product/` URL FIX:** The resolved shortlink format `shopee.co.id/{shop_name}/{shop_id}/{item_id}` loads the STORE PAGE, not the product page. ALWAYS convert to `shopee.co.id/product/{shop_id}/{item_id}` format. Store pages have NO review images. This was SYADAGENTIC's frustration point: "Tolol tolol kenapa masuk ke toko nya sih anjing" and later "INI CONTOH LINK TOKO vs LINK PRODUK". **⚠️ SCROLL LIMITATION (2026-06-27): JS-only extraction cannot reliably distinguish product carousel images from user review photos.** Shopee's rating-media-list uses randomized class names. Next build needs vision model or deterministic DOM traversal to section correct images. SYADAGENTIC corrected this mid-session 2026-06-27: Pinterest search returned a valid-looking review image for the WRONG PRODUCT (Vienna Parfum Mist Rose Garden → wrong bottle). Mismatched photos are WORSE than no image. For Threads, image must match the affiliate product EXACTLY. **2026-06-26: ALWAYS use REAL user review photos. NEVER generate AI images. NEVER use studio mockups.** SYADAGENTIC explicitly prefers real photos from actual user reviews — people holding the product, swatches on skin, products on messy desks/nightstands. These convert better and look more trustworthy than studio shots. ### Acceptance Criteria for Images: - ✅ Tangan memegang produk | Swatches di kulit | Produk ditaruh di meja/kasur kasual - ✅ Pencahayaan natural (bukan studio) | Ada objek sekitar (boneka, gelas, kabel, dsb) - ❌ AI-generated | Render 3D/mockup | Background putih polos terisolasi | Studio lighting sempurna ### Image Sourcing Priority (v15 — 2026-06-27, CORRECTED BY SYADAGENTIC): **CRITICAL: Threads posts MUST use Shopee review images ONLY. Pinterest fallback caused mismatched product photos (SYADAGENTIC flagged this mid-session 2026-06-27 — Vienna Parfum Mist Rose Garden got wrong bottle image). For Threads, NO Pinterest, NO AI, NO random images. Only Shopee review via Camoufox — if invalid, skip image.** #### Threads Posts (AFFILIATE): 1. 🥇 **Shopee Review Image via Camoufox** — PRIMARY Uses `camoufox` CLI attached to Chrome Profile 16 (`chrome_local_102130715962900495`) in headed mode: - **Product URL only:** resolve shortlink → `/product/{shop_id}/{item_id}`. Shop/store URL = hard REJECT. (`shopee_scraper.resolve_product_url`) - Opens product page via `camoufox browser open <profile> "<product_url>" --headed` - Scroll ~18× to mount rating overview (lazy). Do not stop on product-title "Penilaian" count alone. - Click filters in order: **`5 Bintang`** → **`Dengan Media`** - Extract ONLY buyer review imgs: `.rating-media-list img` / `img.rating-media-list__image-wrapper--image` - **HD trap:** use `i.getAttribute('src')` / `i.src` — NOT `currentSrc` (often `@resize_w144_nl.webp` ~5KB thumb) - Strip `@resize_w*_nl`, `.webp`, `_tn`, `_sm` → original `susercontent.com/file/{id}` - Validate: file size ≥20KB AND PIL resolution ≥250×250; pick highest `w*h` - Download to `/tmp/threads_post_image.jpg` - **Fallback:** if scraper fails OR images too small/invalid → empty string (skip image) — NEVER fallback to Pinterest for Threads - Implementation: `~/.hermes/scripts/shopee_scraper.py` + `get_real_review_photo()` in `cron_post.py`
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub