Telegram 与 Google Sheets 集成

问题描述 投票:0回答:1

首先在这里发帖,不知道如何格式化我的问题,但我正在尝试制作一个 Telegram 机器人,它从我的 Telegram 频道中发布的消息中获取信息,然后将它们放入我的 Google 电子表格中。我正在使用 Apps 脚本,我将在下面发布我当前输入的代码。在执行 testDoPost 时,它工作正常并将一行发送到我的电子表格中。它部署正确,webhook 工作正常,网络应用程序链接正常,一切看起来都很好,直到我在 Telegram 中发送消息,然后机器人不会以任何方式对其做出反应。只打印“last_error_message”错误:“来自 webhook 的错误响应:302 暂时移动”

代码如下,不包括机器人令牌和网络应用程序。请让我知道如何解决这个问题,这已经困扰我好几天了。

/**
 * Telegram Bot Integration with Google Sheets
 * 
 * This script receives messages from a Telegram bot via webhook,
 * parses specific data from the messages, and appends the data to a Google Sheet.
 * 
 * Ensure you follow the setup instructions below before deploying.
 */

/**
 * Constants
 */
const SHEET_NAME = '...'; // Name of the Google Sheet to append data

/**
 * =========================
 * 1. TOKEN MANAGEMENT
 * =========================
 */

/**
 * Sets the Telegram bot token securely using Properties Service.
 * 
 * IMPORTANT: Run this function **once** to store your Telegram token securely.
 */
function setTelegramToken() {
  const ui = SpreadsheetApp.getUi();
  const response = ui.prompt('Set Telegram Token', 'Please enter your Telegram bot token:', ui.ButtonSet.OK_CANCEL);

  // Process the user's response.
  if (response.getSelectedButton() == ui.Button.OK) {
    const token = response.getResponseText().trim();
    if (token) {
      PropertiesService.getScriptProperties().setProperty('TELEGRAM_TOKEN', token);
      ui.alert('Success', 'Telegram token has been set successfully.', ui.ButtonSet.OK);
    } else {
      ui.alert('Error', 'No token provided. Please try again.', ui.ButtonSet.OK);
    }
  } else {
    ui.alert('Operation cancelled.', ui.ButtonSet.OK);
  }
}

/**
 * Retrieves the Telegram bot token from Properties Service.
 * 
 * @returns {string} The Telegram bot token.
 */
function getTelegramToken() {
  const token = PropertiesService.getScriptProperties().getProperty('TELEGRAM_TOKEN');
  if (!token) {
    throw new Error('Telegram token not set. Please run setTelegramToken() first.');
  }
  return token;
}

/**
 * =========================
 * 2. WEBHOOK HANDLING
 * =========================
 */

/**
 * Responds to GET requests to verify that the webhook is active.
 * 
 * @param {Object} e - The event parameter.
 * @returns {HtmlOutput} A simple HTML message.
 */
function doGet(e) {
  return HtmlService.createHtmlOutput("Webhook is active. This URL is configured to receive Telegram updates.");
}

/**
 * Handles incoming POST requests from Telegram webhook.
 * Parses the message and appends data to Google Sheet if the message format is correct.
 * 
 * @param {Object} e - The event parameter containing POST data.
 * @returns {TextOutput} A JSON response indicating success or error.
 */
function doPost(e) {
  try {
    Logger.log("doPost triggered.");

    // Validate the event object and POST data.
    if (!e || !e.postData || !e.postData.contents) {
      Logger.log("No postData found.");
      return ContentService.createTextOutput(JSON.stringify({ status: 'error', message: 'No postData found.' }))
                           .setMimeType(ContentService.MimeType.JSON);
    }

    // Log the raw POST data to understand its structure.
    Logger.log("Raw POST Data: " + e.postData.contents);

    // Parse the incoming POST data.
    const data = JSON.parse(e.postData.contents);
    Logger.log("Parsed Data: " + JSON.stringify(data));

    // Check if the message and text exist.
    if (!data.message || !data.message.text) {
      Logger.log("No message text found.");
      return ContentService.createTextOutput(JSON.stringify({ status: 'error', message: 'No message text found.' }))
                           .setMimeType(ContentService.MimeType.JSON);
    }

    const message = data.message.text;
    const chatId = data.message.chat.id;
    Logger.log("Message received: " + message);
    Logger.log("Chat ID: " + chatId);

    // Only process messages that start with "#" and contain numbers.
    if (message.startsWith('#') && /\d/.test(message)) {
      // Extract components using regex.
      const targetNumber = message.match(/#(\d+)/); // Extract number after "#"
      const valueBeforeU = message.match(/(\d+)u/); // Extract value before "u"
      const valueBeforeAt = message.match(/(\d+\.\d+)@/); // Extract value before "@"
      const textAfterAt = message.match(/@([a-zA-Z0-9]+)/); // Extract site after "@"

      Logger.log("Parsed values: " + JSON.stringify({ targetNumber, valueBeforeU, valueBeforeAt, textAfterAt }));

      // Validate all extracted components.
      if (targetNumber && valueBeforeU && valueBeforeAt && textAfterAt) {
        const targetValue = targetNumber[1];
        const uValue = valueBeforeU[1];
        const numberBeforeAt = valueBeforeAt[1];
        const siteName = textAfterAt[1];

        // Append the parsed data to the specified Google Sheet.
        const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
        if (!sheet) {
          Logger.log(`Sheet named "${SHEET_NAME}" not found.`);
          sendTelegramMessage(chatId, `Error: Sheet named "${SHEET_NAME}" not found.`);
          return ContentService.createTextOutput(JSON.stringify({ status: 'error', message: 'Sheet not found.' }))
                               .setMimeType(ContentService.MimeType.JSON);
        }

        sheet.appendRow([targetValue, uValue, numberBeforeAt, siteName]);
        Logger.log("Data appended to sheet successfully.");

        // Respond to the Telegram user confirming the data was recorded.
        sendTelegramMessage(chatId, 'Message recorded successfully.');
      } else {
        // Respond if the message format is incorrect.
        Logger.log("Invalid message format.");
        sendTelegramMessage(chatId, 'Invalid message format. Use #number valueu value@site.');
      }
    } else {
      Logger.log("Message does not start with '#' or does not contain numbers.");
      // Optionally, inform the user about the expected format.
      sendTelegramMessage(chatId, 'Invalid message format. Use #number valueu value@site.');
    }

    // Return a success response to Telegram.
    return ContentService.createTextOutput(JSON.stringify({ status: 'ok' }))
                         .setMimeType(ContentService.MimeType.JSON);

  } catch (error) {
    Logger.log("Error in doPost: " + error.message);
    // Respond with an error message.
    return ContentService.createTextOutput(JSON.stringify({ status: 'error', message: error.message }))
                         .setMimeType(ContentService.MimeType.JSON);
  }
}

/**
 * =========================
 * 3. TELEGRAM COMMUNICATION
 * =========================
 */

/**
 * Sends a message to a Telegram user using the bot's token.
 * 
 * @param {number} chatId - The chat ID to send the message to.
 * @param {string} text - The text message to send.
 */
function sendTelegramMessage(chatId, text) {
  const TELEGRAM_TOKEN = getTelegramToken(); // Retrieve the token securely.
  const url = `https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage`;
  const payload = {
    chat_id: chatId,
    text: text,
  };
  const options = {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify(payload),
  };

  try {
    const response = UrlFetchApp.fetch(url, options);
    Logger.log("sendTelegramMessage response: " + response.getContentText());
  } catch (error) {
    Logger.log('Error sending message: ' + error.message);
  }
}

/**
 * =========================
 * 4. WEBHOOK SETUP
 * =========================
 */

/**
 * Sets the webhook for the Telegram bot to point to the Google Apps Script Web App URL.
 * 
 * IMPORTANT: After deploying the Web App, run this function to set the webhook.
 */
function setWebhook() {
  const TELEGRAM_TOKEN = getTelegramToken(); // Retrieve the token securely.
  
  // Replace with your actual deployed Web App URL..
  const webAppUrl = 'https://script.google.com/macros/s/.../exec; 
  
  const url = `https://api.telegram.org/bot${TELEGRAM_TOKEN}/setWebhook?url=${encodeURIComponent(webAppUrl)}`;
  
  try {
    const response = UrlFetchApp.fetch(url);
    Logger.log('Webhook set successfully: ' + response.getContentText());
  } catch (error) {
    Logger.log('Error setting webhook: ' + error.message);
  }
}

/**
 * =========================
 * 5. TESTING FUNCTION
 * =========================
 */

/**
 * Simulates a POST request to the doPost function for testing purposes.
 * 
 * IMPORTANT: Use this function to test doPost without sending actual messages via Telegram.
 */
function testDoPost() {
  const testEvent = {
    postData: {
      contents: JSON.stringify({
        message: {
          text: "#123 45u 67.89@exampleSite",
          chat: {
            id: 123456789 // Replace with a valid chat ID for testing.
          }
        }
      })
    }
  };
  
  doPost(testEvent);
}

我尝试了所有方法,删除机器人、读取机器人、删除 webhook、再次执行 setWebhook,但毫无帮助。我正处于放弃的边缘,但想了解更多专家的意见,看看可能出了什么问题?代码是用 ChatGPT 完成的,所以我不怀疑它有点偏离,而不是人类编码,但我在编码方面非常无能。

google-sheets google-apps-script telegram telegram-bot telegram-api
1个回答
0
投票

将 Telegram 机器人与 Google Sheets 集成,您可以从 Telegram 频道捕获消息并将其附加到 Google 电子表格中。要实现此集成,请按照下列步骤操作:

1。设置您的 Telegram 机器人:

  • 创建一个新机器人:
    • 在 Telegram 中,搜索 BotFather 并开始聊天。
    • 使用
      /newbot
      命令创建一个新机器人。
    • 按照提示为您的机器人设置名称和用户名。
    • 创建后,BotFather 将提供Bot Token

2。配置 Webhook:

  • 在 Google Apps 脚本中部署 Web 应用程序:

    • 在您的 Google 电子表格中,导航至 扩展 > Apps 脚本
    • 用下面提供的脚本替换默认代码。
    • 将脚本部署为 Web 应用程序:
      • 单击 部署 > 新部署
      • 选择网络应用程序
      • 执行为设置为,将谁有权访问设置为任何人
      • 点击部署并授权所需权限。
      • 复制部署后提供的Web 应用程序 URL
  • 设置Webhook URL:

    • 使用以下 URL 格式设置您的 Webhook:
      https://api.telegram.org/bot<YourBotToken>/setWebhook?url=<YourWebAppURL>
      
      <YourBotToken>
      替换为从 BotFather 获取的令牌,并将
      <YourWebAppURL>
      替换为来自 Web 应用程序部署的 URL。
    • 将此 URL 粘贴到浏览器中,然后按 Enter 键。您应该收到一个 JSON 响应,表明 Webhook 已成功设置。

3.实施 Google Apps 脚本:

/**
 * Telegram Bot Integration with Google Sheets
 * This script receives messages from a Telegram bot via webhook,
 * parses specific data from the messages, and appends the data to a Google Sheet.
 */

/**
 * Constants
 */
const SHEET_NAME = 'Sheet1'; // Replace with your sheet name

/**
 * Retrieves the Telegram bot token from Properties Service.
 * @returns {string} The Telegram bot token.
 */
function getTelegramToken() {
  const token = PropertiesService.getScriptProperties().getProperty('TELEGRAM_TOKEN');
  if (!token) {
    throw new Error('Telegram token not set. Please run setTelegramToken() first.');
  }
  return token;
}

/**
 * Sets the Telegram bot token securely using Properties Service.
 * Run this function once to store your Telegram token securely.
 */
function setTelegramToken() {
  const ui = SpreadsheetApp.getUi();
  const response = ui.prompt('Set Telegram Token', 'Please enter your Telegram bot token:', ui.ButtonSet.OK_CANCEL);

  if (response.getSelectedButton() == ui.Button.OK) {
    const token = response.getResponseText().trim();
    if (token) {
      PropertiesService.getScriptProperties().setProperty('TELEGRAM_TOKEN', token);
      ui.alert('Success', 'Telegram token has been set successfully.', ui.ButtonSet.OK);
    } else {
      ui.alert('Error', 'No token provided. Please try again.', ui.ButtonSet.OK);
    }
  } else {
    ui.alert('Operation cancelled.', ui.ButtonSet.OK);
  }
}

/**
 * Handles POST requests from Telegram.
 * @param {Object} e - The event parameter containing the POST data.
 * @returns {HtmlOutput} An empty HTML output.
 */
function doPost(e) {
  try {
    const contents = JSON.parse(e.postData.contents);
    const message = contents.message;

    if (message && message.text) {
      const userId = message.from.id;
      const username = message.from.username || '';
      const firstName = message.from.first_name || '';
      const lastName = message.from.last_name || '';
      const text = message.text;
      const date = new Date(message.date * 1000); // Telegram provides date as Unix time

      const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
      sheet.appendRow([date, userId, username, firstName, lastName, text]);
    }
  } catch (error) {
    console.error('Error in doPost:', error.toString());
  }
  return HtmlService.createHtmlOutput();
}

/**
 * Test function to simulate a POST request.
 * Useful for debugging purposes.
 */
function testDoPost() {
  const testData = {
    message: {
      message_id: 1,
      from: {
        id: 123456789,
        is_bot: false,
        first_name: 'John',
        last_name: 'Doe',
        username: 'johndoe',
        language_code: 'en'
      },
      chat: {
        id: 123456789,
        first_name: 'John',
        last_name: 'Doe',
        username: 'johndoe',
        type: 'private'
      },
      date: Math.floor(Date.now() / 1000),
      text: 'Hello, this is a test message'
    }
  };

  const e = { postData: { contents: JSON.stringify(testData) } };
  doPost(e);
}
© www.soinside.com 2019 - 2024. All rights reserved.