← Вернуться к списку тем

Прошу помочь в вопросе простого бота опросника

Добрый день, подскажите пожалуйста как сделать простого телеграмм бота опросника с гугл таблицами. Смысл такой: Бот поочередно будет задавать порядка 20 вопросов на которые необходимо ответить и что бы это дело автоматически вносилось в гугл таблицы. Если можно, что бы юзер мог подгрузить фото на запрос. 

Авторизуйтесь через Telegram, чтобы оставить комментарий.
Откройте по ссылке или QR бот @iMakeBot, нажмите кнопку Старт/Start.
Следуйте инструкциям бота.

  • iMakeBots [2 месяца назад]

    Начните с создания скрипта. На стадии когда бот будет отвечать на команду /start - можете начать проектировать структуру вопросов (вопрос, какой тип ответа ожидаете), будет ли это json файл или лист в таблице - не важно.

    После наполните тестовыми данными, и добавьте после обработки команды старт вызов первого вопроса, далее обработка ответа, сохранение и переход к следующему вопросу если такой есть или закрытие опроса ...

  • Игорь [2 месяца назад]

    Честно говоря я в этом не силен и уроков найти не могу, не могли бы мне просто подсказать по скрипту или направить на какой нибудь урок. 

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

    let token = "...................";
    
    function getMe() {
      let response = UrlFetchApp.fetch("https://api.telegram.org/bot............................/getMe/getMe");
      console.log(response.getContentText());
    }
    
    function setWebhook() {
      let webAppUrl = "https://script.google.com/macros/s/AKfycbwIb-AGmMo_p_zZIeZMtuE9eqBqzQj1kq6EZ8hqHl1vBMnT1JOfQHhx6OHwYg-V6pnO/exec";
      let response = UrlFetchApp.fetch("https://api.telegram.org/bot" + token + "/setWebhook?url=" + webAppUrl);
      console.log(response.getContentText());
    }
    
    function sendText(chat_id, text) {
      let data = {
        method: "post",
        payload: {
          method: "sendMessage",
          chat_id: String(chat_id),
          text: text,
          parse_mode: "HTML"
        }
      };
      UrlFetchApp.fetch('https://api.telegram.org/bot' + token + '/', data);
    }
    
    function send() {
      let chat_id = 8063365785;
      let text = "Привет ! Как дела?";
      sendText(chat_id, text);
    }
    
    
    function doPost(e) {
      let contents = JSON.parse(e.postData.contents);
      let chat_id = contents.message.chat.id;
      let text = contents.message.text;
      sendText(chat_id, text);
      SpreadsheetApp.openById("..................").getSheetByName("Messages").appendRow([chat_id, text]);
    }
  • iMakeBots [1 месяц назад]

    Возьмите за основу вот этот скрипт. Комментарии добавил

    /**
     * Определим настройки
     */
    const config = {
      token: "8042*******XbIKt0",
      sheet_id: "1ReQzCh********i5zTJoiaUk",
      questions: [
        {
          text: "Вопрос 1",
          type: "text",
        },
        {
          text: "Вопрос 2",
          type: "text",
        },
        {
          text: "Вопрос 3",
          type: "photo",
        }
      ]
    };
    
    // получим файл по его id
    const file = SpreadsheetApp.openById(config.sheet_id);
    
    /**
     * Получим лист по названию
     */
    function sheet(name) {
      // запросим лист
      const sheet = file.getSheetByName(name);
      // вернем результат
      return !sheet 
        // если лист не найден - создадим и вернем
        ? file.insertSheet(name) 
        // если найден - вернем его
        : sheet;
    }
    
    /**
     * Получим индекс строки в листе по uid пользователя
     */
    function getRowByUID(uid, sheet_name) {
      // вернем результат в виде числа
      return sheet(sheet_name)
        // возьмем весь доступный диапазон данных
        .getDataRange()
        // получим с него массив данных
        .getValues()
        // найдем по первой колонке и так как массивы начинаются с 0, а строки в листе с 1 то увеличим на еденицу
        .findIndex(row => row[0] == uid) + 1
    }
    
    /**
     * Получим данные пользователя
     */
    function getUserDataByUid(uid) {
      // определим в какой строке данные пользователя по uid
      const row_index_user = getRowByUID(uid, "users");
      // если пользователь не найден
      if(!row_index_user) {
        // создадим данные пользователя 
        // [uid пользователя в телеграм, порядковый номер текущего вопроса]
        const data = [uid, 0];
        // добавим новой строкой в лист users
        sheet("users").appendRow(data);
        // вернем данные
        return data;
      }
      // если найден то вернем данные из таблицы
      return sheet("users")
        // запросим диапазон конкретной строки с 1 по 2 колонку
        .getRange(row_index_user, 1, row_index_user, 2)
        // первую строку массива диапазона
        .getValues()[0];
    }
    
    /**
     * Обновим данные пользоваетля
     */
    function setUserData(uid, column, value) {
      // получим индекс строки 
      const row_index_user = getRowByUID(uid, "users");
      // в таблице users
      sheet("users")
        // получим нужную колокнку строки пользователя в таблице по координатам
        .getRange(row_index_user, column)
        // вставим значение
        .setValue(value);
    }
    
    /**
     * Метод обработки POST запроса 
     */
    function doPost(e) {
      // получим параметры запроса
      let tg_data = JSON.parse(e.postData.contents);
      // передадим на обработку
      getAnswer(tg_data);
    }
    
    /**
     * Обработка запроса
     */
    function getAnswer(tg_data) {
      // получим данные пользователя
      const user_data = getUserDataByUid(tg_data.message.chat.id);
      // если это не старт
      if(tg_data.message.text != "/start") {
        // отправим на обработку как ответа
        setAnswer(user_data, tg_data);
      } else {
        // если это старт, обнулим ключ вопроса в данных пользователя
        user_data[1] = 0;
        // запишем изменения пользователю
        setUserData(user_data[0], 2, user_data[1]);
        // выведем вопрос
        setQuestion(user_data);
      }
    }
    
    /**
     * Запишем ответ
     */
    function setAnswer(user_data, tg_data) {
      // если вопрос по ключу найден
      if(config.questions[user_data[1]]?.type) {
        // проверим формат ответа на требуемый
        if(config.questions[user_data[1]].type in tg_data.message) {
          // создадим переменную
          let answer__;
          // если это картинка
          if(config.questions[user_data[1]].type == "photo") {
            // получим file_id как ответ
            answer__ = tg_data.message.photo[0].file_id;
            // отправим на физическое сохранение картинки по file_id
            savePhoto(answer__);
          } else {
            // если это не картинка, то значит текст - так как в данной настройки в вопросах nолько photo и text
            answer__ = tg_data.message.text;
          }
          // получим индекс ранее данных ответов изи таблицы answers
          const row_index_answer = getRowByUID(tg_data.message.chat.id, "answers");
          // если ранние ответы не найдены
          if(!row_index_answer) {
            // добавим [uid пользователя, дата, ответ]
            sheet("answers").appendRow([tg_data.message.chat.id, new Date(), answer__]);
          } else {
            // если ранние ответы найдены, то получим их из таблицы answers
            let data_a = sheet("answers") 
              // определим диапазон по индексу строки с 1 колонки по максимальную колонку таблицы
              .getRange(row_index_answer, 1, row_index_answer, sheet("answers").getLastColumn())
              // получим массив данных - первой найденой строки
              .getValues()[0]
              // отфильтруем - оставим только заполненные колонки
              .filter(val => String(val).length);
            // заменим дату на текущую
            data_a[1] = new Date();
            // отрежем лишние значения, оставим тоько ранние ответы по текущему ключу вопроса пользователя
            data_a = data_a.slice(0, (user_data[1] + 2))
            // добавим новый ответ
            data_a.push(answer__);
            // удалим строку по индексу
            sheet("answers").deleteRow(row_index_answer);
            // добавим новые значения
            sheet("answers").appendRow(data_a);
          }
          // обновим ользователю ключ следующего вопроса
          setUserData(user_data[0], 2, (user_data[1] += 1));
        } else {
          // тип ответа не тот который мы ждем то выведем предупреждение
          sendText(user_data[0], "Направлен не верный формат данных");
        }
      }
      // отправим на вывод вопроса
      setQuestion(user_data);
    }
    
    /**
     * выводим вопрос
     */
    function setQuestion(user_data) {
        // если вопросов уже нет - определяем по ключу в данных пользователя
        if(config.questions.length <= user_data[1]) {
          // выводим предупреждение
          sendText(user_data[0], "Спасибо опрос закончен. /start");
        } else {
          // выводим требуемый вопрос
          sendText(user_data[0], config.questions[user_data[1]]?.text ?? "-");
        }
    }
    
    /**
     * Физическое сохранение картинки
     */
    function savePhoto() {
      // если нужно куда-то сохранить физический файл
    }
    
    /**
     * Отправляем запрос в телеграм
     */
    function sendText(chat_id, text) {
      let data = {
        method: "post",
        payload: {
          method: "sendMessage",
          chat_id: String(chat_id),
          text: text,
          parse_mode: "HTML"
        }
      };
      return UrlFetchApp.fetch('https://api.telegram.org/bot' + config.token + '/', data);
    }