discord-haskell: Write bots for Discord in Haskell

[ library, mit, network, program ] [ Propose Tags ]
Versions [RSS] 0.5.0, 0.5.1, 0.6.0, 0.7.0, 0.7.1, 0.8.0, 0.8.1, 0.8.2, 0.8.3, 0.8.4, 1.0.0, 1.1.0, 1.1.1, 1.1.2, 1.1.3, 1.2.0, 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.5.2, 1.6.0, 1.6.1, 1.7.0, 1.8.0, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.8.5, 1.8.6, 1.8.7, 1.8.8, 1.8.9, 1.9.0, 1.9.1, 1.9.2, 1.10.0, 1.11.0, 1.12.0, 1.12.1, 1.12.2, 1.12.3, 1.12.4, 1.12.5, 1.13.0, 1.14.0, 1.15.0, 1.15.1, 1.15.2, 1.15.3, 1.15.4, 1.15.5, 1.15.6, 1.16.0, 1.16.1
Change log changelog.md
Dependencies aeson (>=1.3.1.1 && <1.5), async (>=2.2.1 && <2.3), base (>=4 && <5), base64-bytestring (>=1.0.0.1 && <1.1), bytestring (>=0.10.8.2 && <0.11), containers (>=0.5.11.0 && <0.7), data-default (>=0.7.1.1 && <0.8), discord-haskell, emoji (==0.1.0.2), http-client (>=0.6.4 && <0.7), iso8601-time (>=0.1.5 && <0.2), JuicyPixels (>=3.2.9.5 && <3.4), MonadRandom (>=0.5.1.1 && <0.6), req (>=2.1.0 && <2.2), safe-exceptions (>=0.1.7.0 && <0.2), text (>=1.2.3.0 && <1.3), time (>=1.8.0.2 && <1.9), unordered-containers (>=0.2.9.0 && <0.3), vector (>=0.12.0.1 && <0.13), websockets (>=0.12.5.1 && <0.13), wuss (>=1.1.10 && <1.2) [details]
License MIT
Copyright 2019 Karl
Author Karl
Maintainer ksfish5@gmail.com
Category Network
Home page https://github.com/aquarial/discord-haskell
Bug tracker https://github.com/aquarial/discord-haskell/issues
Source repo head: git clone https://github.com/aquarial/discord-haskell.git
Uploaded by Aquarial at 2020-01-01T01:51:33Z
Distributions NixOS:1.16.1
Reverse Dependencies 2 direct, 0 indirect [details]
Executables ping-pong
Downloads 17904 total (215 in the last 30 days)
Rating 2.5 (votes: 6) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2020-01-01 [all 1 reports]

Readme for discord-haskell-1.2.0

[back to package description]

discord-haskell Build Status

{-# LANGUAGE OverloadedStrings #-}  -- allows "string literals" to be Text

import Control.Monad (when)
import Data.Text (isPrefixOf, toLower, Text)
import Control.Concurrent (threadDelay)
import qualified Data.Text.IO as TIO

import Discord
import Discord.Types
import qualified Discord.Requests as R

-- | Replies "pong" to every message that starts with "ping"
pingpongExample :: IO ()
pingpongExample = do userFacingError <- runDiscord $ def
                                            { discordToken = "Bot ZZZZZZZZZZZZZZZZZZZ"
                                            , discordOnEvent = eventHandler }
                     TIO.putStrLn userFacingError

eventHandler :: DiscordHandle -> Event -> IO ()
eventHandler dis event = case event of
       MessageCreate m -> when (not (fromBot m) && isPing (messageText m)) $ do
               _ <- restCall dis (R.CreateReaction (messageChannel m, messageId m) "eyes")
               threadDelay (4 * 10^6)
               _ <- restCall dis (R.CreateMessage (messageChannel m) "Pong!")
               pure ()
       _ -> pure ()

fromBot :: Message -> Bool
fromBot m = userIsBot (messageAuthor m)

isPing :: Text -> Bool
isPing = ("ping" `isPrefixOf`) . toLower

Installing

discord-haskell is on hosted on hackage at https://hackage.haskell.org/package/discord-haskell,

In stack.yaml

extra-deps:
- discord-haskell-1.1.3
- emoji-0.1.0.2

In project.cabal

executable haskell-bot
  main-is:             src/Main.hs
  default-language:    Haskell2010
  ghc-options:         -threaded
  build-depends:       base
                     , text
                     , discord-haskell

For a more complete example with various options go to Installing the Library wiki page

Also take a look at Creating your first Bot for some help setting up your bot token

Emoji

For single character Emoji you can use the unicode name ("eyes", "fire", etc).

For multi-character Emoji you must use the discord format. Type \:emoji: into a discord chat and paste that into the Text

For example :thumbsup::skin-tone-3: is "👍\127997". A custom emoji will look like <name:id_number> or name:id_number.

See examples/ping-pong.hs for a CreateReaction request in use.

Limitations

The following features are not implemented:

  • Voice & Audio
  • Authenticating with a user token

Debugging

Always print the userFacingError Text returned from runDiscord. I use this to record errors that cannot be recovered from.

If something else goes wrong with the library please open an issue. It is helpful, but not always necessary, to attach a log of what's going on when the library crashes.

Assign a handler to the discordOnLog :: Text -> IO () to print info as it happens. Remember to remove sensitive information before posting.

Getting Help

Official discord docs

For a list of rest requests, gateway events, and gateway sendables go to the official discord documentation

The rest requests line up very closely. The documentation lists Get Channel and discord-haskell has GetChannel :: ChannelId -> ChannelRequest Channel. Same for gateway Events.

Examples

The examples were crafted to display a variety of use cases. Read them with care.

Open an Issue

For deeper questions about how the library functions, feel free to open an issue.

Discord server

Coming sometime!