


Как научить нейросеть следить за отзывами клиентов и получать автоматические уведомления о проблемах
Если вы постоянно собираете обратную связь от клиентов и хотите автоматизировать процесс анализа отзывов — читайте этот гайд. В нем мы рассказали, как подключить нейросеть к Google таблицам для анализа каждого нового отзыва и сигнализации вам на почту, если клиент остался чем-то недоволен.
Шаг 1. Регистрируемся на платформе OpenAI
Или авторизуемся, если аккаунт уже есть. Затем идем в настройки и привязываем карту.
Важно! Карты РФ и Беларуси не подходят. Можно привязать только европейскую.
Если у вас нет европейской карты, можете воспользоваться сервисами наших партнеров и сэкономить на оплатах:
А еще мы подробно рассказывали об оплате зарубежных сервисов в гайде:
Чтобы привязать карту, на главной странице жмем на шестеренку в правом верхнем углу.

Затем переходим в «Billing» → «Payment methods» и вводим данные карты. Пополняем баланс.

Минимальная сумма — $5. Я рекомендую пополнять на $25-30, этого хватит на анализ сотен или тысяч отзывов в зависимости от размера текста.
После того как прикрепили карту нажимаем «Dashboard» → «API keys» → «Create new secret key» → копируем.

Шаг 2. Создаем Google-форму для сбора отзывов
Вместо Google-формы можно использовать любые другие опросники, которые позволяют собирать информацию в Google таблицах.
В самой форме я рекомендую делать 3 графы в таком порядке:
- email-адрес респондента;
- имя респондента;
- отзыв.

Другие поля лучше не добавлять, потому что скрипт рассчитан на анализ 3 блоков информации. Если их будет больше — скрипт придется редактировать. Как это сделать — показал в конце гайда.
Когда создадите форму, перейдите в раздел «Ответы» и кликните на «Установить связь с таблицами».

Шаг 3. Вставляем скрипт для анализа отзывов в таблицу
Перейдите в таблицу, с которой связали Google-формы.
Откройте раздел «Расширения» → «Apps Script» → на открывшейся странице добавьте скрипт вместо того, что там написан.

// Глобальные переменные
var SHEET_NAME = 'название листа, на котором собираете отзывы, точь-в-точь'; // Имя листа с ответами
var EMAIL_ADDRESS = 'email адрес, куда нужно сигнализировать о проблемах'; // Адрес для уведомлений
function analyzeNewFeedback() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
// Получаем последнюю заполненную строку в таблице
var lastRow = sheet.getLastRow();
// Проверяем, есть ли данные в таблице (кроме заголовков)
if (lastRow <= 1) {
Logger.log("В таблице нет данных для анализа.");
return; // Завершаем выполнение функции
}
// Получаем все данные из таблицы, начиная со второй строки (первая - заголовки)
var data = sheet.getRange(2, 1, lastRow - 1, 4).getValues();
var hasNewFeedback = false;
for (var i = 0; i < data.length; i++) {
var row = data[i];
var timestamp = row[0];
var name = row[1];
var email = row[2];
var feedback = row[3];
if (sheet.getRange(i + 2, 5).getValue() === '') {
hasNewFeedback = true;
var analysis = analyzeFeedback(feedback);
Logger.log("Результат анализа: " + JSON.stringify(analysis));
sheet.getRange(i + 2, 5).setValue(analysis.sentiment);
sheet.getRange(i + 2, 6).setValue(analysis.explicit_issues.join(', '));
sheet.getRange(i + 2, 7).setValue(analysis.criticism_level);
sheet.getRange(i + 2, 8).setValue(analysis.retention_risk);
if (analysis.action_priority !== 'низкий') {
Logger.log("Отправка уведомления для отзыва, требующего внимания");
sendNotification(name, email, feedback, analysis);
} else {
Logger.log("Уведомление не отправлено. Действия не требуются.");
}
}
}
if (!hasNewFeedback) {
Logger.log("Нет новых отзывов для анализа.");
}
}
function analyzeFeedback(feedbackText) {
var apiKey = 'Ваш API-ключ от ChatGPT';
var apiUrl = 'https://api.openai.com/v1/chat/completions';
var prompt = `Проанализируй следующий отзыв клиента. Обрати внимание на скрытый подтекст, сарказм, завуалированные жалобы и общий тон сообщения. Учитывай культурный контекст и возможные эвфемизмы.
Отзыв: "${feedbackText}"
Дай детальный анализ в формате JSON:
{
"sentiment": "позитивная/негативная/смешанная",
"tone": "описание общего тона сообщения",
"explicit_issues": ["список явных проблем"],
"implicit_issues": ["список скрытых или подразумеваемых проблем"],
"criticism_level": "низкий/средний/высокий",
"retention_risk": "низкий/средний/высокий",
"action_priority": "низкий/средний/высокий",
"suggested_actions": ["список рекомендуемых действий"],
}`;
var payload = {
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.7
};
var options = {
'method': 'post',
'contentType': 'application/json',
'headers': {
'Authorization': 'Bearer ' + apiKey
},
'payload': JSON.stringify(payload)
};
try {
var response = UrlFetchApp.fetch(apiUrl, options);
var jsonResponse = JSON.parse(response.getContentText());
var analysis = JSON.parse(jsonResponse.choices[0].message.content);
// Добавляем исходный текст отзыва к анализу
analysis.original_feedback = feedbackText;
return analysis;
} catch (error) {
Logger.log('Ошибка при анализе отзыва: ' + error.toString());
return {
sentiment: 'ошибка',
tone: 'не удалось проанализировать',
explicit_issues: [],
implicit_issues: [],
criticism_level: 'не определено',
retention_risk: 'высокий',
action_priority: 'высокий',
suggested_actions: ['проверить ошибку анализа'],
original_feedback: feedbackText
};
}
}
function sendNotification(name, email, feedback, analysis) {
var subject = "Требуется внимание: отзыв клиента " + name;
var body = `Получен отзыв, требующий внимания:
Имя: ${name}
Email: ${email}
Текст отзыва:
${feedback}
Анализ:
Тональность: ${analysis.sentiment}
Общий тон: ${analysis.tone}
Явные проблемы: ${analysis.explicit_issues.join(', ')}
Скрытые проблемы: ${analysis.implicit_issues.join(', ')}
Уровень критики: ${analysis.criticism_level}
Риск потери клиента: ${analysis.retention_risk}
Рекомендуемые действия: ${analysis.suggested_actions.join(', ')}
Пожалуйста, рассмотрите этот отзыв и примите необходимые меры.`;
Logger.log("Отправка уведомления на адрес: " + EMAIL_ADDRESS);
try {
MailApp.sendEmail(EMAIL_ADDRESS, subject, body);
Logger.log("Уведомление успешно отправлено");
} catch (error) {
Logger.log("Ошибка при отправке уведомления: " + error);
}
}В скрипте обязательно заполните строки:
- var SHEET_NAME = ‘название листа, на котором собираете отзывы’;
- EMAIL_ADDRESS = ’email адрес, куда нужно сигнализировать о проблемах’
- var apiKey = ‘Ваш API-ключ от ChatGPT’
- Кейс



Также вы можете изменить промпт в разделе var prompt. Сейчас я написал для скрипта максимально универсальный промпт, благодаря которому нейронка вычисляет негативные и отрицательные отзывы. А также положительные, в которых клиенты вскользь упоминают о каких-то проблемах. Вот примеры отзывов, которые нейронка посчитает проблемными:
- Остановились у вас на выходные. Номера чистые, персонал дружелюбный, а завтрак вкусный. Однако за время пребывания горячая вода дважды пропадала на несколько часов, что доставило неудобства. Надеюсь, это временные проблемы, так как отель действительно хороший.
- Я обратился в вашу мастерскую для замены экрана телефона. Работа была выполнена качественно, и результатом я доволен. Однако сроки ремонта затянулись на два дня, а мне пришлось самому несколько раз звонить, чтобы уточнить статус. Было бы здорово, если бы вы уведомляли клиентов о задержках.
- Записался в ваш клуб, но за несколько месяцев всё только ухудшалось. Тренажёры часто ломаются, душевые грязные, администраторы постоянно недовольны. Не понимаю, за что я плачу такие деньги.
После этого кликните на значок дискеты и на «Выполнить».

Разрешите запуск скрипта, авторизуйтесь через Google аккаунт.


Скрипт запустится.
После этого перейдите в раздел «Триггеры».

В правом нижнем углу кликните на «Добавление триггера».

В открывшемся окне в разделе «Выберите функцию» кликните на «analyzeNewFeedback».
В разделе «Выберите тип события» — «При отправке формы».
Остальные разделы трогать не нужно.

Сохраните настройки и вновь авторизуйтесь через Google аккаунт.
После этого скрипт заработает в автоматическом режиме: каждый раз, когда кто-то будет отправлять отзыв, скрипт будет анализировать сообщение и сигнализировать на почту в случае проблемы.
Ответ на почту будет приходить примерно в таком виде:

Скрипт будет пересылать текст проблемного сообщения и выдавать краткий анализ:
- тональность сообщения;
- главная проблема, которую отметил клиент;
- скрытые проблемы;
- уровень критики (насколько проблема серьезная);
- риск потери клиента;
- рекомендуемые действия.
Если не хотите получать столько информации, в разделе “function sendNotification” можете удалить строки:
- Уровень критики: ${analysis.criticism_level}
- Риск потери клиента: ${analysis.retention_risk}
- Рекомендуемые действия: ${analysis.suggested_actions.join(‘, ‘)}
Как работать со скриптом в таблице с другими данными
Если вы хотите добавить в таблицу больше информации и столбцов для анализа, вам нужно изменить следующий раздел:
var data = sheet.getRange(2, 1, lastRow - 1, 4).getValues();
var hasNewFeedback = false;
for (var i = 0; i < data.length; i++) {
var row = data[i];
var timestamp = row[0];
var name = row[1];
var email = row[2];
var feedback = row[3];
if (sheet.getRange(i + 2, 5).getValue() === '') {
hasNewFeedback = true;
var analysis = analyzeFeedback(feedback);
Logger.log("Результат анализа: " + JSON.stringify(analysis));
sheet.getRange(i + 2, 5).setValue(analysis.sentiment);
sheet.getRange(i + 2, 6).setValue(analysis.explicit_issues.join(', '));
sheet.getRange(i + 2, 7).setValue(analysis.criticism_level);
sheet.getRange(i + 2, 8).setValue(analysis.retention_risk);Строка var data = sheet.getRange(2, 1, lastRow – 1, 4).getValues() отвечает за количество считываемых столбцов. Здесь цифра 4 означает, что данные считываются из 4 столбцов. Если вы хотите считывать информацию из большего количества столбцов, измените цифру 4 на свое количество.
Индексы в var row должны соответствовать порядку столбцов в вашей таблице. Timestamp — время заполнения формы. Name — имя респондента. Email — адрес респондента. Feedback — отзыв. Число в квадратных скобках означает номер столбца. Например, если у вас первым столбцом идет адрес email респондента, то цифру “2” в квадратных скобках нужно заменить на “1” и т. д.
var timestamp = row[0];
var name = row[1];
var email = row[2];
var feedback = row[3];Номера столбцов в sheet.getRange() после “i + 2” обозначают номера столбцов, куда записываются результаты анализа.
if (sheet.getRange(i + 2, 5).getValue() === '') {
// ...
sheet.getRange(i + 2, 5).setValue(analysis.sentiment);
sheet.getRange(i + 2, 6).setValue(analysis.explicit_issues.join(', '));
sheet.getRange(i + 2, 7).setValue(analysis.criticism_level);
sheet.getRange(i + 2, 8).setValue(analysis.retention_risk);Важно! Если вы хотите, чтобы нейросеть считывала информацию из большего количества столбцов, вам нужно добавить новые строки кода в var и sheet.getRange(). Если до этого вы не работали с кодом, рекомендую ничего не менять, чтобы не сломать скрипт. Но если все же хотите попробовать, можете изменить код с помощью нейронки. Для этого покажите ей скрипт, скриншот таблицы или саму таблицу и попросите адаптировать код.
Твоя задача — проанализировать и адаптировать скрипт к моей таблице. Скрипт должен анализировать [что он должен смотреть в таблице] и сигнализировать мне на почту, если где-то возникла проблема. Вот скриншот моей таблицы/сама таблица.
Например, в моем случае таблица после анализа выглядит так:

Читайте также:
а откуда он отзывы парсит? Только с Гугл карт ?