11 min czytaniaPoradniki

Masowy import krótkich linków z Google Sheets (prawdziwy workflow kampanijny)

Skopiuj 200 URL-i kampanijnych do arkusza, zaimportuj masowo do Elido, uzyskaj krótkie linki z tagowaniem UTM w jednym przebiegu. Kształt arkusza i automatyzacja Apps Script

Ana Kowalska
Marketing solutions engineering
Siatka Google Sheet z ośmioma wierszami URL-i kampanijnych i kolumnami UTM strzałkami prowadzącymi do interfejsu masowego importu Elido, generującego osiem krótkich linków

Uruchomienia kampanii nie zaczynają się w panelu administracyjnym. Zaczynają się w arkuszu kalkulacyjnym, który ktoś udostępnił na Slacku. URL-e są w kolumnie A, metadane UTM wypełniają kolumny B do G, slugi są w kolumnie H, a brief mówi, że launch jest jutro. Najwolniejsza część całego procesu to kopiowanie każdego wiersza do interfejsu skracacza po jednym linku na raz - nie dlatego, że cokolwiek jest technicznie trudne, ale dlatego, że nie ma powodu, żeby to robić w ten sposób.

Ten artykuł to bezpośredni workflow: jak wygląda arkusz, jak mapuje się na punkt końcowy masowego importu Elido, trzy ścieżki importu w zależności od liczby wierszy, krok dry-run, który wychwytuje błędy zanim trafią do produkcji, i fragment Apps Script automatyzujący całość za pomocą wyzwalacza. Szerszy kontekst dotyczący higieny UTM end-to-end znajdziesz w artykule kamienia węgielnego o śledzeniu UTM, który szczegółowo omawia szablony przestrzeni roboczej i przekazywanie konwersji po stronie serwera. Ten artykuł obejmuje wycinek potoku od arkusza do krótkich linków.

TL;DR#

  • Prowadź jeden arkusz na kampanię: target_url, slug, utm_source, utm_medium, utm_campaign, tags jako nazwane kolumny. Puste kolumny UTM są uzupełniane z szablonu przestrzeni roboczej.
  • Trzy ścieżki importu: wklejanie wierszy do interfejsu użytkownika (do 1 000 wierszy), upload CSV (do 10 000 wierszy) lub API przez skrypt (bez ograniczeń, powtarzalne).
  • Zawsze najpierw uruchamiaj z dry_run=true. Podgląd pokazuje rozwiązany krótki link i w pełni wyrenderowany ciąg zapytania UTM bez zapisywania czegokolwiek.
  • Poprzedzaj slugi kampanijne prefiksami (q2-, jun-) jako przestrzeń nazw. Kolizje pojawiają się w dry run, a nie w trakcie importu.

Kształt arkusza#

Wymagane kolumny to target_url i jedna z: slug lub auto_slug. Wszystko inne jest opcjonalne, ale ma zdefiniowaną interpretację gdy jest obecne.

KolumnaWymaganaUwagi
target_urltakPełny docelowy URL wraz ze schematem
slugjedna z dwóchPreferowana - daje przewidywalne krótkie URL-e
auto_slugjedna z dwóchUstaw na true, a Elido wygeneruje slug
utm_sourceopcjonalnaNadpisuje wartość szablonu przestrzeni roboczej
utm_mediumopcjonalnaNadpisuje wartość szablonu przestrzeni roboczej
utm_campaignopcjonalnaNadpisuje wartość szablonu przestrzeni roboczej
utm_contentopcjonalnaZazwyczaj wariant kreacji
utm_termopcjonalnaPłatne słowo kluczowe lub segment odbiorców
tagsopcjonalnaOddzielone przecinkami, stosowane do linku
titleopcjonalnaWyświetlane na liście linków w panelu

Reguła UTM jest prosta: jeśli target_url już zawiera parametr zapytania ?utm_source= (lub jakikolwiek utm_*), te wartości są przekazywane bez zmian. Bez nadpisywania, bez scalania. Jeśli docelowy URL nie ma parametrów UTM, Elido buduje je z kolumn UTM, cofając się do szablonu przestrzeni roboczej dla każdej pustej kolumny. Ma to praktyczne znaczenie - niektóre zespoły utrzymują wstępnie otagowane docelowe URL-e dla swojego dostawcy usług e-mail, a narzędzie do masowego importu, które je cicho ponownie taguje, produkuje uszkodzoną analitykę. Elido ostrzega przy wierszach w trybie mieszanym (niektóre UTM obecne, niektóre brakujące) i prosi o potwierdzenie.

Kolumna tagów zasługuje na osobną uwagę. Wartości to ciągi oddzielone przecinkami: campaign:q2-spring, channel:paid-social, variant:hero-a. Ta trójczęściowa struktura (wymiar:wartość) daje filtrowane osie w panelu bez potrzeby osobnej konfiguracji taksonomii. Więcej na ten temat w sekcji taksonomii tagów poniżej.

Trzy ścieżki importu#

Macierz decyzyjna porównująca wklejanie (do 1000 wierszy, bez narzędzi), upload CSV (do 10000 wierszy, asynchronicznie) oraz skrypt API (ponad 10000 wsadowo, zautomatyzowany i idempotentny) dla masowego importu Elido

Wklejanie wierszy do interfejsu masowego importu (do 1 000 wierszy)#

Dla wszystkiego poniżej 1 000 wierszy najszybszą ścieżką jest skopiowanie zakresu arkusza i wklejenie do pola tekstowego masowego importu. Interfejs Elido automatycznie wykrywa wartości rozdzielane tabulatorami z wklejenia ze spreadsheet i mapuje kolumny według nagłówka. Nie eksportujesz CSV; po prostu wklejasz.

Sprawdza się to dobrze w najczęstszym przypadku: brief kampanijny, który już jest w Sheets, termin launchu za godzinę i brak ochoty na pisanie skryptów. Interfejs pokazuje podgląd wszystkich wierszy przed zatwierdzeniem (ten sam dry-run, który uzyskałbyś z API) i pozwala naprawiać nieudane wiersze bezpośrednio przed kontynuowaniem.

Jedna pułapka: jeśli arkusz ma scalone komórki lub złożone formatowanie, wklejanie może dać zniekształcony wynik. Bezpiecznym posunięciem dla każdego arkusza o nietrywialnej strukturze jest najpierw skopiowanie do czystego arkusza (wklej jako wartości), a następnie wklejenie oczyszczonego zakresu do interfejsu importu.

Upload CSV (do 10 000 wierszy)#

W przypadku uruchomień z więcej niż 1 000 wierszami (duże kampanie katalogowe, kody do wydarzeń, spersonalizowane linki) ścieżka uploadu CSV obsługuje do 10 000 wierszy. Wyeksportuj arkusz jako CSV (Plik > Pobierz > CSV) i prześlij go w oknie dialogowym importu. Mapowanie nagłówków kolumn jest takie samo; różnica polega na tym, że duże uploady są przetwarzane asynchronicznie i raportują swój status przez webhook lub punkt końcowy poll.

Eksport CSV Google Sheets przez API (dostęp: 2026-05-12) obsługuje eksport nazwanego zakresu zamiast całego arkusza, co jest przydatne, gdy arkusz kampanijny ma wiele zakładek lub wiersze nagłówka, których nie chcesz czyścić ręcznie.

Wywołanie API ze skryptu (więcej niż 10 000 wierszy lub powtarzające się uruchomienia)#

W przypadku dużych katalogów lub kampanii prowadzonych co tydzień, wymagających zautomatyzowania tego samego procesu, właściwą ścieżką jest API. Dwie powszechne implementacje: Apps Script (nie wymaga lokalnych narzędzi, działa w przeglądarce) i Python (lepszy dla zespołów z istniejącymi potokami danych). Punkt końcowy jest taki sam w obu przypadkach.

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"

Parametr on_conflict kontroluje, co się dzieje, gdy slug już istnieje: skip pozostawia istniejący link na miejscu i rejestruje ostrzeżenie, fail przerywa cały import przy pierwszej kolizji, a replace aktualizuje docelowy URL istniejącego linku. W przypadku większości importów kampanijnych skip to właściwe ustawienie domyślne: ponowne uruchomienie tego samego CSV nie nadpisze linków już utworzonych.

API akceptuje do 10 000 wierszy na wywołanie. W przypadku większych katalogów przetwarzaj porcje po 5 000 wierszy; każde wywołanie jest niezależne i idempotentne, gdy używasz stabilnych slugów.

Dry run przed importem#

Uruchamiaj każdy import z dry_run=true przed zatwierdzeniem. Odpowiedź jest identyczna jak przy importie na żywo (każdy wiersz pokazuje swój rozwiązany krótki link, sparsowany ciąg zapytania UTM, listę tagów i wszelkie ostrzeżenia), ale nic nie jest zapisywane do bazy danych.

Rzeczy, które dry run wychwytuje, a których nie wychwycisz w żaden inny sposób przed uruchomieniem:

  • Slug w wierszu 14, który koliduje z istniejącym linkiem w twojej przestrzeni roboczej (pojawia się jako ostrzeżenie o konflikcie)
  • Kolumna UTM, która przypadkowo została pusta (Elido oznacza brakujące utm_medium jako ostrzeżenie, a nie twardy błąd, ale chcesz o nim wiedzieć przed uruchomieniem)
  • target_url z końcową spacją, która przetrwała kopiowanie ze spreadsheet (rozwiązany URL wygląda dobrze w CSV, ale faktyczne miejsce docelowe ma dołączone %20)
  • Wartości tagów przekraczające 32 znaki (cicho skracane; dry run ujawnia przechowywana wartość)

Odpowiedź dry run jest paginowana w tym samym formacie co prawdziwy wynik importu. Otwórz pierwszą stronę, sprawdź wiersz 2 (pierwszy wiersz danych po twoim prawdopodobnie idealnym wierszu 1) i ostatni wiersz. Następnie sprawdź wszystkie wiersze z flagą ostrzeżenia. Dwie minuty przeglądu wychwytują błędy, które w przeciwnym razie pojawiłyby się jako „dlaczego ten link kampanijny daje 404?" rano po uruchomieniu.

Diagram przepływu: dane z Google Sheet przepływają przez podgląd dry-run pokazujący rozwiązane UTM i konflikty slugów, a następnie są zatwierdzane, tworząc krótkie linki wyświetlane w panelu Elido

Konflikty slugów#

Konflikty slugów zdarzają się, gdy slug, który próbujesz zaimportować, już istnieje w twojej przestrzeni roboczej lub na twojej domenie niestandardowej. Import ujawnia je w odpowiedzi dry run z typem konfliktu (same_workspace, same_domain, reserved) i docelowym URL-em istniejącego linku.

Praktycznym rozwiązaniem jest przestrzeń nazw. Poprzedzaj slugi kampanijne krótkim identyfikatorem: q2-, jun26-, sm- (dla mediów społecznościowych), em- (dla e-maila). Slug taki jak q2-spring-hero-a jest mało prawdopodobny do kolizji z czymkolwiek z poprzedniej kampanii. Prefiksy czynią też filtr w panelu oczywistym - wszystkie linki oznaczone q2-* należą do jednego kwartału kampanii.

Jeden przypadek wart odnotowania: jeśli migrujesz z innego skracacza i chcesz zachować stare slugi, najpierw zaimportuj je bez prefiksu, a następnie używaj prefiksowanych slugów dla nowej zawartości kampanijnej. Masowy import Elido poinformuje cię w dry run, jeśli któryś ze starych slugów koliduje z już istniejącymi w przestrzeni roboczej.

Taksonomia tagów#

Tagi stosowane w czasie importu mają tę samą trójczęściową strukturę co kolumny arkusza, które je wygenerowały: campaign:q2-spring, channel:email, variant:hero-a. Gdy później otworzysz panel i filtrujesz według channel:email, nie przeszukujesz ciągów tekstu swobodnego - pytasz spójną taksonomię.

Nazwy wymiarów (campaign, channel, variant) pochodzą z konwencji twojego zespołu, nie z żadnego schematu wymuszanego przez Elido. Ograniczeniem jest format: separator dwukropek, bez spacji w kluczu, wartości poniżej 32 znaków. Zespoły, które egzekwują to w arkuszu (kolumna tags, którą formuła buduje jako "campaign:"&E2&", channel:"&F2) nigdy nie mają zniekształconych tagów w panelu. Zespoły, które pozwalają, żeby kolumna tagów była wolnym tekstem, mają problem z czyszczeniem danych po trzech kampaniach.

Przed i po: tagi w wolnym tekście dają trzy niepasujące warianty jednej idei, podczas gdy format wymiar:wartość oddzielony dwukropkiem pozwala czysto filtrować według kanału w panelu

W przeglądzie funkcji kampanii grupowanie oparte na tagach to podstawowy sposób, w jaki Elido grupuje kliknięcia według wymiaru kampanii w panelu analitycznym - więc taksonomia zdefiniowana w arkuszu to taksonomia, według której będziesz filtrować przy raportowaniu.

Automatyzacja Apps Script#

Dla zespołów prowadzących tę samą strukturę kampanijną co tydzień (linki do newslettera, linki do płatnych mediów społecznościowych, warianty e-mailowe), właściwym posunięciem jest całkowita automatyzacja importu. Google Apps Script działa w przeglądarce, ma dostęp do danych arkusza i może wyzwalać się na podstawie czasu lub przesłania formularza.

Wzorzec: wyzwalacz uruchamia się, skrypt odczytuje wszystkie wiersze arkusza, które nie mają wartości short_link w kolumnie I, wysyła je POST do API masowego importu i zapisuje utworzone krótkie linki z powrotem do kolumny I. Przy następnym wyzwalaczu już zaimportowane wiersze są pomijane, ponieważ kolumna I jest wypełniona.

// Google Apps Script - masowy import nowych wierszy przez API Elido
// Wyzwalacz: oparty na czasie, co godzinę (lub przy przesłaniu formularza)
// Dokumentacja: https://developers.google.com/apps-script/guides/triggers (dostęp: 2026-05-12)

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"); // zapisz wynik tutaj

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

  for (let i = 1; i < data.length; i++) {
    const row = data[i];
    if (!row[urlCol] || row[doneCol]) continue; // pomiń puste lub już zaimportowane
    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 || [];

  // Zapisz krótkie linki z powrotem do kolumny I
  created.forEach((link, idx) => {
    if (!link.short_url) return;
    const sheetRow = rowIndexes[idx] + 1; // indeksowanie od 1
    sheet.getRange(sheetRow, doneCol + 1).setValue(link.short_url);
  });
}

Kilka uwag implementacyjnych:

Przechowuj token API w PropertiesService.getScriptProperties(), a nie zakodowany na stałe w skrypcie. Dokumentacja wyzwalaczy Apps Script (dostęp: 2026-05-12) omawia konfigurację zarówno wyzwalaczy opartych na czasie, jak i zdarzeniach. W przypadku arkusza kampanijnego, który zespół wypełnia wspólnie, wyzwalacz onEdit uruchamia się, gdy kolumna A jest wypełniona; krótki link pojawia się w kolumnie I w ciągu kilku sekund od wpisania docelowego URL-a.

Flaga muteHttpExceptions: true jest ważna. Bez niej odpowiedź 422 z API rzuca wyjątek na poziomie skryptu i wyzwalacz przestaje ponawiać próby. Z nią otrzymujesz treść błędu i możesz ją zalogować.

W przypadku cięższej integracji (skrypt Python, krok CI odczytujący arkusz przez Sheets API lub zaplanowane zadanie w istniejącym potoku danych), punkt końcowy spreadsheets.values.get Sheets API (dostęp: 2026-05-12) daje ci JSON bezpośrednio. Stąd kształt wywołania masowego importu jest identyczny z przykładem curl powyżej.

Typowe błędy#

Końcowa spacja w slugach. Slug skopiowany z komórki arkusza może mieć końcową spację niewidoczną w interfejsie. Elido na to pozwala (slug jest technicznie prawidłowy), ale go.example.com/q2-promo z końcową spacją to brzydki URL, a kopiowanie z paska adresu przeglądarki zazwyczaj ją usuwa, więc osoba, która później wkleja krótki link, dostaje 404. Rozwiązaniem jest formuła =TRIM(H2) w kolumnie slug przed eksportem.

Brakujące utm_medium. Elido ostrzega, ale nie blokuje przy brakującym utm_medium, ponieważ niektóre kampanie celowo go pomijają. Ale brakujące medium to prawie zawsze błąd: GA4 kieruje wszystko bez niego do kanału (none), co sprawia, że atrybucja kanałów jest bezużyteczna. Kanoniczne odniesienie do URL buildera GA4 (dostęp: 2026-05-12) wymienia utm_medium jako wymagane do prawidłowego działania atrybucji kampanii. Jeśli twój szablon przestrzeni roboczej ma domyślne utm_medium, puste komórki w kolumnie je dziedziczą; jeśli nie, ostrzeżenie dry run to twoja ostatnia szansa na wykrycie tego.

Wartości tagów przekraczające 32 znaki. Elido cicho skraca wartości tagów przekraczające 32 znaki. Skracanie jest niewidoczne w ostrzeżeniach dry run, chyba że go szukasz (odpowiedź pokazuje przechowywaną wartość, nie oryginalną). Długie wartości tagów zazwyczaj pochodzą z wklejania nazw kampanij UTM do kolumny tagów: spring-2026-dach-email-reactivation-week3 to 42 znaki i w panelu stanie się spring-2026-dach-email-reactivation-we. Utrzymuj krótkie wartości wymiarów tagów; przenoś rozbudowane metadane do tytułu linku.

Zapominanie o dry_run=true przy ponownych uruchomieniach. Jeśli ponownie uruchomisz upload CSV dla kampanii, która już ma linki, on_conflict=skip jest bezpieczne, ale on_conflict=replace zaktualizuje docelowe URL-e przy każdym slugu, który pojawia się zarówno w starym, jak i nowym CSV. W kampanii, gdzie docelowe URL-e się nie zmieniły, jest to nieszkodliwe. W kampanii, gdzie aktualizujesz URL-e stron docelowych w trakcie, jest to właśnie to, czego chcesz. Wiedz, w jakim trybie działasz przed zatwierdzeniem.

Podsumowanie konfiguracji do uruchomienia#

Najbardziej kompletna wersja tego workflow: zbuduj arkusz raz ze stabilnymi nazwami kolumn, zdefiniuj szablon UTM przestrzeni roboczej, żeby puste kolumny UTM dziedziczyły rozsądne wartości domyślne (omówione w setup-branded-short-links), uruchom import testowy, żeby wychwycić konflikty i ostrzeżenia, zatwierdź i napisz wyzwalacz Apps Script, żeby następna kampania nie wymagała żadnych ręcznych kroków.

Warstwę atrybucji zamykającą pętlę po kliknięciu znajdziesz w artykule o śledzeniu konwersji po stronie serwera, który omawia, jak podłączyć click_id z odpowiedzi przekierowania Elido do Meta CAPI i GA4 - część po stronie serwera, która przetrwa Safari ITP i blokery reklam. Ten artykuł i ten razem dają pełny obraz workflow kampanijnego solutions/marketers, od arkusza przez krótki link do przypisanej konwersji.

Pełna powierzchnia zarządzania URL-ami kampanijnymi - szablony, masowy import, grupowanie kampanii, przekazywanie konwersji - jest na stronie funkcji/kampanie.

Wypróbuj Elido

Wklej URL, otrzymaj krótki link

Bez rejestracji. Link działa 30 dni. Zarejestruj się, aby zachować go na zawsze.

Za darmo, bez rejestracji · 2 dziennie

Wypróbuj Elido

Skracarka URL hostowana w UE: własne domeny, głęboka analityka i otwarte API. Darmowy plan - bez karty kredytowej.

Tagi
bulk url shortener
csv import short links
sheets to short links
bulk link creation
campaign url shortener
google sheets automation

Czytaj dalej