Code Monkey home page Code Monkey logo

diskord's Introduction

Diskord - A Kotlin Discord SDK

Maven Central Discord

A multiplatform Kotlin client for Discord bots with a simple and concise DSL supporting JVM and NodeJS

Built as a lean client using coroutines that gets the intricacies of rate limits, async, and data models out of your way in a clean and easy to use SDK

Documentation available here

Using Diskord? Drop by our discord server

How do I import this?

It is strongly recommended to use Gradle version 7 or higher

// Kotlin build.gradle.kts
repositories {
    mavenCentral()
}

dependencies {
    implementation("com.jessecorbett:diskord-bot:5.3.0")
}

Note: The diskord-bot artifact bundles org.slf4j:slf4j-simple to provide basic logging to STDOUT with no configuration. This can be excluded in favor of your own slf4j logger using gradle exclusion:

// Kotlin build.gradle.kts
configurations {
  implementation {
    exclude("org.slf4j", "slf4j-simple")
  }
}

The library is packaged into two artifacts.

diskord-core is the low level implementation of the Discord API. Read more

diskord-bot provides an easier to use API for common bot functions. Read more

How do I use this?

Dokka documentation

For an example project you can easily clone to get started, look at the diskord-starter repo.

There are also a collection of examples in the diskord-examples repo.

Simple Example

import com.jessecorbett.diskord.bot.*
import com.jessecorbett.diskord.util.*

suspend fun main() {
    bot(TOKEN) {
        // Generic hook set for all events
        events {
            onGuildMemberAdd {
                channel(WELCOME_CHANNEL_ID).sendMessage("Welcome to the server, ${it.user?.username}!")
            }
        }
      
        // Modern interactions API for slash commands, user commands, etc
        interactions {
            slashCommand("echo", "Makes the bot say something") {
                val message by stringParameter("message", "The message", optional = true)
                callback {
                    respond {
                        content = if (message != null) {
                            message
                        } else {
                            "The message was null, because it is optional"
                        }
                    }
                }
            }

            commandGroup("emoji", "Send an emoji to the server", guildId = "424046347428167688") {
                subgroup("smile", "Smile emoji") {
                    slashCommand("slight", "A slight smile emoji") {
                        callback {
                            respond {
                                content = "๐Ÿ™‚"
                            }
                        }
                    }
                }

                slashCommand("shh", "The shh emoji") {
                    val secret by stringParameter("secret", "Send the emoji secretly")
                    callback {
                        respond {
                            content = "๐Ÿคซ"
                            if (secret) {
                                ephemeral
                            }
                        }
                    }
                }
            }
        }
      
        // The old-fashioned way, it uses messages, such as .ping, for commands
        classicCommands("!") {
            command("ping") {
                it.respond("pong")
            }
        }
    }
}

FAQ

  • Does this support voice chat?
    • No, voice chat is not supported at this time. If you need it I recommend checking out another SDK
  • Can I contact you to ask a question/contribute to the project/report a bug?
  • What if I'm hip and cool, and I want to use a newer more unstable exciting version?

diskord's People

Contributors

aviadmini avatar battery-staple avatar binarynoise avatar boy0000 avatar dhuckaby avatar fluidsonic avatar incendium avatar jessecorbett avatar kamilkurde avatar maxr1998 avatar null-dev avatar schitcrafter avatar solonovamax avatar syorito-hatsuki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

diskord's Issues

Gateway Intents

With the way Discord is attempting to address various privacy issues, implementing gateway intents as per the documentation really is a must.

It should be relatively simple to support, especially considering Diskord doesn't appear to do any caching (at least as far as a cursory search goes).

Old version of kotlinx.serialization?

I wanted to use the json serialization and deserialization of kotlinx to store data in json files, but Diskord seems to already have an older version of it as a dependency. With Diskord as a dependency removed the json deserialization works with no problems, but with it as a dependency I get an error during building, that kotlinx.serialization.decodeFromString is an unresolved reference.

This is my current build.gradle.kts:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.4.32"
    kotlin("plugin.serialization") version "1.4.32"
}

group = "de.rubixdev"
version = "1.0-SNAPSHOT"

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    implementation("com.jessecorbett:diskord:1.8.1")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0")
    testImplementation(kotlin("test-junit"))
}

tasks.test {
    useJUnit()
}

tasks.withType<KotlinCompile>() {
    kotlinOptions.jvmTarget = "13"
}

If any more information is needed, feel free to ask.

The examples provided in the README are not valid main() entrypoints

The main() function must return Unit, however, in this case:

fun main() = runBlocking {
    bot(BOT_TOKEN) {
        commands {
            command("ping") {
                reply("pong")
                delete()
            }
        }
    }
}

main will implicitly return the return type of runBlocking, which is the type of the last expression in the block, which is Bot.

To fix, either:

  1. Use block body:
fun main() {
    runBlocking {
        bot(BOT_TOKEN) {
            commands {
                command("ping") {
                    reply("pong")
                    delete()
                }
            }
        }
    }
}
  1. Return Unit in runBlocking (confusing, use the first approach)
fun main() = runBlocking {
    bot(BOT_TOKEN) {
        commands {
            command("ping") {
                reply("pong")
                delete()
            }
        }
    }
   Unit
}

JCenter is at end of life

We need jCenter for this amazing library. But IDEs tell us, that "JCenter is at end of life" and we should remove if from our projects.

Get data from Discord server

Is it possible with its current implementation to get information regarding discord server. For example if I want to extract information about member count in a server, active users (online) etc?

Calling Message Extention functions outside of bot context

Hi, I really enjoy this library, but I'm finding it hard to separate this into different readable files/functions

For example I am trying to pass the message from the schedule command out to another function, but the react extension function is not declared outside of the bot block

suspend fun main() {
    bot(BOT_TOKEN) {
        commands("!") {
            command("schedule") {
               schedule(this)
            }
        }
        suspend fun react(m: Message) {
            m.react("โ›”") // This is allowed
        }
    }
}

fun schedule(m: Message) {
    m.react("โ›”") // This is not allowed because the react extension function is only declared within the bot block
}

I was wondering if you had a suggestion/example for breaking up a bot into multiple files or functions
Thanks!

`rgb` function in Colors.kt translates float colours incorrectly.

The rgb function in Colors.kt translates float colours incorrectly.
If provided with the float 0.999, it will compute the RGB color to be 254. This is incorrect. As a float it is computed to be 254.745, which should be rounded to 255, not 254.

This happens because the toInt function does not round and just truncates the decimal.

Either use

fun rgb(red: Double, green: Double, blue: Double): Color {
    require(red in 0.0F..1.0F) { "$red is not between 0 and 1." }
    require(green in 0.0F..1.0F) { "$green is not between 0 and 1." }
    require(blue in 0.0F..1.0F) { "$blue is not between 0 and 1." }

    return rgb((red * 255).roundToInt(), (green * 255).roundToInt(), (blue * 255).roundToInt())
}

or

fun rgb(red: Double, green: Double, blue: Double): Color {
    require(red in 0.0F..1.0F) { "$red is not between 0 and 1." }
    require(green in 0.0F..1.0F) { "$green is not between 0 and 1." }
    require(blue in 0.0F..1.0F) { "$blue is not between 0 and 1." }

    return rgb((red * 255 + 0.5).toInt(), (green * 255 + 0.5).toInt(), (blue * 255 + 0.5).toInt())
}

to fix this.

SLF4J warning when starting bot

I get this concerning warning in red when starting the bot:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

GUILD_CREATE: Emoji deserialization issue

First thanks for a superb project, really made writing my bot easy.

However, I'm getting an exception on some GUILD_CREATE messages at startup as follows:

Exception in thread "DefaultDispatcher-worker-3" java.lang.IllegalStateException: Expected class kotlinx.serialization.json.JsonObject but found class kotlinx.serialization.json.JsonLiteral
    at kotlinx.serialization.json.internal.AbstractJsonTreeInput.beginStructure(TreeJsonInput.kt:183)
    at com.jessecorbett.diskord.api.model.Role$$serializer.deserialize(Role.kt)
    at com.jessecorbett.diskord.api.model.Role$$serializer.deserialize(Role.kt:7)
    at kotlinx.serialization.Decoder$DefaultImpls.decodeSerializableValue(Coders.kt:113)
    // ...
    at kotlinx.serialization.TaggedDecoder.tagBlock(Tagged.kt:267)
    at kotlinx.serialization.TaggedDecoder.decodeNullableSerializableElement(Tagged.kt:257)
    at com.jessecorbett.diskord.api.model.Emoji$$serializer.deserialize(Emoji.kt)
    at com.jessecorbett.diskord.api.model.Emoji$$serializer.deserialize(Emoji.kt:8)
    // ...

I think it's the emoji return data, an example of which is:

{
  "roles": [
    "471093321251422218"
  ],
  "require_colons": false,
  "name": "pajama3StayWild",
  "managed": true,
  "id": "568952139779670048",
  "animated": false
}

To check, I wrote a simple test:

class EmojisTest {
    @Test
    fun `check emoji with roles`() {
        val json = String(this::class.java.getResource("/emoji-with-role.json").readBytes())
        val emoji = Json.nonstrict.parse(Emoji.serializer(), json)
        Assertions.assertThat(emoji).isNotNull
    }

    @Test
    fun `check emoji without roles`() {
        val json = String(this::class.java.getResource("/emoji-empty-roles.json").readBytes())
        val emoji = Json.nonstrict.parse(Emoji.serializer(), json)
        Assertions.assertThat(emoji).isNotNull
    }
}

which when provided with an empty list for the roles field passes, but the non-empty role is failing (the string value doesn't match com.jessecorbett.diskord.api.model.Emoji).

I think this is ultimately the cause of the initial error I'm getting.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.