discord-haskell: Write bots for Discord in Haskell

[ library, mit, network, program ] [ Propose Tags ]

Functions and data types to write discord bots. Official discord docs https://discord.com/developers/docs/reference.

See the project readme for quickstart notes https://github.com/aquarial/discord-haskell#discord-haskell-

[Skip to Readme]
Versions [RSS] [faq] 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
Change log changelog.md
Dependencies aeson, async, base (==4.*), base64-bytestring, bytestring, containers, data-default, discord-haskell, emoji (==, http-client, iso8601-time, JuicyPixels, MonadRandom, mtl, req, safe-exceptions, scientific, text, time, unliftio, unordered-containers, vector, websockets, wuss [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 2022-01-12T07:30:38Z
Distributions NixOS:1.8.8
Executables ping-pong
Downloads 13953 total (105 in the last 30 days)
Rating 2.5 (votes: 5) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2022-01-12 [all 1 reports]


[Index] [Quick Jump]


Maintainer's Corner

For package maintainers and hackage trustees


Readme for discord-haskell-1.11.0

[back to package description]

discord-haskell CI Status Hackage version Discord server


Build that discord bot in Haskell! Also checkout the calamity haskell library for a more advanced interface than discord-haskell.


Local Documentation

Find docs on features, metadata, and parts is found in ./docs/README.md#Documentation

Discord Server

Current project discord server: https://discord.gg/eaRAGgX3bK

Ask questions, get updates, request features, etc

Official Discord Documentation

The official discord documentation lists the rest requests, gateway events, and gateway sendables. The library matches very closely.

For example: Get Channel and discord-haskell has a rest request ADT including [GetChannel :: ChannelId -> ChannelRequest Channel]. Similar matching exists for gateway Events.

Open an Issue

If something goes wrong: check the error message, (optional: check log file), make sure you have the most recent version, ask on discord, or open a github issue.

Implementation and Progress


This is an example bot that replies "pong" to messages that start with "ping". Also checkout the other examples for things like state management.

{-# LANGUAGE OverloadedStrings #-}  -- allows "string literals" to be Text
import Control.Monad (when, void)
import Data.Text (isPrefixOf, toLower, Text)
import qualified Data.Text.IO as TIO
import UnliftIO.Concurrent
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
             , discordOnLog = \s -> TIO.putStrLn s
             , discordForkThreadForEvents = True }
    TIO.putStrLn userFacingError
    -- userFacingError is an unrecoverable error
    -- put normal 'cleanup' code in discordOnEnd (see examples)

eventHandler :: Event -> DiscordHandler ()
eventHandler event = case event of
       MessageCreate m -> when (not (fromBot m) && isPing m) $ do
               void $ restCall (R.CreateReaction (messageChannelId m, messageId m) "eyes")
               threadDelay (2 * 10^6)
               void $ restCall (R.CreateMessage (messageChannelId m) "Pong!")
       _ -> return ()

fromBot :: Message -> Bool
fromBot = userIsBot . messageAuthor

isPing :: Message -> Bool
isPing = ("ping" `isPrefixOf`) . toLower . messageContent
-- ping-pong.cabal

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

Biggest TODOs

  • [ ] Add slash commands issue
  • [ ] APIv9 issue
  • [ ] Event type includes roles and other cached info
  • [ ] higher level bot interface? easier to add state and stuff
  • [x] rewrite eventloop issue


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

In stack.yaml

- emoji-
- discord-haskell-VERSION

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