From 4bfba3683fdd242f12a7d474c14990949503632b Mon Sep 17 00:00:00 2001 From: "Sup#2.0" <102817779+Sup2point0@users.noreply.github.com> Date: Mon, 4 Mar 2024 18:11:22 +0000 Subject: [PATCH] merge `discord.sc` --- discord/disflux/readme.md | 3 + discord/readme.md | 43 +++ discord/slash/readme.md | 3 + discord/slash/structs/option.md | 60 +++++ discord/source/colour.md | 9 + discord/source/functions/mention.md | 22 ++ discord/source/functions/send.md | 55 ++++ discord/source/structs/bot.md | 53 ++++ discord/source/structs/embed.md | 251 ++++++++++++++++++ discord/source/structs/emoji.md | 41 +++ discord/source/structs/foundations/channel.md | 29 ++ discord/source/structs/foundations/user.md | 30 +++ discord/source/structs/view.md | 104 ++++++++ discord/specimens/bot.coffee | 106 ++++++++ .../foundation/inicialyzacino.coffee | 13 + discord/specimens/views/buttons.coffee | 43 +++ 16 files changed, 865 insertions(+) create mode 100644 discord/disflux/readme.md create mode 100644 discord/readme.md create mode 100644 discord/slash/readme.md create mode 100644 discord/slash/structs/option.md create mode 100644 discord/source/colour.md create mode 100644 discord/source/functions/mention.md create mode 100644 discord/source/functions/send.md create mode 100644 discord/source/structs/bot.md create mode 100644 discord/source/structs/embed.md create mode 100644 discord/source/structs/emoji.md create mode 100644 discord/source/structs/foundations/channel.md create mode 100644 discord/source/structs/foundations/user.md create mode 100644 discord/source/structs/view.md create mode 100644 discord/specimens/bot.coffee create mode 100644 discord/specimens/foundation/inicialyzacino.coffee create mode 100644 discord/specimens/views/buttons.coffee diff --git a/discord/disflux/readme.md b/discord/disflux/readme.md new file mode 100644 index 0000000..200304a --- /dev/null +++ b/discord/disflux/readme.md @@ -0,0 +1,3 @@ +# `disflux` + +All Discord-related errors. diff --git a/discord/readme.md b/discord/readme.md new file mode 100644 index 0000000..b7e7c1d --- /dev/null +++ b/discord/readme.md @@ -0,0 +1,43 @@ +# discord.sc 1.2 + +An endorsed supcode extension for interacting with the [Discord API](https://discord.com/developers/docs), specifically for creating bots. + + +## Subextensions + +### [`slash`](slash) +Slash commands implementation and functionality. + + +## Intrinsics + +### [`disflux`](disflux) +Discord-specific errors. + + +## Quick Specimen +Here’s a quick showcase of a simple Discord bot: + +```coffee +spec code { ver = 5.6 | syn = utinax | sty = stan } + +activate discord { ver = 1.2 } + +create discord.bot('demo') [token = discord.token('dQw4w9WgXcQ')] { + create discord.command 'sup' { + define demo.sup(ctx) { + ctx.reply("sup") + } + } +} + +demo.start() +``` + +Many more examples can be found in [specimens](specimens). + + +## Syntax +discord.sc encourages an object-oriented syntax style, although supports various others too. + +Throughout this repository all code blocks will use CoffeeScript syntax highlighting, which is highly flexible and perfect for adding contrast, while not (significantly) disrupting or detracting from any semantics of the code. diff --git a/discord/slash/readme.md b/discord/slash/readme.md new file mode 100644 index 0000000..89476b9 --- /dev/null +++ b/discord/slash/readme.md @@ -0,0 +1,3 @@ +# `slash` + +A subextension implementing slash command functionality. diff --git a/discord/slash/structs/option.md b/discord/slash/structs/option.md new file mode 100644 index 0000000..6e8db11 --- /dev/null +++ b/discord/slash/structs/option.md @@ -0,0 +1,60 @@ +# `option` + +A slash command option. + +```coffee +struct 'option' { + str 'name' + str 'description' + type, pool, dict 'options' + var 'default' + bool 'autocomplete' + bool 'required' + + num 'min' + num 'max' +} +``` + + +
+ + +## Properties + +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `name` | | `str` | The displayed name of the option. | +| `description` | `desc` | `str` | The description of the option. | +| `options` | `choices` | `type`, `pool`, `dict` | The collection of options that can be selected. | +| `default` | | `slot`, variable | The option selected by default. | +| `autocomplete` | `autofill`, `auto` | `bool` | | +| `required` | `req` | `bool` | | +| `min` | | `num` | | +| `max` | | `num` | | + + +
+ + +## Functions + +| function | output | description | +| :------- | :----- | :---------- | +| [`create`](create) | [`slash.option`](#option) | Creates a slash option. | + +### `create` +Creates a slash option. + +```coffee +func[evo] create(ctx) [ + | name = default + | description = none + | options = none + | default = none + | autocomplete = false + | required = true + | min = none + | max = none +] +``` diff --git a/discord/source/colour.md b/discord/source/colour.md new file mode 100644 index 0000000..60b1c37 --- /dev/null +++ b/discord/source/colour.md @@ -0,0 +1,9 @@ +# `colour` + +A collection of Discord-specific colours. + +```coffee +class 'col', 'color', 'colour' { + 'blurple' = 0x5865f2 +} +``` \ No newline at end of file diff --git a/discord/source/functions/mention.md b/discord/source/functions/mention.md new file mode 100644 index 0000000..a3cbfd2 --- /dev/null +++ b/discord/source/functions/mention.md @@ -0,0 +1,22 @@ +## `mention` +Mentions a particular Discord component. + +```coffee +func 'mention'(object 'target' = none) { + +} +``` + +### Inputs +| input | default | type | description | +| :---- | :------ | :--- | :---------- | +| `object` | `self` + +### Example +```coffee +set 'channel' = discord.channel(...) +set 'ping' = discord.mention(discord.user(...)) +set 'message' = "sup `ping`, you’re in `mention(channel)`­­" + +channel.send(message) +``` \ No newline at end of file diff --git a/discord/source/functions/send.md b/discord/source/functions/send.md new file mode 100644 index 0000000..f2cec32 --- /dev/null +++ b/discord/source/functions/send.md @@ -0,0 +1,55 @@ +## `send` +Sends a message to a channel. + +```coffee +func discord.channel.send(str 'content' = none) [ + | react = none + | stickers = none + | attach = none + | embed = none + | embeds = none + | view = none + | views = none + | delete = 0.0 +] +``` + +### Inputs +| input | aliases | type | description | +| :---- | :------ | :--- | :---------- | +| `react` | `reactions` | [`discord.(emoji)s`](emoji.md) | Reaction(s) to add. | +| `sticker` | `stickers` | [`discord.(sticker)s`](sticker.md) | Sticker(s) to add. | +| `attach` | `attachments` | [`discord.(asset)s`](asset.md) | Attachment(s) to upload. | +| `embed` | `embeds` | [`discord.(embed)s`](embed.md) | Embed(s) to add. | +| `view` | `views` | [`discord.(view)s`](view.md) | View(s) to add. | +| `delete` | `delete_after` | `float`, `datix.time`, `datix.date`, `datix.datetime` | The duration after which to delete the message. | + +### Example +```coffee +discord.channel(...).send("sup") [ + | attach = sys.file('sup.svg') + | embed = discord.embed() [...] {...} + | view = discord.view() [...] {...} +] +``` + +
+--- +
+ +## `reply` +Replies to a message. + +```coffee +func discord.message.reply(str 'content' = none) [ + | mention = false + | react = none + | stickers = none + | attach = none + | embed = none + | embeds = none + | view = none + | views = none + | delete = 0.0 +] +``` diff --git a/discord/source/structs/bot.md b/discord/source/structs/bot.md new file mode 100644 index 0000000..ba56c72 --- /dev/null +++ b/discord/source/structs/bot.md @@ -0,0 +1,53 @@ +# `bot` + +A Discord bot. + +```coffee +struct 'bot' { + discord.id 'token' = none + pool[none | default | all] 'intents' = slot(default) + str 'prefix' = "" +} +``` + +
+ +# Properties + +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `token` | `key` | `discord.token` | API key of the bot. | +| `intents` | | `slot` | Intents the bot will be subscribed to. | +| `prefix` | `command_prefix` | `(str)s` | Prefix that precedes all commands. | + +
+ +# Functions + +| function | output | description | +| :------- | :----- | :---------- | +| [`create`](#create) | [`bot`](#bot) | Creates a bot. | +| [`start`](#start) | `none` | Starts the bot. | + + +## `create` +Creates a bot. + +```coffee +evo func create [ + | token = none + | intents = default +] +``` + +### Inputs +| input | aliases | type | description | +| :---- | :------ | :--- | :---------- | + + +## `start` +Starts the bot. + +```coffee +evo func start() [] +``` diff --git a/discord/source/structs/embed.md b/discord/source/structs/embed.md new file mode 100644 index 0000000..bc0df34 --- /dev/null +++ b/discord/source/structs/embed.md @@ -0,0 +1,251 @@ +# `embed` + +A Discord embed. + +```coffee +struct 'embed' { + int 'len' + pool[rich | image | video | gifv | article | link] 'type' + dict 'dict' + + class 'head' { + str 'text' = sys.inv.blank + sys.url 'link' + class 'author' { + str 'text' + sys.url 'link' + sys.url 'icon' + } + } + class 'body' { + str 'text' + hex 'col' + } + class 'foot' { + str 'text' + sys.url 'icon' + datix.time, datix.date, datix.datetime 'time' + } + class 'assets' { + sys.url 'thumb' + sys.url 'image' + } + + (field)s 'fields' + + evo func 'add' + evo func 'insert' + evo func 'del' + evo func 'clear' + + func 'clearfields' + + struct 'field' +} +``` + + +
+ + +## Properties + +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `len` | `length` | `int` | The total character count of the embed, including titles and footers. Useful for checking if an embed is within the 6000 character count limit. | +| `dict` | `info`, `data` | `dict` | A dictionary representation of the embed. Useful for convenient transfer. | +| `type` | | `slot` | The type of the embed. | +| [`head`](#head) | | `class` | The header of the embed. | +| [`body`](#body) | `main` | `class` | The main body of the embed, excluding fields. | +| [`foot`](#foot) | | `class` | The footer of the embed. | +| [`assets`](#assets) | `media` | `class` | Any media within the embed. | +| `fields` | | [`(embed.field)s`](#embedfield) | The fields of the embed. | + +### `head` +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `head.text` | `title` | `str` | The title text. | +| `head.link` | `url` | `sys.url` | The link of the title. | +| `head.author.text` | `name` | `str` | The displayed author. | +| `head.author.icon` | | `sys.url` | The displayed author icon. | + +### `body` +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `body.text` | | `str` | The main text. | +| `body.col` | `colour`, `color`| [`discord.col`](colour.md) | The accent colour. | + +### `foot` +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `foot.text` | | `str` | The footer text. | +| `foot.icon` | | `sys.url` | The footer icon. | +| `foot.time` | `timestamp`| `datix.time`, `datix.date`, `datix.datetime` | The displayed timestamp. | + +### `assets` +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `assets.thumb` | `thumbnail`, `icon`| `sys.url` | The thumbnail. | +| `assets.image` | | `sys.url` | The image. | + + +
+ + +## Functions + +| function | output | description | +| :------- | :----- | :---------- | +| [`create`](#create) | [`embed`](#embed) | Creates an embed. | +| [`clearfields`](#clearFields) | [`embed`](#embed) | Clears fields from the embed. | + +### `create` +Creates an embed. + +```coffee +func[evo] create(ctx) [ + | type = rich + | dict = auto + | + | head { + text = sys.inv.blank + link = none + author { + text = none + link = none + icon = none + } + } + | body { + text = sys.inv.blank + col = none + } + | foot { + text = sys.inv.blank + icon = none + time = none + } + | assets { + thumb = none + image = none + } + | + | fields = none +] +``` + +#### Inputs +{~~} + +#### Examples +```coffee +create discord.embed('content') [ + | head.title = "Example Embed" + | body.text = "testing testing" + | foot.text = "sup" +] +``` + +Specifying the options with `let` afterwards allows you to adjust values based on previous options. + +```coffee +create discord.embed('content') { + let head.title = "Example Embed" + let body.text = "testing *`head.title`* testing" + let foot.text = case(body.text)[lower] +} +``` + +### `clearfields` +Clears fields from the embed. + +```coffee +func embed.clearfields( + 'index' = all +) {} to embed +``` + +#### Inputs +| input | aliases | type | description | +| :---- | :------ | :--- | :---------- | +| `index` | `fields` | `index`, `span`, `slot` | The specific index or indexes to clear. | + +#### Outputs +| output | type | source | notes | +| :----- | :--- | :----- | :---- | +| the embed itself | [`embed`](#embed) | always | Allows for fluent chaining with other functions. | + +#### Example +```coffee +create discord.embed('content') [title = "Example Embed" | fields = ( + embed.field()[title = "first" | text = "sup"], + embed.field()[title = "second" | text = "sup"], + embed.field()[title = "third" | text = "sup"], + embed.field()[title = "fourth" | text = "sup"], + embed.field()[title = "fifth" | text = "sup"], +)] + +content.clearfields(1) +content.clearfields(2~3) +content.clearfields() +``` + +
+ +--- + +
+ +# `embed.field` + +An embed field. + +```coffee +struct embed.'field' { + int 'index' + + str 'title' = sys.inv.blank + str 'text' = sys.inv.blank + bool 'inline' = false +} +``` + + +
+ + +## Properties + +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `title` | `name` | `str` | The title text. | +| `text` | `value` | `str` | The main text. | +| `inline` | | `bool` | Whether or not the field is inline. If `true`, the field before it must also be inline for it have effect. | + + +
+ + +## Functions + +| function | output | description | +| :------- | :----- | :---------- | +| `create` | [`embed.field`](#embedfield) | Creates an embed field. | + +### `create` +Creates an embed field. + +```coffee +func create(ctx) [ + | title = sys.inv.blank + | text = sys.inv.blank + | inline = false +] +``` + +#### Inputs +| input | aliases | type | description | +| :---- | :------ | :--- | :---------- | +| `title` | `name` | `str` | The title text. | +| `text` | `value` | `str` | The main text. | +| `inline` | | `bool` | Whether or not the field is inline. If `true`, the field before it must also be inline for it have effect. | diff --git a/discord/source/structs/emoji.md b/discord/source/structs/emoji.md new file mode 100644 index 0000000..a4cbac5 --- /dev/null +++ b/discord/source/structs/emoji.md @@ -0,0 +1,41 @@ +# `emoji` + +A Discord emoji. + +```coffee +struct 'emoji' { + intr discord.id 'id' + + evo func 'str' +} +``` + +
+ +# Properties + +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `id` | `token` | `discord.id` | The id of the emoji used by Discord for identification. | + +
+ +# Functions + +| function | output | description | +| :------- | :----- | :---------- | +| [`create`](#create) | [`emoji`](#emoji) | Creates an emoji. | + + +## `create` +Creates an emoji. + +```coffee +func create(ctx = void, id) +``` + +## Options +| option | aliases | type | description | +| :----- | :------ | :--- | :---------- | +| `ctx` | | `ctx` | The name of the emoji. If not provided, the first argument should be the id of the emoji. | +| `id` | | `discord.id` | The id of the emoji used by Discord for identification. | diff --git a/discord/source/structs/foundations/channel.md b/discord/source/structs/foundations/channel.md new file mode 100644 index 0000000..9347e08 --- /dev/null +++ b/discord/source/structs/foundations/channel.md @@ -0,0 +1,29 @@ +# `channel` + +A foundational structure for Discord channels. + +```coffee +found struct 'channel' { + intr discord.id 'id' + intr str 'shard' + + intr str 'str' + + intr str 'category' + stat int 'index' +} +``` + +
+ +# Properties + +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | + +
+ +# Functions + +| function | output | description | +| :------- | :----- | :---------- | \ No newline at end of file diff --git a/discord/source/structs/foundations/user.md b/discord/source/structs/foundations/user.md new file mode 100644 index 0000000..4a8a32a --- /dev/null +++ b/discord/source/structs/foundations/user.md @@ -0,0 +1,30 @@ +# `user` + +A Discord user. + +```coffee +struct 'user' [channel] { + intr discord.id 'id' + intr str 'shard' + + intr str 'str' + + intr discord.asset 'avatar' + + synth func 'mention' +} +``` + +
+ +# Properties + +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | + +
+ +# Functions + +| function | output | description | +| :------- | :----- | :---------- | \ No newline at end of file diff --git a/discord/source/structs/view.md b/discord/source/structs/view.md new file mode 100644 index 0000000..7457c14 --- /dev/null +++ b/discord/source/structs/view.md @@ -0,0 +1,104 @@ +# `view` + +A Discord view. + +```coffee +struct 'view' { + num 'timeout' = none +} +``` + + +
+ + +## Properties + +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `timeout` | | `num` | The duration which the view will remain active for. | + + +
+ + +## Functions + +| function | output | description | +| :------- | :----- | :---------- | +| [`create`](create) | [`view`](#view) | Creates a view. | + +### `create` +Creates a view. + +```coffee +func[evo] create(ctx) { + +} +``` + +
+ +--- + +
+ +# `button` + +A button within a view. + +```coffee +struct view.'button' { + discord.id 'id' + + str 'text' + discord.emoji 'icon' + button.style 'style' + sys.url 'link' + + lurk 'press' + lurk 'timeout' + lurk 'stop' + + discord.view 'view' +} +``` + + +
+ + +## Properties + +| property | aliases | type | description | +| :------- | :------ | :--- | :---------- | +| `id` | | `discord.id` | The unique identifier. | +| `text` | `label` | `str` | The text displayed. | +| `icon` | | `discord.emoji` | The icon displayed. | +| `style` | | `button.style` | The button colour. | +| `link` | `url` | `sys.url` | The URL the button links to. | +| `view` | `parent` | `discord.view` | The view the button belongs to. | + + +
+ + +## Functions + +| function | output | description | +| :------- | :----- | :---------- | +| [`create`](create) | [`view.button`](#button) | Creates a button. | + + +### `create` +Creates a button. + +```coffee +func[evo] create(ctx) [ + | 'id' = none + | 'text' = sys.presets.blank + | 'icon' = none + | 'style' = blurple + | 'link' = none +] +``` diff --git a/discord/specimens/bot.coffee b/discord/specimens/bot.coffee new file mode 100644 index 0000000..ee4b645 --- /dev/null +++ b/discord/specimens/bot.coffee @@ -0,0 +1,106 @@ +\ extensive discord bot +\ discord.sc specimen + +spec code { ver = 5.6 | syn = utinax | sty = stan } + +enable sys +activate securex + +locate discord { ver = 1.2 } +activate discord +activate discord.slash + + +create discord.bot('bot') [ + | token = securex.redact('token') + | intents = all + | prefix = "." +] + +on bot.connect {{ + sys.out("connected") +}} + +create discord.command { + define bot.test(ctx) { + ctx.out("sup") + } +} + +create discord.command 'sup' { + define bot.testing(ctx, par) { + ctx.reply("sup `par`")[mention = false] + } +} + +create discord.command 'complex' { + define bot.multi(ctx, str('par1'), int('par2'), bool('par3')) { + if par3 { + if par2 > 2.0 { + ctx.out(str) + } + } + } +} + +define bot.'help'(ctx) { + ctx.reply() [embed = discord.embed() [ + | head.title = "Help" + | body.col = 0x4090f1 + | body.text = "A demonstrative advanced Discord bot, showcasing all of the capabilities of discord.sc" + | foot.text = "Requested by `ctx.user`", + | foot.time = ctx.time + ]] +} + +create discord.slash.command 'commands' [desc = "view a list of available commands"] { + define bot.view(ctx) { + ctx.respond() [embed = discord.embed() [ + | head.title = "Commands" + | body.col = 0xff0090 + | body.text = """ + ... + """ + | foot.text = "Showing `body.text.len[line]` commands" + ]] + } +} + +create discord.slash.command [desc = "get profile picture of a user in the server"] { + define bot.pfp(ctx, discord.member(user)) { + ctx.respond()[attach = user.avatar | ephemeral = true] + } +} + +create discord.slash.command [desc = "select a colour role to add to your profile"] { + define bot.func(ctx, discord.option('col') [ + | name = "colour" + | description = "pick a colour" + | options = {blue, red, green, purple, orange, pink, yellow} + | default = slot(blue) + | required = true + ]) { + role = ctx.guild.roles#(col) + ctx.user.addRole(role) + } +} + +on discord.message.send(ctx) {{ + sys.log("`ctx.message.sender` said `ctx.message.content` in `ctx.channel.name`") + await bot.process(ctx) +}} + +on bot.command.call(ctx) {{ + sys.log("`ctx.user` used `ctx.command.name`") +}} + +on bot.interaction.call(ctx) {{ + sys.log(ctx.data) + if ctx.valid { + sys.log("`ctx.user` used `ctx.command.name`") + await bot.slash.process(ctx) + } +}} + + +bot.start() diff --git a/discord/specimens/foundation/inicialyzacino.coffee b/discord/specimens/foundation/inicialyzacino.coffee new file mode 100644 index 0000000..7da7013 --- /dev/null +++ b/discord/specimens/foundation/inicialyzacino.coffee @@ -0,0 +1,13 @@ +spec code { ver = 5.6 | syn = utinax | sty = stan } + +locate discord { ver = 1.2 } +activate discord + + +create discord.bot 'name' [ + | token = "token" + | intents = all + | prefix = "prefix" +] + +name.start() diff --git a/discord/specimens/views/buttons.coffee b/discord/specimens/views/buttons.coffee new file mode 100644 index 0000000..c548b68 --- /dev/null +++ b/discord/specimens/views/buttons.coffee @@ -0,0 +1,43 @@ +spec code { ver = 5.4 | syn = utinax | sty = stan } + +activate discord { ver = 1.2 } + + +create discord.bot('bot') [token = "dQw4w9WgXcQ"] + +create discord.slash.command { + define bot.test(ctx) { + + create discord.view 'visual' { + create view.button 'test' { + on test.press(ctx) { + ctx.respond("sup") + } + } + } + + ctx.respond() [view = visual] + } +} + +create discord.slash.command { + define bot.test(ctx) { + + create discord.view 'visual' { + create view.button 'test' [ + | style = button.style('green') + | icon = discord.emoji(':cog:') + ] { + on test.press(ctx) { + set test.icon = discord.emoji(':tick:') + ctx.edit()[view = visual] + } + } + } + + ctx.respond()[view = visual] + } +} + + +bot.start()