Seeking assistance with my automation project
I am building a Discord bot that pulls messages from my server and logs them into an Excel spreadsheet using Apps Script. The strange part is that during manual testing with the testDoPost function, everything works without a hitch, and the data successfully populates my spreadsheet.
The webhook setup appears correct, and the deployment is accurate, but when a message is sent from Discord, the bot seems to completely ignore it. Instead, I keep encountering this error: “last_error_message”: “Wrong response from the webhook: 302 Moved Temporarily”
// Discord Bot with Excel Integration
// Captures messages via webhook and stores information in the spreadsheet
const SPREADSHEET_NAME = 'MyData'; // Expected spreadsheet name
// Securely store Discord token
function setDiscordToken() {
const ui = SpreadsheetApp.getUi();
const response = ui.prompt('Enter Discord Token', 'Please provide your Discord bot token:', ui.ButtonSet.OK_CANCEL);
if (response.getSelectedButton() == ui.Button.OK) {
const token = response.getResponseText().trim();
if (token) {
PropertiesService.getScriptProperties().setProperty('DISCORD_TOKEN', token);
ui.alert('Token saved successfully!');
}
}
}
// Retrieve the stored Discord token
function getDiscordToken() {
const token = PropertiesService.getScriptProperties().getProperty('DISCORD_TOKEN');
if (!token) {
throw new Error('Discord token missing. Run setDiscordToken() first.');
}
return token;
}
// Handle GET requests
function doGet(e) {
return HtmlService.createHtmlOutput("Webhook active and ready to receive Discord updates.");
}
// Process incoming webhook data
function doPost(e) {
try {
if (!e || !e.postData || !e.postData.contents) {
return ContentService.createTextOutput(JSON.stringify({ result: 'error', info: 'Missing data' }))
.setMimeType(ContentService.MimeType.JSON);
}
const webhookData = JSON.parse(e.postData.contents);
if (!webhookData.message || !webhookData.message.content) {
return ContentService.createTextOutput(JSON.stringify({ result: 'error', info: 'No message content' }))
.setMimeType(ContentService.MimeType.JSON);
}
const messageText = webhookData.message.content;
const channelId = webhookData.message.channel.id;
// Process messages starting with "!" and containing digits
if (messageText.startsWith('!') && /\d/.test(messageText)) {
const idMatch = messageText.match(/!(\d+)/);
const quantityMatch = messageText.match(/(\d+)x/);
const priceMatch = messageText.match(/(\d+\.\d+)\$/);
const platformMatch = messageText.match(/\$([a-zA-Z0-9]+)/);
if (idMatch && quantityMatch && priceMatch && platformMatch) {
const recordId = idMatch[1];
const quantity = quantityMatch[1];
const price = priceMatch[1];
const platform = platformMatch[1];
const targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SPREADSHEET_NAME);
if (!targetSheet) {
sendDiscordResponse(channelId, `Error: Spreadsheet "${SPREADSHEET_NAME}" not found.`);
return ContentService.createTextOutput(JSON.stringify({ result: 'error', info: 'Spreadsheet missing' }))
.setMimeType(ContentService.MimeType.JSON);
}
targetSheet.appendRow([recordId, quantity, price, platform]);
sendDiscordResponse(channelId, 'Data saved to spreadsheet!');
} else {
sendDiscordResponse(channelId, 'Wrong format. Use: !id quantityx price$platform');
}
}
return ContentService.createTextOutput(JSON.stringify({ result: 'success' }))
.setMimeType(ContentService.MimeType.JSON);
} catch (error) {
return ContentService.createTextOutput(JSON.stringify({ result: 'error', info: error.message }))
.setMimeType(ContentService.MimeType.JSON);
}
}
// Send response back to Discord
function sendDiscordResponse(channelId, message) {
const DISCORD_TOKEN = getDiscordToken();
const apiUrl = `https://discord.com/api/channels/${channelId}/messages`;
const requestData = {
content: message
};
const requestOptions = {
method: 'post',
headers: {
'Authorization': `Bot ${DISCORD_TOKEN}`,
'Content-Type': 'application/json'
},
payload: JSON.stringify(requestData)
};
try {
UrlFetchApp.fetch(apiUrl, requestOptions);
} catch (error) {
Logger.log('Failed to send Discord message: ' + error.message);
}
}
// Configure webhook endpoint
function configureWebhook() {
const DISCORD_TOKEN = getDiscordToken();
const appUrl = 'https://script.google.com/macros/s/.../exec';
const webhookUrl = `https://discord.com/api/webhooks/set?url=${encodeURIComponent(appUrl)}`;
try {
const response = UrlFetchApp.fetch(webhookUrl);
Logger.log('Webhook configured: ' + response.getContentText());
} catch (error) {
Logger.log('Webhook setup failed: ' + error.message);
}
}
// Test function
function testDoPost() {
const mockEvent = {
postData: {
contents: JSON.stringify({
message: {
content: "!456 78x 90.12$testPlatform",
channel: {
id: 987654321
}
}
})
}
};
doPost(mockEvent);
}
I’ve tried numerous solutions: recreating the bot, resetting the webhook repeatedly, redeploying the script, yet nothing seems to resolve the issue. Given that the code was generated with AI support, there might be aspects that I’m overlooking. Any insights on what might be causing this 302 error would be greatly appreciated!