| ID анкеты / Управление | Дата и время | 1. Возраст | 2. Пол | 3. Семейное положение | 4. Ребёнок в семье | 5. Братья/сёстры | 6. Полная семья | 1. Опыт пустоты | 2. Что предшествовало | 3. В чём состояла | 4. Ощущения в теле | 5. Форма и границы | 6. Сила (0–10) | 6 (динамика) | 7. Каково было | 8. Опоры | 9. Как обходились | 10. Что поняли | Поддержанный фонд | Устройство (модель) | Операционная система | Разрешение | Браузер | IP-адрес | Оператор / Сеть |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Загрузка базы ответов... | |||||||||||||||||||||||||
Баланс благотворительных выплат
Учёт начислений (+100 ₽ за анкету), фактически оплаченных сумм и остатка к переводу.
Реестр выплат и переводов в фонды
Внесите платёж и прикрепите документ (JPG, PNG, PDF). Документ сразу публикуется на сайте для участников исследования.
Реестр проведённых выплат: 0 выплат
| Дата | Фонд | Сумма (₽) | Документ | Комментарий | Действия |
|---|---|---|---|---|---|
| Выплаты пока не добавлены. Заполните форму выше, чтобы внести первую выплату в реестр. | |||||
| Итого по всем выплатам: | 0 ₽ | Сумма подтверждена прикреплёнными документами | |||
История переводов и анти-накрутка
Если один человек или бот отправил много анкет с одного устройства или IP, вы можете очистить накрутку в один клик.
| Действие | ID анкеты | Дата и время | Выбранный фонд | Сумма | Устройство | IP-адрес |
|---|---|---|---|---|---|---|
| Загрузка истории... | ||||||
✈️ Уведомления в Telegram
Бот мгновенно присылает сообщение в Telegram при каждом новом заполнении анкеты и выборе фонда.
/newbot) и скопируйте выданный API токен.
Подключение Google Таблицы (нажмите, чтобы развернуть код и инструкцию) ▼
Все поступающие ответы автоматически заносятся в вашу Google Таблицу на два раздельных листа («Устройства и Фонды» и «Анкета (Ответы)»).
Шаг 1: Создайте таблицу и откройте Apps Script
Откройте sheets.new → в верхнем меню выберите Расширения → Apps Script.
Шаг 2: Вставьте готовый код (заголовки строго в 1-й строке, ответы со 2-й строки)
// Заголовки для листа «Анкета (Ответы)» — ровно 19 колонок (БЕЗ фонда!)
var SURVEY_HEADERS = [
"ID анкеты", "Дата и время",
"1. Возраст", "2. Пол", "3. Семейное положение", "4. Ребёнок в семье",
"5. Братья/сёстры от одного брака", "6. Полная семья",
"1. Опыт переживания пустоты", "2. Что предшествовало появлению", "3. В чём состояла пустота",
"4. Ощущения в теле и локализация", "5. Форма, размер и границы", "6. Сила ощущения (0–10)", "6 (динамика). Менялась или нет",
"7. Каково было находиться", "8. Опоры при принятии решений", "9. Как обходились с пустотой", "10. Что поняли благодаря опыту"
];
// Заголовки для листа «Устройства и Фонды» — технические данные и выбор фонда
var DEVICE_HEADERS = [
"ID анкеты", "Дата и время", "Устройство", "Операционная система", "Разрешение экрана", "Браузер / Приложение", "IP-адрес", "Выбранный фонд", "Сумма (+100 ₽)"
];
function doPost(e) {
var lock = LockService.getScriptLock();
lock.tryLock(10000);
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var data = JSON.parse(e.postData.contents);
var rowId = data.id || (data.row && data.row[0]);
var sheetSurvey = getOrCreateSurveySheet(ss);
var sheetDevices = getOrCreateDeviceSheet(ss);
// 1. Запись в лист «Анкета (Ответы)» со 2 строки (первая свободная)
var sRow = data.surveyRow;
if (!sRow && data.row) {
sRow = [
data.row[0], data.row[1],
data.row[7], data.row[8], data.row[9], data.row[10], data.row[11], data.row[12],
data.row[13], data.row[14], data.row[15], data.row[16], data.row[17], data.row[18], data.row[19],
data.row[20], data.row[21], data.row[22], data.row[23]
];
}
if (sRow && rowId) {
upsertRow(sheetSurvey, sRow, 1, 2);
}
// 2. Запись в лист «Устройства и Фонды» со 2 строки (первая свободная)
var dRow = data.deviceRow;
if (!dRow && data.row) {
dRow = [
data.row[0], data.row[1], data.row[2], data.row[3], data.row[4], data.row[5], data.row[6],
data.row[24] || 'Не выбран', (data.row[24] && String(data.row[24]).indexOf('+100') !== -1) ? 100 : 0
];
}
if (dRow && rowId) {
upsertRow(sheetDevices, dRow, 1, 2);
}
return ContentService.createTextOutput(JSON.stringify({ status: "success" })).setMimeType(ContentService.MimeType.JSON);
} catch (err) {
return ContentService.createTextOutput(JSON.stringify({ status: "error", error: err.toString() })).setMimeType(ContentService.MimeType.JSON);
} finally {
lock.releaseLock();
}
}
// Гарантирует наличие шапки в 1-й строке
function ensureHeaders(sheet, headers, bgColor) {
if (sheet.getLastRow() === 0 || sheet.getRange(1, 1).getValue() === "") {
sheet.getRange(1, 1, 1, headers.length).setValues([headers]).setFontWeight("bold").setBackground(bgColor);
sheet.setFrozenRows(1);
}
}
// Вставка в первую свободную строку или обновление существующей строки без дублей
function upsertRow(sheet, rowValues, idColIndex, startRowIndex) {
var lastRow = sheet.getLastRow();
var foundRow = -1;
if (lastRow >= startRowIndex) {
var numRows = lastRow - startRowIndex + 1;
var idList = sheet.getRange(startRowIndex, idColIndex, numRows, 1).getValues();
for (var i = 0; i < idList.length; i++) {
if (idList[i][0] === rowValues[idColIndex - 1]) {
foundRow = startRowIndex + i;
break;
}
}
}
if (foundRow > 0) {
sheet.getRange(foundRow, 1, 1, rowValues.length).setValues([rowValues]);
} else {
// Пишем строго в первую свободную строку, начиная со 2-й (под шапкой)
var targetRow = Math.max(startRowIndex, lastRow + 1);
sheet.getRange(targetRow, 1, 1, rowValues.length).setValues([rowValues]);
}
}
function getOrCreateSurveySheet(ss) {
var s = ss.getSheetByName("Анкета (Ответы)");
if (!s) s = ss.insertSheet("Анкета (Ответы)");
ensureHeaders(s, SURVEY_HEADERS, "#f3f0e8");
return s;
}
function getOrCreateDeviceSheet(ss) {
var s = ss.getSheetByName("Устройства и Фонды");
if (!s) s = ss.insertSheet("Устройства и Фонды", 0);
ensureHeaders(s, DEVICE_HEADERS, "#f0ede6");
return s;
}
// Запустите эту функцию один раз в редакторе (кнопка «Выполнить»),
// чтобы выставить заголовки в 1-ю строку, убрать пустые строки и начать ответы со 2-й строки!
function setupAndFixSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Удаляем любые графики
var allSheets = ss.getSheets();
for (var s = 0; s < allSheets.length; s++) {
try {
var charts = allSheets[s].getCharts();
for (var c = 0; c < charts.length; c++) allSheets[s].removeChart(charts[c]);
} catch(e) {}
}
var sheetSurvey = getOrCreateSurveySheet(ss);
var sheetDevices = getOrCreateDeviceSheet(ss);
// Принудительно ставим правильную шапку в 1-ю строку
sheetSurvey.getRange(1, 1, 1, SURVEY_HEADERS.length).setValues([SURVEY_HEADERS]).setFontWeight("bold").setBackground("#f3f0e8");
sheetSurvey.setFrozenRows(1);
sheetDevices.getRange(1, 1, 1, DEVICE_HEADERS.length).setValues([DEVICE_HEADERS]).setFontWeight("bold").setBackground("#f0ede6");
sheetDevices.setFrozenRows(1);
// Сжимаем пустые строки (если были пустые строки 2-11), переносим данные в строку 2
cleanAndShiftData(sheetDevices, 2, DEVICE_HEADERS.length);
cleanAndShiftData(sheetSurvey, 2, SURVEY_HEADERS.length);
}
function cleanAndShiftData(sheet, startRow, numCols) {
var lastRow = sheet.getLastRow();
if (lastRow < startRow) return;
var data = sheet.getRange(startRow, 1, lastRow - startRow + 1, numCols).getValues();
var rowsWithData = [];
for (var i = 0; i < data.length; i++) {
if (data[i][0] && String(data[i][0]).trim() !== "") {
rowsWithData.push(data[i]);
}
}
sheet.getRange(startRow, 1, Math.max(1, lastRow - startRow + 1), numCols).clearContent();
if (rowsWithData.length > 0) {
sheet.getRange(startRow, 1, rowsWithData.length, numCols).setValues(rowsWithData);
}
}
Шаг 3: Выполните функцию setupAndFixSheets
В выпадающем списке сверху выберите setupAndFixSheets и нажмите «Выполнить». Это моментально запишет заголовки в 1-ю строку и уберёт любые пустые строки.
Шаг 4: Разверните как Веб-приложение (Web App)
Нажмите синюю кнопку «Начать развертывание» → «Новое развертывание» (тип: Веб-приложение, доступ: «Все» / Anyone). Скопируйте полученный URL (заканчивается на /exec) и вставьте в поле выше.
Учётная запись администратора ▼
Резервное копирование и управление данными ▼
Бэкап содержит полную копию всех ответов респондентов, технических характеристик устройств и реестра чеков.