Ворклог по задаче "Настроить Open Graph / meta-теги для корректных превью страниц в мессенджерах"

16 сент. 2026 г., 20:45:24

Прогресс: сначала исполнимая проверка, потом реализация

Перед внесением изменений сначала был написан отдельный терминальный TypeScript-скрипт, который делает HTTP-запрос к странице, парсит HTML через cheerio и проверяет обязательные Open Graph-теги. Это дало объективный baseline до начала правок и готовый критерий приёмки для ИИ-агента.

Проверочный скрипт

import * as cheerio from "cheerio";

const REQUIRED_TAGS = [
  "og:title",
  "og:description",
  "og:image",
  "og:url",
  "og:type",
] as const;

function isAbsoluteHttpUrl(value: string): boolean {
  try {
    const url = new URL(value);
    return url.protocol === "http:" || url.protocol === "https:";
  } catch {
    return false;
  }
}

async function main() {
  const targetUrl = process.argv[2];

  if (!targetUrl) {
    console.error("Usage: npx tsx check-open-graph.ts <url>");
    process.exit(2);
  }

  const response = await fetch(targetUrl, {
    redirect: "follow",
    headers: {
      "User-Agent": "OpenGraphChecker/1.0",
    },
  });

  if (!response.ok) {
    console.error(`HTTP ${response.status} ${response.statusText}`);
    process.exit(1);
  }

  const html = await response.text();
  const $ = cheerio.load(html);

  let hasErrors = false;

  console.log(`HTTP: ${response.status}\n`);

  const values = Object.fromEntries(
    REQUIRED_TAGS.map((property) => {
      const value =
        $(`meta[property="${property}"]`).first().attr("content")?.trim() ?? "";

      if (!value) {
        console.log(`${property}: missing`);
        hasErrors = true;
      } else {
        console.log(`${property}: ${value}`);
      }

      return [property, value];
    }),
  );

  const image = values["og:image"];
  const ogUrl = values["og:url"];

  if (image && !isAbsoluteHttpUrl(image)) {
    console.log(`✗ og:image is not absolute: ${image}`);
    hasErrors = true;
  }

  if (ogUrl && !isAbsoluteHttpUrl(ogUrl)) {
    console.log(`✗ og:url is not absolute: ${ogUrl}`);
    hasErrors = true;
  }

  console.log(
    hasErrors
      ? "\nRESULT: invalid or incomplete"
      : "\nRESULT: OK",
  );

  process.exit(hasErrors ? 1 : 0);
}

main().catch((error) => {
  console.error(error);
  process.exit(1);
});

Состояние до реализации

Первый запуск дал ожидаемо отрицательный результат:

HTTP: 200

✗ og:title: missing
✗ og:description: missing
✗ og:image: missing
✗ og:url: missing
✗ og:type: missing

RESULT: invalid or incomplete

После этого задача была передана ИИ-агенту уже не в абстрактной формулировке «добавить Open Graph», а вместе с конкретным скриптом проверки и воспроизводимым способом проверить результат.

Отчёт агента

Агент сообщил о следующих изменениях:

Готово. Изменения:

index.tsx — добавлены props image и ogType, выводятся og:title, og:description, og:image, og:url, og:type
index.tsx — вычисляется imageUrl и передаётся в SeoHeaders с ogType="product"
Можешь проверить скриптом:

npx tsx scripts/check-page-image/index.ts "http://localhost:3000/catalog/product.html"

Повторная проверка

После изменений тот же проверочный подход дал:

HTTP: 200

✓ og:title: Мелкогабаритная площадка Корабль
✓ og:description: Размер 3.48 х 1.78 х 2.32 м.
✓ og:image: http://localhost:3000/images/resized/middle/images/img.jpg
✓ og:url: http://localhost:3000/catalog/product.html
✓ og:type: product

RESULT: OK

Практический вывод

Подход оказался полезным: сначала создаётся маленькая исполнимая проверка, фиксирующая текущее состояние и критерий готовности, а затем эта же проверка передаётся исполнителю вместе с задачей. Это уменьшает неоднозначность постановки и делает результат проверяемым не по отчёту агента, а по фактическому поведению системы.

Следующий шаг — усиливать этот шаблон: если агенту даётся проверочный скрипт, в постановке сразу требовать не только внести изменения, но и самостоятельно запустить этот скрипт после реализации и приложить фактический результат. Тогда цикл становится замкнутым: reproduce → implement → verify, а человеку остаётся уже контрольная, а не первичная проверка.

16.09.2026

Явно задать для страниц сайта метаданные превью (заголовок, описание, изображение), чтобы мессенджеры и соцсети корректно формировали карточку ссылки.