# Reel Radar

> Контент-разведка Instagram под съёмку: берёт эталонный аккаунт твоей ниши, сканирует его подписки, вытаскивает залетевшие рилсы за последние 7 дней, фильтрует по ключевым словам ниши, ранжирует композитно (просмотры + комментарии + ER), транскрибирует, сопоставляет с тем, что уже работает на твоём аккаунте, и отдаёт HTML-дашборд с 25 референсами плюс 15 готовых ТЗ на съёмку — телесуфлёр, монтажный timeline, код-слово. Используй этот скилл, когда просят найти рилсы, сделать разведку рилсов, придумать что снимать, собрать референсы или идеи для съёмки, разобрать что залетает у конкурентов в Instagram, подготовить ТЗ для съёмки на неделю — даже если слово «reel-radar» не произнесено. НЕ для: публикации в Instagram, накрутки, сбора персональных данных, YouTube и TikTok.

- Skill: `qwwiwi/reel-radar` (Agent Skill, multi-file: 23 files)
- Install (CLI): `npx skillmds@latest add qwwiwi/reel-radar`
- Raw SKILL.md: https://api.skillmd.com/api/skills/qwwiwi/reel-radar/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: qwwiwi (https://skillmd.com/u/qwwiwi)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/qwwiwi/reel-radar

---


# Reel Radar — разведка рилсов под съёмку

Пайплайн: подписки эталонного аккаунта → свежие рилсы → фильтр по нише →
ранжирование → транскрипция → сопоставление с твоим аккаунтом → артефакты для
съёмки.

Скилл отвечает на один вопрос: **что снимать на этой неделе**. Не «какие рилсы
хорошие вообще», а «какие форматы прямо сейчас залетают у аккаунтов, за которыми
следит твоя ниша, и какие из них ложатся на твой аккаунт».

## Когда запускать

- Нужны идеи и референсы под съёмку рилсов
- Планёрка по контенту, нужен запас ТЗ на неделю
- Хочешь понять, какие форматы сейчас работают в нише

## Что на выходе

Два типа артефактов, оба HTML (никаких .mp4 на выходе):

1. **`dashboard.html`** — 25 рилсов-референсов: метрики (просмотры, лайки,
   комментарии, ER), почему залетел (формула), темы и ключевые слова, ссылка на
   оригинал, сводная таблица с трендами.

2. **`tz-01.html … tz-15.html`** — готовые задания на съёмку: телесуфлёр, монтажный
   timeline с таймкодами, код-слово для CTA, ссылка на оригинал.

**Отбор 15 из 25** — по релевантности к топ-рилсам твоего собственного аккаунта за
30 дней. Идея простая: не гнаться за чужим успехом, а взять из чужого успеха то,
что уже подтверждено твоей аудиторией.

## Что нужно до запуска

| Что | Зачем | Где взять |
|---|---|---|
| Python 3.9+ | скрипты, только стандартная библиотека | https://python.org |
| FFmpeg | сжатие видео и извлечение аудио | https://ffmpeg.org |
| `HIKER_KEY` | данные Instagram | https://hikerapi.com |
| `GROQ_KEY` | транскрипция (Whisper) | https://console.groq.com |
| `TELEGRAM_BOT_TOKEN` + `TELEGRAM_CHAT_ID` | доставка артефактов, опционально | @BotFather |

```bash
export HIKER_KEY="..."        # понимается и HIKER_API_KEY
export GROQ_KEY="..."         # понимается и GROQ_API_KEY
export TARGET_USER="account"  # эталонный аккаунт ниши, без @
```

Ключи — только через переменные окружения. В скилле не лежит ни одного ключа, ни
одного аккаунта и ни одного chat_id: без настройки скрипты падают с понятной
ошибкой, а не работают «по чужим данным».

## Настройка под свою нишу

**1. Эталонный аккаунт** (`TARGET_USER`, или `target_user` в
`config/defaults.json`, или `--username`). Это аккаунт, чьи подписки сканируются.
Логика: возьми аккаунт, который сам живёт в нише и подписан на её лидеров — его
лента подписок и есть карта ниши. Обычно это твой собственный рабочий аккаунт.

**2. Ключевые слова** — `config/keywords.txt`, по одному на строку, `#` в начале
строки = комментарий. Матч по границе слова, регистр не важен, работает и для
кириллицы. В комплекте лежит пример под нишу AI/агентов — замени на свою
вокабулярку, иначе фильтр выкинет всё релевантное.

**3. Код-слова CTA** — по умолчанию восемь примеров в `scripts/10-gen-tz.py`.
Свои: `CODE_WORDS_FILE=/path/words.json` в формате `[["СЛОВО", "что человек за
это получит"], ...]`, либо разово на весь батч — `FORCE_CTA_CODE` +
`FORCE_CTA_BENEFIT`.

**4. Запасной список аккаунтов** (опционально) — `data/watchlist.example.json`
скопируй в `data/watchlist.json` и заполни своими. Нужен, когда у эталонного
аккаунта закрытые или недоступные подписки: тогда пайплайн идёт по твоему списку.

### Переменные окружения целиком

| Переменная | Что делает |
|---|---|
| `HIKER_KEY` / `HIKER_API_KEY` | ключ провайдера данных, обязателен |
| `GROQ_KEY` / `GROQ_API_KEY` | ключ транскрипции, обязателен |
| `TARGET_USER` | эталонный аккаунт, перекрывает конфиг |
| `TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID` | доставка артефактов |
| `TELEGRAM_EXPECT_BOT` | ожидаемый username бота, проверка перед отправкой |
| `REEL_RADAR_ENV` | путь к своему env-файлу вместо `<skill>/.env` |
| `TOP_FINAL` | сколько ТЗ на выходе, перекрывает `top_final` |
| `COMPRESS_THRESHOLD_MB` | порог сжатия видео, перекрывает конфиг |
| `CACHE_TTL_HOURS` | время жизни кэша подписок |
| `CODE_WORDS_FILE` | свой список код-слов CTA |
| `WATCHLIST` | свой путь к запасному списку аккаунтов |
| `FORCE_CTA_CODE`, `FORCE_CTA_BENEFIT`, `FORCE_CTA_BRIDGE_LEAD` | одинаковый CTA на весь батч |

Остальные пороги и размеры выборок — в `config/defaults.json`; переменные
окружения имеют приоритет над файлом.

## Временное окно

**Рилсы подписок:** последние 7 дней включая сегодня.
**Твои собственные рилсы для релевантности:** последние 30 дней.

Окно всегда считается от `today()` и логируется на старте. Даты нигде не
захардкожены — не подставляй их руками.

## Процесс (11 шагов)

Скрипты в `scripts/`, оркестратор `scripts/run.sh` с поддержкой resume.

**1. Подписки эталонного аккаунта** (`1-fetch-following.py`)
HikerAPI `/v2/user/by/username` → user_id, затем `/v2/user/following` с
пагинацией. Кэш на 24 часа, отдельный файл на каждый аккаунт.

**2. Рилсы по всем найденным аккаунтам** (`2-fetch-reels.py`)
Параллельно (async, semaphore=8): `/v2/user/clips`, фильтр `taken_at` по окну 7
дней, сортировка по `play_count`, топ-3 с аккаунта.

**3. Фильтр по ключевым словам** (`3-filter-relevant.py`)
Матч `config/keywords.txt` против caption, хэштегов и bio автора.

**4. Композитное ранжирование** (`4-rank-composite.py`)
`rank_views + rank_comments + rank_er`, меньше — лучше. Топ-25.

**5. Скачать видео** (`5-download-videos.sh`)
`/v1/media/by/code` → `video_url` → curl. Если больше 50 МБ — сжатие ffmpeg
(libx264, crf 28, scale 720).

**6. Транскрибация** (`6-transcribe.sh`)
ffmpeg → ogg/opus 64k → Groq `whisper-large-v3-turbo`. Успех проверяется по HTTP
200, не по grep по тексту.

**7. Свои топ-рилсы за 30 дней** (`7-fetch-own-reels.py`)
Тот же clips-эндпоинт для твоего аккаунта, топ-10 по просмотрам.

**8. Матч по релевантности** (`8-relevance-match.py`)
Для каждого из 25 кандидатов score 0-100: темы +40, формула +30,
engagement-профиль +30. Топ-15.

**9. Дашборд** (`9-gen-dashboard.py`) — по шаблону `templates/dashboard.html`.

**10. 15 ТЗ** (`10-gen-tz.py`) — по шаблону `templates/tz-reel.html`.

**11. Доставка в Telegram** (`11-deliver-telegram.sh`, опционально)
Проверка личности бота через `getMe`, затем intro → дашборд → 15 ТЗ → финальное
сообщение. Видео не отправляются, папка `videos/` удаляется после транскрипции.

Отдельно, вне основного пайплайна: `find-creators.py` — поиск новых аккаунтов
ниши по ключевым словам и хэштегам, с фильтрами по подписчикам и частоте
публикаций. Нужен, когда подписок эталонного аккаунта мало и пул надо расширить.

## Запуск

```bash
export HIKER_KEY=... GROQ_KEY=... TARGET_USER=...
bash scripts/run.sh --skip-telegram
```

Опции:
- `--resume` — продолжить с последнего завершённого шага
- `--skip-telegram` — не отправлять, только сложить файлы
- `--out /path` — своя папка вывода (по умолчанию `/tmp/reel-radar/YYYY-MM-DD`)

## Правило 1-в-1 (hard rule)

Телесуфлёр в ТЗ = **перевод транскрипта оригинала**, не пересказ и не
переработка. Берёшь фразы по порядку, переводишь, подставляешь свой tone of
voice, меняешь CTA. Всё.

**Остаётся 1-в-1 из оригинала:** продукт и инструмент; workflow и число шагов в
том же порядке; фичи и примеры; логика хука; структура «проблема → решение →
демо → результат»; длина и ритм.

**Меняется только три вещи:**
1. **Язык** — переводится, а не пересказывается своими словами.
2. **Tone of voice** — под твой голос.
3. **CTA в конце** — призыв автора («comment X», «link in bio») заменяется на
   твоё код-слово + бенефит.

**Запрещено:** пересказывать своими словами; подставлять шаблонную формулу
(«Ты не знал, что…», «3 шага, чтобы…») вместо содержания оригинала; менять
продукт; сокращать число шагов «для ритма». Формула используется только для
монтажного timeline, не для текста.

### Пример

Транскрипт (EN):
> This tool is now here and it's going to be coming after the big three. So they just gave us a new application that allows us to build mobile apps, web apps, presentations, front-end design, anything from a graphical interface.

Телесуфлёр (RU, 1-в-1):
> Инструмент вышел. Идёт за большой тройкой. Нам дали приложение, в котором ты собираешь мобильные приложения, веб-приложения, презентации, фронт-энд-дизайн — всё из графического интерфейса.

Тот же продукт, та же мысль, тот же порядок — только переведено и с «ты».

### CTA вшит в телесуфлёр, не отдельным блоком

CTA — **последний абзац самого телесуфлёра**, с плавным переходом из содержания
ролика в код-слово. Единый текст, который читается в кадре без склейки: хук →
контент → CTA.

Мостик строится из содержания именно этого ролика: «…так это и внедряют. И это
только верх айсберга — всю схему разбираю целиком. Напиши СХЕМА в комментах…».
В шаблоне секция «код-слово» остаётся как визуальный дубль для монтажёра — сам
призыв звучит в телесуфлёре.

### Короткий или неруссский транскрипт

Если транскрипт пустой, короче 40 символов или почти без кириллицы, генератор
ставит маркер `[TO_BE_ADAPTED_BY_CLAUDE]` и кладёт сырой транскрипт в
`<details>`. Такой телесуфлёр дописывается вручную — переводом, не выдумкой.
Транскрипт короче 40 символов = пометить ТЗ «требует пересмотра оригинала».

## Валидация перед отправкой (обязательно)

LLM при адаптации склонен добавлять отсебятину и терять блоки оригинала. Два слоя
проверки:

**Слой 1 — детерминированный скрипт:**

```bash
python3 scripts/validate-fidelity.py pairs.json
```

`pairs.json` = `[{"id":…, "reference":<транскрипт>, "teleprompter":<текст без
HTML>, "expected_swaps":["хабспот->амо"], "codeword":"ГАЙД"}]`.

Ловит язык-инвариантные сигналы: потерянные или выдуманные **числа**,
подменённые **бренд-якоря**, **объём** вне нормы (дроп блока или вода), вшито ли
код-слово в хвост. Вердикт PASS / WARN / FAIL, код возврата 1 при FAIL. FAIL —
чинить. WARN — смотреть глазами, часто легитимно (транслит имён, «108000» →
«108 тысяч», намеренный свап через `expected_swaps`).

**Слой 2 — LLM-critic:** прочитать пару (референс ↔ телесуфлёр) и выписать
ADDED (чего нет в оригинале → удалить), REMOVED (что выпало → вернуть), CHANGED
(намеренные правки → ок). Непустые ADDED/REMOVED = переделать. На объёме
выносить в субагента.

Спот-чек перед отправкой: 2-3 ТЗ открыть глазами — совпадает ли продукт,
совпадает ли число шагов, вшит ли CTA последним абзацем.

## Ограничения (честно)

- **Без ключей не работает.** `HIKER_KEY` — обязателен, весь сбор данных стоит на
  нём. `GROQ_KEY` — без него нет транскриптов, а значит ТЗ будут пустыми
  болванками: шаги 6, 10 и правило 1-в-1 держатся на транскрипте.
- **Доступ к данным Instagram неофициальный.** HikerAPI — сторонний сервис,
  официального API для чужих рилсов не существует. Формы ответов меняются без
  предупреждения, эндпоинт может отдать 404/403 на аккаунт, который вчера
  работал. Это не баг скилла, это природа источника.
- **Риск для аккаунта.** Скилл только читает публичные данные и ничего не
  публикует, не лайкает и не подписывается — но сам факт использования
  неофициального доступа к Instagram противоречит его ToS. Не используй чужие
  логины, не подставляй сюда аккаунт, который тебе жалко потерять.
- **Закрытые и забаненные аккаунты.** Если у эталонного аккаунта нет публичного
  списка подписок — шаг 1 вернёт пусто. Тогда нужен `data/watchlist.json`
  вручную; это не автоматизируется.
- **Чего нет в данных в принципе:** досматриваемость, охваты, сохранения,
  переходы, демография. Снаружи их не видит никто. Доступны просмотры, лайки,
  комментарии, дата — из них и считается ER.
- **Транскрипт — не истина.** Whisper ошибается на именах, терминах и плохом
  звуке. Перед съёмкой ТЗ читается глазами.
- **Формула хука определяется эвристикой** по ключевым словам, а не пониманием
  ролика. На пограничных случаях будет «Инсайт» — общий формат по умолчанию.
- **15 ТЗ ≠ 15 готовых сценариев.** Это заготовки с телесуфлёром из перевода
  оригинала. Финальный текст всегда правится человеком.
- **Это инструмент для анализа рынка.** Не собирай персональные данные, не строй
  профили на людей, не копируй чужие ролики дословно — используй как источник
  форматов и формул, а не как копипаст.

## Lessons encoded

- Для пакетного скачивания видео HikerAPI стабильнее публичных даунлоадеров
- Успех транскрипции проверять по HTTP-коду, а не по grep «error» в ответе
- Ключи из env-файла подтягивать через `source`, а не парсингом строк на
  `startswith` — иначе в переменную уедет строка с `export` и получишь 401
- Фоновые прогоны — `nohup … & disown`
- Проверка личности бота перед отправкой обязательна: один неверный токен в
  окружении = отчёт улетел не в тот чат
- Видео больше 50 МБ сжимать до транскрипции
- CTA вшивается в телесуфлёр последним абзацем, не отдельным блоком

