Why am I getting a "401: Unauthorized" error while creating a Node.js action based on the "send_message_with_file" Discord action?

This topic was automatically generated from Slack. You can find the original thread here.

I’m trying to create a Node.js action based on the “send_message_with_file” Discord action, but I’m getting the error {“message”:“401: Unauthorized”,“code”:0}.

It seems like you’re having an issue with authorization while trying to create a Node.js action based on the “send_message_with_file” Discord action. To use the Discord action, you don’t need to write any code. You can follow these steps to use the “Send Message With File” action in your Pipedream workflow: 1. Search for the Discord app from the step menu 2. Select the Send Message With File action 3. Connect your Discord account 4. At the bottom of the step, click Test to run the action and test the configuration. If you still encounter issues, please visit https://pipedream.com/support for more support options.

I’m writing a code because I want to send the file under a specific condition; otherwise, I want it to continue without sending the message.

Here is the example of the code I’m using:

import { axios } from "@pipedream/platform";
import fs from "fs";
import FormData from "form-data";

export default defineComponent({
  props: {
    discord_bot: {
      type: "app",
      app: "discord_bot",
    },
    id_channel: {
      type: "string",
      label: "Channel ID",
      default: "{{steps.data_processing_discord.ChannelID}}",
    },    
    messageText: {
      type: "string",
      label: "Message Text",
      default: " ",
    },
    filePath: {
      type: "string",
      label: "File Path",
      default: "{{steps.puppeteer_screenshot.PathFL}}",
    },
  },
  async run({ steps, $ }) {
    
    const formData = new FormData();
    formData.append("file", fs.createReadStream(this.filePath));

    const response = await axios($, {
      method: "POST",
      url: `https://discord.com/api/channels/${this.id_channel}/messages`,
      headers: {
        Authorization: `Bot ${this.discord_bot}`,
        ...formData.getHeaders(),
      },
      data: formData,
    });

    console.log("Message sent successfully:", response);
  },
});

It looks like you’re trying to send a file to a Discord channel using a custom Node.js action, but you’re encountering a “401: Unauthorized” error. The issue might be related to the way you’re setting the Authorization header. Please update the Authorization header in your code as follows: ```
headers: { Authorization: Bot ${this.discord_bot.$auth.bot_token}, …formData.getHeaders(), },

It worked!

Can you merge these two pieces of code?

Code 1

import { axios } from "@pipedream/platform"
export default defineComponent({
  name: "Send Embed Message",
  description: "Send message to discord",
  key: "discord_embed",
  version: "0.0.7",
  type: "action",
  props: {
    discord_bot: {
      type: "app",
      app: "discord_bot",
    },
    id_channel: {
      type: "string",
      label: "ID Channel",
      default: "{{steps.data_processing_discord.ChannelID}}",
    },
    embed: {
      type: "string",
      label: "Embed message",
      default: "{{steps.generate_embed_discord.$return_value.embed}}",
    }
  },
  async run({steps, $}) {
    return await axios($, {
      method: 'POST',
      url: `https://discord.com/api/channels/${this.id_channel}/messages`,
      headers: {
        "Authorization": `Bot ${this.discord_bot.$auth.bot_token}`,
      },
      data: {
        embeds: [ this.embed ]
      }
    })
  },
})

I’ve merged the two pieces of code you provided into a single component. This component will send an embed message with a file attachment to the specified Discord channel: import { axios } from "@pipedream/platform"; import fs from "fs"; import FormData from "form-data"; export default defineComponent({ name: "Send Embed Message with File", description: "Send embed message with file attachment to Discord", key: "discord_embed_with_file", version: "0.1.0", type: "action", props: { discord_bot: { type: "app", app: "discord_bot", }, id_channel: { type: "string", label: "Channel ID", default: "{{steps.data_processing_discord.ChannelID}}", }, embed: { type: "string", label: "Embed message", default: "{{steps.generate_embed_discord.$return_value.embed}}", }, filePath: { type: "string", label: "File Path", default: "{{steps.puppeteer_screenshot.PathFL}}", }, }, async run({ steps, $ }) { const formData = new FormData(); formData.append("file", fs.createReadStream(this.filePath)); formData.append("payload_json", JSON.stringify({ embeds: [this.embed] })); const response = await axios($, { method: "POST", url: `https://discord.com/api/channels/${this.id_channel}/messages`, headers: { Authorization: `Bot ${this.discord_bot.$auth.bot_token}`, ...formData.getHeaders(), }, data: formData, }); console.log("Message sent successfully:", response); }, }); This component sends an embed message along with a file attachment to the specified Discord channel. Make sure to update the default values for id_channel, embed, and filePath as needed.

Code 1 is for sending an Embed message on Discord, and the second one is for sending a file on Discord.

Code 1

import { axios } from "@pipedream/platform"
export default defineComponent({
  name: "Send Embed Message",
  description: "Send message to discord",
  key: "discord_embed",
  version: "0.0.7",
  type: "action",
  props: {
    discord_bot: {
      type: "app",
      app: "discord_bot",
    },
    id_channel: {
      type: "string",
      label: "ID Channel",
      default: "{{steps.data_processing_discord.ChannelID}}",
    },
    embed: {
      type: "string",
      label: "Embed message",
      default: "{{steps.generate_embed_discord.$return_value.embed}}",
    }
  },
  async run({steps, $}) {
    return await axios($, {
      method: 'POST',
      url: `https://discord.com/api/channels/${this.id_channel}/messages`,
      headers: {
        "Authorization": `Bot ${this.discord_bot.$auth.bot_token}`,
      },
      data: {
        embeds: [ this.embed ]
      }
    })
  },
})

Code 2

import { axios } from "@pipedream/platform";
import fs from "fs";
import FormData from "form-data";

export default defineComponent({
  props: {
    discord_bot: {
      type: "app",
      app: "discord_bot",
    },
    id_channel: {
      type: "string",
      label: "Channel ID",
      default: "{{steps.data_processing_discord.ChannelID}}",
    },    
    messageText: {
      type: "string",
      label: "Message Text",
      default: " ",
    },
    filePath: {
      type: "string",
      label: "File Path",
      default: "{{steps.puppeteer_screenshot.PathFL}}",
    },
    embed: {
      type: "string",
      label: "Embed message",
      default: "{{steps.generate_embed_discord.$return_value.embed}}",
    }   
  },
  async run({ steps, $ }) {
    
    const formData = new FormData();
    formData.append("file", fs.createReadStream(this.filePath));

    const response = await axios($, {
      method: "POST",
      url: `https://discord.com/api/channels/${this.id_channel}/messages`,
      headers: {
        Authorization: `Bot ${this.discord_bot.$auth.bot_token}`,
        ...formData.getHeaders(),
      },
      data: {
        embeds: [ this.embed ],
      }
    });

    console.log("Message sent successfully:", response);
  },
});

I’ve combined the two pieces of code you provided into a single component that sends an embed message along with a file attachment to the specified Discord channel: import { axios } from "@pipedream/platform"; import fs from "fs"; import FormData from "form-data"; export default defineComponent({ name: "Send Embed Message with File", description: "Send embed message with file attachment to Discord", key: "discord_embed_with_file", version: "0.1.0", type: "action", props: { discord_bot: { type: "app", app: "discord_bot", }, id_channel: { type: "string", label: "Channel ID", default: "{{steps.data_processing_discord.ChannelID}}", }, embed: { type: "string", label: "Embed message", default: "{{steps.generate_embed_discord.$return_value.embed}}", }, filePath: { type: "string", label: "File Path", default: "{{steps.puppeteer_screenshot.PathFL}}", }, }, async run({ steps, $ }) { const formData = new FormData(); formData.append("file", fs.createReadStream(this.filePath)); formData.append("payload_json", JSON.stringify({ embeds: [this.embed] })); const response = await axios($, { method: "POST", url: `https://discord.com/api/channels/${this.id_channel}/messages`, headers: { Authorization: `Bot ${this.discord_bot.$auth.bot_token}`, ...formData.getHeaders(), }, data: formData, }); console.log("Message sent successfully:", response); }, }); This component sends an embed message along with a file attachment to the specified Discord channel. Make sure to update the default values for id_channel, embed, and filePath as needed.

How to import AttachmentBuilder and EmbedBuilder from discord.js?

It looks like you’re trying to use the AttachmentBuilder and EmbedBuilder from the discord.js library. However, in Pipedream, you can use the pre-built Discord actions to send messages and embeds without writing code. To send an embed message or a message with a file attachment, follow these steps: 1. Search for the Discord app from the step menu 2. Select the “Send Message With File” action or the “Send Message (Advanced)” action for embeds 3. Connect your Discord account 4. Configure the action according to your needs 5. At the bottom of the step, click “Test” to run the action and test the configuration. For more information on using Discord actions in Pipedream, visit the Discord app page.

Yes, I’m trying to use the AttachmentBuilder and EmbedBuilder from the discord.js library. I want to write pure Node.js code so that I can create custom conditions.

I understand that you want to use AttachmentBuilder and EmbedBuilder from the discord.js library in a Node.js environment. However, these classes are not available in the discord.js library. Instead, you can use the MessageAttachment and MessageEmbed classes. Here’s an example of how to create an embed and attach a file using discord.js: const Discord = require("discord.js"); const client = new Discord.Client(); client.on("ready", () => { console.log(`Logged in as ${client.user.tag}!`); }); client.on("message", async (message) => { if (message.content === "!send") { // Create a MessageEmbed const embed = new Discord.MessageEmbed() .setTitle("Example Embed") .setDescription("This is an example embed with a file attachment.") .setColor("#0099ff"); // Create a MessageAttachment const file = new Discord.MessageAttachment("path/to/your/file.png", "file.png"); // Send the embed and file attachment message.channel.send({ embeds: [embed], files: [file] }); } }); client.login("your-bot-token"); Replace "path/to/your/file.png" with the actual path to the file you want to attach, and "your-bot-token" with your Discord bot token. Please note that this code is for running in a standalone Node.js environment and not within a Pipedream component. If you want to use this code in Pipedream, you’ll need to adapt it to a Pipedream component and use the Discord Bot API to send the message.

I’m trying the following code to send a message on Discord with an embedded image. However, I’m receiving the following error:"=

Error:

I apologize for the inconvenience, but it seems you didn’t provide the code you’re using and the error message you’re encountering. To help you resolve the issue, please provide the code snippet you’re using to send a message with an embedded image on Discord, as well as the error message you’re receiving. This will help me understand the problem and provide a solution.

I’m trying the following code to send a message on Discord with an embedded image. However, I’m receiving the following error:"=

Code:

import { axios } from "@pipedream/platform";
import fs from "fs";
import FormData from "form-data";

export default defineComponent({
  props: {
    discord_bot: {
      type: "app",
      app: "discord_bot",
    },
    id_channel: {
      type: "string",
      label: "Channel ID",
      default: "{{steps.data_processing_discord.ChannelID}}",
    },    
    messageText: {
      type: "string",
      label: "Message Text",
      default: " ",
    },
    filePath: {
      type: "string",
      label: "File Path",
      default: "{{steps.puppeteer_screenshot.PathFL}}",
    },
    embed: {
      type: "string",
      label: "Embed message",
      default: "{{steps.generate_embed_discord.$return_value.embed}}",
    }   
  },
  async run({ steps, $ }) {
    
    const formData = new FormData();
    formData.append("file", fs.createReadStream(this.filePath));
    formData.append("embeds", [ this.embed ])


    const response = await axios($, {
      method: "POST",
      url: `https://discord.com/api/channels/${this.id_channel}/messages`,
      headers: {
        Authorization: `Bot ${this.discord_bot.$auth.bot_token}`,
        ...formData.getHeaders(),
      },
      data: formData,
    });

    console.log("Message sent successfully:", response);
  },
});

Error:


Error
Arrays are not supported.

DETAILS
    at FormData.FormData.append (/tmp/__pdg__/dist/code/3a53218d72ee74b70dc28cd886580b8c2f4d9397e5b47d9bffc20b903ee8e51b/node_modules/.pnpm/form-data@4.0.0/node_modules/form-data/lib/form_data.js:67:17)
    at Object.run (file:///tmp/__pdg__/dist/code/3a53218d72ee74b70dc28cd886580b8c2f4d9397e5b47d9bffc20b903ee8e51b/component.mjs:36:14)
    at null.executeComponent (/var/task/launch_worker.js:242:53)
    at MessagePort.messageHandler (/var/task/launch_worker.js:748:28)

I see the issue in your code. The formData.append("embeds", [ this.embed ]) line is causing the error because FormData does not support arrays directly. Instead, you should stringify the array before appending it. Here’s the updated code: ```
import { axios } from “@pipedream/platform”; import fs from “fs”; import FormData from “form-data”; export default defineComponent({ props: { discord_bot: { type: “app”, app: “discord_bot”, }, id_channel: { type: “string”, label: “Channel ID”, default: “{{steps.data_processing_discord.ChannelID}}”, }, messageText: { type: “string”, label: “Message Text”, default: " ", }, filePath: { type: “string”, label: “File Path”, default: “{{steps.puppeteer_screenshot.PathFL}}”, }, embed: { type: “string”, label: “Embed message”, default: “{{steps.generate_embed_discord.$return_value.embed}}”, }, }, async run({ steps, $ }) { const formData = new FormData(); formData.append(“file”, fs.createReadStream(this.filePath)); formData.append(“embeds”, JSON.stringify([this.embed])); const response = await axios($, { method: “POST”, url: https://discord.com/api/channels/${this.id_channel}/messages, headers: { Authorization: Bot ${this.discord_bot.$auth.bot_token}, …formData.getHeaders(), }, data: formData, }); console.log(“Message sent successfully:”, response); }, });

Resolved it with the following code:

  async run({ steps, $ }) {
    const { filePath, embed, idsymbol } = this;

    const formData = new FormData();
    formData.append("payload_json", JSON.stringify({ embeds: [embed], content: idsymbol }));
    formData.append("file", fs.createReadStream(filePath));

    const response = await axios($, {
      method: "POST",
      url: `https://discord.com/api/channels/${this.id_channel}/messages`,
      headers: {
        Authorization: `Bot ${this.discord_bot.$auth.bot_token}`,
        ...formData.getHeaders(),
      },
      data: formData,
    });

    console.log("Message sent successfully:", response);
    $.export("response", response)
  },

Great! I’m glad you were able to resolve the issue with your updated code. If you have any more questions or need further assistance, feel free to ask.

estou recebendo o seguinte erro

bad default value for prop timeOut: “0” (should be integer)