Коротко
Статья показывает, как расширение publishing-kit переносит Markdown в Substack через браузер, поскольку у платформы нет API публикации. Ключевой приём — подготовить HTML, учесть потери редактора и проверить сохранённый черновик через его JSON, а не полагаться на то, что видно на экране.
Контекст
Автор развивает publishing-kit — инструмент для Claude Code, Codex и Antigravity, который публикует материалы на нескольких площадках; Substack стал его пятой целью после dev.to, Medium, AWS Builder Center и LinkedIn. Исходная задача: надёжно переносить статьи в редактор Substack, который может молча удалять или менять элементы форматирования.
Главное
- Substack не предоставляет API публикации, поэтому статья использует веб-редактор и браузерную автоматизацию.
- Решение описано для publishing-kit 0.32.0 и Claude Code, Codex или Antigravity; в проверенном запуске использовались Claude Code и Linux.
- Для Substack берётся Medium HTML через
python3 make-medium.py devto-substack-destination.md medium --cover=cover.325bdb37.jpg; нужный файл —-hosted.html, где изображения доступны по публичным URL. - Таблиц в редакторе нет: сборщик преобразует их в PNG. Substack загружает внешние изображения и сохраняет их alt-текст.
- Встроенная ссылка вида
<a><code>текст</code></a>теряет ссылку, потому что схема ProseMirror запрещает совмещать markcodeс другими marks.prepare()снимает обёртку ссылки вокруг кода. - Языковой класс у
<pre>удаляется: блок с меткойtextиначе сохраняется как математическийlatex_block; Substack не сохраняет язык кодовых блоков. - HTML и helper передаются в редактор через
window.name, поскольку Content Security Policy страницы мешает запросу к локальной машине; вставка выполняется вызовомss.paste(). - Автор проверяет не только DOM страницы, но и сохранённый черновик через
/api/v1/drafts/<id>: так можно увидеть потерянные ссылки и сверить число блоков и изображений. - Заголовок и подзаголовок задаются отдельно; лимит подзаголовка — 255 символов. Превышение может остановить сохранение всего черновика.
- Публикация по умолчанию отправляет письмо всем подписчикам; helper требует явно подтвердить email и аудиторию и обрабатывает дополнительный диалог о кнопках подписки.
Как сделано
Для Substack повторно используют HTML-сборку для Medium: python3 make-medium.py devto-substack-destination.md medium --cover=cover.325bdb37.jpg. Таблицы и схемы превращаются в PNG, размещённые по публичным GitHub URL; Substack загружает изображения и размещает их у себя. В сборке нужно использовать -hosted.html, а не вариант с data: URI.
Браузерный агент переносит HTML и скрипт skills/publishing/scripts/browser/substack-editor.js через window.name, открывает страницу создания черновика и вызывает ss.prepare(p.html), затем ss.paste(). Подготовка удаляет заголовочный блок, распаковывает ссылки вокруг inline code, меняет <h4> на <h3> и снимает языковые классы с <pre>, чтобы блок text не превратился в LaTeX. После вставки ss.audit() проверяет JSON черновика по /api/v1/drafts/<id>; ss.setTitle() задаёт заголовок и подзаголовок.
Перед публикацией ss.openPublish() проверяет настройки. ss.publish({email: true, audience: "everyone"}) публикует только при совпадении ожидаемых настроек и отвечает на дополнительный диалог о кнопках подписки. Затем ss.published() получает фактический URL и идентификатор публикации.
Результаты
В описанном запуске publishing-kit 0.32.0 опубликовал статью 5 октября 2026 года в Substack из фоновой вкладки в Claude Code на Linux. В сохранённом черновике обнаружены 4 многострочных блока кода с исходным числом строк, 2 изображения с сохранённым alt-текстом, 7 заголовков h3 и все 4 целевые ссылки после исправления ссылок вокруг inline code. Опубликованная ссылка была получена из ответа Substack и проверена скриптом объявлений; проверка дала 0 ошибок и 1 предупреждение для Medium из-за HTTP 403 на запрос с браузерным User-Agent.
Ограничения
Проверен один материал, одна публикация и одна конфигурация — publishing-kit 0.32.0, Claude Code на Linux, дата 2026-10-05; свойства редактора и его схемы могут измениться. У Substack нет API публикации и нет таблиц: таблицы приходится превращать в изображения и отправлять через браузер. По умолчанию публикация рассылает email всем подписчикам и отправляет push-уведомление; действие нельзя отменить. Подзаголовок длиннее 255 символов блокирует сохранение всего черновика, даже если редактор визуально показывает тело статьи. Автор не приводит оценку затрат или систематическое сравнение на большом наборе публикаций.
Что взять себе
- При публикации через веб-редактор проверяйте сохранённую структуру документа, а не только визуальное отображение: некоторые потери происходят без ошибки.
- Перед переносом Markdown выясните ограничения целевого редактора и заранее преобразуйте неподдерживаемые элементы — например, таблицы в изображения.
- Осторожно обращайтесь с сочетаниями форматирования: ссылки вокруг inline code могут исчезнуть, даже если код остаётся видимым.
- До нажатия кнопки публикации явно проверьте настройки рассылки; для Substack отправка всем подписчикам включена по умолчанию.
- Учитывайте отдельные поля заголовка и лимит подзаголовка в 255 символов, иначе может не сохраниться весь материал.
Читать оригинал, если…
Откройте оригинал, если нужны команды и код helper-скрипта, структура publishing-kit или подробные шаги настройки браузерной автоматизации и публикации.