1

I was looking for a cool way I could automate some interesting news articles on my discord server. I wanted to use webhooks at first but then decided to go with APIs. I looked all around and saw that I should go with New York Times API but when I went to code it, it came up with a few errors.

const Discord = require("discord.js");
const client = new Discord.Client();
const token = require("./token.js");
const fetch = require('node-fetch');
const prefix = '!';

const trim = (str, max) => str.length > max ? `${str.slice(0, max - 3)}...` : str;

client.once('ready', () => {
    console.log('Ready!');

});

client.on('message', async message => {
    if (!message.content.startsWith(prefix) || message.author.bot) return;

    const args = message.content.slice(prefix.length).trim().split(/ +/);
    const command = args.shift().toLowerCase();

    if (command === 'news') {
        const { file } = await fetch('https://api.nytimes.com/svc/topstories/v2/technology.json?api-key=').then(response => response.json());

        message.channel.sendMessage(file);

    }
    }).then((state) => {
        assert(state.action === 'DONE', 'should change state');
    })
        .catch((error) => {
            assert.isNotOk(error, 'Promise error');
        });
throw
client.login(token);

This is my code, I know this is probably riddled with mistakes but I am just starting out with node.js I looked at the example from the discord.js website and took some stuff from there. I don't know what I should do and if you could explain it out a little to help me learn that would be great. I keep getting the Unhandled Rejection Promise Warning and the Cannot send an empty message errors. I am using Visual Studio Code.

Zsolt Meszaros
  • 21,961
  • 19
  • 54
  • 57
Crispy1836
  • 13
  • 1
  • 3

2 Answers2

0

The response from the Top Stories API does not have a file key and so is undefined. You want to destructure results to access the articles array.

The error message says that you cannot call sendMessage with an empty message (undefined in this case).

I'm not sure of the message you want to send but you can send the link to the first article with the following code, for example.

const res = await fetch(`https://api.nytimes.com/svc/topstories/v2/technology.json?api-key=${NYTIMES_API_KEY}`)
const { results } = await res.json()

if (results.length) {
  message.channel.sendMessage(results[0].url)
} else {
  message.channel.sendMessage('No articles found')
}
Arun Kumar Mohan
  • 11,517
  • 3
  • 23
  • 44
  • Ok so now it says this "Cannot read property 'length' of undefined" and still this "UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict`" – Crispy1836 Feb 25 '21 at 22:03
  • Interesting. Can you share the output of `console.log(await fetch('https://api.nytimes.com/svc/topstories/v2/technology.json?api-key=NYTIMES_API_KEY').then(response => response.json()))`? You have to replacee `NYTIMES_API_KEY` with your key, of course. – Arun Kumar Mohan Feb 25 '21 at 22:04
0

You can use the async/await to get the results array from the API response, then send the details in embeds. You can either send the first article, a random article or more than one articles.

The following should work, it sends the first three articles:

const { Client, MessageEmbed } = require('discord.js');
const fetch = require('node-fetch');

const token = require("./token.js");

const client = new Client();
const API_KEY = 'QerEdX953-NOT-REAL-hdvgx7UPs';
const prefix = '!';

client.on('message', async (message) => {
  if (!message.content.startsWith(prefix) || message.author.bot) return;

  const args = message.content.slice(prefix.length).split(/ +/);
  const command = args.shift().toLowerCase();

  if (command === 'news') {
    try {
      const response = await fetch(
        `https://api.nytimes.com/svc/topstories/v2/technology.json?api-key=${API_KEY}`,
      );
      const data = await response.json();

      if (data.results.length === 0) {
        return message.channel.send('There are no top stories for you today ');
      }

      const embed = new MessageEmbed();
      // you could also get the number of stories from args[0]
      const MAX_STORIES = 3;

      data.results.slice(0, MAX_STORIES).forEach((result) => {
        embed.setTitle(result.title);
        embed.setDescription(result.abstract);
        embed.setURL(result.url);
        embed.setTimestamp(result.published_date);

        if (result.multimedia.length && result.multimedia[2]) {
          embed.setThumbnail(result.multimedia[2].url);
        }

        message.channel.send(embed);
      });
    } catch (error) {
      message.channel.send('Oops, there was an error fetching the API');
      console.log(error);
    }
  }
});

enter image description here

Zsolt Meszaros
  • 21,961
  • 19
  • 54
  • 57
  • I keep getting this "SyntaxError: await is only valid in async function at wrapSafe (internal/modules/cjs/loader.js:979:16) at Module._compile (internal/modules/cjs/loader.js:1027:27) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10) at Module.load (internal/modules/cjs/loader.js:928:32) at Function.Module._load (internal/modules/cjs/loader.js:769:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) at internal/main/run_main_module.js:17:47" – Crispy1836 Feb 25 '21 at 22:15
  • You must have missed the `async` keyword. Have you copy-pasted my code? Because the message handler is an async function. – Zsolt Meszaros Feb 25 '21 at 22:17
  • now it says that client is not identified – Crispy1836 Feb 25 '21 at 22:19
  • Ah, yes, that was my fault, I missed that. I've just updated my answer. – Zsolt Meszaros Feb 25 '21 at 22:23
  • Thanks! That was it. – Crispy1836 Feb 25 '21 at 22:26
  • You're welcome. I've just made another update to include the timestamp and change the thumbnail used. – Zsolt Meszaros Feb 25 '21 at 22:27
  • Now as a extra little question. Do you know a better news api for tech news? – Crispy1836 Feb 25 '21 at 22:28