@erinjs/core 1.0.0 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{core/LICENSE → LICENSE} +203 -203
- package/README.md +46 -0
- package/dist/index.d.mts +2084 -0
- package/dist/index.d.ts +2084 -0
- package/dist/index.js +3867 -0
- package/dist/index.mjs +3809 -0
- package/package.json +50 -15
- package/core/.changeset/README.md +0 -8
- package/core/.changeset/community-bootstrap-release.md +0 -17
- package/core/.changeset/config.json +0 -11
- package/core/.changeset/no-changelog.js +0 -16
- package/core/.changeset/pre.json +0 -17
- package/core/.editorconfig +0 -13
- package/core/.gitattributes +0 -2
- package/core/.github/CODE_OF_CONDUCT.md +0 -23
- package/core/.github/FUNDING.yml +0 -7
- package/core/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
- package/core/.github/ISSUE_TEMPLATE/feature_request.md +0 -23
- package/core/.github/PULL_REQUEST_TEMPLATE.md +0 -16
- package/core/.github/dependabot.yml +0 -16
- package/core/.github/workflows/autoapp.yml +0 -16
- package/core/.github/workflows/ci.yml +0 -187
- package/core/.github/workflows/codeql.yml +0 -30
- package/core/.github/workflows/deploy-docs.yml +0 -54
- package/core/.github/workflows/publish.yml +0 -43
- package/core/.lintstagedrc.json +0 -4
- package/core/.nvmrc +0 -1
- package/core/.prettierignore +0 -8
- package/core/.prettierrc +0 -11
- package/core/CONTRIBUTING.md +0 -70
- package/core/README.md +0 -61
- package/core/SECURITY.md +0 -21
- package/core/apps/docs/index.html +0 -28
- package/core/apps/docs/middleware.ts +0 -21
- package/core/apps/docs/package.json +0 -33
- package/core/apps/docs/public/@flux.png +0 -0
- package/core/apps/docs/public/docs/latest/guides.json +0 -1420
- package/core/apps/docs/public/docs/latest/main.json +0 -14981
- package/core/apps/docs/public/docs/latest/rag-index.json +0 -1
- package/core/apps/docs/public/docs/v1.0.5/guides.json +0 -226
- package/core/apps/docs/public/docs/v1.0.5/main.json +0 -7920
- package/core/apps/docs/public/docs/v1.0.6/guides.json +0 -226
- package/core/apps/docs/public/docs/v1.0.6/main.json +0 -7920
- package/core/apps/docs/public/docs/v1.0.7/guides.json +0 -259
- package/core/apps/docs/public/docs/v1.0.7/main.json +0 -8652
- package/core/apps/docs/public/docs/v1.0.8/guides.json +0 -313
- package/core/apps/docs/public/docs/v1.0.8/main.json +0 -9618
- package/core/apps/docs/public/docs/v1.0.9/guides.json +0 -319
- package/core/apps/docs/public/docs/v1.0.9/main.json +0 -10694
- package/core/apps/docs/public/docs/v1.1.0/guides.json +0 -589
- package/core/apps/docs/public/docs/v1.1.0/main.json +0 -12576
- package/core/apps/docs/public/docs/v1.1.2/guides.json +0 -650
- package/core/apps/docs/public/docs/v1.1.2/main.json +0 -13239
- package/core/apps/docs/public/docs/v1.1.3/guides.json +0 -650
- package/core/apps/docs/public/docs/v1.1.3/main.json +0 -13239
- package/core/apps/docs/public/docs/v1.1.4/guides.json +0 -708
- package/core/apps/docs/public/docs/v1.1.4/main.json +0 -13231
- package/core/apps/docs/public/docs/v1.1.5/guides.json +0 -1035
- package/core/apps/docs/public/docs/v1.1.5/main.json +0 -13838
- package/core/apps/docs/public/docs/v1.1.6/guides.json +0 -1041
- package/core/apps/docs/public/docs/v1.1.6/main.json +0 -14313
- package/core/apps/docs/public/docs/v1.1.8/guides.json +0 -1047
- package/core/apps/docs/public/docs/v1.1.8/main.json +0 -14421
- package/core/apps/docs/public/docs/v1.1.9/guides.json +0 -1047
- package/core/apps/docs/public/docs/v1.1.9/main.json +0 -14421
- package/core/apps/docs/public/docs/v1.2.0/guides.json +0 -1212
- package/core/apps/docs/public/docs/v1.2.0/main.json +0 -14663
- package/core/apps/docs/public/docs/v1.2.1/guides.json +0 -1293
- package/core/apps/docs/public/docs/v1.2.1/main.json +0 -14828
- package/core/apps/docs/public/docs/v1.2.2/guides.json +0 -1293
- package/core/apps/docs/public/docs/v1.2.2/main.json +0 -15025
- package/core/apps/docs/public/docs/v1.2.3/guides.json +0 -1420
- package/core/apps/docs/public/docs/v1.2.3/main.json +0 -14954
- package/core/apps/docs/public/docs/v1.2.4/guides.json +0 -1420
- package/core/apps/docs/public/docs/v1.2.4/main.json +0 -14981
- package/core/apps/docs/public/docs/versions.json +0 -24
- package/core/apps/docs/public/flux.png +0 -0
- package/core/apps/docs/public/locales/en.json +0 -50
- package/core/apps/docs/public/locales/guides-en.json +0 -512
- package/core/apps/docs/public/robots.txt +0 -4
- package/core/apps/docs/public/sitemap.xml +0 -33
- package/core/apps/docs/src/App.vue +0 -538
- package/core/apps/docs/src/components/ApiCategorySection.vue +0 -42
- package/core/apps/docs/src/components/ApiDiscordCompat.vue +0 -65
- package/core/apps/docs/src/components/ApiEndpointCard.vue +0 -313
- package/core/apps/docs/src/components/ApiSchemaBlock.vue +0 -131
- package/core/apps/docs/src/components/CodeBlock.vue +0 -177
- package/core/apps/docs/src/components/CommunityCallout.vue +0 -90
- package/core/apps/docs/src/components/ConstructorSection.vue +0 -82
- package/core/apps/docs/src/components/DocDescription.vue +0 -40
- package/core/apps/docs/src/components/FluxerLogo.vue +0 -3
- package/core/apps/docs/src/components/Footer.vue +0 -106
- package/core/apps/docs/src/components/GuideCodeBlock.vue +0 -102
- package/core/apps/docs/src/components/GuideDiscordCompat.vue +0 -77
- package/core/apps/docs/src/components/GuideDiscordCompatCallout.vue +0 -83
- package/core/apps/docs/src/components/GuideTable.vue +0 -77
- package/core/apps/docs/src/components/GuideTip.vue +0 -38
- package/core/apps/docs/src/components/MethodsSection.vue +0 -195
- package/core/apps/docs/src/components/ParamsTable.vue +0 -70
- package/core/apps/docs/src/components/PropertiesSection.vue +0 -143
- package/core/apps/docs/src/components/SearchBar.vue +0 -76
- package/core/apps/docs/src/components/SearchModal.vue +0 -361
- package/core/apps/docs/src/components/SidebarNav.vue +0 -225
- package/core/apps/docs/src/components/SponsorBanner.vue +0 -153
- package/core/apps/docs/src/components/TypeSignature.vue +0 -187
- package/core/apps/docs/src/components/VersionPicker.vue +0 -191
- package/core/apps/docs/src/composables/useSearchIndex.ts +0 -144
- package/core/apps/docs/src/composables/useVersionedPath.ts +0 -20
- package/core/apps/docs/src/data/apiEndpoints.ts +0 -1073
- package/core/apps/docs/src/data/changelog.ts +0 -717
- package/core/apps/docs/src/data/guides.ts +0 -2362
- package/core/apps/docs/src/env.d.ts +0 -7
- package/core/apps/docs/src/locales/guides-en.json +0 -512
- package/core/apps/docs/src/main.ts +0 -27
- package/core/apps/docs/src/pages/ApiReferenceLayout.vue +0 -175
- package/core/apps/docs/src/pages/ApiReferencePage.vue +0 -128
- package/core/apps/docs/src/pages/Changelog.vue +0 -288
- package/core/apps/docs/src/pages/ClassPage.vue +0 -319
- package/core/apps/docs/src/pages/ClassesList.vue +0 -100
- package/core/apps/docs/src/pages/DocsLayout.vue +0 -127
- package/core/apps/docs/src/pages/GuidePage.vue +0 -279
- package/core/apps/docs/src/pages/GuidesIndex.vue +0 -166
- package/core/apps/docs/src/pages/GuidesLayout.vue +0 -245
- package/core/apps/docs/src/pages/Home.vue +0 -125
- package/core/apps/docs/src/pages/NotFound.vue +0 -57
- package/core/apps/docs/src/pages/TypedefPage.vue +0 -230
- package/core/apps/docs/src/pages/TypedefsList.vue +0 -168
- package/core/apps/docs/src/pages/VersionLayout.vue +0 -15
- package/core/apps/docs/src/router.ts +0 -73
- package/core/apps/docs/src/stores/docs.ts +0 -54
- package/core/apps/docs/src/stores/guides.ts +0 -53
- package/core/apps/docs/src/stores/version.ts +0 -67
- package/core/apps/docs/src/styles/main.css +0 -278
- package/core/apps/docs/src/styles/prism.css +0 -95
- package/core/apps/docs/src/types/doc-schema.ts +0 -112
- package/core/apps/docs/tsconfig.json +0 -17
- package/core/apps/docs/tsconfig.node.json +0 -10
- package/core/apps/docs/vite.config.d.ts +0 -2
- package/core/apps/docs/vite.config.js +0 -26
- package/core/apps/docs/vite.config.ts +0 -28
- package/core/apps/docs-vitepress/.vitepress/config.ts +0 -141
- package/core/apps/docs-vitepress/api-data/latest/main.json +0 -15035
- package/core/apps/docs-vitepress/api-data/v1.2.4/main.json +0 -15035
- package/core/apps/docs-vitepress/api-data/versions.json +0 -6
- package/core/apps/docs-vitepress/index.md +0 -15
- package/core/apps/docs-vitepress/package-lock.json +0 -2924
- package/core/apps/docs-vitepress/package.json +0 -20
- package/core/apps/docs-vitepress/public/CNAME +0 -1
- package/core/apps/docs-vitepress/scripts/generate-api.ts +0 -243
- package/core/apps/docs-vitepress/scripts/migrate-guides.ts +0 -129
- package/core/apps/docs-vitepress/tsconfig.json +0 -11
- package/core/apps/docs-vitepress/v/latest/guides/attachments-by-url.md +0 -57
- package/core/apps/docs-vitepress/v/latest/guides/attachments.md +0 -62
- package/core/apps/docs-vitepress/v/latest/guides/basic-bot.md +0 -49
- package/core/apps/docs-vitepress/v/latest/guides/channels.md +0 -180
- package/core/apps/docs-vitepress/v/latest/guides/deprecated-apis.md +0 -58
- package/core/apps/docs-vitepress/v/latest/guides/discord-js-compatibility.md +0 -42
- package/core/apps/docs-vitepress/v/latest/guides/editing-embeds.md +0 -65
- package/core/apps/docs-vitepress/v/latest/guides/embed-media.md +0 -87
- package/core/apps/docs-vitepress/v/latest/guides/embeds.md +0 -166
- package/core/apps/docs-vitepress/v/latest/guides/emojis.md +0 -77
- package/core/apps/docs-vitepress/v/latest/guides/events.md +0 -202
- package/core/apps/docs-vitepress/v/latest/guides/gifs.md +0 -47
- package/core/apps/docs-vitepress/v/latest/guides/installation.md +0 -10
- package/core/apps/docs-vitepress/v/latest/guides/moderation.md +0 -89
- package/core/apps/docs-vitepress/v/latest/guides/permissions.md +0 -130
- package/core/apps/docs-vitepress/v/latest/guides/prefix-commands.md +0 -41
- package/core/apps/docs-vitepress/v/latest/guides/profile-urls.md +0 -58
- package/core/apps/docs-vitepress/v/latest/guides/reactions.md +0 -69
- package/core/apps/docs-vitepress/v/latest/guides/roles.md +0 -130
- package/core/apps/docs-vitepress/v/latest/guides/sending-without-reply.md +0 -172
- package/core/apps/docs-vitepress/v/latest/guides/voice.md +0 -109
- package/core/apps/docs-vitepress/v/latest/guides/wait-for-guilds.md +0 -37
- package/core/apps/docs-vitepress/v/latest/guides/webhook-attachments-embeds.md +0 -73
- package/core/apps/docs-vitepress/v/latest/guides/webhooks.md +0 -131
- package/core/eslint.config.js +0 -80
- package/core/examples/.env.example +0 -22
- package/core/examples/README.md +0 -68
- package/core/examples/first-steps-bot.js +0 -118
- package/core/examples/minimal-bot.js +0 -17
- package/core/examples/moderation-bot.js +0 -209
- package/core/examples/package.json +0 -14
- package/core/examples/ping-bot.js +0 -1146
- package/core/examples/reaction-bot.js +0 -70
- package/core/examples/reaction-roles-bot.js +0 -140
- package/core/examples/webhook-bot.js +0 -239
- package/core/flux.png +0 -0
- package/core/package.json +0 -78
- package/core/packages/builders/package.json +0 -51
- package/core/packages/builders/src/index.ts +0 -13
- package/core/packages/builders/src/messages/AttachmentBuilder.test.ts +0 -79
- package/core/packages/builders/src/messages/AttachmentBuilder.ts +0 -69
- package/core/packages/builders/src/messages/EmbedBuilder.test.ts +0 -266
- package/core/packages/builders/src/messages/EmbedBuilder.ts +0 -239
- package/core/packages/builders/src/messages/MessagePayload.test.ts +0 -118
- package/core/packages/builders/src/messages/MessagePayload.ts +0 -122
- package/core/packages/builders/tsconfig.json +0 -9
- package/core/packages/builders/tsup.config.ts +0 -9
- package/core/packages/builders/vitest.config.ts +0 -9
- package/core/packages/collection/package.json +0 -47
- package/core/packages/collection/src/Collection.test.ts +0 -232
- package/core/packages/collection/src/Collection.ts +0 -196
- package/core/packages/collection/src/index.ts +0 -1
- package/core/packages/collection/tsconfig.json +0 -9
- package/core/packages/collection/tsup.config.ts +0 -9
- package/core/packages/collection/vitest.config.ts +0 -9
- package/core/packages/docgen/package.json +0 -26
- package/core/packages/docgen/src/extract.ts +0 -262
- package/core/packages/docgen/src/formatType.ts +0 -24
- package/core/packages/docgen/src/index.ts +0 -103
- package/core/packages/docgen/src/schema.ts +0 -100
- package/core/packages/docgen/src/visitor.ts +0 -147
- package/core/packages/docgen/tsconfig.json +0 -9
- package/core/packages/docgen/tsup.config.ts +0 -9
- package/core/packages/fluxer-core/README.md +0 -26
- package/core/packages/fluxer-core/package.json +0 -60
- package/core/packages/fluxer-core/src/client/ChannelManager.ts +0 -143
- package/core/packages/fluxer-core/src/client/Client.gateway.test.ts +0 -84
- package/core/packages/fluxer-core/src/client/Client.resolveEmoji.test.ts +0 -45
- package/core/packages/fluxer-core/src/client/Client.ts +0 -558
- package/core/packages/fluxer-core/src/client/ClientUser.ts +0 -40
- package/core/packages/fluxer-core/src/client/EventHandlerRegistry.ts +0 -469
- package/core/packages/fluxer-core/src/client/GuildManager.ts +0 -79
- package/core/packages/fluxer-core/src/client/GuildMemberManager.ts +0 -91
- package/core/packages/fluxer-core/src/client/MessageManager.ts +0 -58
- package/core/packages/fluxer-core/src/client/UsersManager.ts +0 -122
- package/core/packages/fluxer-core/src/errors/ErrorCodes.test.ts +0 -19
- package/core/packages/fluxer-core/src/errors/ErrorCodes.ts +0 -12
- package/core/packages/fluxer-core/src/errors/FluxerError.test.ts +0 -32
- package/core/packages/fluxer-core/src/errors/FluxerError.ts +0 -15
- package/core/packages/fluxer-core/src/index.ts +0 -85
- package/core/packages/fluxer-core/src/structures/Base.ts +0 -7
- package/core/packages/fluxer-core/src/structures/Channel.ts +0 -508
- package/core/packages/fluxer-core/src/structures/Guild.test.ts +0 -189
- package/core/packages/fluxer-core/src/structures/Guild.ts +0 -734
- package/core/packages/fluxer-core/src/structures/GuildBan.ts +0 -35
- package/core/packages/fluxer-core/src/structures/GuildEmoji.ts +0 -57
- package/core/packages/fluxer-core/src/structures/GuildMember.test.ts +0 -203
- package/core/packages/fluxer-core/src/structures/GuildMember.ts +0 -213
- package/core/packages/fluxer-core/src/structures/GuildMemberRoleManager.ts +0 -121
- package/core/packages/fluxer-core/src/structures/GuildSticker.ts +0 -56
- package/core/packages/fluxer-core/src/structures/Invite.test.ts +0 -103
- package/core/packages/fluxer-core/src/structures/Invite.ts +0 -121
- package/core/packages/fluxer-core/src/structures/Message.test.ts +0 -109
- package/core/packages/fluxer-core/src/structures/Message.ts +0 -397
- package/core/packages/fluxer-core/src/structures/MessageReaction.ts +0 -72
- package/core/packages/fluxer-core/src/structures/PartialMessage.ts +0 -12
- package/core/packages/fluxer-core/src/structures/Role.test.ts +0 -77
- package/core/packages/fluxer-core/src/structures/Role.ts +0 -112
- package/core/packages/fluxer-core/src/structures/User.test.ts +0 -110
- package/core/packages/fluxer-core/src/structures/User.ts +0 -109
- package/core/packages/fluxer-core/src/structures/Webhook.test.ts +0 -109
- package/core/packages/fluxer-core/src/structures/Webhook.ts +0 -258
- package/core/packages/fluxer-core/src/util/Constants.test.ts +0 -16
- package/core/packages/fluxer-core/src/util/Constants.ts +0 -7
- package/core/packages/fluxer-core/src/util/Events.ts +0 -46
- package/core/packages/fluxer-core/src/util/MessageCollector.ts +0 -87
- package/core/packages/fluxer-core/src/util/Options.ts +0 -33
- package/core/packages/fluxer-core/src/util/ReactionCollector.ts +0 -116
- package/core/packages/fluxer-core/src/util/cdn.test.ts +0 -108
- package/core/packages/fluxer-core/src/util/cdn.ts +0 -130
- package/core/packages/fluxer-core/src/util/guildUtils.ts +0 -33
- package/core/packages/fluxer-core/src/util/messageUtils.test.ts +0 -74
- package/core/packages/fluxer-core/src/util/messageUtils.ts +0 -119
- package/core/packages/fluxer-core/src/util/permissions.test.ts +0 -95
- package/core/packages/fluxer-core/src/util/permissions.ts +0 -43
- package/core/packages/fluxer-core/tsconfig.json +0 -9
- package/core/packages/fluxer-core/tsup.config.ts +0 -9
- package/core/packages/fluxer-core/vitest.config.ts +0 -9
- package/core/packages/rest/package.json +0 -52
- package/core/packages/rest/src/REST.test.ts +0 -64
- package/core/packages/rest/src/REST.ts +0 -90
- package/core/packages/rest/src/RateLimitManager.test.ts +0 -71
- package/core/packages/rest/src/RateLimitManager.ts +0 -60
- package/core/packages/rest/src/RequestManager.test.ts +0 -87
- package/core/packages/rest/src/RequestManager.ts +0 -172
- package/core/packages/rest/src/errors/FluxerAPIError.test.ts +0 -57
- package/core/packages/rest/src/errors/FluxerAPIError.ts +0 -21
- package/core/packages/rest/src/errors/HTTPError.test.ts +0 -55
- package/core/packages/rest/src/errors/HTTPError.ts +0 -25
- package/core/packages/rest/src/errors/RateLimitError.test.ts +0 -41
- package/core/packages/rest/src/errors/RateLimitError.ts +0 -15
- package/core/packages/rest/src/errors/index.ts +0 -3
- package/core/packages/rest/src/index.ts +0 -6
- package/core/packages/rest/src/utils/constants.test.ts +0 -31
- package/core/packages/rest/src/utils/constants.ts +0 -5
- package/core/packages/rest/src/utils/files.test.ts +0 -37
- package/core/packages/rest/src/utils/files.ts +0 -75
- package/core/packages/rest/tsconfig.json +0 -9
- package/core/packages/rest/tsup.config.ts +0 -9
- package/core/packages/rest/vitest.config.ts +0 -9
- package/core/packages/types/package.json +0 -46
- package/core/packages/types/src/api/ban.ts +0 -8
- package/core/packages/types/src/api/channel.ts +0 -65
- package/core/packages/types/src/api/embed.ts +0 -82
- package/core/packages/types/src/api/emoji.ts +0 -12
- package/core/packages/types/src/api/errors.ts +0 -68
- package/core/packages/types/src/api/gateway.ts +0 -14
- package/core/packages/types/src/api/guild.ts +0 -123
- package/core/packages/types/src/api/index.ts +0 -15
- package/core/packages/types/src/api/instance.ts +0 -32
- package/core/packages/types/src/api/interaction.ts +0 -26
- package/core/packages/types/src/api/invite.ts +0 -28
- package/core/packages/types/src/api/message.ts +0 -140
- package/core/packages/types/src/api/role.ts +0 -41
- package/core/packages/types/src/api/sticker.ts +0 -14
- package/core/packages/types/src/api/user.ts +0 -79
- package/core/packages/types/src/api/webhook.ts +0 -41
- package/core/packages/types/src/common/index.ts +0 -1
- package/core/packages/types/src/common/snowflake.test.ts +0 -9
- package/core/packages/types/src/common/snowflake.ts +0 -8
- package/core/packages/types/src/gateway/events.ts +0 -189
- package/core/packages/types/src/gateway/index.ts +0 -3
- package/core/packages/types/src/gateway/opcodes.ts +0 -17
- package/core/packages/types/src/gateway/payloads.ts +0 -481
- package/core/packages/types/src/index.ts +0 -4
- package/core/packages/types/src/rest/index.ts +0 -1
- package/core/packages/types/src/rest/routes.test.ts +0 -169
- package/core/packages/types/src/rest/routes.ts +0 -109
- package/core/packages/types/tsconfig.json +0 -9
- package/core/packages/types/tsup.config.ts +0 -9
- package/core/packages/types/vitest.config.ts +0 -9
- package/core/packages/util/package.json +0 -51
- package/core/packages/util/src/BitField.test.ts +0 -96
- package/core/packages/util/src/BitField.ts +0 -105
- package/core/packages/util/src/MessageFlagsBitField.test.ts +0 -42
- package/core/packages/util/src/MessageFlagsBitField.ts +0 -20
- package/core/packages/util/src/PermissionsBitField.test.ts +0 -79
- package/core/packages/util/src/PermissionsBitField.ts +0 -97
- package/core/packages/util/src/SnowflakeUtil.test.ts +0 -69
- package/core/packages/util/src/SnowflakeUtil.ts +0 -65
- package/core/packages/util/src/UserFlagsBitField.test.ts +0 -39
- package/core/packages/util/src/UserFlagsBitField.ts +0 -48
- package/core/packages/util/src/deprecation.test.ts +0 -44
- package/core/packages/util/src/deprecation.ts +0 -28
- package/core/packages/util/src/emojiShortcodes.generated.ts +0 -5
- package/core/packages/util/src/emojiShortcodes.test.ts +0 -41
- package/core/packages/util/src/emojiShortcodes.ts +0 -22
- package/core/packages/util/src/formatters.test.ts +0 -65
- package/core/packages/util/src/formatters.ts +0 -35
- package/core/packages/util/src/index.ts +0 -34
- package/core/packages/util/src/resolvers.test.ts +0 -198
- package/core/packages/util/src/resolvers.ts +0 -127
- package/core/packages/util/src/tenorUtils.test.ts +0 -75
- package/core/packages/util/src/tenorUtils.ts +0 -86
- package/core/packages/util/tsconfig.json +0 -9
- package/core/packages/util/tsup.config.ts +0 -9
- package/core/packages/util/vitest.config.ts +0 -9
- package/core/packages/voice/README.md +0 -42
- package/core/packages/voice/package.json +0 -67
- package/core/packages/voice/src/LiveKitRtcConnection.receive.test.ts +0 -24
- package/core/packages/voice/src/LiveKitRtcConnection.ts +0 -1767
- package/core/packages/voice/src/VoiceConnection.ts +0 -413
- package/core/packages/voice/src/VoiceManager.receive.test.ts +0 -61
- package/core/packages/voice/src/VoiceManager.test.ts +0 -44
- package/core/packages/voice/src/VoiceManager.ts +0 -503
- package/core/packages/voice/src/exports.test.ts +0 -38
- package/core/packages/voice/src/index.ts +0 -51
- package/core/packages/voice/src/livekit.test.ts +0 -48
- package/core/packages/voice/src/livekit.ts +0 -33
- package/core/packages/voice/src/mp4box.d.ts +0 -32
- package/core/packages/voice/src/opusUtils.test.ts +0 -29
- package/core/packages/voice/src/opusUtils.ts +0 -86
- package/core/packages/voice/src/streamPreviewPlaceholder.test.ts +0 -16
- package/core/packages/voice/src/streamPreviewPlaceholder.ts +0 -8
- package/core/packages/voice/src/ws.d.ts +0 -1
- package/core/packages/voice/tsconfig.json +0 -5
- package/core/packages/voice/tsup.config.ts +0 -10
- package/core/packages/voice/vitest.config.ts +0 -9
- package/core/packages/ws/package.json +0 -52
- package/core/packages/ws/src/WebSocketManager.ts +0 -130
- package/core/packages/ws/src/WebSocketShard.ts +0 -296
- package/core/packages/ws/src/index.ts +0 -12
- package/core/packages/ws/src/utils/constants.test.ts +0 -46
- package/core/packages/ws/src/utils/constants.ts +0 -22
- package/core/packages/ws/src/utils/getWebSocket.ts +0 -55
- package/core/packages/ws/src/ws.d.ts +0 -10
- package/core/packages/ws/tsconfig.json +0 -9
- package/core/packages/ws/tsup.config.ts +0 -9
- package/core/pnpm-lock.yaml +0 -7033
- package/core/pnpm-workspace.yaml +0 -4
- package/core/scripts/generate-ai-rag.ts +0 -240
- package/core/scripts/generate-docs.ts +0 -143
- package/core/scripts/generate-emoji-shortcodes.ts +0 -58
- package/core/scripts/generate-types.ts +0 -6
- package/core/scripts/publish-ordered.js +0 -63
- package/core/scripts/test-cjs-require.mjs +0 -43
- package/core/scripts/test-esm-imports.mjs +0 -42
- package/core/scripts/test-package-exports.mjs +0 -98
- package/core/scripts/test-smoke.mjs +0 -103
- package/core/tsconfig.json +0 -18
- package/core/turbo.json +0 -30
- package/core/vitest.config.ts +0 -17
- package/core/wrangler.jsonc +0 -9
|
@@ -1,589 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "installation",
|
|
4
|
-
"slug": "installation",
|
|
5
|
-
"title": "Installation",
|
|
6
|
-
"description": "Install the package and configure your bot token.",
|
|
7
|
-
"category": "getting-started",
|
|
8
|
-
"sections": [
|
|
9
|
-
{
|
|
10
|
-
"code": "npm install @fluxerjs/core\n\n# Run your bot (Node 18+)\nFLUXER_BOT_TOKEN=your_token node your-bot.js",
|
|
11
|
-
"language": "bash"
|
|
12
|
-
}
|
|
13
|
-
]
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"id": "basic-bot",
|
|
17
|
-
"slug": "basic-bot",
|
|
18
|
-
"title": "Basic Bot",
|
|
19
|
-
"description": "A minimal bot that responds to !ping with Pong.",
|
|
20
|
-
"category": "getting-started",
|
|
21
|
-
"sections": [
|
|
22
|
-
{
|
|
23
|
-
"code": "import { Client, Events } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.Ready, () => console.log('Ready!'));\nclient.on(Events.MessageCreate, async (message) => {\n if (message.content === '!ping') {\n await message.reply('Pong!');\n }\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
24
|
-
"language": "javascript"
|
|
25
|
-
}
|
|
26
|
-
]
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"id": "sending-without-reply",
|
|
30
|
-
"slug": "sending-without-reply",
|
|
31
|
-
"title": "Sending Without Reply",
|
|
32
|
-
"description": "Send messages to the same channel or to specific channels. Covers message.send(), message.sendTo(), client.channels.send(), and client.channels.fetch().",
|
|
33
|
-
"category": "sending-messages",
|
|
34
|
-
"sections": [
|
|
35
|
-
{
|
|
36
|
-
"title": "message.send() vs message.reply()",
|
|
37
|
-
"description": "message.reply() sends a message that references another message (shows as a \"reply\" in Discord). message.send() sends to the same channel with no reference—a regular standalone message."
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"title": "Sending to the same channel",
|
|
41
|
-
"description": "Use message.send() when you want to post in the channel without replying. Same signature as reply(): pass a string or object with content and/or embeds.",
|
|
42
|
-
"code": "import { Client, Events } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.MessageCreate, async (message) => {\n if (message.content === '!hello') {\n await message.send('Hello! This is a regular message, not a reply.');\n }\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
43
|
-
"language": "javascript"
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"title": "Sending to a specific channel (e.g. logging)",
|
|
47
|
-
"description": "Use message.sendTo(channelId, payload) to send to another channel—handy for logging, announcements, or forwarding. You only need the target channel ID.",
|
|
48
|
-
"code": "import { Client, Events, EmbedBuilder } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\nconst LOG_CHANNEL_ID = process.env.LOG_CHANNEL_ID; // Your log channel's snowflake\n\nclient.on(Events.MessageCreate, async (message) => {\n if (message.content === '!report' && message.guildId && LOG_CHANNEL_ID) {\n const embed = new EmbedBuilder()\n .setTitle('User report')\n .setDescription(message.content)\n .addFields(\n { name: 'Author', value: message.author.username, inline: true },\n { name: 'Channel', value: `<#${message.channelId}>`, inline: true }\n )\n .setTimestamp();\n\n await message.sendTo(LOG_CHANNEL_ID, { embeds: [embed.toJSON()] });\n await message.send('Report logged.');\n }\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
49
|
-
"language": "javascript"
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
"title": "client.channels.send() — send by channel ID",
|
|
53
|
-
"description": "Use client.channels.send(channelId, payload) when you have a channel ID. Works even if the channel is not cached. No need to fetch first when you only need to send.",
|
|
54
|
-
"code": "import { Client, Events } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\nconst ANNOUNCE_CHANNEL_ID = process.env.ANNOUNCE_CHANNEL_ID;\n\nclient.on(Events.Ready, async () => {\n if (ANNOUNCE_CHANNEL_ID) {\n await client.channels.send(ANNOUNCE_CHANNEL_ID, 'Bot is online!');\n }\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
55
|
-
"language": "javascript"
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
"title": "client.channels.fetch() — get channel by ID",
|
|
59
|
-
"description": "Fetch a channel by ID from the API (or cache). Use channel.isSendable() before sending. For sending when you only have an ID, prefer client.channels.send() which skips the fetch.",
|
|
60
|
-
"code": "import { Client } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\nawait client.login(process.env.FLUXER_BOT_TOKEN);\n\n// Fetch channel (from API if not cached)\nconst channel = await client.channels.fetch(channelId);\nif (channel?.isSendable()) {\n await channel.send('Hello!');\n}\n// Or for webhooks: if (channel?.createWebhook) { ... }",
|
|
61
|
-
"language": "javascript"
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
"title": "fetch message by id",
|
|
65
|
-
"description": "Use channel.messages.fetch(messageId) when you have the channel. For IDs-only, fetch the channel first.",
|
|
66
|
-
"code": "// When you have the channel\nconst message = await channel.messages.fetch(messageId);\nif (message) {\n await message.edit({ content: 'Updated!' });\n await message.react('👍');\n}\n\n// When you only have IDs (e.g. from sqlite)\nconst ch = await client.channels.fetch(channelId);\nconst msg = await ch?.messages?.fetch(messageId);\nif (msg) await msg.delete();\n\n// When channel is cached\nconst m = client.channels.get(channelId);\nif (m?.isSendable()) {\n const mes = await m.messages.fetch(messageId);\n if (mes) await mes.edit({ content: 'Edited!' });\n}\n\n// Refresh a stale message instance\nconst updated = await message.fetch();\nif (updated) console.log(updated.content);",
|
|
67
|
-
"language": "javascript"
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
"title": "message.channel and message.guild",
|
|
71
|
-
"description": "Access the channel or guild from a message. Resolved from cache; null if not cached (e.g. DM channel).",
|
|
72
|
-
"code": "client.on(Events.MessageCreate, async (message) => {\n const channel = message.channel; // TextChannel or DMChannel | null\n const guild = message.guild; // Guild | null (null for DMs)\n if (message.channel?.isSendable()) {\n await message.channel.send('Same channel, different API');\n }\n});",
|
|
73
|
-
"language": "javascript"
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
"title": "Quick reference",
|
|
77
|
-
"code": "// Same channel, no reply\nawait message.send('Pong!');\n\n// Reply to the message\nawait message.reply('Pong!');\n\n// Send to a specific channel\nawait message.sendTo(logChannelId, 'User joined!');\nawait client.channels.send(channelId, 'New update available!');",
|
|
78
|
-
"language": "javascript"
|
|
79
|
-
}
|
|
80
|
-
]
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
"id": "embeds",
|
|
84
|
-
"slug": "embeds",
|
|
85
|
-
"title": "Embeds",
|
|
86
|
-
"description": "Complete reference for EmbedBuilder: title, description, author, footer, fields, color, media, and more.",
|
|
87
|
-
"category": "sending-messages",
|
|
88
|
-
"sections": [
|
|
89
|
-
{
|
|
90
|
-
"title": "Overview",
|
|
91
|
-
"description": "Use EmbedBuilder to create rich embeds. Call toJSON() when passing to reply(), send(), or edit(). An embed must have at least one of: title, description, fields, or image/thumbnail. A description-only embed (no title) is valid."
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
"title": "Basic embed",
|
|
95
|
-
"description": "Minimal embed with title, description, color, fields, footer, and timestamp.",
|
|
96
|
-
"code": "import { Client, Events, EmbedBuilder } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.MessageCreate, async (message) => {\n if (message.content === '!embed') {\n const embed = new EmbedBuilder()\n .setTitle('Hello!')\n .setDescription('This is a Fluxer embed.')\n .setColor(0x5865f2)\n .addFields(\n { name: 'Field 1', value: 'Value 1', inline: true },\n { name: 'Field 2', value: 'Value 2', inline: true }\n )\n .setFooter({ text: 'Powered by Fluxer.js' })\n .setTimestamp();\n\n await message.reply({ embeds: [embed.toJSON()] });\n }\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
97
|
-
"language": "javascript"
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
"title": "Title, Description, and URL",
|
|
101
|
-
"description": "setTitle() and setDescription() accept strings (max 256 and 4096 chars). setURL() makes the title a clickable link.",
|
|
102
|
-
"code": "const embed = new EmbedBuilder()\n .setTitle('Clickable Title')\n .setDescription('Main body text here.')\n .setURL('https://example.com');",
|
|
103
|
-
"language": "javascript"
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
"title": "Color",
|
|
107
|
-
"description": "setColor() accepts: number (0x5865f2), hex string (\"#5865f2\"), or [r, g, b] array.",
|
|
108
|
-
"code": "embed.setColor(0x5865f2);\nembed.setColor('#57f287');\nembed.setColor([88, 101, 242]);",
|
|
109
|
-
"language": "javascript"
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
"title": "Author",
|
|
113
|
-
"description": "setAuthor() adds a header line with name. Optional: iconURL, url.",
|
|
114
|
-
"code": "embed.setAuthor({\n name: 'Fluxer.js',\n iconURL: 'https://example.com/icon.png',\n url: 'https://fluxerjs.dev',\n});",
|
|
115
|
-
"language": "javascript"
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
"title": "Footer",
|
|
119
|
-
"description": "setFooter() adds text at the bottom. Optional: iconURL.",
|
|
120
|
-
"code": "embed.setFooter({\n text: 'Powered by Fluxer.js',\n iconURL: 'https://example.com/footer-icon.png',\n});",
|
|
121
|
-
"language": "javascript"
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
"title": "Timestamp",
|
|
125
|
-
"description": "setTimestamp() shows a date. Omit or pass null for current time. Pass Date or number (ms) for a specific time.",
|
|
126
|
-
"code": "embed.setTimestamp(); // current time\nembed.setTimestamp(new Date('2026-01-01'));\nembed.setTimestamp(Date.now() - 3600000); // 1 hour ago",
|
|
127
|
-
"language": "javascript"
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
"title": "Fields",
|
|
131
|
-
"description": "addFields() adds name/value pairs. Max 25 fields. Use inline: true for side-by-side layout. spliceFields() to insert/remove.",
|
|
132
|
-
"code": "embed.addFields(\n { name: 'Field 1', value: 'Value 1', inline: true },\n { name: 'Field 2', value: 'Value 2', inline: true },\n { name: 'Long field', value: 'Not inline, full width' }\n);\n\n// Insert/replace fields\nembed.spliceFields(1, 1, { name: 'Replaced', value: 'New value' });",
|
|
133
|
-
"language": "javascript"
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
"title": "Image and Thumbnail",
|
|
137
|
-
"description": "setImage() adds a large image. setThumbnail() adds a small image (e.g. top-right). Pass a URL string or EmbedMediaOptions (url, width, height, content_type, etc).",
|
|
138
|
-
"code": "embed.setImage('https://example.com/image.png');\nembed.setThumbnail('https://example.com/thumb.png');\n\n// With metadata\nembed.setImage({\n url: 'https://example.com/image.png',\n width: 400,\n height: 200,\n content_type: 'image/png',\n});",
|
|
139
|
-
"language": "javascript"
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
"title": "Video and Audio",
|
|
143
|
-
"description": "setVideo() and setAudio() add video/audio to embeds (Fluxer supports these). Pass URL or EmbedMediaOptions. Include a title when using video. See Embed Media guide for full examples.",
|
|
144
|
-
"code": "embed.setVideo('https://example.com/video.mp4');\nembed.setAudio({\n url: 'https://example.com/audio.mp3',\n duration: 120,\n content_type: 'audio/mpeg',\n});",
|
|
145
|
-
"language": "javascript"
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
"title": "Multiple embeds",
|
|
149
|
-
"description": "Messages can include up to 10 embeds. Pass an array to embeds.",
|
|
150
|
-
"code": "await message.reply({\n embeds: [\n new EmbedBuilder().setTitle('First').setColor(0x5865f2).toJSON(),\n new EmbedBuilder().setTitle('Second').setColor(0x57f287).toJSON(),\n ],\n});",
|
|
151
|
-
"language": "javascript"
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
"title": "Load from existing embed",
|
|
155
|
-
"description": "EmbedBuilder.from() creates a builder from an API embed (e.g. from a received message). Edit and toJSON() to send.",
|
|
156
|
-
"code": "const existing = message.embeds[0];\nif (existing) {\n const edited = EmbedBuilder.from(existing)\n .setTitle('Updated title')\n .setColor(0x57f287);\n await message.edit({ embeds: [edited.toJSON()] });\n}",
|
|
157
|
-
"language": "javascript"
|
|
158
|
-
},
|
|
159
|
-
{
|
|
160
|
-
"title": "Limits",
|
|
161
|
-
"description": "Title ≤256, description ≤4096, field name ≤256, field value ≤1024, footer ≤2048, author name ≤256. Max 25 fields. Combined title+description+fields+footer ≤6000 chars."
|
|
162
|
-
}
|
|
163
|
-
]
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
"id": "editing-embeds",
|
|
167
|
-
"slug": "editing-embeds",
|
|
168
|
-
"title": "Editing Embeds",
|
|
169
|
-
"description": "Edit existing message embeds with message.edit().",
|
|
170
|
-
"category": "sending-messages",
|
|
171
|
-
"sections": [
|
|
172
|
-
{
|
|
173
|
-
"title": "Overview",
|
|
174
|
-
"description": "The Fluxer API supports editing existing messages via PATCH. You can update the message content, embeds, or both. Only the message author (or admins with proper permissions) can edit messages."
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
"title": "Edit Content",
|
|
178
|
-
"description": "Update the text content of a message you sent.",
|
|
179
|
-
"code": "const reply = await message.reply('Initial message');\nawait reply.edit({ content: 'Updated message!' });",
|
|
180
|
-
"language": "javascript"
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
"title": "Edit Embeds",
|
|
184
|
-
"description": "Replace or update embeds on an existing message. Pass an array of EmbedBuilder instances or APIEmbed objects.",
|
|
185
|
-
"code": "import { Client, Events, EmbedBuilder } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.MessageCreate, async (message) => {\n if (message.content === '!editembed') {\n const embed = new EmbedBuilder()\n .setTitle('Loading...')\n .setColor(0x5865f2)\n .setTimestamp();\n\n const reply = await message.reply({ embeds: [embed.toJSON()] });\n\n // Simulate loading, then update the embed\n await new Promise((r) => setTimeout(r, 2000));\n\n const updatedEmbed = new EmbedBuilder()\n .setTitle('Done!')\n .setDescription('This embed was edited after 2 seconds.')\n .setColor(0x57f287)\n .setTimestamp();\n\n await reply.edit({ embeds: [updatedEmbed] });\n }\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
186
|
-
"language": "javascript"
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
"title": "Edit Content and Embeds Together",
|
|
190
|
-
"description": "You can update both content and embeds in a single edit call.",
|
|
191
|
-
"code": "await message.edit({\n content: 'Updated text',\n embeds: [new EmbedBuilder().setTitle('Updated embed').setColor(0x5865f2).toJSON()],\n});",
|
|
192
|
-
"language": "javascript"
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
"title": "API Reference",
|
|
196
|
-
"description": "The edit endpoint is PATCH /channels/{channel_id}/messages/{message_id}. See openapi.json for the full request body schema. The SDK Message.edit() accepts { content?: string; embeds?: (APIEmbed | EmbedBuilder)[] }."
|
|
197
|
-
}
|
|
198
|
-
]
|
|
199
|
-
},
|
|
200
|
-
{
|
|
201
|
-
"id": "embed-media",
|
|
202
|
-
"slug": "embed-media",
|
|
203
|
-
"title": "Embed Media",
|
|
204
|
-
"description": "Add images, thumbnails, video, and audio to embeds with EmbedBuilder and EmbedMediaOptions.",
|
|
205
|
-
"category": "media",
|
|
206
|
-
"sections": [
|
|
207
|
-
{
|
|
208
|
-
"title": "Images and Thumbnails",
|
|
209
|
-
"description": "Use setImage() and setThumbnail() with a URL string, or pass full EmbedMediaOptions for width, height, content_type, and other metadata.",
|
|
210
|
-
"code": "import { Client, Events, EmbedBuilder } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.MessageCreate, async (message) => {\n if (message.content === '!embedimg') {\n const embed = new EmbedBuilder()\n .setTitle('Image Embed')\n .setDescription('Simple image from URL.')\n .setImage('https://placehold.co/400x200/5865f2/white?text=Image')\n .setThumbnail('https://placehold.co/100x100/57f287/white?text=Thumb')\n .setColor(0x5865f2);\n\n await message.reply({ embeds: [embed.toJSON()] });\n }\n});",
|
|
211
|
-
"language": "javascript"
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
"title": "Image with Full Media Options",
|
|
215
|
-
"description": "Pass an object to setImage or setThumbnail with url, width, height, content_type, description, placeholder, duration, and flags. Use EmbedMediaFlags.IS_ANIMATED for animated GIFs.",
|
|
216
|
-
"code": "const embed = new EmbedBuilder()\n .setTitle('Image with metadata')\n .setDescription('EmbedMediaOptions: width, height')\n .setImage({\n url: 'https://placehold.co/400x200/5865f2/white?text=Image',\n width: 400,\n height: 200,\n content_type: 'image/png',\n })\n .setColor(0x5865f2);",
|
|
217
|
-
"language": "javascript"
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
"title": "GIFs in embeds",
|
|
221
|
-
"description": "Embeds require GIF format for animated images (not MP4). Add EmbedMediaFlags.IS_ANIMATED to the flags field. For Tenor URLs, use resolveTenorToImageUrl() to get the GIF URL and flag — see the GIFs (Tenor) guide."
|
|
222
|
-
},
|
|
223
|
-
{
|
|
224
|
-
"title": "Video in Embeds",
|
|
225
|
-
"description": "Use setVideo() to add video to a rich embed. Fluxer supports the .video field. Include a title when using video. Pass a URL or EmbedMediaOptions (e.g. duration for progress bars).",
|
|
226
|
-
"code": "const embed = new EmbedBuilder()\n .setTitle('Video embed')\n .setDescription('Rich embed with video field.')\n .setVideo('https://example.com/sample.mp4')\n .setURL('https://example.com/sample.mp4')\n .setColor(0x5865f2);\n\n// With full options (duration, dimensions for progress bar):\nconst embedWithDuration = new EmbedBuilder()\n .setTitle('Video with metadata')\n .setVideo({\n url: 'https://example.com/video.mp4',\n duration: 120,\n width: 1280,\n height: 720,\n })\n .setColor(0x5865f2);",
|
|
227
|
-
"language": "javascript"
|
|
228
|
-
},
|
|
229
|
-
{
|
|
230
|
-
"title": "Audio in Embeds",
|
|
231
|
-
"description": "Use setAudio() to add audio to an embed. Pass a URL or EmbedMediaOptions (e.g. duration, content_type).",
|
|
232
|
-
"code": "const embed = new EmbedBuilder()\n .setTitle('Audio embed')\n .setDescription('Rich embed with audio field.')\n .setAudio({\n url: 'https://example.com/sample.mp3',\n duration: 180,\n content_type: 'audio/mpeg',\n })\n .setColor(0x5865f2);",
|
|
233
|
-
"language": "javascript"
|
|
234
|
-
}
|
|
235
|
-
]
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
"id": "gifs",
|
|
239
|
-
"slug": "gifs",
|
|
240
|
-
"title": "GIFs (Tenor)",
|
|
241
|
-
"description": "Send Tenor GIFs as content (gifv) or in embeds using resolveTenorToImageUrl() for GIF URLs.",
|
|
242
|
-
"category": "media",
|
|
243
|
-
"sections": [
|
|
244
|
-
{
|
|
245
|
-
"title": "How Tenor GIFs Work",
|
|
246
|
-
"description": "Tenor embeds are created by the Fluxer unfurler when you send a Tenor URL as message content. Do not use custom embeds for Tenor GIFs—the API turns the URL into a type: \"gifv\" embed."
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
"title": "Send a Tenor GIF",
|
|
250
|
-
"description": "Send the Tenor URL as content. No embeds needed. The unfurler detects the URL and creates the gifv embed.",
|
|
251
|
-
"code": "import { Client, Events } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.MessageCreate, async (message) => {\n if (message.content === '!gif') {\n const tenorUrl = 'https://tenor.com/view/stressed-gif-7048057395502071840';\n await message.reply({ content: tenorUrl });\n }\n});",
|
|
252
|
-
"language": "javascript"
|
|
253
|
-
},
|
|
254
|
-
{
|
|
255
|
-
"title": "Tenor URL in an embed",
|
|
256
|
-
"description": "Tenor page URLs do not work as setImage() URLs. Use resolveTenorToImageUrl() to fetch the Tenor page or oEmbed, derive the GIF URL (embeds require GIF, not MP4), and return { url, flags: IS_ANIMATED }. For full gifv embeds, send the Tenor URL as content.",
|
|
257
|
-
"code": "import { EmbedBuilder, resolveTenorToImageUrl } from '@fluxerjs/core';\n\nconst tenorUrl = 'https://tenor.com/view/stressed-gif-7048057395502071840';\nconst media = await resolveTenorToImageUrl(tenorUrl);\nif (media) {\n const embed = new EmbedBuilder()\n .setTitle('Tenor in embed')\n .setDescription('GIF URL + IS_ANIMATED flag')\n .setImage(media)\n .setColor(0x5865f2);\n await message.reply({ embeds: [embed.toJSON()] });\n}",
|
|
258
|
-
"language": "javascript"
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
"title": "Important",
|
|
262
|
-
"description": "Custom embeds cannot create gifv embeds. For full animated gifv, send the Tenor URL as content. resolveTenorToImageUrl() returns GIF URL + IS_ANIMATED (derived from media.tenor.com path)."
|
|
263
|
-
}
|
|
264
|
-
]
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
"id": "attachments",
|
|
268
|
-
"slug": "attachments",
|
|
269
|
-
"title": "File Attachments",
|
|
270
|
-
"description": "Upload files with messages and set attachment metadata (title, description, flags for spoiler, animated, explicit).",
|
|
271
|
-
"category": "media",
|
|
272
|
-
"sections": [
|
|
273
|
-
{
|
|
274
|
-
"title": "Basic File Upload",
|
|
275
|
-
"description": "Pass files in your send options. Each file needs a name and data (Buffer, Blob, Uint8Array). Use with message.reply(), message.send(), or channel.send().",
|
|
276
|
-
"code": "import { Client, Events } from '@fluxerjs/core';\nimport { readFileSync } from 'fs';\n\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.MessageCreate, async (message) => {\n if (message.content === '!file') {\n const data = Buffer.from('Hello from Fluxer!', 'utf-8');\n await message.reply({\n content: 'Here is a file:',\n files: [{ name: 'hello.txt', data }],\n });\n }\n});",
|
|
277
|
-
"language": "javascript"
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
"title": "Attachment Metadata",
|
|
281
|
-
"description": "When using files, you can pass attachments to set metadata per file: filename, title, description, and flags. The id in each attachment matches the file index (0, 1, 2...).",
|
|
282
|
-
"code": "import { MessageAttachmentFlags } from '@fluxerjs/core';\n\nawait message.reply({\n content: 'Spoiler image:',\n files: [{ name: 'secret.png', data: imageBuffer }],\n attachments: [\n {\n id: 0,\n filename: 'secret.png',\n title: 'Hidden image',\n flags: MessageAttachmentFlags.IS_SPOILER,\n },\n ],\n});",
|
|
283
|
-
"language": "javascript"
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
"title": "Attachment Flags",
|
|
287
|
-
"description": "MessageAttachmentFlags: IS_SPOILER (8) blurs until clicked, CONTAINS_EXPLICIT_MEDIA (16) for explicit content, IS_ANIMATED (32) for GIFs and animated WebP. Combine with bitwise OR.",
|
|
288
|
-
"code": "import { MessageAttachmentFlags } from '@fluxerjs/core';\n\n// Spoiler (blurred until clicked)\nflags: MessageAttachmentFlags.IS_SPOILER\n\n// Animated image (GIF, animated WebP)\nflags: MessageAttachmentFlags.IS_ANIMATED\n\n// Combine flags\nflags: MessageAttachmentFlags.IS_SPOILER | MessageAttachmentFlags.IS_ANIMATED",
|
|
289
|
-
"language": "javascript"
|
|
290
|
-
}
|
|
291
|
-
]
|
|
292
|
-
},
|
|
293
|
-
{
|
|
294
|
-
"id": "profile-urls",
|
|
295
|
-
"slug": "profile-urls",
|
|
296
|
-
"title": "Profile URLs",
|
|
297
|
-
"description": "Get avatar, banner, and other CDN URLs easily with User/Webhook/GuildMember methods or standalone CDN helpers for raw API data.",
|
|
298
|
-
"category": "media",
|
|
299
|
-
"sections": [
|
|
300
|
-
{
|
|
301
|
-
"title": "User avatar and banner",
|
|
302
|
-
"description": "When you have a User object (e.g. message.author), use avatarURL(), displayAvatarURL(), and bannerURL(). These handle animated avatars (a_ prefix) and default fallbacks.",
|
|
303
|
-
"code": "import { Client, Events, EmbedBuilder } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.MessageCreate, async (message) => {\n if (message.content === '!avatar') {\n const user = message.author;\n // avatarURL() returns null if no custom avatar; displayAvatarURL() uses default\n const avatarUrl = user.displayAvatarURL({ size: 256 });\n const bannerUrl = user.bannerURL({ size: 512 });\n\n const embed = new EmbedBuilder()\n .setTitle(`${user.username}'s profile`)\n .setThumbnail(avatarUrl)\n .setColor(user.avatarColor ?? 0x5865f2);\n if (bannerUrl) embed.setImage(bannerUrl);\n await message.reply({ embeds: [embed.toJSON()] });\n }\n});",
|
|
304
|
-
"language": "javascript"
|
|
305
|
-
},
|
|
306
|
-
{
|
|
307
|
-
"title": "Raw API data: CDN helpers",
|
|
308
|
-
"description": "When you have raw API data (e.g. from client.rest.get(Routes.user(id))), use the standalone CDN helpers. They work with id + hash and support size and extension options.",
|
|
309
|
-
"code": "import { cdnAvatarURL, cdnBannerURL } from '@fluxerjs/core';\n\n// From REST response\nconst userData = await client.rest.get(Routes.user(userId));\nconst avatarUrl = cdnAvatarURL(userData.id, userData.avatar, { size: 256 });\nconst bannerUrl = cdnBannerURL(userData.id, profile?.banner ?? null, { size: 512 });\n\n// Or use User: client.getOrCreateUser(userData) then user.displayAvatarURL()\nconst user = client.getOrCreateUser(userData);\nconst avatarUrl2 = user.displayAvatarURL({ size: 256 });",
|
|
310
|
-
"language": "javascript"
|
|
311
|
-
},
|
|
312
|
-
{
|
|
313
|
-
"title": "Guild member and webhook avatars",
|
|
314
|
-
"description": "GuildMember has displayAvatarURL() (guild avatar or fallback to user) and bannerURL(). Webhook has avatarURL().",
|
|
315
|
-
"code": "// Member avatar (guild-specific or user fallback)\nconst memberAvatar = member.displayAvatarURL({ size: 128 });\n\n// Webhook avatar\nconst webhookAvatar = webhook.avatarURL({ size: 64 });",
|
|
316
|
-
"language": "javascript"
|
|
317
|
-
}
|
|
318
|
-
]
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
"id": "reactions",
|
|
322
|
-
"slug": "reactions",
|
|
323
|
-
"title": "Reactions",
|
|
324
|
-
"description": "Add, remove, and listen for message reactions with Message.react(), removeReaction(), and reaction events.",
|
|
325
|
-
"category": "sending-messages",
|
|
326
|
-
"sections": [
|
|
327
|
-
{
|
|
328
|
-
"title": "Add a Reaction",
|
|
329
|
-
"description": "Use message.react() to add an emoji reaction as the bot. Pass a unicode emoji string or custom emoji { name, id }.",
|
|
330
|
-
"code": "const reply = await message.reply('React to this!');\nawait reply.react('👍');\nawait reply.react({ name: 'customemoji', id: '123456789012345678' });",
|
|
331
|
-
"language": "javascript"
|
|
332
|
-
},
|
|
333
|
-
{
|
|
334
|
-
"title": "Remove Reactions",
|
|
335
|
-
"description": "Remove the bot's reaction with removeReaction(emoji). Remove a specific user's reaction with removeReaction(emoji, userId). Clear all reactions with removeAllReactions() or removeReactionEmoji(emoji).",
|
|
336
|
-
"code": "// Remove the bot's reaction\nawait message.removeReaction('👍');\n\n// Remove a specific user's reaction (requires moderator permissions)\nawait message.removeReaction('👍', userId);\n\n// Remove all reactions of one emoji from the message\nawait message.removeReactionEmoji('👍');\n\n// Remove all reactions from the message\nawait message.removeAllReactions();",
|
|
337
|
-
"language": "javascript"
|
|
338
|
-
},
|
|
339
|
-
{
|
|
340
|
-
"title": "Listen for Reactions",
|
|
341
|
-
"description": "MessageReactionAdd and MessageReactionRemove emit (reaction, user, messageId, channelId, emoji, userId). Use client.on(Events.X, handler) or client.events.MessageReactionAdd(handler).",
|
|
342
|
-
"code": "client.on(Events.MessageReactionAdd, async (reaction, user, messageId, channelId, emoji, userId) => {\n if (emoji.name === '👍') {\n console.log(`User ${userId} voted yes on message ${messageId}`);\n const message = await reaction.fetchMessage();\n if (message) await message.react('✅');\n }\n});\n\nclient.on(Events.MessageReactionRemove, (reaction, user, messageId, channelId, emoji, userId) => {\n console.log(`User ${userId} removed ${emoji.name} from message ${messageId}`);\n});",
|
|
343
|
-
"language": "javascript"
|
|
344
|
-
},
|
|
345
|
-
{
|
|
346
|
-
"title": "Reaction Roles Example",
|
|
347
|
-
"description": "See examples/reaction-roles-bot.js for a full bot that assigns roles when users react to a message. Uses (reaction, user), Guild.fetchMember(), and GuildMember.addRole()/removeRole().",
|
|
348
|
-
"code": "// Simplified reaction-roles logic\nclient.on(Events.MessageReactionAdd, async (reaction, user) => {\n if (!reaction.guildId || reaction.messageId !== rolesMessageId) return;\n const roleId = ROLE_EMOJI_MAP[reaction.emoji.name];\n if (!roleId) return;\n const guild = client.guilds.get(reaction.guildId);\n const member = await guild?.fetchMember(user.id);\n if (member && !member.roles.includes(roleId)) await member.addRole(roleId);\n});",
|
|
349
|
-
"language": "javascript"
|
|
350
|
-
}
|
|
351
|
-
]
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
"id": "webhooks",
|
|
355
|
-
"slug": "webhooks",
|
|
356
|
-
"title": "Webhooks",
|
|
357
|
-
"description": "A complete guide to Discord webhooks—sending messages without a gateway, creating, editing, and managing webhooks.",
|
|
358
|
-
"category": "webhooks",
|
|
359
|
-
"sections": [
|
|
360
|
-
{
|
|
361
|
-
"title": "What are Webhooks?",
|
|
362
|
-
"description": "Webhooks let you send messages to a channel using a URL (ID + token). You can use them in scripts, CI pipelines, or anywhere you need to post without a full bot connection. No gateway, no events—just REST."
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
"title": "Webhooks Without a Bot",
|
|
366
|
-
"description": "A Client with intents: 0 is enough. No need to connect to the gateway or handle events. Ideal for scripts or one-off sends.",
|
|
367
|
-
"code": "import { Client, Webhook } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\nconst webhook = Webhook.fromToken(client, webhookId, webhookToken);\nawait webhook.send('Message from a script!');",
|
|
368
|
-
"language": "javascript"
|
|
369
|
-
},
|
|
370
|
-
{
|
|
371
|
-
"title": "Creating a Webhook",
|
|
372
|
-
"description": "Create a webhook on a text channel. Requires Manage Webhooks permission. The token is returned only when creating—store it securely. It will never be returned when listing or fetching.",
|
|
373
|
-
"code": "import { Client } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\nawait client.login(process.env.FLUXER_BOT_TOKEN);\n\nconst channel = client.channels.get(channelId);\nif (!channel?.createWebhook) throw new Error('Channel does not support webhooks');\n\nconst webhook = await channel.createWebhook({ name: 'My Webhook' });\nconsole.log(webhook.id, webhook.token); // Store token—it won't be returned when listing",
|
|
374
|
-
"language": "javascript"
|
|
375
|
-
},
|
|
376
|
-
{
|
|
377
|
-
"title": "Sending Messages",
|
|
378
|
-
"description": "Send text, embeds, or both. You can override the username and avatar for each message.",
|
|
379
|
-
"code": "import { Client, Webhook, EmbedBuilder } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\nconst webhook = Webhook.fromToken(client, webhookId, webhookToken);\n\nawait webhook.send({\n content: 'Hello from webhook!',\n embeds: [\n new EmbedBuilder()\n .setTitle('Webhook Message')\n .setColor(0x5865f2)\n .setTimestamp()\n .toJSON(),\n ],\n username: 'Custom Name',\n avatar_url: 'https://example.com/avatar.png',\n});",
|
|
380
|
-
"language": "javascript"
|
|
381
|
-
},
|
|
382
|
-
{
|
|
383
|
-
"title": "Simple text only",
|
|
384
|
-
"code": "await webhook.send('Plain text message');",
|
|
385
|
-
"language": "javascript"
|
|
386
|
-
},
|
|
387
|
-
{
|
|
388
|
-
"title": "Embeds without a title",
|
|
389
|
-
"description": "Embeds can use only a description—no title required. At least one of title, description, fields, or image is needed.",
|
|
390
|
-
"code": "await webhook.send({\n embeds: [\n new EmbedBuilder()\n .setDescription('Description-only embed works.')\n .setColor(0x5865f2)\n .toJSON(),\n ],\n});",
|
|
391
|
-
"language": "javascript"
|
|
392
|
-
},
|
|
393
|
-
{
|
|
394
|
-
"title": "Fetching & Listing Webhooks",
|
|
395
|
-
"description": "Fetch by ID or list channel/guild webhooks. Requires a logged-in bot. Fetched webhooks have no token and cannot send—but you can edit or delete them with bot auth.",
|
|
396
|
-
"code": "import { Client, Webhook } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\nawait client.login(process.env.FLUXER_BOT_TOKEN);\n\n// Fetch single webhook (no token)\nconst webhook = await Webhook.fetch(client, webhookId);\n\n// List channel webhooks\nconst channel = client.channels.get(channelId);\nconst channelWebhooks = await channel?.fetchWebhooks() ?? [];\n\n// List guild webhooks\nconst guild = client.guilds.get(guildId);\nconst guildWebhooks = await guild?.fetchWebhooks() ?? [];",
|
|
397
|
-
"language": "javascript"
|
|
398
|
-
},
|
|
399
|
-
{
|
|
400
|
-
"title": "Editing a Webhook",
|
|
401
|
-
"description": "Use webhook.edit() to change name, avatar, or (with bot auth) channel. With a token (e.g. from createWebhook or fromToken), you can update name and avatar. Without a token (fetched webhook), bot auth lets you also change the target channel.",
|
|
402
|
-
"code": "import { Client, Webhook } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\nawait client.login(process.env.FLUXER_BOT_TOKEN);\n\n// With token (name and avatar only)\nconst webhook = Webhook.fromToken(client, webhookId, webhookToken);\nawait webhook.edit({ name: 'New Name', avatar: null });\n// avatar: null clears the webhook avatar\n\n// With bot auth (fetched webhook — can also move to another channel)\nconst fetched = await Webhook.fetch(client, webhookId);\nawait fetched.edit({\n name: 'Updated Name',\n channel_id: newChannelId, // move webhook to different channel\n});",
|
|
403
|
-
"language": "javascript"
|
|
404
|
-
},
|
|
405
|
-
{
|
|
406
|
-
"title": "Deleting a Webhook",
|
|
407
|
-
"code": "const webhook = await Webhook.fetch(client, webhookId);\nawait webhook.delete();",
|
|
408
|
-
"language": "javascript"
|
|
409
|
-
}
|
|
410
|
-
]
|
|
411
|
-
},
|
|
412
|
-
{
|
|
413
|
-
"id": "webhook-attachments-embeds",
|
|
414
|
-
"slug": "webhook-attachments-embeds",
|
|
415
|
-
"title": "Webhook Attachments & Embeds",
|
|
416
|
-
"description": "Send embeds with or without a title, and attach files to webhook messages—same API as channel messages.",
|
|
417
|
-
"category": "webhooks",
|
|
418
|
-
"sections": [
|
|
419
|
-
{
|
|
420
|
-
"title": "Overview",
|
|
421
|
-
"description": "Webhooks support rich embeds and file attachments. Embeds can have just a description (no title required), and you can attach files the same way as with channel.send or message.reply."
|
|
422
|
-
},
|
|
423
|
-
{
|
|
424
|
-
"title": "Embeds Without a Title",
|
|
425
|
-
"description": "You do not need a title for embeds to work. At least one of title, description, fields, or image/thumbnail is required. A description-only embed is valid.",
|
|
426
|
-
"code": "import { Client, Webhook, EmbedBuilder } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\nconst webhook = Webhook.fromToken(client, webhookId, webhookToken);\n\n// Description only—no title\nawait webhook.send({\n embeds: [\n new EmbedBuilder()\n .setDescription('This embed has no title. Description-only works fine.')\n .setColor(0x5865f2)\n .setTimestamp()\n .toJSON(),\n ],\n});",
|
|
427
|
-
"language": "javascript"
|
|
428
|
-
},
|
|
429
|
-
{
|
|
430
|
-
"title": "Direct Attachments",
|
|
431
|
-
"description": "Attach files to webhook messages using the files array. Each file needs name and data (Blob, ArrayBuffer, or Uint8Array). Optional filename overrides the display name.",
|
|
432
|
-
"code": "import { Client, Webhook } from '@fluxerjs/core';\nimport { readFileSync } from 'fs';\n\nconst client = new Client({ intents: 0 });\nconst webhook = Webhook.fromToken(client, webhookId, webhookToken);\n\nconst buffer = readFileSync('report.pdf');\nawait webhook.send({\n content: 'Report attached',\n files: [\n { name: 'report.pdf', data: buffer },\n { name: 'log.txt', data: new TextEncoder().encode('Log content'), filename: 'log-2025.txt' },\n ],\n});",
|
|
433
|
-
"language": "javascript"
|
|
434
|
-
},
|
|
435
|
-
{
|
|
436
|
-
"title": "Full Example: Embed + Files",
|
|
437
|
-
"description": "Combine content, description-only embed, and file attachments in a single webhook send.",
|
|
438
|
-
"code": "import { Client, Webhook, EmbedBuilder } from '@fluxerjs/core';\nimport { readFileSync } from 'fs';\n\nconst client = new Client({ intents: 0 });\nconst webhook = Webhook.fromToken(client, webhookId, webhookToken);\n\nawait webhook.send({\n content: 'Build completed',\n embeds: [\n new EmbedBuilder()\n .setDescription('Deploy succeeded. See attachment for logs.')\n .setColor(0x57f287)\n .setTimestamp()\n .toJSON(),\n ],\n files: [{ name: 'deploy.log', data: readFileSync('deploy.log') }],\n username: 'CI Bot',\n});",
|
|
439
|
-
"language": "javascript"
|
|
440
|
-
}
|
|
441
|
-
]
|
|
442
|
-
},
|
|
443
|
-
{
|
|
444
|
-
"id": "voice",
|
|
445
|
-
"slug": "voice",
|
|
446
|
-
"title": "Voice",
|
|
447
|
-
"description": "Join voice channels and play audio with @fluxerjs/voice. Supports WebM/Opus streams—no FFmpeg required.",
|
|
448
|
-
"category": "voice",
|
|
449
|
-
"sections": [
|
|
450
|
-
{
|
|
451
|
-
"title": "Installation",
|
|
452
|
-
"description": "Add the voice package alongside the core library.",
|
|
453
|
-
"code": "pnpm add @fluxerjs/voice @fluxerjs/core",
|
|
454
|
-
"language": "bash"
|
|
455
|
-
},
|
|
456
|
-
{
|
|
457
|
-
"title": "Setup",
|
|
458
|
-
"description": "Create a VoiceManager before login so it receives VoiceStatesSync from READY/GUILD_CREATE. This lets the manager see users already in voice when the bot starts.",
|
|
459
|
-
"code": "import { Client, Events, VoiceChannel } from '@fluxerjs/core';\nimport { getVoiceManager } from '@fluxerjs/voice';\n\nconst client = new Client({ intents: 0 });\ngetVoiceManager(client); // Must be before login\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
460
|
-
"language": "javascript"
|
|
461
|
-
},
|
|
462
|
-
{
|
|
463
|
-
"title": "Join a Voice Channel",
|
|
464
|
-
"description": "Get the user's voice channel with getVoiceChannelId, then join. The connection resolves when ready.",
|
|
465
|
-
"code": "const voiceManager = getVoiceManager(client);\nconst voiceChannelId = voiceManager.getVoiceChannelId(guildId, userId);\nif (!voiceChannelId) return; // User not in voice\n\nconst channel = client.channels.get(voiceChannelId);\nif (!(channel instanceof VoiceChannel)) return;\n\nconst connection = await voiceManager.join(channel);",
|
|
466
|
-
"language": "javascript"
|
|
467
|
-
},
|
|
468
|
-
{
|
|
469
|
-
"title": "Play Audio",
|
|
470
|
-
"description": "Play a WebM/Opus URL or stream. The voice package does not use FFmpeg—input must be WebM with Opus. Use yt-dlp or similar to get direct stream URLs from YouTube.",
|
|
471
|
-
"code": "// URL (fetched and demuxed automatically)\nawait connection.play('https://example.com/audio.webm');\n\n// Or a Node.js ReadableStream of Opus\nawait connection.play(opusStream);",
|
|
472
|
-
"language": "javascript"
|
|
473
|
-
},
|
|
474
|
-
{
|
|
475
|
-
"title": "Getting Stream URLs from YouTube",
|
|
476
|
-
"description": "Use youtube-dl-exec or yt-dlp to extract a WebM/Opus URL.",
|
|
477
|
-
"code": "import youtubedl from 'youtube-dl-exec';\n\nconst result = await youtubedl(videoUrl, {\n getUrl: true,\n f: 'bestaudio[ext=webm][acodec=opus]/bestaudio[ext=webm]/bestaudio',\n}, { timeout: 15000 });\n\nconst streamUrl = String(result ?? '').trim();\nawait connection.play(streamUrl);",
|
|
478
|
-
"language": "javascript"
|
|
479
|
-
},
|
|
480
|
-
{
|
|
481
|
-
"title": "Stop and Leave",
|
|
482
|
-
"description": "Stop playback and disconnect from the guild's voice channel.",
|
|
483
|
-
"code": "const connection = voiceManager.getConnection(guildId);\nconnection?.stop();\nif (connection) voiceManager.leave(guildId);",
|
|
484
|
-
"language": "javascript"
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
"title": "LiveKit and serverLeave",
|
|
488
|
-
"description": "If using LiveKit, the server may emit serverLeave. Listen and reconnect if needed.",
|
|
489
|
-
"code": "connection.on?.('serverLeave', async () => {\n try {\n const conn = await voiceManager.join(channel);\n await conn.play(streamUrl);\n } catch (e) {\n console.error('Auto-reconnect failed:', e);\n }\n});",
|
|
490
|
-
"language": "javascript"
|
|
491
|
-
}
|
|
492
|
-
]
|
|
493
|
-
},
|
|
494
|
-
{
|
|
495
|
-
"id": "events",
|
|
496
|
-
"slug": "events",
|
|
497
|
-
"title": "Events",
|
|
498
|
-
"description": "Listen to gateway events with client.on. Handle messages, guild updates, voice state changes, and more.",
|
|
499
|
-
"category": "events",
|
|
500
|
-
"sections": [
|
|
501
|
-
{
|
|
502
|
-
"title": "Basic Usage",
|
|
503
|
-
"description": "Use client.on(Events.X, handler) to subscribe to events. Handlers receive event-specific payloads.",
|
|
504
|
-
"code": "import { Client, Events } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.Ready, () => {\n console.log('Bot is ready!');\n});\n\nclient.on(Events.MessageCreate, async (message) => {\n console.log(message.content);\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
505
|
-
"language": "javascript"
|
|
506
|
-
},
|
|
507
|
-
{
|
|
508
|
-
"title": "Common Events",
|
|
509
|
-
"description": "Essential events for most bots.",
|
|
510
|
-
"code": "// Bot finished loading\nclient.on(Events.Ready, () => {});\n\n// New message (DM or guild)\nclient.on(Events.MessageCreate, async (message) => {});\n\n// Reaction events\nclient.on(Events.MessageReactionAdd, (reaction, user, messageId, channelId, emoji, userId) => {});\nclient.on(Events.MessageReactionRemove, (reaction, user, messageId, channelId, emoji, userId) => {});\n\n// Guild joined/left/updated\nclient.on(Events.GuildCreate, (guild) => {});\nclient.on(Events.GuildDelete, (guild) => {});\n\n// Channel created/updated/deleted\nclient.on(Events.ChannelCreate, (channel) => {});\nclient.on(Events.ChannelDelete, (channel) => {});\n\n// Member joined/left/updated\nclient.on(Events.GuildMemberAdd, (member) => {});\nclient.on(Events.GuildMemberRemove, (member) => {});\n\n// Voice state changed (for @fluxerjs/voice)\nclient.on(Events.VoiceStateUpdate, (data) => {});\nclient.on(Events.VoiceServerUpdate, (data) => {});",
|
|
511
|
-
"language": "javascript"
|
|
512
|
-
},
|
|
513
|
-
{
|
|
514
|
-
"title": "Reaction Events",
|
|
515
|
-
"description": "Listen for when users add or remove reactions. Handlers receive (reaction, user, messageId, channelId, emoji, userId). Use MessageReactionRemoveAll and MessageReactionRemoveEmoji for moderator actions.",
|
|
516
|
-
"code": "import { Client, Events } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.MessageReactionAdd, (reaction, user, messageId, channelId, emoji, userId) => {\n const emojiStr = emoji.id ? `<:${emoji.name}:${emoji.id}>` : emoji.name;\n console.log(`User ${userId} reacted with ${emojiStr} on message ${messageId}`);\n\n // Filter for specific message (e.g. poll) or emoji\n if (emoji.name === '👍') {\n console.log('Someone voted yes!');\n }\n});\n\nclient.on(Events.MessageReactionRemove, (reaction, user, messageId, channelId, emoji, userId) => {\n console.log(`User ${userId} removed ${emoji.name} from message ${messageId}`);\n});\n\nclient.on(Events.MessageReactionRemoveAll, (data) => {\n console.log(`All reactions cleared from message ${data.message_id}`);\n});\n\nclient.on(Events.MessageReactionRemoveEmoji, (data) => {\n console.log(`All ${data.emoji.name} reactions removed from message ${data.message_id}`);\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
517
|
-
"language": "javascript"
|
|
518
|
-
},
|
|
519
|
-
{
|
|
520
|
-
"title": "Error Handling",
|
|
521
|
-
"code": "client.on(Events.Error, (err) => {\n console.error('Client error:', err);\n});",
|
|
522
|
-
"language": "javascript"
|
|
523
|
-
}
|
|
524
|
-
]
|
|
525
|
-
},
|
|
526
|
-
{
|
|
527
|
-
"id": "permissions-moderation",
|
|
528
|
-
"slug": "permissions-moderation",
|
|
529
|
-
"title": "Permissions & Moderation",
|
|
530
|
-
"description": "Check member permissions (including guild owner override), use PermissionFlags, and implement ban/kick/unban commands.",
|
|
531
|
-
"category": "other",
|
|
532
|
-
"sections": [
|
|
533
|
-
{
|
|
534
|
-
"title": "Overview",
|
|
535
|
-
"description": "Use member.permissions for guild-level checks (roles only) and member.permissionsIn(channel) for channel-specific permissions (includes overwrites). The server owner always has all permissions."
|
|
536
|
-
},
|
|
537
|
-
{
|
|
538
|
-
"title": "Guild-level permissions",
|
|
539
|
-
"description": "member.permissions returns an object with has(permission). Use it for server-wide actions like ban, kick, manage roles.",
|
|
540
|
-
"code": "import { Client, Events, PermissionFlags } from '@fluxerjs/core';\n\nconst client = new Client({ intents: 0 });\n\nasync function getModeratorPerms(message) {\n const guild = message.guild ?? await message.client.guilds.fetch(message.guildId);\n if (!guild) return null;\n const member = guild.members.get(message.author.id) ?? await guild.fetchMember(message.author.id);\n return member?.permissions ?? null;\n}\n\nclient.on(Events.MessageCreate, async (message) => {\n const perms = await getModeratorPerms(message);\n if (!perms) return;\n\n // Server owner always has all permissions\n if (perms.has(PermissionFlags.BanMembers)) {\n await message.reply('You can ban members.');\n }\n if (perms.has(PermissionFlags.Administrator)) {\n await message.reply('You have Administrator.');\n }\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
541
|
-
"language": "javascript"
|
|
542
|
-
},
|
|
543
|
-
{
|
|
544
|
-
"title": "Owner override",
|
|
545
|
-
"description": "The guild owner automatically receives all permissions regardless of roles. No need to give the owner a role with Administrator.",
|
|
546
|
-
"code": "// When the message author is the server owner:\nconst perms = member.permissions;\nperms.has(PermissionFlags.BanMembers); // true\nperms.has(PermissionFlags.ManageRoles); // true\nperms.has(PermissionFlags.Administrator); // true\n// ... all permission flags return true for the owner",
|
|
547
|
-
"language": "javascript"
|
|
548
|
-
},
|
|
549
|
-
{
|
|
550
|
-
"title": "Channel-specific permissions",
|
|
551
|
-
"description": "member.permissionsIn(channel) applies channel overwrites. Use it when checking if a user can send messages, read history, or connect to voice in a specific channel.",
|
|
552
|
-
"code": "const channel = message.channel;\nif (channel?.isSendable?.()) {\n const perms = member.permissionsIn(channel);\n if (perms.has(PermissionFlags.SendMessages)) {\n await channel.send('You can send here!');\n }\n}",
|
|
553
|
-
"language": "javascript"
|
|
554
|
-
},
|
|
555
|
-
{
|
|
556
|
-
"title": "PermissionFlags reference",
|
|
557
|
-
"description": "Common flags: BanMembers, KickMembers, Administrator, ManageRoles, ManageChannels, ManageGuild, ViewAuditLog, ManageMessages, SendMessages, EmbedLinks, AttachFiles, ReadMessageHistory, MentionEveryone, Connect, Speak, MuteMembers, ModerateMembers, CreateExpressions, PinMessages, BypassSlowmode.",
|
|
558
|
-
"code": "import { PermissionFlags } from '@fluxerjs/core';\n\n// Check multiple\nconst canModerate = perms.has(PermissionFlags.BanMembers) || perms.has(PermissionFlags.Administrator);\n\n// List all permissions the user has\nconst names = Object.keys(PermissionFlags).filter((name) =>\n perms.has(PermissionFlags[name])\n);\nawait message.reply(`Your permissions: ${names.join(', ')}`);",
|
|
559
|
-
"language": "javascript"
|
|
560
|
-
},
|
|
561
|
-
{
|
|
562
|
-
"title": "Moderation example",
|
|
563
|
-
"description": "See examples/moderation-bot.js for a full bot with !ban, !kick, !unban, and !perms commands.",
|
|
564
|
-
"code": "import { Client, Events, PermissionFlags, EmbedBuilder, FluxerError, ErrorCodes } from '@fluxerjs/core';\n\nconst PREFIX = '!';\nconst client = new Client({ intents: 0 });\n\nasync function getModeratorPerms(message) {\n const guild = message.guild ?? await message.client.guilds.fetch(message.guildId);\n if (!guild) return null;\n const member = guild.members.get(message.author.id);\n const resolved = member ?? await guild.fetchMember(message.author.id);\n return resolved?.permissions ?? null;\n}\n\nclient.on(Events.MessageCreate, async (message) => {\n if (message.author.bot || !message.content?.startsWith(PREFIX)) return;\n const [cmd, target, ...rest] = message.content.slice(PREFIX.length).trim().split(/\\s+/);\n const perms = await getModeratorPerms(message);\n if (!perms) {\n await message.reply('Could not load your member data.');\n return;\n }\n\n const guild = message.guild ?? await message.client.guilds.fetch(message.guildId);\n if (!guild) return;\n\n if (cmd === 'ban' && (perms.has(PermissionFlags.BanMembers) || perms.has(PermissionFlags.Administrator))) {\n const userId = target?.match(/^<@!?(\\d+)>$/)?.[1] ?? target;\n if (userId) {\n await guild.ban(userId, { reason: rest.join(' ') || undefined });\n await message.reply(`Banned <@${userId}>.`);\n }\n }\n if (cmd === 'kick' && (perms.has(PermissionFlags.KickMembers) || perms.has(PermissionFlags.Administrator))) {\n const userId = target?.match(/^<@!?(\\d+)>$/)?.[1] ?? target;\n if (userId) {\n await guild.kick(userId, { reason: rest.join(' ') || undefined });\n await message.reply(`Kicked <@${userId}>.`);\n }\n }\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
565
|
-
"language": "javascript"
|
|
566
|
-
}
|
|
567
|
-
]
|
|
568
|
-
},
|
|
569
|
-
{
|
|
570
|
-
"id": "prefix-commands",
|
|
571
|
-
"slug": "prefix-commands",
|
|
572
|
-
"title": "Prefix Commands",
|
|
573
|
-
"description": "Handle !commands by listening to MessageCreate and parsing the content.",
|
|
574
|
-
"category": "events",
|
|
575
|
-
"sections": [
|
|
576
|
-
{
|
|
577
|
-
"title": "Basic Structure",
|
|
578
|
-
"description": "Check for a prefix, split args, and dispatch to command handlers.",
|
|
579
|
-
"code": "import { Client, Events } from '@fluxerjs/core';\n\nconst PREFIX = '!';\nconst client = new Client({ intents: 0 });\n\nclient.on(Events.MessageCreate, async (message) => {\n if (message.author.bot || !message.content) return;\n if (!message.content.startsWith(PREFIX)) return;\n\n const args = message.content.slice(PREFIX.length).trim().split(/\\s+/);\n const command = args.shift()?.toLowerCase();\n\n if (command === 'ping') {\n await message.reply('Pong!');\n }\n if (command === 'hello') {\n const name = args[0] ?? 'there';\n await message.reply(`Hello, ${name}!`);\n }\n});\n\nawait client.login(process.env.FLUXER_BOT_TOKEN);",
|
|
580
|
-
"language": "javascript"
|
|
581
|
-
},
|
|
582
|
-
{
|
|
583
|
-
"title": "Guild-Only Commands",
|
|
584
|
-
"code": "if (!message.guildId) {\n await message.reply('This command only works in a server.');\n return;\n}",
|
|
585
|
-
"language": "javascript"
|
|
586
|
-
}
|
|
587
|
-
]
|
|
588
|
-
}
|
|
589
|
-
]
|