Skip to content

Instantly share code, notes, and snippets.

@pmonks
Last active July 7, 2024 00:58
Show Gist options
  • Save pmonks/4176180a32272665debe1fb5d019caa8 to your computer and use it in GitHub Desktop.
Save pmonks/4176180a32272665debe1fb5d019caa8 to your computer and use it in GitHub Desktop.
Super simple example of a Discord slash command implemented in Clojure, that provides a /echo command that simply echos its input. Uses the discljord and slash libraries.
;
; Copyright © 2024 Peter Monks
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; SPDX-License-Identifier: Apache-2.0
;
{:deps
{org.clojure/clojure {:mvn/version "1.11.3"}
com.github.discljord/discljord {:mvn/version "1.3.1"}
com.github.johnnyjayjay/slash {:mvn/version "0.6.0-SNAPSHOT"}
; Transitive dependency version overrides
org.clojure/core.specs.alpha {:mvn/version "0.4.74"}
org.clojure/spec.alpha {:mvn/version "0.5.238"}
org.clojure/core.async {:mvn/version "1.6.681"}
http-kit/http-kit {:mvn/version "2.8.0"}
stylefruits/gniazdo {:mvn/version "1.2.2"}
org.eclipse.jetty.websocket/websocket-client {:mvn/version "9.4.55.v20240627"}
org.eclipse.jetty.websocket/websocket-common {:mvn/version "9.4.55.v20240627"}
org.eclipse.jetty.websocket/websocket-api {:mvn/version "9.4.55.v20240627"}}
:aliases
{:outdated {:deps {com.github.liquidz/antq {:mvn/version "RELEASE"}}
:main-opts ["-m" "antq.core"]}}}
;
; Copyright © 2024 Peter Monks
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; SPDX-License-Identifier: Apache-2.0
;
; To run, add a valid Discord bot token (from the Discord Developer portal), then:
;
; clj -i ./discljord_slash_echo_bot.clj
;
(require '[discljord.messaging :as rest]
'[discljord.connections :as gateway]
'[discljord.events :as events]
'[clojure.core.async :as a]
'[slash.core :as sc]
'[slash.command :as cmd]
'[slash.command.structure :as cmds]
'[slash.response :as rsp]
'[slash.gateway :as sg])
(def api-token "discord API token")
(defn discljord-deref
"discljord defaults to 'fire & forget' API calls, which silently swallows errors. This corrects that behaviour."
[discljord-api-result]
(if (instance? java.lang.Throwable @discljord-api-result)
(throw @discljord-api-result)
@discljord-api-result))
(def echo-command
(cmds/command
"echo"
"Echoes your input"
:options
[(cmds/option "input" "Your input" :string :required true)]))
(cmd/defhandler echo-handler
["echo"]
_interaction
[input]
(println "ℹ️ Echo handler got message" input)
(rsp/channel-message {:content input}))
(cmd/defpaths command-paths
#'echo-handler)
(let [rest-conn (rest/start-connection! api-token)
event-channel (a/chan 100)
gateway-conn (gateway/connect-bot! api-token event-channel :intents #{})
app-id (:id (discljord-deref (rest/get-current-application-information! rest-conn)))
s-event-handler (-> sc/route-interaction
(partial (assoc sg/gateway-defaults :application-command command-paths))
(sg/wrap-response-return (fn [id token {:keys [type data]}]
(discljord-deref (rest/create-interaction-response! rest-conn id token type :data data)))))]
(println "ℹ️ Registering commands...")
(discljord-deref (rest/bulk-overwrite-global-application-commands! rest-conn app-id [echo-command]))
(println "ℹ️ Starting message pump (note: this blocks indefinitely)...")
(events/message-pump! event-channel (partial events/dispatch-handlers {:interaction-create [#(s-event-handler %2)]})))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment