Сложность: Уровень сложностиУровень сложностиУровень сложности

Как научить нейросеть следить за отзывами клиентов и получать автоматические уведомления о проблемах

Если вы постоянно собираете обратную связь от клиентов и хотите автоматизировать процесс анализа отзывов — читайте этот гайд. В нем мы рассказали, как подключить нейросеть к 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);
Prompt

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

Например, в моем случае таблица после анализа выглядит так:

Читайте также:

1 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
mike_myatov
1 год назад

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