Giter VIP home page Giter VIP logo

discord.clj's People

Contributors

codonnell avatar gizmo385 avatar pixelcmtd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

discord.clj's Issues

Duplicated DM help message on command trigger

When triggering the <prefix>help command (auto-handled by the library), it sends two messages instead of one.

My core code is

(ns disclojure.core
  (:gen-class)
  (:require [discord.bot :as bot]))

(defn -main
  "Boots the bot."
  [& _]
  (bot/start))

bot/create-bot throwing NoClassDefFoundError

Trying to set up a notifications bot using this library. Not sure if I'm missing an import or something?

(ns gcloud-monitoring.core
  (:require [ring.adapter.jetty :refer [run-jetty]]
            [ring.util.request]
            [clojure.data.json :as json]
            [discord.http]
            [discord.bot :as bot]
            [discord.types]))

(bot/create-bot "CloudNotifications"
                "!"
                (discord.types/configuration-auth)) => Execution error (NoClassDefFoundError) at org.eclipse.jetty.websocket.common.extensions.fragment.FragmentExtension/<init> (FragmentExtension.java:44).

Improve Storage/Management of Extensions/Extension Documentation

Currently, when extensions are declared, information about those extensions, handlers, and their relevant documentation is maintained in a series of global atoms. This isn't ideal and can cause confusion (see #10) where extensions can be duplicated if files are reloaded without properly clearing out the global atoms.

Ideally, I think we should try and remove this from global state. At the moment, I don't have a great solution to this problem and would love input from others :)

Improve Docs or move them to a /docs/ folder so users can edit them in push requests

Basically what the title says. I'm new to clojure, so I rely on documentation to understand where bugs are coming from. In my testing of this API, I've been running into seemingly simple bugs that I don't understand the nature of, and the lack current documentation definitely doesn't help.

When I get better, maybe I could help with documentation, but because it's done via the permlocked wiki, I can't controbute through a pull request or something.

Attempting to close a DiscordBot fails

If I try to call the close method on an instance of discord.bot.DiscordBot, I get the error IllegalArgumentException No implementation of method: :close of protocol: #'gniazdo.core/Client found for class: clojure.lang.Atom clojure.core/-cache-protocol-fn (core_deftype.clj:583).

I believe the reason is that https://github.com/gizmo385/discord.clj/blob/master/src/discord/gateway.clj#L52 should deref the websocket atom with (ws/close @(:websocket this)). I'd be happy to submit a PR, but it seems a little silly for such a small change.

Thanks for all the work you've put into this! ๐Ÿ‘

Custom documentation "items"

I have a custom handler that handles a set of "formats".

I'd like to document them.

In bot.clj I found about register-extension-docs!, which seems to be for this exact purpose, but... How do one actually use it?

I tried a primitive code with typings as (register-extension-docs! "" "") (with actual values), but I get a HTTP 400 error, with the following body:

:body "{\"embed\": [\"fields\"]}"

Starting a new bot after closing an old bot restarts (maybe?) the old bot

(defn start
  "Starts the bot asynchronously."
  []
  (dosync
    (bot/load-extension-folders!)
    (ref
      (bot/create-bot (config/get-bot-name) (config/get-prefix)))))

(defn stop
  "Stops the bot."
  [client]
  (.close @client))

...

(bot/defcommand working
  [client message]
  "Posts the Star Wars Episode 1 'It's working' gif in the channel"
  (bot/say "https://giphy.com/gifs/9K2nFglCAQClO"))

If I start a bot and call !working it responds perfectly. If I stop that bot and start another, when I call !working it posts the same response twice. If you do it again you get 3 responses and so on. Am I not stopping correctly? I'm relatively new to clojure (and nearly entirely new to discord.clj) so apologies if I'm missing something basic!

Also, thanks for making this!

HTTP 400 randomly

I am getting an HTTP 400 quite randomly when I send some messages. Its reproducible at will though.

20-06-08 16:41:21 gimli ERROR [discord.client:77] - Error sending message: 

clojure.lang.ExceptionInfo: clj-http: status 400 

{:cached nil, :request-time 472, :repeatable? false, 
:protocol-version {:name "HTTP", :major 1, :minor 1}, 
:streaming? true, 
:http-client #object[org.apache.http.impl.client.InternalHttpClient 0x45bff638 "org.apache.http.impl.client.InternalHttpClient@45bff638"], 
:chunked? false, 
:type :clj-http.client/unexceptional-status, 
:reason-phrase "Bad Request", 
:headers {"x-envoy-upstream-service-time" "9", 
                "Server" "cloudflare", 
                "x-ratelimit-reset-after" "5", 
                "Via" "1.1 google", 
                "Content-Type" "application/json", 
                "Content-Length" "21", 
                 "strict-transport-security" "max-age=31536000; includeSubDomains", 
                  "x-ratelimit-limit" "5", 
                  "x-ratelimit-remaining" "4", 
                  "x-ratelimit-reset" "1591634487", 
                  "x-ratelimit-bucket" "80c17d2f203122d936070c88c8d10f33", 
                  "Connection" "close", 
                  "cf-request-id" "033667e7180000df4b73824200000001", 
                   "Set-Cookie" ["__cfduid=d646323f023029fc337c7d79d9e1eed701591634480; expires=Wed, 08-Jul-20 16:41:20 GMT; path=/; domain=.discordapp.com; HttpOnly; SameSite=Lax" "__cfruid=8b7f57ba621570e90aaa72ecff2886c33d034cd0-1591634481; path=/; domain=.discordapp.com; HttpOnly; Secure; SameSite=None"], 
                   "Expect-CT" "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"", "CF-Cache-Status" "DYNAMIC", "CF-RAY" "5a040f51c9dbdf4b-BOM", "Date" "Mon, 08 Jun 2020 16:41:21 GMT"
                  }, 
:orig-content-encoding nil, 
:status 400, 
:length 21, 
:body "{\"embed\": [\"fields\"]}", :trace-redirects []
}

logs-from limit not respected

discord.http/logs-from returns all results regardless of the limit supplied. I haven't checked this that thoroughly, I only had 16 messages and it returned all when I tried limit as 0, 1, 2, or 50.

Bot getting disconnected and not reconnecting

My bot running on my prod machine, once disconnected stays offline forever

[discord.gateway:111] - Event of Type: :reconnect
[discord.gateway:258] - Closing Gateway websocket, not reconnecting (1001).
Exception in thread "async-dispatch-1" org.eclipse.jetty.websocket.api.WebSocketException: RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]
        at org.eclipse.jetty.websocket.common.WebSocketSession.getRemote(WebSocketSession.java:299)

Once this happens, it would be nice if we could periodically try to reconnect and go back online when you could.

stateful macros from discord.bot do not work

Once again, I'm new to clojure, so bear with me. I tried looking for logic errors, but there's so much that I don't understand, I'd have to come back with a better understanding of the language.

Here's my core file:

(ns devbot.core
	(:require [discord.bot :as bot]
		  [discord.http :as http]
		  [discord.config :as config])
	(:gen-class))

(defn say 
	"Repeats the message back to the user"
	[client message]
	(bot/say (:content message)))

(bot/defcommand ping [_ _] 
	"Ping!"
	(bot/say "Pong!"))

(defn -main
	"Creates a new discord bot and supplies a series of extensions to it."
	[& args]
	(let [bot-name (config/get-bot-name)
		prefix (config/get-prefix)]
	  (bot/with-extensions bot-name prefix
		:say say)))

Sorry about the formatting, IntelliJ was sorta mangling the tabbing and spacing.
I've been trying to test the use of inline command definitions and macros. In my testing, the bot worked perfectly with the say command, but not with the ping command. On top of that, standard builtins like the help command doesn't work correctly with say, nor with any functions. The commands simply pass the bot by, with no exceptions or anything printed out onto the screen.

Create documentation for other types of events

The docs only cover message receiving, but there are other events as well. Can the docs cover events like user joining/leaving server, bot joining/leaving server and other useful events as well?

Client message receive and send go-loops never stop

The go-loops at https://github.com/gizmo385/discord.clj/blob/master/src/discord/client.clj#L63-L78 need to check for when their respective channels have been closed to stop recurring. As it is now, once these channels are closed, the go-loops will take nil values forever. To verify the behavior, you can do this at the repl:

=> (require '[clojure.core.async :as a])
nil
=> (def c (a/chan))
#'discord.core/c
=> (a/go-loop [] (let [v (a/<! c)] (println v) (recur)))
#object[clojure.core.async.impl.channels.ManyToManyChannel 0x55d32427 "clojure.core.async.impl.channels.ManyToManyChannel@55d32427"]
=> (a/>!! c "hello")
hello
true
=> (a/close! c)
nil
nil
nil
...

I'll put up a PR with what I think is a reasonable fix. Appreciate the work you've put into this project!

Disconnection causes program to hang

The server that hosts my bot that uses your library often disconnects. This causes an error above 1001. Right now the bot doesn't reconnect or exit the program. https://github.com/gizmo385/discord.clj/blob/master/src/discord/gateway.clj#L258 which causes my bot to hang and then i have to log into my server and restart it manually.

WARN [discord.gateway:259] - Closing Gateway websocket, not reconnecting (1006).
Exception in thread "async-dispatch-7" org.eclipse.jetty.websocket.api.WebSocketException: RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]
	at org.eclipse.jetty.websocket.common.WebSocketSession.getRemote(WebSocketSession.java:299)
	at gniazdo.core$connect_with_client$reify__11265.send_msg(core.clj:138)
	at discord.gateway.DiscordGateway.send_message(gateway.clj:62)
	at discord.gateway$send_heartbeat.invokeStatic(gateway.clj:204)
	at discord.gateway$send_heartbeat.invoke(gateway.clj:202)
	at discord.gateway$connect_to_gateway$fn__15913$state_machine__5591__auto____15932$fn__15934.invoke(gateway.clj:292)
	at discord.gateway$connect_to_gateway$fn__15913$state_machine__5591__auto____15932.invoke(gateway.clj:292)
	at clojure.core.async.impl.ioc_macros$run_state_machine.invokeStatic(ioc_macros.clj:973)
	at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:972)
	at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invokeStatic(ioc_macros.clj:977)
	at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:975)
	at clojure.core.async$ioc_alts_BANG_$fn__5794.invoke(async.clj:384)
	at clojure.core.async$do_alts$fn__5740$fn__5743.invoke(async.clj:253)
	at clojure.core.async.impl.channels.ManyToManyChannel$fn__509.invoke(channels.clj:265)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
^C

I made the changes

(if (> 1001 status)
                      (do
                        (timbre/warnf "Socket closed for unexpected reason (%d): %s" status reason)
                        (timbre/warnf "Attempting to reconnect to websocket...")
                        (reconnect-gateway gateway))
                      (do (timbre/warnf "Closing Gateway websocket, not reconnecting (%d)." status)
                          (System/exit 1)))

which causes the program to exit if an abnormal error occurs.

WARN [discord.gateway:259] - Closing Gateway websocket, not reconnecting (1006).
Exception in thread "async-dispatch-6" org.eclipse.jetty.websocket.api.WebSocketException: RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]
	at org.eclipse.jetty.websocket.common.WebSocketSession.getRemote(WebSocketSession.java:299)
	at gniazdo.core$connect_with_client$reify__11265.send_msg(core.clj:138)
	at discord.gateway.DiscordGateway.send_message(gateway.clj:62)
	at discord.gateway$send_heartbeat.invokeStatic(gateway.clj:204)
	at discord.gateway$send_heartbeat.invoke(gateway.clj:202)
	at discord.gateway$connect_to_gateway$fn__15913$state_machine__5591__auto____15932$fn__15934.invoke(gateway.clj:293)
	at discord.gateway$connect_to_gateway$fn__15913$state_machine__5591__auto____15932.invoke(gateway.clj:293)
	at clojure.core.async.impl.ioc_macros$run_state_machine.invokeStatic(ioc_macros.clj:973)
	at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:972)
	at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invokeStatic(ioc_macros.clj:977)
	at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:975)
	at clojure.core.async$ioc_alts_BANG_$fn__5794.invoke(async.clj:384)
	at clojure.core.async$do_alts$fn__5740$fn__5743.invoke(async.clj:253)
	at clojure.core.async.impl.channels.ManyToManyChannel$fn__509.invoke(channels.clj:265)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
2020-04-03 22:42:58.216:WARN:oejut.QueuedThreadPool:Thread-2: WebSocketClient@282234594{STOPPING,8<=8<=200,i=0,q=1} Couldn't stop Thread[WebSocketClient@282234594-13,5,main]

is it all right if i make a PR?

Heartbeat loop isn't halted along with the gateway

After closing the gateway (and its websocket), the heartbeat loop continues running, resulting in this error a bit afterwards:

Exception in thread "async-dispatch-9" org.eclipse.jetty.websocket.api.WebSocketException: RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]
        at org.eclipse.jetty.websocket.common.WebSocketSession.getRemote(WebSocketSession.java:299)
        at gniazdo.core$connect_with_client$reify__20760.send_msg(core.clj:138)
        at discord.gateway.DiscordGateway.send_message(gateway.clj:62)
        at discord.gateway$send_heartbeat.invokeStatic(gateway.clj:205)
        at discord.gateway$send_heartbeat.invoke(gateway.clj:203)
        at discord.gateway$connect_to_gateway$fn__25400$state_machine__13838__auto____25417$fn__25419.invoke(gateway.clj:292)
        at discord.gateway$connect_to_gateway$fn__25400$state_machine__13838__auto____25417.invoke(gateway.clj:292)
        at clojure.core.async.impl.ioc_macros$run_state_machine.invokeStatic(ioc_macros.clj:973)
        at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:972)
        at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invokeStatic(ioc_macros.clj:977)
        at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:975)
        at clojure.core.async.impl.ioc_macros$take_BANG_$fn__13856.invoke(ioc_macros.clj:986)
        at clojure.core.async.impl.channels.ManyToManyChannel$fn__8788.invoke(channels.clj:265)
        at clojure.lang.AFn.run(AFn.java:22)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

I'm happy to submit a PR fixing this if you'd like.

Is there a straightforward way to send a message that isn't a reply?

I'm looking to set up a reminder such that the bot will post a message to a specific channel on a specific server on a schedule.

I see that say needs to be called within the context of build-handler-fn and can't specify a channel directly. I also see that say* looks like it can specify a channel but is private. I tried debugging to check out a message's channel and saw that it only had an id. Could I potentially use that id or just save that entire channel object if I tried to make a say function that worked outside of build-handler-fn?

Is there already a way to do what I'm looking for or maybe there's a better way to go about it?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.