Governor Bets
Governor Bets

Reputation: 1

Telegram integration with Google Sheets

First post here, not sure how to format my question, but I am trying to make a Telegram Bot, which takes information from messages posted in my Telegram channel, and then puts them into my Google Spreadsheet. I am using Apps Script and I will post the code below which I have currently input. When doing the testDoPost, it works fine and sends a line into my spreadsheet. It is properly deployed, webhook works fine, the web app links fine, everything seems fine, until I get to sending the message in Telegram and then the bot does not react to it in any way. Only prints an error of "last_error_message": "Wrong response from the webhook: 302 Moved Temporarily"

The code is below with the bot token and web app not included. Please let me know how to fix this, it's been killing me for days.

/**
 * 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);
}

I tried absolutely everything, removing the bot, readding it, deleting the webhook, doing setWebhook again and absolutely nothing helps. I am on the verge of giving up but would like some more expert opinions on what could be wrong? The code is done with ChatGPT so I wouldn't doubt it being a bit off rather than a human coding it, but I am pretty clueless when it comes to coding.

Upvotes: 0

Views: 196

Answers (0)

Related Questions