Xurl

X/Twitter через CLI xurl: посты, поиск, личные сообщения, медиа, API v2.

Метаданные навыка

ИсточникВстроенный (установлен по умолчанию)
Путьskills/social-media/xurl
Версия1.1.1
Авторxdevplatform + openclaw + Hermes Agent
ЛицензияMIT
Платформыlinux, macos
Тегиtwitter, x, social-media, xurl, official-api

Справочник: полный SKILL.md

инфо

Ниже приведено полное определение навыка, которое Hermes загружает при его срабатывании. Именно это агент видит как инструкции, когда навык активен.

xurl — API X (Twitter) через официальный CLI

xurl — официальный CLI платформы для разработчиков X, работающий с X API. Он умеет и сокращённые команды для частых действий, и сырой доступ в стиле curl к любому эндпоинту v2. Все команды возвращают JSON в stdout.

Навык пригодится, чтобы:

  • публиковать посты, отвечать, цитировать, удалять
  • искать посты и читать ленты/упоминания
  • ставить лайки, репостить, добавлять в закладки
  • подписываться, отписываться, блокировать, заглушать
  • отправлять личные сообщения
  • загружать медиа (картинки и видео)
  • получать сырой доступ к любому эндпоинту X API v2
  • работать с несколькими приложениями и аккаунтами

Этот навык приходит на смену старому навыку xitter (он оборачивал сторонний Python-CLI). xurl поддерживается командой платформы для разработчиков X, работает с OAuth 2.0 PKCE и авто-обновлением токенов, а покрытие API существенно шире.


Безопасность секретов (ОБЯЗАТЕЛЬНО)

Критические правила при работе внутри сессии агента/LLM:

  • Никогда не читай, не выводи, не разбирай, не пересказывай, не загружай и не отправляй ~/.xurl в контекст LLM.
  • Никогда не проси пользователя вставлять учётные данные/токены в чат.
  • Пользователь заполняет ~/.xurl секретами вручную на своей машине. В Docker это должен быть тот ~, который видят подпроцессы инструментов Hermes; см. примечание про Docker ниже.
  • Никогда не советуй и не выполняй команды авторизации с секретами в строке в сессиях агента.
  • Никогда не используй --verbose / -v в сессиях агента — это может раскрыть заголовки авторизации и токены.
  • Чтобы проверить наличие учётных данных, применяй только: xurl auth status.

Запрещённые флаги в командах агента (они принимают секреты прямо в строке): --bearer-token, --consumer-key, --consumer-secret, --access-token, --token-secret, --client-id, --client-secret

Регистрацию учётных данных приложения и их ротацию пользователь делает вручную, вне сессии агента. После регистрации учётных данных пользователь авторизуется командой xurl auth oauth2 — тоже вне сессии агента. Токены сохраняются в ~/.xurl в формате YAML. У каждого приложения свои изолированные токены. Токены OAuth 2.0 обновляются автоматически.


Установка

Выбери ОДИН способ. На Linux проще всего shell-скрипт или go install.

# Shell-скрипт (ставит в ~/.local/bin, без sudo, работает на Linux + macOS)
curl -fsSL https://raw.githubusercontent.com/xdevplatform/xurl/main/install.sh | bash

# Homebrew (macOS)
brew install --cask xdevplatform/tap/xurl

# npm
npm install -g @xdevplatform/xurl

# Go
go install github.com/xdevplatform/xurl@latest

Проверка:

xurl --help
xurl auth status

Если xurl установлен, но auth status не показывает ни приложений, ни токенов, пользователю нужно завершить авторизацию вручную — см. следующий раздел.


Разовая настройка пользователем (пользователь выполняет это вне агента)

Эти шаги пользователь делает сам, НЕ агент, потому что они связаны со вставкой секретов. Направь пользователя к этому блоку; не выполняй его за него.

  1. Создай или открой приложение на https://developer.x.com/en/portal/dashboard

  2. Укажи redirect URI как http://localhost:8080/callback

  3. Скопируй Client ID и Client Secret приложения

  4. Зарегистрируй приложение локально (выполняет пользователь):

    xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET
  5. Авторизуйся (укажи --app, чтобы привязать токен к своему приложению):

    xurl auth oauth2 --app my-app

    (Откроется браузер для потока OAuth 2.0 PKCE.)

    Если X возвращает ошибку UsernameNotFound или 403 при пост-OAuth запросе /2/users/me, передай свой хэндл явно (xurl v1.1.0+):

    xurl auth oauth2 --app my-app YOUR_USERNAME

    Так токен привязывается к твоему хэндлу, а сломанный вызов /2/users/me пропускается.

  6. Сделай приложение приложением по умолчанию, чтобы все команды использовали его:

    xurl auth default my-app
  7. Проверь:

    xurl auth status
    xurl whoami

После этого агент может использовать любую команду ниже без дополнительной настройки. Токены OAuth 2.0 обновляются автоматически.

Частая ошибка: если пропустить --app my-app в xurl auth oauth2, токен OAuth сохранится во встроенный профиль приложения default — у которого нет ни client-id, ни client-secret. Команды будут падать с ошибками авторизации, хотя поток OAuth вроде бы прошёл успешно. Если попался на это, перезапусти xurl auth oauth2 --app my-app и xurl auth default my-app.

Ловушка с HOME в Docker: в официальной раскладке Hermes Docker /opt/data — это HERMES_HOME, но подпроцессы инструментов Hermes используют /opt/data/home как HOME. Значит, для запускаемых через Hermes команд xurl путь ~/.xurl разрешается в /opt/data/home/.xurl, а не в /opt/data/.xurl. Выполни настройку пользователя с тем же HOME:

HOME=/opt/data/home xurl auth apps add my-app --client-id YOUR_CLIENT_ID --client-secret YOUR_CLIENT_SECRET
HOME=/opt/data/home xurl auth oauth2 --app my-app YOUR_USERNAME
HOME=/opt/data/home xurl auth default my-app YOUR_USERNAME
HOME=/opt/data/home xurl auth status

Если HOME=/opt/data xurl auth status срабатывает, а HOME=/opt/data/home xurl auth status не показывает ни приложений, ни токенов, то вызовы инструментов Hermes учётных данных не увидят.


Быстрый справочник

ДействиеКоманда
Опубликовать постxurl post "Hello world!"
Ответитьxurl reply POST_ID "Nice post!"
Процитироватьxurl quote POST_ID "My take"
Удалить постxurl delete POST_ID
Прочитать постxurl read POST_ID
Искать постыxurl search "QUERY" -n 10
Кто яxurl whoami
Найти пользователяxurl user @handle
Домашняя лентаxurl timeline -n 20
Упоминанияxurl mentions -n 10
Лайк / Снять лайкxurl like POST_ID / xurl unlike POST_ID
Репост / Отменитьxurl repost POST_ID / xurl unrepost POST_ID
Закладка / Убратьxurl bookmark POST_ID / xurl unbookmark POST_ID
Список закладок / лайковxurl bookmarks -n 10 / xurl likes -n 10
Подписаться / Отписатьсяxurl follow @handle / xurl unfollow @handle
Подписки / Подписчикиxurl following -n 20 / xurl followers -n 20
Блок / Разблокxurl block @handle / xurl unblock @handle
Заглушить / Снятьxurl mute @handle / xurl unmute @handle
Отправить ЛСxurl dm @handle "message"
Список ЛСxurl dms -n 10
Загрузить медиаxurl media upload path/to/file.mp4
Статус медиаxurl media status MEDIA_ID
Список приложенийxurl auth apps list
Удалить приложениеxurl auth apps remove NAME
Задать приложение по умолчаниюxurl auth default APP_NAME [USERNAME]
Приложение для одного запросаxurl --app NAME /2/users/me
Статус авторизацииxurl auth status

Примечания:

  • POST_ID принимает и полные URL (например, https://x.com/user/status/1234567890) — xurl извлекает ID сам.
  • Имена пользователей работают как с ведущим @, так и без него.

Подробности по командам

Публикация

xurl post "Hello world!"
xurl post "Check this out" --media-id MEDIA_ID
xurl post "Thread pics" --media-id 111 --media-id 222

xurl reply 1234567890 "Great point!"
xurl reply https://x.com/user/status/1234567890 "Agreed!"
xurl reply 1234567890 "Look at this" --media-id MEDIA_ID

xurl quote 1234567890 "Adding my thoughts"
xurl delete 1234567890

Чтение и поиск

xurl read 1234567890
xurl read https://x.com/user/status/1234567890

xurl search "golang"
xurl search "from:elonmusk" -n 20
xurl search "#buildinpublic lang:en" -n 15

Для X Articles используй режим сырого API вместо сокращения read. xurl read ждёт ID поста или URL поста; не ставь read перед эндпоинтом /2/tweets/.... Запроси поле твита article и забери data.article.plain_text из ответа JSON:

xurl --app APP_NAME '/2/tweets/2057909493250539891?expansions=author_id,attachments.media_keys,referenced_tweets.id&tweet.fields=created_at,lang,public_metrics,context_annotations,entities,possibly_sensitive,conversation_id,in_reply_to_user_id,referenced_tweets,article'

Пользователи, лента, упоминания

xurl whoami
xurl user elonmusk
xurl user @XDevelopers

xurl timeline -n 25
xurl mentions -n 20

Взаимодействие

xurl like 1234567890
xurl unlike 1234567890

xurl repost 1234567890
xurl unrepost 1234567890

xurl bookmark 1234567890
xurl unbookmark 1234567890

xurl bookmarks -n 20
xurl likes -n 20

Социальный граф

xurl follow @XDevelopers
xurl unfollow @XDevelopers

xurl following -n 50
xurl followers -n 50

# Граф другого пользователя
xurl following --of elonmusk -n 20
xurl followers --of elonmusk -n 20

xurl block @spammer
xurl unblock @spammer
xurl mute @annoying
xurl unmute @annoying

Личные сообщения

xurl dm @someuser "Hey, saw your post!"
xurl dms -n 25

Загрузка медиа

# Автоопределение типа
xurl media upload photo.jpg
xurl media upload video.mp4

# Явный тип/категория
xurl media upload --media-type image/jpeg --category tweet_image photo.jpg

# Видео нужна обработка на сервере — проверь статус (или опрашивай)
xurl media status MEDIA_ID
xurl media status --wait MEDIA_ID

# Полный сценарий
xurl media upload meme.png                  # возвращает id медиа
xurl post "lol" --media-id MEDIA_ID

Сырой доступ к API

Сокращения покрывают частые операции. Для всего остального используй сырой режим в стиле curl к любому эндпоинту X API v2:

# GET
xurl /2/users/me

# POST с телом JSON
xurl -X POST /2/tweets -d '{"text":"Hello world!"}'

# DELETE / PUT / PATCH
xurl -X DELETE /2/tweets/1234567890

# Свои заголовки
xurl -H "Content-Type: application/json" /2/some/endpoint

# Принудительный стриминг
xurl -s /2/tweets/search/stream

# Полные URL тоже работают
xurl https://api.x.com/2/users/me

Глобальные флаги

ФлагКраткоОписание
--appИспользовать конкретное зарегистрированное приложение (переопределяет умолчание)
--authПринудительный тип авторизации: oauth1, oauth2 или app
--username-uКакой аккаунт OAuth2 использовать (если их несколько)
--verbose-vЗапрещён в сессиях агента — утекают заголовки авторизации
--trace-tДобавить трассировочный заголовок X-B3-Flags: 1

Стриминг

Стриминговые эндпоинты определяются автоматически. Среди известных:

  • /2/tweets/search/stream
  • /2/tweets/sample/stream
  • /2/tweets/sample10/stream

Принудительно включить стриминг на любом эндпоинте можно флагом -s.


Формат вывода

Все команды возвращают JSON в stdout. Структура повторяет X API v2:

{ "data": { "id": "1234567890", "text": "Hello world!" } }

Ошибки тоже приходят в JSON:

{ "errors": [ { "message": "Not authorized", "code": 403 } ] }

Типовые сценарии

Пост с изображением

xurl media upload photo.jpg
xurl post "Check out this photo!" --media-id MEDIA_ID

Ответ в ветке

xurl read https://x.com/user/status/1234567890
xurl reply 1234567890 "Here are my thoughts..."

Поиск и взаимодействие

xurl search "topic of interest" -n 10
xurl like POST_ID_FROM_RESULTS
xurl reply POST_ID_FROM_RESULTS "Great point!"

Проверка своей активности

xurl whoami
xurl mentions -n 20
xurl timeline -n 20

Несколько приложений (учётные данные настроены вручную заранее)

xurl auth default prod alice               # приложение prod, пользователь alice
xurl --app staging /2/users/me             # разовый запрос к staging

Обработка ошибок

  • Любая ошибка даёт ненулевой код выхода.
  • Ошибки API всё равно печатаются в stdout как JSON, так что их можно разобрать.
  • Ошибки авторизации → пусть пользователь перезапустит xurl auth oauth2 вне сессии агента.
  • Команды, которым нужен ID вызывающего пользователя (лайк, репост, закладка, подписка и т. д.), сами получат его через /2/users/me. Сбой авторизации там проявится как ошибка авторизации.

Рабочий процесс агента

  1. Проверь требования: xurl --help и xurl auth status.
  2. Убедись, что у приложения по умолчанию есть учётные данные. Разбери вывод auth status. Приложение по умолчанию отмечено знаком . Если приложение по умолчанию показывает oauth2: (none), а у другого приложения есть валидный пользователь oauth2, скажи пользователю выполнить xurl auth default <это-приложение>, чтобы это исправить. Это самая частая ошибка настройки — пользователь добавил приложение со своим именем, но не сделал его приложением по умолчанию, и xurl продолжает обращаться к пустому профилю default.
  3. Если авторизации нет вообще, остановись и направь пользователя в раздел «Разовая настройка пользователем» — НЕ пытайся регистрировать приложения или передавать секреты сам.
  4. Начни с дешёвого чтения (xurl whoami, xurl user @handle, xurl search ... -n 3), чтобы подтвердить доступность.
  5. Подтверди целевой пост/пользователя и намерение пользователя перед любым действием на запись (пост, ответ, лайк, репост, ЛС, подписка, блок, удаление).
  6. Используй вывод JSON напрямую — каждый ответ уже структурирован.
  7. Никогда не вставляй содержимое ~/.xurl обратно в разговор.

Устранение неполадок

СимптомПричинаРешение
Ошибки авторизации после успешного потока OAuthТокен сохранён в приложение default (без client-id/secret) вместо твоего именованного приложенияxurl auth oauth2 --app my-app, затем xurl auth default my-app
unauthorized_client во время OAuthТип приложения в панели X выставлен как «Native App»Поменяй на «Web app, automated app or bot» в User Authentication Settings
UsernameNotFound или 403 на /2/users/me сразу после OAuthX ненадёжно возвращает имя пользователя из /2/users/meПерезапусти xurl auth oauth2 --app my-app YOUR_USERNAME (xurl v1.1.0+), чтобы передать хэндл явно
401 на каждом запросеТокен истёк или не то приложение по умолчаниюПроверь xurl auth status — убедись, что указывает на приложение с токенами oauth2
client-forbidden / client-not-enrolledПроблема с регистрацией на платформе XDashboard → Apps → Manage → переведи на пакет «Pay-per-use» → окружение Production
CreditsDepletedНулевой баланс в X APIКупи кредиты (минимум $5) в Developer Console → Billing
media processing failed при загрузке картинкиКатегория по умолчанию — amplify_videoДобавь --category tweet_image --media-type image/png
Два значения «Client Secret» в панели XБаг интерфейса — первое на самом деле Client IDСверься на странице «Keys and tokens»; ID оканчивается на MTpjaQ

Примечания

  • Лимиты запросов: X применяет лимиты на каждый эндпоинт. Код 429 значит «подожди и повтори». У эндпоинтов на запись (пост, ответ, лайк, репост) лимиты жёстче, чем у чтения.
  • Скоупы: токены OAuth 2.0 используют широкие скоупы. Код 403 на конкретном действии обычно значит, что токену не хватает скоупа — пусть пользователь перезапустит xurl auth oauth2.
  • Обновление токенов: токены OAuth 2.0 обновляются автоматически. Делать ничего не нужно.
  • Несколько приложений: у каждого приложения свои изолированные учётные данные/токены. Переключайся через xurl auth default или --app.
  • Несколько аккаунтов на приложение: выбирай через -u / --username или задай умолчание командой xurl auth default APP USER.
  • Хранение токенов: ~/.xurl — это YAML. В Docker используй HOME подпроцесса Hermes (/opt/data/home в официальном образе), чтобы токены легли в /opt/data/home/.xurl. Никогда не читай этот файл и не отправляй его в контекст LLM.
  • Стоимость: доступ к X API для сколько-нибудь серьёзного использования обычно платный. Многие сбои — это проблемы тарифа/прав, а не кода.

Атрибуция

ESC