 (defonce the-keepalive (atom false))
 (defonce the-seq (atom nil))
 (defonce reconnect-needed (atom false))
-
-(def default-max-text-message-size (* 64 1024))
 
 (defn disconnect []
   (reset! reconnect-needed false)

  (:import (org.eclipse.jetty.util.ssl SslContextFactory)
           (org.eclipse.jetty.websocket.client WebSocketClient)))

(defonce the-token (atom nil))
(defonce the-gateway (atom nil))
(defonce the-socket (atom nil))

  (reset! the-heartbeat-interval nil))

(defn connect
  ([token functions]
    (connect token functions default-log-events? default-log-function default-max-text-message-size))
  ([token functions log-events?]
    (connect token functions log-events? default-log-function default-max-text-message-size))
  ([token functions log-events? max-text-message-size]
    (connect token functions log-events? default-log-function max-text-message-size))
  ([token functions log-events? log-function max-text-message-size]  
    (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
            (let [client (new WebSocketClient (new SslContextFactory))]
              (.setMaxTextMessageSize (.getPolicy client) max-text-message-size)
              (.start client)
              (ws/connect
                @the-gateway
                :client client
                :on-receive #(let [received (json/read-str %)
                                   logevent (if log-events? (log-function %))
                                   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? (log-function "Sending 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
                                              (log-function "Caught 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))
    (try
      (connect token functions log-events? log-function max-text-message-size)
      (catch java.net.UnknownHostException e 
        (do
          (log-function "Caught exception: " (.getMessage e))
          (Thread/sleep 10000)
          (connect token functions log-events? log-function max-text-message-size))))))

(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})
