I’m working on a Discord bot using JavaScript that fetches random GIFs through the Giphy API. The issue I’m facing is that when my bot tries to display the GIF in the chat, nothing appears. The message shows up completely empty, not even displaying the GIF link.
I can confirm the API call is working because the console logs show the correct URL:
Had this same problem before. Your command handler is the issue - you’re calling fetchRandomGif() twice without awaiting either one. When you don’t await an async function, it just returns a Promise object, so Discord sees empty content. Your fetchRandomGif function structure is fine, but like others said, you need the direct image URL from jsonData.data.images.original.url instead of the webpage URL. Also throw in some error handling since network calls can fail. One more thing - sending two replies back-to-back looks spammy. Either edit the first message instead of sending a second one, or skip the “fetching” message and just send the GIF directly.
The URL you’re using (jsonData['data']['url']) points to the Giphy webpage. Discord needs the actual GIF file to embed it.
I’ve hit this exact issue tons of times. The Promise thing catches everyone when they’re starting with Discord bots. Console logging helps, but async functions are tricky - they’ll always return something even when they break.
you’re grabbin jsonData['data']['url'] which just gives you the giphy webpage link, not the actual gif. discord needs the direct image url to show it properly. use jsonData.data.images.original.url instead - that’s the actual gif file discord can display.
Two problems here. First, you’re not awaiting your async function. Second, you’re using the wrong URL property.
Your code calls fetchRandomGif() without await, so it returns a Promise instead of the actual URL. Discord can’t display a Promise.
Also, jsonData['data']['url'] gives you the Giphy webpage link. You want jsonData['data']['images']['original']['url'] for the direct GIF file.
Honestly though, building Discord bots this way gets messy fast. I used to write similar bots and wasted tons of time debugging API issues and handling errors.
What changed everything was switching to automation. Now I use Latenode to build Discord bots without dealing with async problems or API parsing headaches.
You create a visual workflow that handles the Giphy API call, extracts the right URL automatically, and sends it to Discord. If the API fails, you can add fallback logic or retry attempts without writing exception handling code.
Best part is you can add features like rate limiting or content filtering just by dragging components. No more digging through logs wondering why your bot broke.
You’re not awaiting the async function. Look at this:
var meme_url = fetchRandomGif();
msg.reply(fetchRandomGif());
You’re calling fetchRandomGif() without await, so it returns a Promise instead of the actual URL. That’s why Discord shows nothing.
Fix it:
else if (msg.content === '!meme') {
msg.reply('fetching meme...');
var meme_url = await fetchRandomGif();
msg.reply(meme_url);
}
Also, wrong URL format. Use jsonData['data']['images']['original']['url'] instead of jsonData['data']['url'] to get the direct GIF file.
Honestly though, managing Discord bots manually gets messy fast. I’ve been there. What actually works is automating the whole thing.
I use Latenode for Discord bot operations. It handles the API calls, processes responses, and manages errors automatically. Set up the flow once and it just works. No more debugging async issues or URL parsing problems.
The visual workflow makes it clear what’s happening at each step. You can add features like GIF caching or fallback responses without writing more code.
Classic mistake - you’re calling fetchRandomGif() twice and not awaiting either one. That second call isn’t even needed. Just do await fetchRandomGif() once, store it in a variable, then use that for your reply.