Jump to content

Grab latest movies added to the server using Discord bot API


Kyrunner
Go to solution Solved by Kyrunner,

Recommended Posts

Kyrunner

I created a discord bot that can connect to emby and grab the latest information like the latest moves added. 

 

the issue I'm running into is what is the URL to grab the data on the latest movies. here is the code. xxx is the real ip of my server

 

this is the command I run on the discord server @Emby   !recent_movies

require('dotenv').config();
const Discord = require('discord.js');
const axios = require('axios');
const { Client, Intents } = Discord;
const intents = new Intents([Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES]);
const client = new Client({ intents });
 
const EMBY_URL = process.env.EMBY_URL || 'http://xxx.xxx.x.xx:8096';
const EMBY_API_KEY = process.env.EMBY_API_KEY;
const DISCORD_BOT_TOKEN = process.env.DISCORD_BOT_TOKEN;
const CHANNEL_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';
 
client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);
});
 
client.on('messageCreate', async (msg) => {
  console.log(`Received message from channel ${msg.channel.id}: ${msg.content}`);
 
  if (msg.channel.id === CHANNEL_ID) {
    if (msg.content.includes('!recent_movies')) {
      const url = `${EMBY_URL}/movies/recent`;
      console.log(`Requesting URL: ${url}`);
      console.log(`Using X-Emby-Token: ${EMBY_API_KEY}`);
 
      try {
        const response = await axios.get(url, {
          headers: { 'X-Emby-Token': EMBY_API_KEY },
        });
        const movies = response.data;
        msg.reply(movies.map((movie) => movie.Name).join('\n'));
      } catch (error) {
        console.error(error);
        msg.reply('An error occurred while fetching the movies.');
      }
    } else if (msg.content.includes('!hello')) {
      msg.reply('Hello there!');
    }
  }
});
 
client.login(DISCORD_BOT_TOKEN);


 

here is the error message.

 

AxiosError: Request failed with status code 404
    at settle xxxxxxxxxxxxxx\Emby\node_modules\axios\dist\node\axios.cjs:1909:12)
    at IncomingMessage.handleStreamEnd xxxxxxxxxxx\Desktop\Emby\node_modules\axios\dist\node\axios.cjs:2989:11)
    at IncomingMessage.emit (node:events:525:35)
    at endReadableNT (node:internal/streams/readable:1359:12)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  code: 'ERR_BAD_REQUEST',
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [ 'xhr', 'http' ],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    env: { FormData: [Function], Blob: [class Blob] },
    validateStatus: [Function: validateStatus],
    headers: AxiosHeaders {
      Accept: 'application/json, text/plain, */*',
      'X-Emby-Token': 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
      'User-Agent': 'axios/1.4.0',
      'Accept-Encoding': 'gzip, compress, deflate, br'
    },
    method: 'get',
    url: 'http://xxx.xxx.x.xx:8096/movies/recent',
    data: undefined
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      finish: [Function: requestOnFinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: false,
    _last: true,
    chunkedEncoding: false,
    shouldKeepAlive: false,
    maxRequestsOnConnectionReached: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: false,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    strictContentLength: false,
    _contentLength: 0,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    _closed: false,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: null,
      _closeAfterHandlingError: false,
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: null,
      _server: null,
      parser: null,
      _httpMessage: [Circular *1],
      [Symbol(async_id_symbol)]: 90,
      [Symbol(kHandle)]: [TCP],
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kSetNoDelay)]: true,
      [Symbol(kSetKeepAlive)]: true,
      [Symbol(kSetKeepAliveInitialDelay)]: 60,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0
    },
    _header: 'GET /movies/recent HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'X-Emby-Token: xxxxxxxxxxxxxxxxxxxxxxxx\r\n' +
      'User-Agent: axios/1.4.0\r\n' +
      'Accept-Encoding: gzip, compress, deflate, br\r\n' +
      'Host: xxx.xxx.x.xx:8096\r\n' +
      'Connection: close\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: nop],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 80,
      protocol: 'http:',
      options: [Object: null prototype],
      requests: [Object: null prototype] {},
      sockets: [Object: null prototype],
      freeSockets: [Object: null prototype] {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 1,
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'GET',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    joinDuplicateHeaders: undefined,
    path: '/movies/recent',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 4,
      _maxListeners: undefined,
      socket: [Socket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      joinDuplicateHeaders: undefined,
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 404,
      statusMessage: 'Not Found',
      client: [Socket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      responseUrl: 'http://xxx.xxx.x.xx:8096/movies/recent',
      redirects: [],
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 22,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'xxx.xxx.x.xx',
    protocol: 'http:',
    _redirectable: Writable {
      _writableState: [WritableState],
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 0,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'http://xxx.xxx.x.xx:8096/movies/recent',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'x-emby-token': [Array],
      'user-agent': [Array],
      'accept-encoding': [Array],
      host: [Array]
    },
    [Symbol(errored)]: null,
    [Symbol(kUniqueHeaders)]: null
  },
  response: {
    status: 404,
    statusText: 'Not Found',
    headers: AxiosHeaders {
      'content-length': '34',
      connection: 'close',
      'content-type': 'text/html',
      date: 'Wed, 02 Aug 2023 19:52:27 GMT',
      server: 'Kestrel',
      'access-control-allow-headers': 'Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Token, X-Emby-Client, X-Emby-Client-Version, X-Emby-Device-Id, X-Emby-Device-Name, X-Emby-Authorization',
      'access-control-allow-methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
      'access-control-allow-origin': '*',
      'access-control-allow-private-network': 'true',
      'private-network-access-name': 'xxxxxxxxxxxx',
      'private-network-access-id': 'xxxxxxxxxxxxxxxxxxxxxxx'
    },
    config: {
      transitional: [Object],
      adapter: [Array],
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      maxBodyLength: -1,
      env: [Object],
      validateStatus: [Function: validateStatus],
      headers: [AxiosHeaders],
      method: 'get',
      url: 'http://xxx.xxx.x.xx:8096/movies/recent',
      data: undefined
    },
    request: <ref *1> ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      maxRequestsOnConnectionReached: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: false,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      strictContentLength: false,
      _contentLength: 0,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      _closed: false,
      socket: [Socket],
      _header: 'GET /movies/recent HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'X-Emby-Token: xxxxxxxxxxxxxxxxxxx\r\n' +
        'User-Agent: axios/1.4.0\r\n' +
        'Accept-Encoding: gzip, compress, deflate, br\r\n' +
        'Host: xxx.xxx.x.xx:8096\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _keepAliveTimeout: 0,
      _onPendingData: [Function: nop],
      agent: [Agent],
      socketPath: undefined,
      method: 'GET',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      joinDuplicateHeaders: undefined,
      path: '/movies/recent',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'xxx.xxx.x.xx',
      protocol: 'http:',
      _redirectable: [Writable],
      [Symbol(kCapture)]: false,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype],
      [Symbol(errored)]: null,
      [Symbol(kUniqueHeaders)]: null
    },
    data: 'Unable to find the specified file.'
  }
}

 

Link to comment
Share on other sites

  • Solution
Kyrunner
36 minutes ago, Kyrunner said:

Is there anyway to get this just for recent movie items 

 

Display all Movies

http://localhost:8096/emby/Users/e8837bc1ad67520e8cd2f629e3155721/Items?Recursive=true&IncludeItemTypes=Movie

I fixed it here is the code to create a discord bot that can be asked to check the last 10 movies added to the server 

require('dotenv').config();
const Discord = require('discord.js');
const axios = require('axios');
const { Client, Intents } = Discord;
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
 
const EMBY_URL = process.env.EMBY_URL || 'http://xxx.xxx.x.xx:8096/emby/Users/API Key would go here/Items?Recursive=true&IncludeItemTypes=Movie&SortBy=DateCreated&SortOrder=Descending&Limit=10';
const EMBY_API_KEY = process.env.EMBY_API_KEY;
const DISCORD_BOT_TOKEN = process.env.DISCORD_BOT_TOKEN;
const CHANNEL_ID = 'discord channle ID would go here';
 
client.on('ready', () => {
  console.log(`Logged in as ${client.user.tag}!`);
});
 
client.on('messageCreate', async (msg) => {
  console.log(`Received message from channel ${msg.channel.id}: ${msg.content}`);
 
  if (msg.channel.id === CHANNEL_ID) {
    if (msg.content.includes('!recent_movies')) {
      const url = EMBY_URL;
      console.log(`Requesting URL: ${url}`);
      console.log(`Using X-Emby-Token: ${EMBY_API_KEY}`);
 
      try {
        const response = await axios.get(url, {
          headers: { 'X-Emby-Token': EMBY_API_KEY },
        });
        console.log('Emby response:', response);
 
        const movies = response.data.Items;
 
        const movieNames = movies.map((movie) => movie.Name).join('\n');
        const chunkSize = 2000;
        for (let i = 0; i < movieNames.length; i += chunkSize) {
          const chunk = movieNames.substring(i, i + chunkSize);
          msg.reply(chunk);
        }
      } catch (error) {
        console.error(error);
        msg.reply('An error occurred while fetching the movies.');
      }
    } else if (msg.content.includes('!hello')) {
      msg.reply('Hello there!');
    }
  }
});
 
client.login(DISCORD_BOT_TOKEN);

 

  • Thanks 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...