{"id":29432654,"url":"https://github.com/bebancode/commandkit-plugin-riffy","last_synced_at":"2025-07-23T10:06:46.695Z","repository":{"id":305536086,"uuid":"1018847018","full_name":"BebanCode/commandkit-plugin-riffy","owner":"BebanCode","description":"A CommandKit Runtime Plugin for initializing Riffy Lavalink Client.","archived":false,"fork":false,"pushed_at":"2025-07-20T16:10:36.000Z","size":36,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-20T18:08:38.892Z","etag":null,"topics":["commandkit","commandkit-plugin","riffy"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BebanCode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-13T07:09:06.000Z","updated_at":"2025-07-20T16:09:51.000Z","dependencies_parsed_at":"2025-07-20T18:08:48.580Z","dependency_job_id":"cbb5e73a-da50-4b76-9f5e-ad9f60b92b0e","html_url":"https://github.com/BebanCode/commandkit-plugin-riffy","commit_stats":null,"previous_names":["bebancode/commandkit-plugin-riffy"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/BebanCode/commandkit-plugin-riffy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BebanCode%2Fcommandkit-plugin-riffy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BebanCode%2Fcommandkit-plugin-riffy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BebanCode%2Fcommandkit-plugin-riffy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BebanCode%2Fcommandkit-plugin-riffy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BebanCode","download_url":"https://codeload.github.com/BebanCode/commandkit-plugin-riffy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BebanCode%2Fcommandkit-plugin-riffy/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266658036,"owners_count":23963618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["commandkit","commandkit-plugin","riffy"],"created_at":"2025-07-12T23:06:58.802Z","updated_at":"2025-07-23T10:06:46.681Z","avatar_url":"https://github.com/BebanCode.png","language":"TypeScript","readme":"# CommandKit Plugin: Riffy\n\n[![npm version](https://img.shields.io/npm/v/commandkit-plugin-riffy.svg)](https://www.npmjs.com/package/commandkit-plugin-riffy)\n\nThis plugin for **CommandKit** seamlessly integrates the [Riffy](https://riffy.js.org) Lavalink client, enabling robust audio playback for your Discord bot using CommandKit's intuitive event system. It fully manages the Riffy client's lifecycle, from initialization to event handling.\n\n## Features\n\n*   **Seamless Integration**: Automatically initializes and manages the Riffy client.\n*   **Event-Driven**: Leverages CommandKit's event system to handle all Riffy events.\n*   **Easy Configuration**: Simple to set up within your `commandkit.config.ts`.\n*   **Extensible**: Provides direct access to the Riffy instance via `client.riffy`.\n\n## Installation\n\n```bash\nnpm install commandkit-plugin-riffy\n```\n\n## Usage\n\nTo get started, register the plugin in your `commandkit.config.ts` file.\n\n```ts\nimport { defineConfig } from 'commandkit';\nimport { riffyPlugin } from 'commandkit-plugin-riffy';\n\nexport default defineConfig({\n  plugins: [\n    riffyPlugin({\n      riffyNodes: [\n        {\n          host: 'localhost',\n          port: 2333,\n          password: 'your_lavalink_password',\n          secure: false,\n        },\n      ],\n    }),\n  ],\n});\n```\n\nThis setup initializes Riffy and makes it available throughout your CommandKit application.\n\n## Configuration Options\n\nThe plugin can be customized with the following options:\n\n| Option           | Type                                                              | Description                                                                                             | Required |\n| ---------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | :------: |\n| `riffyNodes`     | `LavalinkNode[]`                                                  | An array of Lavalink node objects for Riffy to connect to.                                              |   Yes    |\n| `riffyOptions`   | `Partial\u003cRiffyOptions\u003e`                                           | Optional settings to pass to the Riffy constructor, which will be merged with the plugin's defaults.    |    No    |\n| `eventNamespace` | `string`                                                          | The CommandKit event namespace for all Riffy events. Defaults to `'riffy'`.                               |    No    |\n\n## Handling Events\n\nThe plugin bridges Riffy events into CommandKit's event system under a specified namespace (defaulting to `riffy`).\n\nTo handle these events, create files inside the `events` directory, following the CommandKit event handling structure.\n\n\u003e **Note:** The folder for the event namespace must be enclosed in parentheses, for example: `(riffy)`.\n\n### Project Structure\n\nYour event handlers should be organized as follows:\n\n```\nsrc/\n└── events/\n    └── (riffy)/\n        ├── nodeConnect/\n        │   └── logger.js\n        └── trackStart/\n            └── now-playing.js\n```\n\n### Example: Handling Events\n\nHere are a few examples of how you can listen to Riffy events:\n\n#### Logging Node Connections\n\nThis handler will log a message whenever a Lavalink node connects.\n\n**File:** `/src/events/(riffy)/nodeConnect/logging.js`\n\n```javascript\nexport default function handleNodeConnect(node) {\n  console.log(`[Riffy] Node \"${node.name}\" has connected.`);\n}\n```\n\n#### Announcing Started Tracks\n\nThis handler sends a \"Now Playing\" message when a new track begins.\n\n**File:** `/src/events/(riffy)/trackStart/nowPlaying.js`\n\n```javascript\nimport { EmbedBuilder } from 'discord.js';\n\nexport default async function handleTrackStart(player, track) {\n  const channel = player.textChannel;\n  if (!channel) return;\n\n  const embed = new EmbedBuilder()\n    .setColor('#00FF00')\n    .setTitle('Now Playing')\n    .setDescription(`[${track.title}](${track.uri})`)\n    .setThumbnail(track.thumbnail)\n    .addFields({ name: 'Author', value: track.author, inline: true })\n    .setTimestamp();\n\n  await channel.send({ embeds: [embed] });\n}\n```\n\n### Available Events\n\nThe plugin emits the following events within the configured namespace:\n\n*   `nodeConnect`\n*   `nodeDisconnect`\n*   `nodeError`\n*   `nodeReconnect`\n*   `nodeCreate`\n*   `nodeDestroy`\n*   `playerCreate`\n*   `playerDisconnect`\n*   `playerMove` \n*   `playerUpdate`\n*   `trackStart`\n*   `trackEnd`\n*   `trackError`\n*   `trackStuck`\n*   `queueEnd`\n*   `debug`\n\n## Accessing the Riffy Client\n\nThe Riffy instance is attached to the Discord.js `Client` object and can be accessed anywhere via `client.riffy`.\n\n### Example: Play Command\n\nHere is a basic example of a `play` command that uses the `client.riffy` instance to search for and play a track.\n\n**File:** `/src/commands/play.js`\n```javascript\nimport { SlashCommandBuilder } from 'discord.js';\n\nexport const data = new SlashCommandBuilder()\n  .setName('play')\n  .setDescription('Plays a song in your voice channel.')\n  .addStringOption(option =\u003e\n    option.setName('query')\n      .setDescription('The name of the song or a URL.')\n      .setRequired(true)\n  );\n\nexport const chatInput = async (ctx) =\u003e {\n  const { guild, member, channel } = ctx.interaction;\n  const query = interaction.options.getString('query');\n\n  // Check if the user is in a voice channel\n  if (!member.voice.channel) {\n    return interaction.reply({\n      content: 'You must be in a voice channel to use this command.',\n      ephemeral: true,\n    });\n  }\n\n  let player = client.riffy.players.get(guild.id);\n\n  if (!player) {\n    player = client.riffy.createConnection({\n      guildId: guild.id,\n      voiceChannel: voiceChannel.id,\n      textChannel: channel.id,\n      deaf: true,\n      defaultVolume: client.config.riffyOptions.defaultVolume || 50,\n    });\n  }\n\n  await interaction.deferReply();\n\n  // Resolve the query to get track(s)\n  const resolve = await client.riffy.resolve({\n    query: query,\n    requester: interaction.user\n  });\n\n  const { loadType, tracks, playlistInfo } = resolve;\n\n  // Add track(s) to the queue based on the load type\n  if (loadType === 'PLAYLIST_LOADED') {\n    for (const track of tracks) {\n      player.queue.add(track);\n    }\n    await interaction.editReply(`Added **${tracks.length}** tracks from the playlist \"${playlistInfo.name}\" to the queue.`);\n  } else if (loadType === 'SEARCH_RESULT' || loadType === 'TRACK_LOADED') {\n    const track = tracks.shift();\n    player.queue.add(track);\n    await interaction.editReply(`Added **${track.info.title}** to the queue.`);\n  } else {\n    return interaction.editReply('I could not find any tracks for that query.');\n  }\n\n  // Start playing if the player is not already active\n  if (!player.playing \u0026\u0026 !player.paused) {\n    player.play();\n  }\n}\n```\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.\n\n## Contributing\n\nContributions are welcome! Please feel free to open an issue or submit a pull request for any improvements or bug fixes.\n\n## Acknowledgments\n\n*   **[Riffy](https://riffy.js.org/)**: For the powerful Lavalink client.\n*   **[CommandKit](https://commandkit.dev/)**: For the modern and feature-rich Discord.js framework.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbebancode%2Fcommandkit-plugin-riffy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbebancode%2Fcommandkit-plugin-riffy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbebancode%2Fcommandkit-plugin-riffy/lists"}