Elido
11 мин чтенияТуториалы

Массовый импорт коротких ссылок из Google Sheets (реальный рабочий процесс кампании)

Скопируйте 200 URL-адресов кампаний в таблицу, выполните массовый импорт в Elido и получите короткие ссылки с UTM-метками за один проход. Структура таблицы и автоматизация с помощью Apps Script.

Ana Kowalska
Marketing solutions engineering
Google Sheet grid with eight rows of campaign URLs and UTM columns arrowed into Elido's bulk-import interface producing eight short links

Запуски кампаний начинаются не в панели управления. Они начинаются в таблице, которой кто-то поделился в Slack. URL-адреса живут в колонке А, UTM-метаданные заполняют колонки с B по G, слаги находятся в колонке H, а в брифе сказано, что запуск завтра. Самая медленная часть процесса - копирование каждой строки в интерфейс сокращателя по одной ссылке за раз. Не потому, что это технически сложно, а потому, что нет причин делать это именно так.

Этот пост посвящен прямому рабочему процессу: как выглядит таблица, как она сопоставляется с эндпоинтом массового импорта Elido, трем путям импорта в зависимости от количества строк, шагу пробного запуска, который отлавливает ошибки до их попадания в продакшн, и фрагменту кода Apps Script, который автоматизирует все это по триггеру. Для более широкого контекста сквозной гигиены UTM основная статья о UTM-трекинге подробно описывает шаблоны рабочего пространства и серверную пересылку конверсий. Этот пост - часть этого пайплайна, посвященная переходу от таблицы к коротким ссылкам.

TL;DR#

  • Ведите по одной таблице на кампанию: target_url, slug, utm_source, utm_medium, utm_campaign, tags в качестве именованных колонок. Пустые колонки UTM заполняются из вашего шаблона рабочего пространства.
  • Три пути импорта: вставка строк в интерфейс (до 1 000 строк), загрузка CSV (до 10 000 строк) или API через скрипт (неограниченно, повторяемо).
  • Всегда сначала запускайте с dry_run=true. Предварительный просмотр показывает итоговую короткую ссылку и полностью отрендеренную строку UTM-запроса без сохранения изменений.
  • Добавляйте префиксы к слагам кампаний (q2-, jun-), чтобы разграничить пространства имен. Коллизии проявятся при пробном запуске, а не в середине импорта.

Структура таблицы#

Обязательными колонками являются target_url и одна из двух: slug или auto_slug. Все остальное необязательно, но имеет определенную интерпретацию при наличии.

КолонкаОбязательноПримечания
target_urlдаПолный целевой URL, включая протокол
slugодна из двухПредпочтительно - дает предсказуемые короткие URL
auto_slugодна из двухУстановите true, и Elido сгенерирует слаг
utm_sourceнеобязательноПереопределяет значение из шаблона рабочего пространства
utm_mediumнеобязательноПереопределяет значение из шаблона рабочего пространства
utm_campaignнеобязательноПереопределяет значение из шаблона рабочего пространства
utm_contentнеобязательноОбычно вариант креатива
utm_termнеобязательноПлатное ключевое слово или сегмент аудитории
tagsнеобязательноРазделенные запятыми, применяются к ссылке
titleнеобязательноОтображается в списке ссылок в панели управления

Правило UTM простое: если target_url уже содержит параметры запроса ?utm_source= (или любые utm_*), эти значения передаются без изменений. Никакой перезаписи или слияния. Если в целевом URL нет UTM-параметров, Elido создает их из колонок UTM, используя шаблон вашего рабочего пространства для любых пустых колонок. Это важно на практике - некоторые команды используют заранее помеченные целевые URL для своего сервиса рассылок, и инструмент массового импорта, который незаметно перемечает их, ломает аналитику. Elido предупреждает о строках смешанного типа (некоторые UTM присутствуют, некоторые отсутствуют) и просит подтверждения.

Колонка тегов заслуживает отдельного упоминания. Значения представляют собой строки, разделенные запятыми: campaign:q2-spring, channel:paid-social, variant:hero-a. Такая трехчастная структура (dimension:value) дает вам фильтруемые оси в панели управления без необходимости отдельной настройки таксономии. Подробнее об этом в разделе о таксономии тегов ниже.

Три способа импорта#

Матрица решений: вставка (до 1 000 строк, без инструментов), загрузка CSV (до 10 000 строк, асинхронно) и скрипт через API (от 10 000 батчами, автоматически и идемпотентно) для массового импорта в Elido

Вставка строк в интерфейс массового импорта (до 1 000 строк)#

Для любого объема менее 1 000 строк самый быстрый путь - скопировать диапазон таблицы и вставить его в текстовое поле массового импорта. Интерфейс Elido автоматически распознает значения, разделенные табуляцией, при вставке из электронной таблицы и сопоставляет колонки по заголовкам. Вам не нужно экспортировать CSV; вы просто вставляете данные.

Это хорошо работает для самого распространенного случая: бриф кампании уже живет в Google Sheets, дедлайн запуска через час, и нет желания писать скрипты. Интерфейс показывает предварительный просмотр всех строк перед подтверждением (тот же dry-run, который вы получили бы через API) и позволяет исправить любые строки с ошибками прямо на месте перед продолжением.

Один нюанс: если в вашей таблице есть объединенные ячейки или сложное форматирование, вставка может привести к искажению данных. Надежный ход для любой таблицы с нетривиальной структурой - сначала скопировать данные на чистый лист (вставить как значения), а затем вставить очищенный диапазон в интерфейс импорта.

Загрузка CSV (до 10 000 строк)#

Для запусков с более чем 1 000 строк (большие каталоги, коды мероприятий, персонализированные ссылки) подходит путь загрузки CSV, который обрабатывает до 10 000 строк. Экспортируйте таблицу как CSV (Файл > Скачать > CSV) и загрузите ее в диалоговом окне импорта. Сопоставление заголовков колонок идентично; разница в том, что большие загрузки обрабатываются асинхронно и сообщают о своем статусе через вебхук или эндпоинт опроса.

Экспорт CSV из Google Sheets через API (доступ получен 12.05.2026) поддерживает экспорт именованного диапазона, а не всего листа, что полезно, когда в вашей таблице кампании несколько вкладок или строк заголовков, которые вы не хотите очищать вручную.

Вызов API из скрипта (более 10 000 строк или регулярные запуски)#

Для больших каталогов или для кампаний, которые запускаются еженедельно и требуют автоматизации того же процесса, правильным выбором будет путь через API. Две распространенные реализации: Apps Script (не требует локальных инструментов, работает в браузере) и Python (лучше подходит для команд с существующими пайплайнами данных). Эндпоинт в обоих случаях один и тот же.

curl -X POST \
  https://api.elido.app/v1/links/bulk \
  -H "Authorization: Bearer $ELIDO_TOKEN" \
  -H "Content-Type: multipart/form-data" \
  -F "csv=@q2_spring_links.csv" \
  -F "campaign_id=cmp_8a2f" \
  -F "dry_run=false" \
  -F "on_conflict=skip"

Параметр on_conflict контролирует, что происходит, когда слаг уже существует: skip оставляет существующую ссылку и записывает предупреждение, fail прерывает весь импорт при первой коллизии, а replace обновляет цель существующей ссылки. Для большинства импортов кампаний skip - правильный выбор по умолчанию: повторный запуск того же CSV не перезапишет уже созданные ссылки.

API принимает до 10 000 строк за один вызов. Для более крупных каталогов делайте импорт частями по 5 000 строк; каждый вызов независим и идемпотентен, если вы используете стабильные слаги.

Пробный запуск перед импортом (dry run)#

Запускайте каждый импорт с dry_run=true перед финальным подтверждением. Ответ идентичен живому импорту (для каждой строки показана итоговая короткая ссылка, распарсенная строка UTM-запроса, список тегов и любые предупреждения), но ничего не записывается в базу данных.

Что ловит dry-run, чего не поймать иначе до запуска:

  • Слаг в строке 14, который конфликтует с существующей ссылкой в вашем рабочем пространстве (выводится как предупреждение о конфликте)
  • Колонка UTM, которую случайно оставили пустой (Elido помечает отсутствие utm_medium как предупреждение, а не критическую ошибку, но об этом стоит знать до запуска)
  • target_url с лишним пробелом в конце, который сохранился при копировании таблицы (итоговый URL в CSV выглядит нормально, но фактическая цель имеет добавленный %20)
  • Значения тегов, превышающие 32 символа (незаметно обрезаются; пробный запуск делает сохраненное значение видимым)

Ответ dry-run разбивается на страницы в том же формате, что и результат реального импорта. Откройте первую страницу, выборочно проверьте строку 2 (первую строку данных после заголовка) и последнюю строку. Затем посмотрите на любые строки с предупреждениями. Две минуты проверки избавляют от ошибок, которые иначе всплыли бы как «почему эта ссылка кампании выдает 404?» на следующее утро после запуска.

Блок-схема: данные из Google Sheet проходят через предварительный просмотр dry-run с разрешенными UTM и конфликтами слагов, затем подтверждаются и создают короткие ссылки в панели Elido

Конфликты слагов#

Конфликты слагов возникают, когда слаг, который вы пытаетесь импортировать, уже существует в вашем рабочем пространстве или на вашем пользовательском домене. Импорт выводит их в ответе dry-run с типом конфликта (same_workspace, same_domain, reserved) и целевым URL существующей ссылки.

Практическое решение - использование пространств имен. Добавляйте к слагам кампании короткий идентификатор: q2-, jun26-, sm- (для соцсетей), em- (для имейлов). Слаг типа q2-spring-hero-a вряд ли столкнется с чем-либо из предыдущей кампании. Префиксы также делают фильтрацию в панели управления очевидной - все ссылки с тегом q2-* принадлежат одному кварталу кампании.

Один случай, о котором стоит упомянуть: если вы переходите с другого сокращателя и хотите сохранить старые слаги, сначала импортируйте их без префиксов, а затем используйте префиксные слаги для нового контента кампании. Массовый импорт Elido сообщит вам при пробном запуске, если какие-либо из старых слагов конфликтуют с уже имеющимися в рабочем пространстве.

Таксономия тегов#

Теги, примененные во время импорта, получают ту же трехчастную структуру, что и колонки таблицы: campaign:q2-spring, channel:email, variant:hero-a. Когда вы позже откроете панель управления и отфильтруете по channel:email, вы не будете просеивать произвольные текстовые строки - вы будете запрашивать согласованную таксономию.

Названия измерений (campaign, channel, variant) берутся из соглашений вашей команды, а не из какой-либо схемы, навязанной Elido. Ограничение заключается в формате: двоеточие в качестве разделителя, отсутствие пробелов в ключе, значения менее 32 символов. Команды, которые обеспечивают это в таблице (колонка tags, которую формула собирает как "campaign:"&E2&", channel:"&F2), никогда не имеют проблем с некорректными тегами в панели управления. Команды, позволяющие колонке тегов быть произвольным текстом, сталкиваются с проблемой очистки данных уже через три кампании.

До и после: свободный текст тегов дает три несовместимых варианта одной идеи, тогда как формат dimension:value с двоеточием позволяет чисто фильтровать по каналу в панели управления

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

Автоматизация через Apps Script#

Для команд, которые еженедельно запускают одну и ту же структуру кампании (ссылки на рассылку, ссылки для платной рекламы, варианты электронных писем), правильным решением будет полная автоматизация импорта. Google Apps Script работает в браузере, имеет доступ к данным таблицы и может запускаться по триггеру времени или при отправке формы.

Схема такая: срабатывает триггер, скрипт считывает любые строки таблицы, у которых нет значения short_link в колонке I, отправляет их (POST) в API массового импорта и записывает созданные короткие ссылки обратно в колонку I. При следующем срабатывании триггера уже импортированные строки пропускаются, так как колонка I заполнена.

// Google Apps Script - массовый импорт новых строк через Elido API
// Триггер: по времени, каждый час (или при отправке формы)
// Документация: https://developers.google.com/apps-script/guides/triggers (доступ 12.05.2026)

function importNewLinks() {
  const sheet =
    SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Q2 Spring");
  const data = sheet.getDataRange().getValues();
  const headers = data[0];

  const urlCol = headers.indexOf("target_url");
  const slugCol = headers.indexOf("slug");
  const srcCol = headers.indexOf("utm_source");
  const medCol = headers.indexOf("utm_medium");
  const campCol = headers.indexOf("utm_campaign");
  const tagsCol = headers.indexOf("tags");
  const doneCol = headers.indexOf("short_link"); // записываем результат сюда

  const newRows = [];
  const rowIndexes = [];

  for (let i = 1; i < data.length; i++) {
    const row = data[i];
    if (!row[urlCol] || row[doneCol]) continue; // пропускаем пустые или уже импортированные
    newRows.push({
      destination: row[urlCol],
      slug: row[slugCol] || undefined,
      utm_source: row[srcCol] || undefined,
      utm_medium: row[medCol] || undefined,
      utm_campaign: row[campCol] || undefined,
      tags: row[tagsCol]
        ? String(row[tagsCol])
            .split(",")
            .map((t) => t.trim())
        : [],
    });
    rowIndexes.push(i);
  }

  if (!newRows.length) return;

  const payload = JSON.stringify({
    links: newRows,
    campaign_id: "cmp_8a2f",
    on_conflict: "skip",
  });

  const resp = UrlFetchApp.fetch("https://api.elido.app/v1/links/bulk", {
    method: "post",
    contentType: "application/json",
    headers: {
      Authorization:
        "Bearer " +
        PropertiesService.getScriptProperties().getProperty("ELIDO_TOKEN"),
    },
    payload: payload,
    muteHttpExceptions: true,
  });

  const result = JSON.parse(resp.getContentText());
  const created = result.links || [];

  // Записываем короткие ссылки обратно в колонку I
  created.forEach((link, idx) => {
    if (!link.short_url) return;
    const sheetRow = rowIndexes[idx] + 1; // 1-индексация
    sheet.getRange(sheetRow, doneCol + 1).setValue(link.short_url);
  });
}

Несколько примечаний по реализации:

Храните токен API в PropertiesService.getScriptProperties(), а не прописывайте его жестко в скрипте. Документация по триггерам Apps Script (доступ 12.05.2026) охватывает настройку как триггеров по времени, так и триггеров по событиям. Для таблицы кампании, которую команда заполняет совместно, триггер onEdit срабатывает при заполнении колонки A; короткая ссылка появляется в колонке I в течение нескольких секунд после ввода целевого URL.

Флаг muteHttpExceptions: true важен. Без него ошибка 422 от API вызовет исключение на уровне скрипта, и триггер перестанет делать повторные попытки. С ним вы получите тело ошибки и сможете его залогировать.

Для более серьезной интеграции (скрипт на Python, шаг CI, который читает таблицу через Sheets API, или запланированная задача в вашем существующем пайплайне данных) эндпоинт Sheets API spreadsheets.values.get (доступ 12.05.2026) отдает вам JSON напрямую. Оттуда структура вызова массового импорта идентична примеру с curl выше.

Распространенные ошибки#

Лишние пробелы в слагах. Слаг, скопированный из ячейки таблицы, может иметь невидимый пробел в конце. Elido допускает это (слаг технически валиден), но go.example.com/q2-promo с пробелом - это некрасивый URL, а копирование из адресной строки браузера обычно отсекает его, так что человек, который вставит ссылку позже, получит 404. Решение - формула =TRIM(H2) для колонки слага перед экспортом.

Отсутствие utm_medium. Elido предупреждает, но не блокирует импорт при отсутствии utm_medium, так как в некоторых кампаниях его намеренно пропускают. Но отсутствие медиума почти всегда является ошибкой: GA4 направляет все, что его не имеет, в канал (none), что делает атрибуцию по каналам бесполезной. Канонический справочник компоновщика URL GA4 (доступ 12.05.2026) указывает utm_medium как обязательный параметр для корректной атрибуции кампании. Если в вашем шаблоне рабочего пространства есть значение по умолчанию для utm_medium, пустые ячейки унаследуют его; если нет - предупреждение dry-run ваш последний шанс это исправить.

Значения тегов длиннее 32 символов. Elido незаметно обрезает значения тегов, превышающие 32 символа. Обрезка незаметна в предупреждениях dry-run, если не приглядываться (в ответе показано сохраненное значение, а не исходное). Длинные теги обычно появляются при вставке названий UTM-кампаний в колонку тегов: spring-2026-dach-email-reactivation-week3 состоит из 42 символов и превратится в spring-2026-dach-email-reactivation-we в панели управления. Делайте значения измерений тегов короткими; переместите подробные метаданные в заголовок ссылки.

Забытый dry_run=true при повторных запусках. Если вы повторно запускаете загрузку CSV для кампании, в которой уже есть ссылки, on_conflict=skip безопасен, но on_conflict=replace обновит целевые URL для любого слага, который есть и в старом, и в новом CSV. В кампании, где целевые URL не менялись, это безвредно. В кампании, где вы обновили URL лендингов в середине работы, это именно то, что вам нужно. Определитесь с режимом до подтверждения.

Резюме: от настройки до запуска#

Самая полная версия этого рабочего процесса: создайте таблицу один раз со стабильными названиями колонок, определите шаблон UTM рабочего пространства, чтобы пустые колонки UTM наследовали разумные значения по умолчанию (описано в setup-branded-short-links), запустите пробный импорт для отлова конфликтов и предупреждений, подтвердите импорт и напишите триггер Apps Script, чтобы следующая кампания требовала ноль ручных действий.

Что касается уровня атрибуции, который замыкает цикл после клика, статья серверный трекинг конверсий описывает, как пробросить click_id из ответа редиректа Elido в Meta CAPI и GA4 - серверную часть, которая выживает после Safari ITP и вмешательства блокировщиков рекламы. Тот пост и этот вместе дают полную картину рабочего процесса маркетологов: от таблицы до короткой ссылки и атрибутированной конверсии.

Весь функционал управления URL-адресами кампаний - шаблоны, массовый импорт, группировка кампаний, пересылка конверсий - находится на странице функций кампаний.

Попробуйте Elido

Вставьте URL - получите короткую ссылку

Без регистрации. Ссылка живёт 30 дней. Зарегистрируйтесь, чтобы оставить её навсегда.

Бесплатно, без регистрации · 2 в день

Попробуйте Elido

URL-сокращатель с хостингом в ЕС: собственные домены, глубокая аналитика, открытый API. Бесплатный тариф - без банковской карты.

Теги
bulk url shortener
csv import short links
sheets to short links
bulk link creation
campaign url shortener
google sheets automation

Читать дальше