← Back to portfolio

Discord · Node.js · TMDB API

Movie
Bot

A Discord bot that brings the full TMDB movie catalogue into your server. Search for any film with a single slash command and get an interactive poster collage back in seconds.

discord.js TMDB API Node.js Open Source
View on GitHub How it works

// flow

How it works.

01
💬
User invokes /movie
A Discord server member types the slash command followed by a title. Discord routes the interaction to the bot via the Gateway API.
02
InteractionCreate fires
The event listener receives the interaction object, extracts the search query, and defers the reply so Discord doesn't time out while the API call is in flight.
03
🎬
TMDB API fetch
The bot sends an authenticated request to TMDB's search endpoint. Results are parsed for title, release year, overview, and poster image paths — with graceful handling for missing artwork.
04
🖼️
Embed + poster collage
Up to four poster images are assembled into a collage and sent back as a rich embed with interactive navigation buttons for browsing further results.

// capabilities

What it can do.

🔍

Slash Command Search

Native Discord slash command integration gives auto-complete in the command bar. No prefix to remember — just /movie and a title.

🖼️

Visual Poster Collages

Search results render as a grid of up to four poster thumbnails pulled directly from TMDB, giving users an immediate visual scan rather than a wall of text.

🔘

Interactive Buttons

Discord component buttons let users page through results, fetch more details, or dismiss the embed — all without leaving the chat window.

🌐

Live TMDB Data

Powered by The Movie Database API — the same data source behind major streaming apps. Includes release year, overview text, and high-resolution artwork.

🛡️

Graceful Error Handling

Missing posters, empty search results, and partial API responses are all handled cleanly so users always get a sensible reply rather than a broken embed.

🧩

Modular Architecture

Commands and events are loaded dynamically from separate module directories, making it straightforward to add new commands without touching core bot logic.

// under the hood

Code architecture.

The bot follows the discord.js modular convention: commands live in a commands/ directory and events in events/. On startup, the client loader walks both directories and registers each module dynamically — no manual imports needed when adding new commands.

The two core events are ClientReady (registers slash commands with Discord's API on login) and InteractionCreate (dispatches incoming interactions to the correct command handler).

TMDB authentication uses a bearer token stored in environment variables, keeping credentials out of source control. The fs and path modules are used to build dynamic file paths for the poster collage assembly step.

events/interactionCreate.js
// Dispatch incoming interaction to correct handler
export default {
  name: 'interactionCreate',
  async execute(interaction, client) {
    if (!interaction.isChatInputCommand()) return;

    const command = client.commands.get(interaction.commandName);
    if (!command) return;

    try {
      await command.execute(interaction);
    } catch (err) {
      console.error(err);
      await interaction.reply({
        content: 'Something went wrong!',
        ephemeral: true
      });
    }
  }
};
Project structure
📁 movie-bot/
📁 commands/
📄 movie.js ← main slash command
📁 events/
📄 ready.js ← ClientReady, registers cmds
📄 interactionCreate.js ← dispatcher
📄 index.js ← entry point, loads modules
📄 deploy-commands.js ← register with Discord
📄 .env ← BOT_TOKEN, TMDB_KEY
📄 package.json
📄 .eslintrc.json
commands/movie.js (excerpt)
// Fetch from TMDB and build embed
const query = interaction.options.getString('title');
await interaction.deferReply();

const res = await fetch(
  `https://api.themoviedb.org/3/search/movie?query=${query}`,
  { headers: { Authorization: `Bearer ${process.env.TMDB_TOKEN}` } }
);

const { results } = await res.json();
const top4 = results.slice(0, 4).filter(m => m.poster_path);

// stack

Built with.

Node.js
Runtime environment. Async I/O handles concurrent API calls efficiently without blocking the event loop.
discord.js v14
Full-featured Discord library. Handles the WebSocket gateway, REST API calls, and all interaction types.
TMDB API
Movie Database REST API. Provides search, metadata, and poster image URLs for hundreds of thousands of titles.
ESLint
Static analysis enforces consistent code style and catches common errors before runtime.

// roadmap

What's next.

// source

Open source.

The full source code is on GitHub — explore the codebase, open an issue, or fork it to build your own movie bot.