Знакът на КАГАМИ КАГАМИ
kagami.bg/academy · lesson · machine-readable viewVERIFIED 2026-10-01 · UPDATED 2026-10-01
IDENTITY
module
DevStation 5 · Marketing AI agent with n8n: draft, approval, publishing
series
DevStation · lesson 5 of 6
level
Intermediate to advanced
duration
about 3 h
prerequisites
DevStation 2 (Ollama), 3 (n8n + Postgres in Docker), 4 (Canva Connect API + n8n)
trust_label
VERIFIED 2026-10-01 (Canva, Meta, LinkedIn, n8n, Ollama documentation; EU AI Act Art. 50; Bulgarian e-commerce and consumer law; Code-node logic executed as plain JavaScript with mock input) · UPDATED 2026-10-01 · NOT tested end to end (no live LLM, Canva, Meta or LinkedIn calls)
versions
n8n 2.41.x · Ollama models qwen2.5:7b and mistral:7b · Canva Connect REST API v1 · Instagram Platform / Graph API v24+ · LinkedIn Posts API (versioned, YYYYMM)
language
human view: bg · english edition: /en/academy/devstation/ (lesson 5)
previous
DevStation 4 · Canva API designs
next
DevStation 6 · AI decision clone
PURPOSE

Build an n8n pipeline that turns a topic into a DRAFT social-media package: a brief (local LLM, JSON), three copy variants, a Canva design (autofill + export) and a database row with status "draft". Nothing is published automatically: a named human reviews the package, sets status to "approved", and only then does a separate, optional step publish through the platforms' official APIs, or the human posts manually. The lesson also covers platform API rules (Instagram, Facebook Pages, LinkedIn), AI-content disclosure (EU AI Act Art. 50), Google's scaled-content spam policy and commercial e-mail consent rules.

KEY CONCEPTS
COMMANDS / PATHS
CHECKLIST
NEXT MODULE

DevStation 6 · AI decision clone · consent and "AI" label for decision assistants · offer: Quick experiment (kagami.bg/stalbata/)

SOURCES
TAGS
n8nmarketingsocial-mediaollamacanva-apihuman-in-the-loopai-act-art-50instagram-apilinkedin-apigdpr
ПРОВЕРЕНО · 01.10.2026 ОБНОВЕНО · 01.10.2026

Маркетинг AI агент: AI подготвя, човек решава

Задаваш тема, а конвейерът в n8n връща чернова: идея, три варианта на текст, дизайн от Canva и предложен час. Нищо не излиза в мрежата, докато човек не го прегледа и одобри. Това е най-важната разлика от стария вариант на урока, който завършваше със „напълно автоматизирано“.

⏱ около 3 ч Средно–напреднало DevStation · Обучение 5/6 n8n · Ollama · Canva · одобрение от човек
n8n (конвейерът)🔒 локално Ollama: qwen2.5:7b, mistral:7b🔒 локално Postgres (опашката с чернови)🔒 локално Canva Connect API🌐 глобален Meta и LinkedIn API (по избор)🌐 глобален
🔄
ОБНОВЕНО · 01.10.2026 — какво
Дизайн с човек в цикъла: конвейерът спира на статус „чернова“; одобрението е отделно, записано действие (кой и кога), а публикуването чете само одобрени редове. Автоматичното публикуване не е част от основния път. Поправени пътища на Canva: старият урок викаше /designs/{id}/autofill и /designs/{id}/export, които не са в документацията; верните са POST /v1/autofills и POST /v1/exports с проверка на задачата. PNG → JPG: API-то на Instagram приема само JPEG. Махнати са непроверими числа: таблицата с „оптимални часове“ (Instagram Вт, Ср, Пт 10:00 и т.н.) нямаше източник; сега часът се предлага от твой собствен график и твоята статистика. Махнат е и капанът „AI брои символите“: броим в код. Добавени са правилата: Instagram, Facebook Pages и LinkedIn (кой достъп е самообслужване и кой иска одобрение), етикетът за AI съдържание по чл. 50 от AI Act (в сила от 02.08.2026), политиката на Google срещу масово съдържание, съгласие за търговски имейли (ЗЕТ, GDPR). Поправен код: парсване с проверка на полетата, часови пояс Европа/София вместо „EET“ с фиксиран час, SQL със статуси и проверка. Санирано: махнати вътрешната машина и видеокартата, вътрешни папки и потребителски имена. Тезата „имейл кампании с AI“ от стария агентски блок я нямаше в съдържанието — тук имейлът е само вътрешен преглед. Не е пускано от край до край с жив модел, Canva или платформи — затова етикетът е ПРОВЕРЕНО, не ТЕСТВАНО.

01Какво ще научиш

02Преди да започнеш

⛔
Правилата на играта
1) Нищо не се публикува без одобрение от човек. 2) Не измисляме цени, отстъпки, отзиви, цитати и клиенти: моделът ползва само фактите от входа. 3) Ключовете за достъп живеят в Credentials на n8n, не в работния процес и не в този урок.

03Стъпки

  1. Схемата: конвейер, който спира при човек

    Шест етапа, но с една разлика от стария вариант: етап 6 е чернова, а не „пакет за публикуване“. Човекът е отделна стъпка с име и час на решението. Защо? Малкият модел може да сгреши факт, тон или език, а публикацията е публична и трудно се връща.

    #ЕтапКакво правиКой отговаря
    1ВходWebhook със защита, или ред от Google SheetsТи
    2Брифqwen2.5:7b → JSON: заглавие, кука, аудитория, стил, CTAМодел + проверка в код
    3Текстmistral:7b → три варианта; символите се броят в кодМодел + код
    4ДизайнCanva autofill → export JPGCanva API
    5ЧасПредложение по твой график, в часовия пояс Европа/СофияКод
    6ЧерноваРед в Postgres със статус draft + преглед по имейл до тебn8n
    7ОдобрениеЧовек чете, поправя, сменя статуса на approvedЧовек
    8ПубликуванеРъчно, или по официалното API само за одобрени редовеЧовек / отделен процес
  2. Входът: Webhook със защита

    Webhook възелът поддържа Basic, Header и JWT удостоверяване. Включи Header auth: без него всеки, който познае адреса, пуска твоя конвейер. Докато строиш, ползвай Test URL; след като публикуваш процеса, работи Production URL.

    JSON · тяло на заявката
    {
      "topic": "Нова услуга: AI консултации за ресторанти",
      "platform": "linkedin",
      "brand_voice": "професионален и приятелски",
      "brand_template_id": "<ID на brand шаблона от Canva>",
      "facts": "Само проверени факти за услугата: какво е, за кого е, как се записва час."
    }
    💡
    Защо „facts“
    Полето facts е единственото, от което моделът има право да взема конкретики. Без него малкият модел ще „допълни“ цени и обещания, които не съществуват.
  3. Бриф с локален модел

    Задачата няма инструменти — не ти трябва AI Agent, стига Basic LLM Chain с Ollama Chat Model (qwen2.5:7b). Искаш само JSON и ясна граница на знанията.

    Basic LLM Chain · системно съобщение и подсказка
    // System message
    Ти си маркетинг стратег. Анализираш теми за социални мрежи на български.
    Използвай САМО фактите от полето „Факти“. Не измисляй цени, отстъпки,
    отзиви, цитати, клиенти и числа. Отговаряй САМО с валиден JSON.
    
    // Prompt (Define below)
    Тема: {{ $json.body.topic }}
    Платформа: {{ $json.body.platform }}
    Тон: {{ $json.body.brand_voice }}
    Факти: {{ $json.body.facts }}
    
    Върни JSON с точно тези полета:
    {
      "headline": "до 8 думи",
      "hook": "първото изречение",
      "target_audience": "кой е читателят",
      "visual_style": "какво да се види на дизайна",
      "hashtags_bg": ["#…"],
      "hashtags_en": ["#…"],
      "cta": "призив, до 5 думи"
    }
  4. Код: парсване и проверка на брифа

    Моделите често добавят обяснение или ограда от ``` около JSON-а. Този Code възел (режим „Run once for each item“) изрязва JSON-а, проверява полетата и спира процеса с ясна грешка, вместо да пусне половин чернова. Къде е текстът — text или output — зависи от възела; виж го в Executions.

    JavaScript · Code възел „Parse brief“
    const raw = $json.text ?? $json.output ?? '';
    const m = String(raw).match(/\{[\s\S]*\}/);
    if (!m) throw new Error('Няма JSON в отговора на модела');
    let brief;
    try { brief = JSON.parse(m[0]); } catch (e) { throw new Error('Невалиден JSON от модела'); }
    const need = ['headline', 'hook', 'target_audience', 'visual_style', 'cta'];
    const miss = need.filter(k => typeof brief[k] !== 'string' || !brief[k].trim());
    if (miss.length) throw new Error('Липсват полета: ' + miss.join(', '));
    const tags = a => (Array.isArray(a) ? a : []).map(String).filter(h => /^#\S+$/.test(h)).slice(0, 8);
    const wh = $('Webhook').item.json.body;
    return { json: { ...brief,
      hashtags_bg: tags(brief.hashtags_bg), hashtags_en: tags(brief.hashtags_en),
      topic: wh.topic, platform: wh.platform, brand_template_id: wh.brand_template_id } };
    ✅
    Изпълнен като обикновен JavaScript
    Тази и двете следващи Code части са пуснати в Node с примерни входове: валиден JSON в ограда, липсващ JSON, липсващи полета, вариант над лимита, преход на лятно/зимно часово време. Самите n8n възли и моделите не са пускани.
  5. Три варианта на текст — и броене в код

    Втори Basic LLM Chain, с mistral:7b. Този път не искаме от модела да брои символите: моделът може да сгреши. Броим в Code възел и отбелязваме варианти над лимита — лимитите са наши работни цели, не правило на платформите.

    Basic LLM Chain · подсказка за текста
    // System message
    Ти си копирайтър за социални мрежи. Пишеш на български. Използвай САМО
    дадените факти. Без измислени цени, отстъпки, отзиви и клиенти.
    Отговаряй САМО с JSON.
    
    // Prompt
    Тема: {{ $json.topic }}
    Заглавие: {{ $json.headline }}
    Кука: {{ $json.hook }}
    CTA: {{ $json.cta }}
    Аудитория: {{ $json.target_audience }}
    Платформа: {{ $json.platform }}
    
    Върни JSON: { "short": {"text": "…"}, "medium": {"text": "…"}, "long": {"text": "…"} }
    short до ~150 знака · medium до ~350 · long до ~600 със кратка история.
    JavaScript · Code възел „Count characters“
    const raw = $json.text ?? $json.output ?? '';
    const m = String(raw).match(/\{[\s\S]*\}/);
    if (!m) throw new Error('Няма JSON в отговора на модела');
    let copy;
    try { copy = JSON.parse(m[0]); } catch (e) { throw new Error('Невалиден JSON от модела'); }
    const LIMITS = { short: 150, medium: 350, long: 600 };
    const out = {};
    for (const [k, max] of Object.entries(LIMITS)) {
      const text = String(copy[k]?.text ?? '').trim();
      if (!text) throw new Error('Липсва вариант: ' + k);
      const chars = [...text].length;        // брои символи, не кодови единици
      out['copy_' + k] = text;
      out['chars_' + k] = chars;
      out['over_' + k] = chars > max;
    }
    return { json: out };
  6. Canva: autofill, изчакване, export

    Повикванията са асинхронни задачи: пускаш, питаш за състоянието, докато стане success или failed. Точните пътища (проверени в документацията на Canva към 01.10.2026) са по-долу; OAuth и създаването на шаблона са в Обучение 4. В HTTP Request възела ползвай OAuth2 данните от Credentials, не ключ в тялото.

    СтъпкаПовикванеПраво (scope)Лимит
    AutofillPOST /rest/v1/autofillsdesign:content:write60 заявки/мин на потребител
    СъстояниеGET /rest/v1/autofills/{jobId} → job.result.design.iddesign:meta:read120/мин
    ExportPOST /rest/v1/exportsdesign:content:read20/мин; до 75 за 5 мин на документ
    СъстояниеGET /rest/v1/exports/{exportId} → job.urls[]design:content:read120/мин
    JSON · тяло на POST /v1/autofills (хост: api.canva.com)
    {
      "type": "create_from_brand_template",
      "brand_template_id": "{{ $json.brand_template_id }}",
      "title": "{{ $json.headline }}",
      "data": {
        "title": { "type": "text", "text": "{{ $json.headline }}" },
        "cta":   { "type": "text", "text": "{{ $json.cta }}" }
      }
    }
    JSON · тяло на POST /v1/exports
    {
      "design_id": "{{ $json.job.result.design.id }}",
      "format": { "type": "jpg", "quality": 90 }
    }
    ⚠️
    JPG, не PNG, и свали файла веднага
    Instagram API приема като снимка само JPEG, затова експортът е jpg (старият урок искаше PNG). Адресите за сваляне от Canva важат 24 часа: свали файла в възел „Read/Write Files“ или в твое хранилище и пази пътя му, не адреса на Canva. Имената на полетата (title, cta) трябва да са същите като в шаблона; ако полето не съществува, Canva го прескача мълчаливо.

    За изчакване не гадай „5 секунди, после 10“: след заявката добави цикъл Wait (например 3 секунди) → HTTP Request (GET на задачата) → IF (status е success?), с таван на опитите.

  7. Предложение за час: от твой график, не от „бенчмарк“

    Старият урок имаше готова таблица „най-добри часове“ за шест мрежи без източник. Такива таблици се различават от автор на автор и зависят от твоята аудитория. Махнахме ги. Вземи часовете от статистиката на собствените си страници и ги запиши в PLAN; примерният график по-долу е само заместител. Кодът намира следващия подходящ час в часовия пояс Европа/София, вкл. при смяна на лятно/зимно време.

    JavaScript · Code възел „Propose slot“
    // Пример за форма на данните — замени с часовете от собствената си статистика.
    // Дни: 0 = неделя … 6 = събота. Часове: локално време (Европа/София).
    const PLAN = {
      instagram: { days: [2, 3, 5], hours: [10, 19] },
      facebook:  { days: [3, 4, 5], hours: [12, 18] },
      linkedin:  { days: [2, 3, 4], hours: [8, 17] },
    };
    const platform = $json.platform;
    const plan = PLAN[platform];
    if (!plan) throw new Error('Непозната платформа: ' + platform);
    const fmt = new Intl.DateTimeFormat('en-US', { timeZone: 'Europe/Sofia', weekday: 'short', hour: 'numeric', hourCycle: 'h23' });
    const DOW = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 };
    const start = new Date(); start.setUTCMinutes(0, 0, 0);
    for (let h = 1; h <= 24 * 14; h++) {
      const t = new Date(start.getTime() + h * 3600e3);
      const p = Object.fromEntries(fmt.formatToParts(t).map(x => [x.type, x.value]));
      if (plan.days.includes(DOW[p.weekday]) && plan.hours.includes(Number(p.hour))) {
        return { json: { proposed_publish_at: t.toISOString(), platform,
          local_label: new Intl.DateTimeFormat('bg-BG', { timeZone: 'Europe/Sofia', dateStyle: 'full', timeStyle: 'short' }).format(t) } };
      }
    }
    return { json: { proposed_publish_at: null, platform } };

    Това е предложение: човекът при одобрението може да го промени. Платформите дават собствени инструменти за планиране — ползвай тях, ако не искаш да пишеш този код.

  8. Опашката с чернови в Postgres

    Таблицата пази текстовете, пътя на снимката и — важното — статуса и кой го е сменил. Ограничението CHECK не позволява статус, който не познаваме. Не пазим адреса на Canva (изтича); пазим файла.

    SQL · създаване на таблицата
    CREATE TABLE IF NOT EXISTS content_queue (
      id                   SERIAL PRIMARY KEY,
      topic                TEXT NOT NULL,
      platform             VARCHAR(20) NOT NULL CHECK (platform IN ('instagram','facebook','linkedin')),
      headline             TEXT,
      copy_short           TEXT,
      copy_medium          TEXT,
      copy_long            TEXT,
      hashtags             JSONB,
      cta                  TEXT,
      design_id            TEXT,
      design_file          TEXT,
      ai_image             BOOLEAN NOT NULL DEFAULT FALSE,  -- изображението AI ли е генерирано?
      proposed_publish_at  TIMESTAMPTZ,
      status               VARCHAR(20) NOT NULL DEFAULT 'draft'
                           CHECK (status IN ('draft','approved','rejected','published')),
      reviewed_by          TEXT,
      reviewed_at          TIMESTAMPTZ,
      created_at           TIMESTAMPTZ NOT NULL DEFAULT NOW()
    );

    В n8n ползвай възела Postgres с операция Insert и картографиране на колоните от предните възли (така стойностите се предават като параметри, а не се лепят в SQL текст). Задай status = draft изрично, а hashtags = обединение на двата списъка.

  9. Човекът: преглед и одобрение

    Последният възел на конвейера е Send Email (SMTP) до теб: заглавие, платформа, предложен час и трите варианта. Това е вътрешен преглед, не маркетингов имейл до клиенти. Прегледът има чеклист:

    • Всеки факт е верен и е от входа (няма измислени цени, отстъпки, отзиви, клиенти).
    • Езикът е чист български, тонът е на марката.
    • Имаш права върху изображението; ако то е реалистична AI снимка на хора, места или събития — виж етикета в следващата стъпка.
    • Хаштаговете и връзките са уместни и работят.
    SQL · одобрение (прави го човек)
    UPDATE content_queue
       SET status = 'approved', reviewed_by = '<твоето име>', reviewed_at = NOW()
     WHERE id = <id> AND status = 'draft';
    ✅
    Други форми на вратата
    Вместо SQL можеш да сложиш във възела Wait условие „On Webhook Call“ или „On Form Submitted“ (документирани са), или да ползваш вградената „човешка проверка“ за инструменти на AI агент (одобряване/отказ през Slack, Telegram или чата на n8n). Принципът е същият: решението е на човек и остава записано.
  10. Публикуване: какво разрешават платформите

    Най-безопасният начин да публикуваш одобрен пост е на ръка или през вградения планировчик на платформата. Ако все пак искаш отделен процес, той чете само status = 'approved' и ползва официалните API-та:

    ПлатформаКакво казва документацията
    InstagramСамо „професионални“ акаунти. Единственият формат на снимка е JPEG. Медията трябва да е на публично достъпен адрес в момента на опита. Лимит: 100 публикувани през API поста за 24 часа в плаващ прозорец (/content_publishing_limit показва остатъка). Двустъпково: контейнер (/media), после /media_publish. Нужни са права като instagram_content_publish; документацията разграничава ниво на достъп Standard и Advanced ⚠ провери кое ти трябва за твоя случай.
    Facebook страницаPOST /{page-id}/feed; трябва да имаш задача CREATE_CONTENT на страницата, достъпен ключ на страницата и права като pages_manage_posts ⚠ (Meta може да изисква преглед на приложението — провери в документацията на Pages API). Планиране: scheduled_publish_time от 10 минути до 75 дни напред.
    LinkedInПост от свое име: право w_member_social, достъпно през продукта „Share on LinkedIn“. Пост от името на фирмена страница: w_organization_social — иска одобрен достъп до Community Management API и роля на администратор на страницата. Потребителското споразумение забранява ботове и неразрешени автоматизирани методи за създаване, споделяне и коментиране на постове.
    TikTok, YouTube, XТук не са покрити. Старият урок ги включваше само в таблицата с часове без източник. Провери техните условия преди да ги вържеш.
    curl · Instagram: два стъпки (пример по документацията, ⚠ не е пускан тук)
    # 1) контейнер — снимката (JPEG) е на публичен адрес
    curl -X POST "https://graph.facebook.com/<ВЕРСИЯ>/<IG_ID>/media" \
      -H "Authorization: Bearer <КЛЮЧ_ЗА_ДОСТЪП>" -H "Content-Type: application/json" \
      -d '{"image_url":"https://<твой-публичен-адрес>/post.jpg","caption":"<одобреният текст>"}'
    
    # 2) публикуване на контейнера
    curl -X POST "https://graph.facebook.com/<ВЕРСИЯ>/<IG_ID>/media_publish" \
      -H "Authorization: Bearer <КЛЮЧ_ЗА_ДОСТЪП>" -H "Content-Type: application/json" \
      -d '{"creation_id":"<ID от стъпка 1>"}'
    ⛔
    Без заобикалки
    Не скрапвай и не ползвай неофициални ботове, които „пишат“ като потребител. Освен че нарушават условията (LinkedIn го казва изрично), рискуваш акаунта на фирмата. Ако нямаш одобрен достъп до API, публикувай на ръка.
  11. Седмичен план от Google Sheets — пак само чернови

    Вторият работен процес чете месечен план от таблица и подава редовете на първия. Старият пример се противоречеше сам на себе си (заглавие „всяка неделя“, коментар „Вт“). Ето едно ясно правило: процесът само подготвя чернови и спира на статус draft; нищо не се публикува.

    план · WF-MA02: седмична партида чернови
    // Schedule Trigger: всяка седмица в избран ден и час (ден и час в настройките на възела)
    // Google Sheets: Read rows от лист „Content Plan“
    //   колони: Topic | Platform | Week | BrandTemplateID | Facts | Status
    // Filter: Status = "planned" И Week = текущата седмица
    // Loop Over Items (Split in Batches), размер 1 + таван на редовете за седмицата
    //   → Execute Sub-workflow: WF-MA01 за всеки ред (не повикване през HTTP към себе си)
    // Google Sheets: Update → Status = "drafted"   (не „published“)
    // Накрая — един имейл до теб: „Има N нови чернови за одобрение“
    ⚠️
    Масово съдържание за сайт
    Политиката на Google срещу спам казва, че е „масово генериране на съдържание“ (scaled content abuse), когато се създават много страници основно за да се манипулират класирания и без полза за читателя — независимо как са направени; пример е генерирането на много страници с AI без добавена стойност. Тук правим постове за социални мрежи, но ако пренасочиш същите чернови към блог или сайт на тон, прегледът от човек и реалната добавена стойност са задължителни.
  12. Етикет „AI“, имейли и реклама — кратка карта на правилата

    Не е правен съвет; прочети първоизточниците в раздел 06 и, при съмнение, попитай юрист.

    ТемаКакво пишеКакво значи за конвейера
    AI Act, чл. 50Прозрачността важи от 02.08.2026. Който използва AI система, за да създаде изображение, аудио или видео, което е „дълбока фалшификация“ (реалистично, би изглеждало автентично), трябва да обяви, че е изкуствено създадено или променено. За текст, публикуван, за да информира обществеността по въпроси от обществен интерес, също се обявява — освен ако е минал човешки преглед или редакторски контрол и някой носи редакторска отговорност. Машинночетимото маркиране (чл. 50, пар. 2) е задължение на доставчиците на системите.Реалистична AI снимка на човек, място или събитие — сложи етикет „AI“ (колоната ai_image). Рекламен пост за твоя услуга не е „въпрос от обществен интерес“ ⚠ (наше четене на текста, не тълкуване на регулатор), но човешкият преглед ти е нужен така или иначе. Цветен шаблон от Canva със заглавие не е дълбока фалшификация.
    Digital OmnibusПо вторични източници: в сила от 27.07.2026, отлага правилата за високорисковите системи, но не пипа чл. 50; само доставчиците на генеративни системи, пуснати на пазара преди 02.08.2026, получават срок до 02.12.2026 за машинночетимото маркиране. ⚠ Провери в Официален вестник на ЕС.Сроковете за машинночетимо маркиране касаят доставчика (напр. на модела), не твоя процес. Твоят дълг като ползвател е обявяването.
    Търговски имейлиЗЕТ, чл. 6, ал. 4: забранено е изпращането на непоискани търговски съобщения на потребители без предварително съгласие (ал. 3 — и на адреси от регистъра на КЗП). GDPR, чл. 21, ал. 2–3: правото на възражение срещу директен маркетинг, което се поставя ясно и отделно.Този конвейер пише само до теб. Ако някога го вържеш към имейл до клиенти — нужно е съгласие, ясно разпознаване като търговско съобщение, лесна отписка.
    ЗЗПЧл. 68в: нелоялните търговски практики са забранени; чл. 68г, ал. 1: практика е нелоялна, ако противоречи на добросъвестността и променя или може да промени съществено поведението на потребителя.Измислени отзиви, „само днес“ отстъпки или неверни свойства, добавени от модела, са риск. Затова „няма измислени факти“ е в чеклиста за одобрение.
  13. Тест на конвейера — първо без Canva

    Провери AI частта, преди да вържеш Canva. Изпрати заявка към Test URL на Webhook възела и гледай Executions. Подай ключа за Header auth така, както е записан в твоето credential (тук е маркиран с „<…>“).

    bash · тестова заявка към Test URL
    curl -X POST "<TEST_URL_ОТ_WEBHOOK_ВЪЗЕЛА>" \
      -H "<ИМЕ_НА_ЗАГЛАВИЕТО>: <СТОЙНОСТ_ОТ_CREDENTIAL>" \
      -H "Content-Type: application/json" \
      -d '{
        "topic": "Летни намаления на счетоводни услуги",
        "platform": "linkedin",
        "brand_voice": "професионален",
        "brand_template_id": "TEST_NO_CANVA",
        "facts": "Проверена информация за услугата."
      }'
    SQL · последните чернови
    SELECT id, headline, platform, proposed_publish_at, status, reviewed_by
      FROM content_queue ORDER BY created_at DESC LIMIT 5;

    Очакваш нови редове със status = draft и празни reviewed_by. Ако видиш реда като approved без да си го одобрил — има грешка в процеса; спри го.

04Проверка

Чеклист

Тест

1. Кога чернова от конвейера може да стане публикация?

2. Защо експортът от Canva за Instagram е jpg, а не png?

3. Кой брои символите на трите варианта?

4. Искаш да изпратиш генерираните рекламни текстове като имейл на клиенти, които не са се съгласили. Може ли?

05Какво следва

06Източници

  1. Canva: Create design autofill job 🌐 глобален — път, права, лимит, планове.
  2. Canva: Get design autofill job — състояние и резултат.
  3. Canva: Create design export job — формати, jpg с quality, лимити.
  4. Canva: Get design export job — urls[] важат 24 часа.
  5. Canva: права (scopes).
  6. Meta: Instagram Content Publishing — професионални акаунти, JPEG, лимит 100/24 ч, контейнер и публикуване.
  7. Meta: Page Feed — публикуване в страница, scheduled_publish_time.
  8. LinkedIn: Posts API — w_member_social, w_organization_social.
  9. LinkedIn: Share on LinkedIn — самообслужване за лични постове.
  10. LinkedIn: Increasing Access — нива на достъп до Community Management API.
  11. LinkedIn: потребителско споразумение — забрана за ботове и неразрешена автоматизация.
  12. AI Act, чл. 50 — задължения за прозрачност (пълен текст).
  13. Jones Walker и aiactblog.nl — вторични анализи на Digital Omnibus и срока 02.12.2026.
  14. Google Search: политики срещу спам — „scaled content abuse“.
  15. Закон за електронната търговия, чл. 6 · Закон за защита на потребителите, чл. 68в–68г — сверявай с Държавен вестник за последни промени.
  16. GDPR, чл. 21 — право на възражение, вкл. срещу директен маркетинг.
  17. n8n: Webhook · Wait · Loop Over Items · Execute Sub-workflow · Send Email · Code.
  18. n8n: човек в цикъла за инструменти · Basic LLM Chain · Ollama Chat Model.
  19. Ollama: qwen2.5 и mistral 🔒 локално — модели.