{"id":44713644,"url":"https://github.com/execaman/discolink","last_synced_at":"2026-04-16T09:05:41.726Z","repository":{"id":315704856,"uuid":"1060542032","full_name":"execaman/discolink","owner":"execaman","description":"A javascript library for discord bots to interact with Lavalink","archived":false,"fork":false,"pushed_at":"2026-02-13T11:16:58.000Z","size":655,"stargazers_count":4,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-13T20:20:27.948Z","etag":null,"topics":["api","client","discord","lavalink","library","music"],"latest_commit_sha":null,"homepage":"https://execaman.github.io/discolink/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/execaman.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-20T05:26:02.000Z","updated_at":"2026-02-13T11:16:41.000Z","dependencies_parsed_at":"2025-09-20T07:28:52.249Z","dependency_job_id":"a763d06b-a474-4492-ba0a-f7c64a55f16e","html_url":"https://github.com/execaman/discolink","commit_stats":null,"previous_names":["execaman/discolink"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/execaman/discolink","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/execaman%2Fdiscolink","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/execaman%2Fdiscolink/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/execaman%2Fdiscolink/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/execaman%2Fdiscolink/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/execaman","download_url":"https://codeload.github.com/execaman/discolink/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/execaman%2Fdiscolink/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29478954,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-15T11:35:25.641Z","status":"ssl_error","status_checked_at":"2026-02-15T11:34:57.128Z","response_time":118,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["api","client","discord","lavalink","library","music"],"created_at":"2026-02-15T13:04:19.787Z","updated_at":"2026-04-16T09:05:41.721Z","avatar_url":"https://github.com/execaman.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg alt=\"Discolink\" src=\"assets/music-album.png\" width=\"120\" /\u003e\n  \n  [Icon by juicy_fish](https://www.flaticon.com/authors/juicy-fish)\n  \u003cbr/\u003e\n  [API Reference](https://execaman.github.io/discolink) | [Coverage](http://app.codecov.io/gh/execaman/discolink)\n\n![NPM Version](https://img.shields.io/npm/v/discolink?style=flat\u0026logo=npm)\n![Codecov Coverage](https://img.shields.io/codecov/c/github/execaman/discolink?label=codecov\u0026logo=codecov)\n\n\u003c/div\u003e\n\n## 🎯 Purpose\n\nThe goal of this library is to abstract away obvious steps involved in the process of acting as an intermediary between [Lavalink](https://lavalink.dev/api) and [Discord](https://discord.com/developers/docs/events/gateway) to give developers a cleaner and intuitive interface to work with.\n\n## 🙌 Motivation\n\nIt's the JS ecosystem, how can we not have 30 libs for the same thing. My friends were monkey-patching, applying hotfixes, despite their clients being open-source; and I wanted to do a project professionally while exploring more of GitHub. **This project follows [SemVer](https://semver.org/) and an [Agile SDLC](https://www.geeksforgeeks.org/software-engineering/agile-sdlc-software-development-life-cycle/)**.\n\n## ⚙️ Requirements\n\n- **Runtime** - one of the following:\n  - [Node.js](https://nodejs.org) v22+\n  - [Bun](https://bun.com) v1+\n  - [Deno](https://deno.com) v2+\n- **Library** - any [gateway client](https://docs.discord.com/developers/events/gateway) that supports:\n  - sending raw payloads over the connection\n  - receiving raw payloads from the connection\n\n## 📝 Implementation\n\n### Examples\n\n\u003cdetails\u003e\n\u003csummary\u003eBasic Setup - JavaScript (ESM)\u003c/summary\u003e\n\n```js\nimport { Client } from \"main-lib\";\nimport { Player } from \"discolink\";\n\nconst client = new Client(...);\n\nconst player = new Player({\n  nodes: [ // add your nodes\n    {\n      name: \"local\",\n      origin: \"http://localhost:2333\",\n      password: \"youshallnotpass\"\n    }\n  ],\n  async forwardVoiceUpdate(guildId, payload) {\n    // send the given payload to your gateway connection\n    client.guilds.cache.get(guildId).shard.send(payload);\n  }\n});\n\nclient.on(\"raw\", (payload) =\u003e {\n  // call the handler on gateway dispatch\n  player.voices.handleDispatch(payload);\n});\n\nclient.login();\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eModule Augmentation - TypeScript\u003c/summary\u003e\n\n```ts\n/**\n * fields defined here appear wherever they're concerned\n */\ndeclare module \"discolink\" {\n  // appears on queue, related options, etc\n  interface QueueContext {\n    textId: string;\n  }\n\n  // appears on track, related options, etc\n  interface CommonUserData {\n    id: string;\n    username: string;\n    displayName: string;\n  }\n\n  // appears on track, playlist, etc\n  interface CommonPluginInfo {\n    save_uri?: string;\n  }\n\n  // appears throughout filter management\n  interface CommonPluginFilters {\n    custom: string;\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCustom Plugin (with events) - TypeScript\u003c/summary\u003e\n\n```ts\nimport { PlayerPlugin, type Player } from \"discolink\";\n\nexport class CustomPlugin extends PlayerPlugin\u003c{\n  // define events you want to emit on player\n  eventName: [s: number, d: object];\n}\u003e {\n  readonly name = \"custom\"; // 'readonly' is mandatory\n  #player!: Player; // optional, just for convenience\n\n  init(player: Player) {\n    this.#player = player;\n    player.on(\"nodeDispatch\", this.#onDispatch);\n  }\n\n  transform(...args: unknown[]): [s: number, d: object] {}\n\n  #onDispatch(this: Player, ...args: unknown[]) {\n    // work with data\n    // e.g. transform -\u003e rename event -\u003e dispatch\n    const transformed = this.transform(...args);\n    this.emit(\"eventName\", ...transformed);\n  }\n}\n```\n\n\u003c/details\u003e\n\n### Additional Notes\n\n- Destroy queues when necessary, e.g. events like guild/channel delete, etc.\n\n- Check voice states like [`reconnecting`](https://execaman.github.io/discolink/classes/Voice.VoiceState.html#reconnecting) and [`changingNode`](https://execaman.github.io/discolink/classes/Voice.VoiceState.html#changingnode) before taking action\n\n- Handle track end reasons other than [`cleanup`](https://execaman.github.io/discolink/enums/Typings.TrackEndReason.html#cleanup) and [`finished`](https://execaman.github.io/discolink/enums/Typings.TrackEndReason.html#finished) - especially [`replaced`](https://execaman.github.io/discolink/enums/Typings.TrackEndReason.html#replaced)\n\n\u003e [!NOTE]\n\u003e [`replaced`](https://execaman.github.io/discolink/enums/Typings.TrackEndReason.html#replaced) is an edge case where we cannot reliably determine the exact track object in queue that ended. The queue implements a workaround for this and provides a [`inQueue`](https://execaman.github.io/discolink/interfaces/Typings.PlayerEventMap.html#trackstart) (think cache hit/miss) boolean in track events\n\n### Session Resumption\n\nResuming a node's session after your bot restarts requires careful planning, depending on scale. As such, the lib has no plans to provide built-in support for it. Disable either or both of [`autoSync`](https://execaman.github.io/discolink/interfaces/Typings.PlayerOptions.html#autosync) and [`relocateQueues`](https://execaman.github.io/discolink/interfaces/Typings.PlayerOptions.html#relocatequeues) options for predictable behavior if you're implementing this feature.\n\n## 🤖 Bots in Production\n\n| Name                                                                          | Since         | Owner                                                            |\n| ----------------------------------------------------------------------------- | ------------- | ---------------------------------------------------------------- |\n| [`Mesuic`](https://discord.com/discovery/applications/1157589891287367730)    | 18th Feb 2026 | [`@knifecodez`](https://discord.com/users/1053918356375351386)   |\n| [`Fuego`](https://discord.com/discovery/applications/1050423676689985606)     | 19th Feb 2026 | [`@painfuego`](https://discord.com/users/692617937512562729)     |\n| [`Flame`](https://discord.com/discovery/applications/1476630661996613755)     | 28th Feb 2026 | [`@aiosqlite.db`](https://discord.com/users/1243212619825942568) |\n| [`Bumblebee`](https://discord.com/discovery/applications/1232384723188449283) | 2nd Apr 2026  | [`@freycikkk`](https://discord.com/users/1156173961034465333)    |\n\n## 🤝 Acknowledgements\n\nKey aspects of this lib were inspired from the following projects:\n\n- [`distube`](https://github.com/skick1234/DisTube) player-queue design\n- [`discord.js`](https://github.com/discordjs/discord.js) manager-cache concept\n- [`Hoshimi`](https://github.com/Ganyu-Studios/Hoshimi) module augmentation (typings)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexecaman%2Fdiscolink","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexecaman%2Fdiscolink","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexecaman%2Fdiscolink/lists"}