Skip to content

Commit

Permalink
Forgive me
Browse files Browse the repository at this point in the history
  • Loading branch information
hagmonk committed May 19, 2017
0 parents commit c348598
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/target
/classes
/checkouts
pom.xml
pom.xml.asc
*.jar
*.class
/.lein-*
/.nrepl-port
.hgignore
.hg/
/repl-bot.iml
/repl-bot-1.iml
.idea/*
1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Go nuts
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# repl-bot

An experiment inside the clojurians Discord that should never see the light of day.
14 changes: 14 additions & 0 deletions project.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(defproject repl-bot "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.8.0"]
[clj-http "3.5.0"]
[stylefruits/gniazdo "1.0.0"]
[environ/environ.core "0.3.1"]
[org.clojure/data.json "0.2.6"]
[org.clojure/tools.nrepl "0.2.13"]]
:main ^:skip-aot repl-bot.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
41 changes: 41 additions & 0 deletions src/repl_bot/core.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
(ns repl-bot.core
(:require [repl-bot.discord :as discord]
[environ.core :refer [env]]
[clojure.tools.nrepl :as repl])
(:gen-class))

(defonce repl-agent (agent (let [{:keys [nrepl-host nrepl-port]
:or {nrepl-host "localhost" nrepl-port 9876}} env]
(repl/connect :host nrepl-host :port nrepl-port))))

(defn log-event [type data]
(println "\nReceived: " type " -> " data))

(defn repl-send-and-receive! [message]
(send-off repl-agent #(-> %
(repl/client 5000)
(repl/message {:op "eval" :code message})))
; probably racy ...
(if (await-for 5000 repl-agent)
(-> @repl-agent
repl/response-values
pr-str)
"Message timed out"))

(defn repl-command [type data]
(let [command (get data "content")
channel (get data "channel_id")]
(when (and (= (some-> channel str Long/parseLong) 315213511120912386)
(not (re-find #"^\s*=>" command)))
(discord/answer data (repl-send-and-receive! command)))))

; channel-id 315213511120912386
(defn -main [& args]
(let [{:keys [token nrepl-host nrepl-port] :or {nrepl-host "localhost"
nrepl-port 9876}} env]

(discord/connect token
{
"MESSAGE_CREATE" [repl-command]
"ALL_OTHER" [log-event]}
true)))
94 changes: 94 additions & 0 deletions src/repl_bot/discord.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
(ns repl-bot.discord
(:gen-class)
(:require [clj-http.client :as http]
[clojure.data.json :as json]
[gniazdo.core :as ws]))

; !!!!
; stolen wholesale from https://github.com/yotsov/clj-discord/blob/master/src/clj_discord/core.clj
; !!!!


(defonce the-token (atom nil))
(defonce the-gateway (atom nil))
(defonce the-socket (atom nil))
(defonce the-heartbeat-interval (atom nil))
(defonce the-keepalive (atom false))
(defonce the-seq (atom nil))
(defonce reconnect-needed (atom false))

(defn disconnect []
(reset! reconnect-needed false)
(reset! the-keepalive false)
(if (not (nil? @the-socket)) (ws/close @the-socket))
(reset! the-token nil)
(reset! the-gateway nil)
(reset! the-socket nil)
(reset! the-seq nil)
(reset! the-heartbeat-interval nil))

(defn connect [token functions log-events]
(disconnect)
(reset! the-keepalive true)
(reset! the-token (str "Bot " token))
(reset! the-gateway (str
(get
(json/read-str
(:body (http/get "https://discordapp.com/api/gateway"
{:headers {:authorization @the-token}})))
"url")
"?v=6&encoding=json"))
(reset! the-socket
(ws/connect
@the-gateway
:on-receive #(let [received (json/read-str %)
logevent (if log-events (println "\n" %))
op (get received "op")
type (get received "t")
data (get received "d")
seq (get received "s")]
(if (= 10 op) (reset! the-heartbeat-interval (get data "heartbeat_interval")))
(if (not (nil? seq)) (reset! the-seq seq))
(if (not (nil? type)) (doseq [afunction (get functions type (get functions "ALL_OTHER" []))] (afunction type data))))))
(.start (Thread. (fn []
(try
(while @the-keepalive
(if (nil? @the-heartbeat-interval)
(Thread/sleep 100)
(do
(if log-events (println "\nSending heartbeat " @the-seq))
(ws/send-msg @the-socket (json/write-str {:op 1, :d @the-seq}))
(Thread/sleep @the-heartbeat-interval)
)))
(catch Exception e (do
(println "\nCaught exception: " (.getMessage e))
(reset! reconnect-needed true)
))))))
(Thread/sleep 1000)
(ws/send-msg @the-socket (json/write-str {:op 2, :d {"token" @the-token
"properties" {"$os" "linux"
"$browser" "clj-discord"
"$device" "clj-discord"
"$referrer" ""
"$referring_domain" ""}
"compress" false}}))
(while (not @reconnect-needed) (Thread/sleep 1000))
(connect token functions log-events))

(defn post-message [channel_id message]
(http/post (str "https://discordapp.com/api/channels/" channel_id "/messages")
{:body (json/write-str {:content message
:nonce (str (System/currentTimeMillis))
:tts false})
:headers {:authorization @the-token}
:content-type :json
:accept :json}))

(defn post-message-with-mention [channel_id message user_id]
(post-message channel_id (str "<@" user_id ">" message)))

(defn answer [data answer]
(post-message-with-mention
(get data "channel_id")
(str "=> " answer)
(get (get data "author") "id")))

0 comments on commit c348598

Please sign in to comment.