KWIGA справочный центр Сервисы, интеграции, API, Настройки проекта Подключение сервисов Экспорт данных в Google Sheets

Экспорт данных в Google Sheets

Статьи:

Покажем, как настроить автоматический экспорт данных из Kwiga в Google Sheets (Таблицу Google).


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

Дополнительно Вы можете использовать возможность отправки вебхука при использовании виджет, принцип действий остается таким же. 

Основные шаги:

  1. Создать файл и добавить в него скрипт

  2. Создать webapp и получить ссылку для отправки вебхука

  3. Настроить отправку вебхука используя автоматизацию на Kwiga или же отправку форму в виджете. 

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

 

Шаг 1: Создать файл, куда будут передаваться данные из Kwiga

Откройте Google Sheets и создайте новый файл и откройте редактор скриптов. 

Откроется новое окно, в редактор которого Вам необходимо вставить скрипт. Скачать скрипт Вы можете по ссылке (или же скопируйте текст внизу статьи). Весь текст, который уже есть в редакторе Вам необходимо удалить. 

Итоговый вид: 

Шаг 2: Создать webapp и получить ссылку для отправки вебхука

В том же редакторе скрипта найдите кнопку Deploy и выберите New deployment

Укажите Web app в типе, а в дропдауне У кого есть доступ установите Все, и нажмите Deploy.

В результате Вы получите Web App URL, которую и нужно будет добавить на Kwiga.

 

Шаг 3: Настройка отправки данных на Kwiga

Нажмите на кнопку Все решения в верхнем меню и выберите Автоматизация. Создайте новый триггер и выберите событие, при котором будет запускаться автоматизация. Это может быть добавление контакта, добавление тега, оплата или же любое другое событие. 

После этого опуститесь ниже и выберите в действиях Вебхук - Отправка данных. В ссылке укажите  Web App URL, тип запроса POST,  и выберите поля, которые должны быть экспортированы в таблицу. 

Сохраните и все шаги выполнены. 

 

Альтернативно, Вы можете настроить отправку вебхука из виджета, это доступно при использовании элемента Форма. Установите отметку Дополнительно передавать в сторонний сервис, в открывшейся форме добавьте ссылку, тип запроса POST,   и выберите параметры для передачи. В этом списке будут доступны только те параметры, которые есть в форме (этом виджете). 

 

Как работает скрипт Google Sheets для вебхуков

  • При первом обращении вебхука автоматически создаются заголовки таблицы на основе ключей входящих данных
  • Если в таблице уже есть заголовки и нужно начать получать новые поля данных, добавьте эти заголовки в таблицу вручную
  • Заголовки можно менять местами в таблице - скрипт автоматически определит их позиции
  • По умолчанию скрипт добавляет новые записи при каждом получении вебхука
  • Если указать поля в keyColumns, скрипт будет обновлять существующие записи или добавлять новые, если не найдет совпадения
  • ⚠️ Важно: После изменения скрипта необходимо сделать новое развертывание в Google Apps Script и обновить ссылку на вебхук

Выбор листа таблицы:

  • По умолчанию используется активный лист
  • Можно переопределить через параметры вебхука:
  • "sheet_name": "Название листа" - для выбора листа по имени
  • "sheet_index": 2 - для выбора листа по номеру (начиная с 1)
// ============================================================
// НАСТРОЙКИ СКРИПТА
// ============================================================

// Проверка дубликатов - укажите поля для поиска существующих записей
// Примеры использования:
// var keyColumns = ["email"];           - проверка по email
// var keyColumns = ["order_id"];        - проверка по ID заказа
// var keyColumns = ["email", "order_id"];  - проверка по нескольким полям
var keyColumns = []; // Проверка дубликатов отключена

// ============================================================

// Функция для отправки ответа
function sendResponse(success, message) {
    var response = {
        "status": success ? "success" : "error",
        "message": message
    };
    return ContentService.createTextOutput(JSON.stringify(response))
        .setMimeType(ContentService.MimeType.JSON);
}

// Получение целевой страницы для записи данных
function getTargetSheet(hook_data) {
    var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

    // Проверяем, указано ли имя страницы
    if (hook_data && hook_data.sheet_name) {
        try {
            var sheet = spreadsheet.getSheetByName(hook_data.sheet_name);
            if (sheet) {
                return sheet;
            }
        } catch (error) {
            // Страница не найдена
        }
    }

    // Проверяем, указан ли номер страницы
    if (hook_data && hook_data.sheet_index && !isNaN(hook_data.sheet_index)) {
        try {
            var sheets = spreadsheet.getSheets();
            var index = parseInt(hook_data.sheet_index) - 1; // Конвертируем в индекс от 0
            if (index >= 0 && index < sheets.length) {
                return sheets[index];
            }
        } catch (error) {
            // Неверный индекс страницы
        }
    }

    // По умолчанию используем активную страницу
    return SpreadsheetApp.getActiveSheet();
}

// Создаёт заголовки в таблице на основе переданных данных
function populateHeaders(hook_data, sheet) {
    if (!hook_data || typeof hook_data !== 'object') {
        return false;
    }

    if (!sheet) {
        sheet = getTargetSheet(hook_data);
    }
    var last_row = Math.max(sheet.getLastRow(), 1);
    sheet.insertRowAfter(last_row);

    var headers_row = ['timestamp'];
    var hook_data_keys = Object.keys(hook_data);

    for (var i = 0; i < hook_data_keys.length; i++) {
        headers_row.push(hook_data_keys[i]);
    }

    sheet.appendRow(headers_row);
    SpreadsheetApp.flush();
    return true;
}

// Обработка входящего вебхука
function doPost(e) {
    var hook_load = null;

    // Проверяем наличие POST данных
    if (!e || !e.postData || !e.postData.contents) {
        return sendResponse(false, "Нет данных для обработки");
    }

    // Парсим JSON данные
    try {
        hook_load = JSON.parse(e.postData.contents);
    } catch (error) {
        return sendResponse(false, "Ошибка парсинга JSON данных");
    }

    // Валидация полученных данных
    if (!hook_load || typeof hook_load !== 'object' || Object.keys(hook_load).length === 0) {
        return sendResponse(false, "Получены некорректные или пустые данные");
    }

    try {
        // Получаем целевую страницу
        var sheet = getTargetSheet(hook_load);
        if (!sheet) {
            return sendResponse(false, "Не удалось найти указанную страницу");
        }

        // Создание заголовков, если таблица пустая
        if (sheet.getLastColumn() === 0) {
            populateHeaders(hook_load, sheet);
        }

        var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];

        if (headers.length === 0 || headers[0] === "") {
            populateHeaders(hook_load, sheet);
            headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
        }

        // Проверка дубликатов
        var data = [];
        var targetRow = -1;
        var numRows = sheet.getLastRow() - 1;

        if (keyColumns.length > 0 && numRows > 0) {
            data = sheet.getRange(2, 1, numRows, sheet.getLastColumn()).getValues();

            for (var r = 0; r < data.length; r++) {
                var row = data[r];
                var match = true;

                for (var k = 0; k < keyColumns.length; k++) {
                    var key = keyColumns[k];
                    var idx = headers.indexOf(key);
                    if (idx === -1 || row[idx] != hook_load[key]) {
                        match = false;
                        break;
                    }
                }

                if (match) {
                    targetRow = r + 2; // учёт заголовков
                    break;
                }
            }
        }

        // Подготовка данных для записи
        var new_sheet_row = new Array(headers.length).fill('');
        for (var h = 0; h < headers.length; h++) {
            var key = headers[h];
            if (key === 'timestamp') {
                new_sheet_row[h] = new Date();
            } else if (hook_load.hasOwnProperty(key)) {
                new_sheet_row[h] = hook_load[key];
            }
        }

        // Сохранение данных в таблицу
        if (targetRow > -1) {
            sheet.getRange(targetRow, 1, 1, new_sheet_row.length).setValues([new_sheet_row]);
        } else {
            sheet.appendRow(new_sheet_row);
        }

        SpreadsheetApp.flush();

        return sendResponse(true, "Данные успешно сохранены");

    } catch (error) {
        return sendResponse(false, "Ошибка при сохранении данных: " + error.message);
    }
}