Hello everyone! I’m a newcomer here, so I appreciate your patience if I make any mistakes with my question. I’m trying to create a Discord bot that captures messages from my Discord server and saves this information into an online Excel spreadsheet. I’m utilizing Google Apps Script for this task.
I have written some code that tests fine with the testDoPost function. The data is added to my spreadsheet successfully when testing. I’ve confirmed that everything is set up correctly - the webhook is activated, the web app is deployed, and all connections appear to function.
However, the strange issue is that when I send a message in Discord, the bot doesn’t respond at all. Instead, I receive this error message: “last_error_message”: “Wrong response from the webhook: 302 Moved Temporarily”
I have attempted all sorts of solutions. I deleted the bot and created it again, removed the webhook, and then re-established it. I’ve even redeployed the web app repeatedly with no success, which is making me quite frustrated.
Here’s my current code (I’ve removed the actual tokens and URLs for security purposes):
const SPREADSHEET_NAME = 'MyData';
function storeDiscordToken() {
const interface = SpreadsheetApp.getUi();
const prompt = interface.prompt('Enter Discord Token', 'Type your Discord bot token here:', interface.ButtonSet.OK_CANCEL);
if (prompt.getSelectedButton() == interface.Button.OK) {
const botToken = prompt.getResponseText().trim();
if (botToken) {
PropertiesService.getScriptProperties().setProperty('DISCORD_TOKEN', botToken);
interface.alert('Token saved successfully!');
} else {
interface.alert('Please enter a valid token');
}
}
}
function getDiscordToken() {
const savedToken = PropertiesService.getScriptProperties().getProperty('DISCORD_TOKEN');
if (!savedToken) {
throw new Error('Discord token missing. Run storeDiscordToken() first.');
}
return savedToken;
}
function doGet(request) {
return HtmlService.createHtmlOutput("Bot webhook is running and ready to receive messages.");
}
function doPost(request) {
try {
console.log("Webhook triggered by Discord");
if (!request || !request.postData || !request.postData.contents) {
console.log("No data received from Discord");
return ContentService.createTextOutput(JSON.stringify({ result: 'error', info: 'No data received' }))
.setMimeType(ContentService.MimeType.JSON);
}
console.log("Raw message data: " + request.postData.contents);
const messageData = JSON.parse(request.postData.contents);
console.log("Parsed message: " + JSON.stringify(messageData));
if (!messageData.message || !messageData.message.text) {
console.log("No text content found in message");
return ContentService.createTextOutput(JSON.stringify({ result: 'error', info: 'No text found' }))
.setMimeType(ContentService.MimeType.JSON);
}
const textContent = messageData.message.text;
const channelId = messageData.message.chat.id;
console.log("Processing message: " + textContent);
console.log("Channel ID: " + channelId);
if (textContent.startsWith('!') && /\d/.test(textContent)) {
const orderNumber = textContent.match(/!(\d+)/);
const quantityMatch = textContent.match(/(\d+)x/);
const priceMatch = textContent.match(/(\d+\.\d+)\$/);
const storeMatch = textContent.match(/\$([a-zA-Z0-9]+)/);
console.log("Extracted data: " + JSON.stringify({ orderNumber, quantityMatch, priceMatch, storeMatch }));
if (orderNumber && quantityMatch && priceMatch && storeMatch) {
const orderId = orderNumber[1];
const quantity = quantityMatch[1];
const price = priceMatch[1];
const store = storeMatch[1];
const dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SPREADSHEET_NAME);
if (!dataSheet) {
console.log(`Cannot find sheet: ${SPREADSHEET_NAME}`);
replyToDiscord(channelId, `Error: Cannot find spreadsheet ${SPREADSHEET_NAME}`);
return ContentService.createTextOutput(JSON.stringify({ result: 'error', info: 'Sheet not found' }))
.setMimeType(ContentService.MimeType.JSON);
}
dataSheet.appendRow([orderId, quantity, price, store]);
console.log("Successfully added data to spreadsheet");
replyToDiscord(channelId, 'Order data saved successfully!');
} else {
console.log("Message format is incorrect");
replyToDiscord(channelId, 'Wrong format. Use: !order quantityx price$store');
}
} else {
console.log("Message does not match expected pattern");
replyToDiscord(channelId, 'Invalid format. Use: !order quantityx price$store');
}
return ContentService.createTextOutput(JSON.stringify({ result: 'success' }))
.setMimeType(ContentService.MimeType.JSON);
} catch (err) {
console.log("Error processing request: " + err.message);
return ContentService.createTextOutput(JSON.stringify({ result: 'error', info: err.message }))
.setMimeType(ContentService.MimeType.JSON);
}
}
function replyToDiscord(channelId, messageText) {
const BOT_TOKEN = getDiscordToken();
const apiUrl = `https://api.discord.com/bot${BOT_TOKEN}/sendMessage`;
const requestData = {
chat_id: channelId,
text: messageText,
};
const requestOptions = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(requestData),
};
try {
const apiResponse = UrlFetchApp.fetch(apiUrl, requestOptions);
console.log("Discord reply sent: " + apiResponse.getContentText());
} catch (err) {
console.log('Failed to send Discord message: ' + err.message);
}
}
function setupWebhook() {
const BOT_TOKEN = getDiscordToken();
const webAppEndpoint = 'https://script.google.com/macros/s/YOUR_SCRIPT_ID/exec';
const webhookUrl = `https://api.discord.com/bot${BOT_TOKEN}/setWebhook?url=${encodeURIComponent(webAppEndpoint)}`;
try {
const response = UrlFetchApp.fetch(webhookUrl);
console.log('Webhook configured: ' + response.getContentText());
} catch (err) {
console.log('Webhook setup failed: ' + err.message);
}
}
function testWebhook() {
const mockRequest = {
postData: {
contents: JSON.stringify({
message: {
text: "!456 12x 34.56$testStore",
chat: {
id: 987654321
}
}
})
}
};
doPost(mockRequest);
}
I suspect the issue lies within my code as I used an AI tool to assist in writing it, but I’m unsure how to pinpoint the problem. Has anyone experienced this 302 error before? I would greatly appreciate any suggestions that might explain what could be going wrong.