I am developing a Discord bot using Google Apps Script. The bot's primary function is to post an approval message as a reply in a channel and then immediately add a '👍' reaction to its own message.
While the message posting works perfectly, the subsequent API call to add the reaction fails with a very specific error:
* **HTTP Response Code:** `403`
* **Response Body:** `{"message": "internal network error", "code": 40333}`
This is confusing because my bot has the **Administrator** role in the Discord server, which should grant it all necessary permissions.
#### **The Workflow**
1. A user triggers an action in a Google Sheets-backed web app.
2. The `processApproval` function is called in Google Apps Script.
3. `sendBotReply` successfully posts a message to the correct channel via the Discord API. It returns the new message's link/ID.
4. `addDiscordReaction` is called immediately with the new message's details. **This is the step that fails.**
#### **Relevant Code (Google Apps Script)**
Here is the simplified code for the core logic. The `sendBotReply` function is included to show that `UrlFetchApp` and the Bot Token are working correctly for posting messages.
```javascript
const BOT_TOKEN = '...'; // My bot token is valid and works for posting.
/**
* Main orchestrator function.
*/
function processApproval() {
try {
// This part works: The bot posts the message and I get a valid link.
const messageLinkFromBot = sendBotReply();
// This is the call that fails.
addDiscordReaction(messageLinkFromBot);
} catch (error) {
Logger.log('Error in processApproval: ' + error.toString());
}
}
/**
* Sends a message as the bot. THIS FUNCTION WORKS.
* Returns the URL of the newly created message.
*/
function sendBotReply() {
const channelId = '123456789012345678'; // Example Channel ID
const apiUrl = `
https://discord.com/api/v10/channels/${channelId}/messages`;
const payload = {
content: `This is a test message from the bot.`
};
const options = {
method: 'post',
contentType: 'application/json',
headers: {
'Authorization': 'Bot ' + BOT_TOKEN
},
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(apiUrl, options);
const responseData = JSON.parse(response.getContentText());
// Example return: "
https://discord.com/channels/SERVER_ID/CHANNEL_ID/MESSAGE_ID"
return `
https://discord.com/channels/${responseData.guild_id}/${responseData.channel_id}/${responseData.id}`;
}
/**
* Tries to add a reaction to a message. THIS FUNCTION FAILS.
*/
function addDiscordReaction(messageLink) {
// Assume parseDiscordLink correctly extracts IDs from the messageLink
const ids = parseDiscordLink(messageLink);
// ids = { channelId: '...', messageId: '...' }
if (!ids) {
throw new Error(`Could not parse IDs from message link for reaction: ${messageLink}`);
}
const reactionEmoji = encodeURIComponent('👍'); // Thumbs Up
const url = `
https://discord.com/api/v10/channels/${ids.channelId}/messages/${ids.messageId}/reactions/${reactionEmoji}/@me`;
const options = {
method: 'put',
headers: {
'Authorization': 'Bot ' + BOT_TOKEN
},
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(url, options);
const responseCode = response.getResponseCode();
const responseBody = response.getContentText();
// THE PROBLEM IS HERE:
// responseCode is 403
// responseBody is {"message": "internal network error", "code": 40333}
if (responseCode !== 204) {
Logger.log(`Failed to add reaction. Code: ${responseCode}, Body: ${responseBody}`);
throw new Error(`Failed to add reaction. API responded with code ${responseCode}.`);
}
Logger.log(`Successfully added reaction to message ${ids.messageId}`);
}
// Helper function to extract IDs
function parseDiscordLink(link) {
if (!link) return null;
const match = link.match(/channels\/\d+\/(\d+)\/(\d+)/);
if (match && match.length === 3) {
return { channelId: match[1], messageId: match[2] };
}
return null;
}
```
#### **What I've Checked**
1. **Permissions:** The bot has the **Administrator** role. This includes `Add Reactions` and `Read Message History`.
2. **Bot Token:** The token is correct and has the necessary scopes (`bot`, `applications.commands`). It works perfectly for the `sendBotReply` function.
3. **API Endpoint:** The URL `.../reactions/{emoji}/@me` with the `PUT` method is correct according to the [Discord API documentation](
https://discord.com/developers/docs/resources/channel#create-reaction).
4. **IDs and Emoji:** The `channelId`, `messageId`, and URL-encoded `emoji` are all correct. I have logged them and they are valid.
5. **Timing:** I tried adding a `Utilities.sleep(2000)` between posting and reacting, but it made no difference.
6. **Error Code:** The error is not the typical `50013: Missing Permissions` error. The `40333: internal network error` seems to indicate something else is wrong.
#### **The Question**
What could be causing this specific `40333: internal network error` when trying to add a reaction? Given that the bot has full Administrator permissions and can successfully post the message it's trying to react to, what could be the root cause? Is this a known issue with Google Apps Script's `UrlFetchApp` or a more obscure Discord API behavior?