Git Product home page Git Product logo

discordcr's Introduction

docs

discordcr

(The "cr" stands for "creative name".)

discordcr is a minimalist Discord API library for Crystal, designed to be a complement to discordrb for users who want more control and performance and who care less about ease-of-use.

discordcr isn't designed for beginners to the Discord API - while experience with making bots isn't required, it's certainly recommended. If you feel overwhelmed by the complex documentation, try discordrb first and then check back.

Unlike many other libs which handle a lot of stuff, like caching or resolving, themselves automatically, discordcr requires the user to do such things manually. It also doesn't provide any advanced abstractions for REST calls; the methods perform the HTTP request with the given data but nothing else. This means that the user has full control over them, but also full responsibility. discordcr does not support user accounts; it may work but likely doesn't.

Installation

Add this to your application's shard.yml:

dependencies:
  discordcr:
    github: discordcr/discordcr

Usage

An example bot can be found here. More examples will come in the future.

A short overview of library structure: the Client class includes the REST module, which handles the REST parts of Discord's API; the Client itself handles the gateway, i. e. the interactive parts such as receiving messages. It is possible to use only the REST parts by never calling the #run method on a Client, which is what does the actual gateway connection.

The example linked above has an example of an event (on_message_create) that is called through the gateway, and of a REST call (client.create_message). Other gateway events and REST calls work much in the same way - see the documentation for what specific events and REST calls do.

Caching is done using a separate Cache class that needs to be added into clients manually:

client = Discord::Client.new # ...
cache = Discord::Cache.new(client)
client.cache = cache

Resolution requests for objects can now be done on the cache object instead of directly over REST, this ensures that if an object is needed more than once there will still only be one request to Discord. (There may even be no request at all, if the requested data has already been obtained over the gateway.) An example of how to use the cache once it has been instantiated:

# Get the username of the user with ID 66237334693085184
user = cache.resolve_user(66237334693085184_u64)
user = cache.resolve_user(66237334693085184_u64) # won't do a request to Discord
puts user.username

Apart from this, API documentation is also available, at https://discordcr.github.io/discordcr/doc/v0.4.0/.

Contributing

  1. Fork it (https://github.com/discordcr/discordcr/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

  • meew0 - creator, maintainer
  • RX14 - Crystal expert, maintainer

discordcr's People

Contributors

andrewzah avatar daniel-worrall avatar deingithub avatar geopjr avatar greenbigfrog avatar hedgehog1029 avatar ivan2002 avatar lucasintel avatar meew0 avatar panissupraomnia avatar pixelinc avatar rx14 avatar snapcase avatar swarley avatar wooster0 avatar z64 avatar zatherz 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

discordcr's Issues

Guild Members and Users not being cached

In events such as GUILD_CREATE (and others), discordcr will not populate @users and @members as expected.


discordrb illustrates the missing behavior on GUILD_CREATE:

  1. GUILD_CREATE in the gateway case is called, which follows up with Cache#ensure_server.

https://github.com/meew0/discordrb/blob/master/lib/discordrb/cache.rb#L163

  1. #ensure_server instances a new server, whose #initialize calls Server#process_members

https://github.com/meew0/discordrb/blob/master/lib/discordrb/data.rb#L2795-L2801

  1. This calls Member#initialize, which caches the User

https://github.com/meew0/discordrb/blob/master/lib/discordrb/data.rb#L541


discordcr's cache behavior processes the guild, the roles, and the channels, but not members:

https://github.com/meew0/discordcr/blob/master/src/discordcr/client.cr#L387-L404

It would appear that it is very likely that resolve_member is almost always making a REST call for members we've could have already known about.

The GuildMember (or similar User-bearing class) #cache overload also doesn't cache the User object that GuildMember carries. Whether or not this is actually desired, I'm not sure.

https://github.com/meew0/discordcr/blob/master/src/discordcr/cache.cr#L152-L156

Minor note, but it would be nice to have getters for the Cache's attributes for doing work across all of the cached data at once.

HTTP Concurrency improvements

Under load, it's easy to get rate limited:

client.on_message_create do |payload|
  if payload.content == "!!run"
    parallel(
      client.create_message(ID, "1"),
      client.create_message(ID, "2"),
      client.create_message(ID, "3"),
      client.create_message(ID, "4"),
      client.create_message(ID, "5"),
      client.create_message(ID, "6")
    )
  end
end
I, [2018-02-06 23:49:48 -05:00 #3549]  INFO -- discordcr: [HTTP OUT] GET /gateway (0 bytes)
I, [2018-02-06 23:49:49 -05:00 #3549]  INFO -- discordcr: [HTTP IN] 200 OK (35)
I, [2018-02-06 23:49:49 -05:00 #3549]  INFO -- discordcr: [Client] Received READY, v: 6
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP OUT] POST /channels/345687437722386433/messages (28 bytes)
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP OUT] POST /channels/345687437722386433/messages (28 bytes)
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP OUT] POST /channels/345687437722386433/messages (28 bytes)
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP OUT] POST /channels/345687437722386433/messages (28 bytes)
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP OUT] POST /channels/345687437722386433/messages (28 bytes)
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP OUT] POST /channels/345687437722386433/messages (28 bytes)
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP IN] 200 OK (455)
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP IN] 429 TOO MANY REQUESTS (91)
W, [2018-02-06 23:49:55 -05:00 #3549]  WARN -- discordcr: Pausing requests for channels_cid_messages in 345687437722386433 for 4.981
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP IN] 200 OK (455)
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP IN] 200 OK (455)
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP IN] 200 OK (455)
I, [2018-02-06 23:49:55 -05:00 #3549]  INFO -- discordcr: [HTTP IN] 200 OK (455)
W, [2018-02-06 23:49:55 -05:00 #3549]  WARN -- discordcr: Pausing requests for channels_cid_messages in 345687437722386433 for 00:00:06
I, [2018-02-06 23:50:06 -05:00 #3549]  INFO -- discordcr: [HTTP OUT] POST /channels/345687437722386433/messages (28 bytes)
I, [2018-02-06 23:50:06 -05:00 #3549]  INFO -- discordcr: [HTTP IN] 200 OK (455)

I think this is pretty tame, and while rate limiting would/should probably be done on the bots end so users can't spam it that much, I think this can be improved. I'm not sure what the best way forward is, though; thought I would open an issue for discussion at some point.

Iterators for paginated endpoints

It would be great if we provided iterators for paginated endpoints, namely for traversing channel message history to backfill logs or guild members for stateless apps over REST.

What would be the preferred API for this? For example, should we provide a different method/overload, something like:

def get_channel_messages(channel_id, start_message_id = 1_u64, direction = Direction::Down, limit = nil)

and similar for other endpoints?

"An exception occurred during message parsing!"

I got this as an error in the console. And it says I should report it.

The things I censored here are just the ID and the GUILD_ID. I replaced this with "censored"
I hope its still useful

E, [2018-01-09 09:05:52 +01:00 #168] ERROR -- discordcr: An exception occurred during message parsing! Please report this.
Missing json attribute: username at 1:1
(pertaining to previous exception) Raised with packet:
{"t":"GUILD_BAN_ADD","s":5,"op":0,"d":{"user":{"username":"dorit","id":"censored","discriminator":"3413","bot":true,"avatar":null},"guild_id":"censored"}}

Im very sure this happened while client.create_message or client.create_guild_ban
But I could still see the message and he got banned successfully.

Does this work? What version of crystal is required?

I'm having some troubles getting this lib to work correctly. Firstly it's telling me that MemoryIO is not supported, so I went in and changed it to IO::Memory since it was changed MemoryIO -> IO::Memory. Though, I still seem to be getting some errors from the JSON PullParser, telling me that json.null is not a method for IO::Memory.

Still very new to Crystal, so I'm not entirely sure what's going on. Would love some help, or info as to what I should do.

Update pong example to reflect changes to crystal

in the ping example, the require line no longer works.
I have gotten this require to work: require "../lib/discordcr/src/discordcr"
the change in shard install location is detailed in issue #3897 on the crystal github repo

Voice heartbeat fiber not stopped after closing connection

Disconnecting from voice by sending a status update and closing the socket:

client.voice_state_update(guild, nil, false, false)
voice_client.close

results in the following traceback:

Unhandled exception in spawn:
Closed socket (IO::Error)
0x4e6e6b: *CallStack::unwind:Array(Pointer(Void)) at ??
0x647d30: check_open at /usr/lib/crystal/http/web_socket.cr 61:5
0x647cd8: send at /usr/lib/crystal/http/web_socket.cr 64:5
0x646de5: send at /home/snapcase/devel/crystal/wat/lib/discordcr/src/discordcr/websocket.cr 35:5
0x6a2c72: heartbeat_loop at /home/snapcase/devel/crystal/wat/lib/discordcr/src/discordcr/voice.cr 102:11
0x4e2f49: ??? at /usr/lib/crystal/kernel.cr 0:3
0x503e2e: run at /usr/lib/crystal/fiber.cr 255:3
0x4d49f6: ~proc2Proc(Fiber, (IO::FileDescriptor | Nil)) at /usr/lib/crystal/concurrent.cr 0:3
0x0: ??? at ??

which seems to be Discord::VoiceClient#heartbeat_loop trying to keep the connection alive after disconnecting.

(Crystal 0.34) Error: wrong number of block argument's arguments (given 1, expected 2)

Got this error while trying to run ping.cr:

In lib/discordcr/src/discordcr/websocket.cr:45:18

 45 | @websocket.on_close(&handler)
                 ^-------
Error: wrong number of block argument's arguments (given 1, expected 2)

I'm running on WSL Ubuntu 18.04, using Crystal version 0.34.0. This looks like another issue with 0.34.0 -- specifically, the changes made to HTTP::WebSocket.

I got discordcr working more or less working by changing Discord::WebSocket's on_close method to

def on_close(&handler : HTTP::WebSocket::CloseCode, String ->)
   @websocket.on_close(&handler)
end

This led to another similar error on line 160 of client.cr, so I made similar changes to line 160 and the on_close method in this file:

# line 160
websocket.on_close(&->on_close(HTTP::WebSocket::CloseCode, String))

# line 165
private def on_close(close_code : HTTP::WebSocket::CloseCode, message : String)

..but I'd be lying if I said I had any idea what I was doing. I've never properly used Crystal or any Discord bot library, so I'm sure there's more to be done than this.

Websocket.on_close want's a CloseCode now

https://crystal-lang.org/api/0.35.1/HTTP/WebSocket.html#on_close(&on_close:CloseCode,String-%3E)-instance-method

In lib/discordcr/src/discordcr/mappings/channel.cr:16:5

 16 | JSON.mapping(
      ^
Warning: expanding macro


There was a problem expanding macro 'mapping'

Called macro defined in /usr/share/crystal/src/json/mapping.cr:232:3

 232 | macro mapping(**_properties_)

Which expanded to:

 > 1 |     ::JSON.mapping({type: {type: MessageType, converter: MessageTypeConverter}, content: String, id: Snowflake, channel_id: Snowflake, author: User, timestamp: {type: Time, converter: TimestampConverter}, tts: Bool, mention_everyone: Bool, mentions: Array(User), mention_roles: Array(Snowflake), attachments: Array(Attachment), embeds: Array(Embed), pinned: ::Union(Bool, ::Nil), reactions: ::Union(Array(Reaction), ::Nil), activity: ::Union(Activity, ::Nil)})
   2 |   
Warning: Deprecated JSON.mapping. use JSON::Serializable instead (the legacy behaviour is also available in a shard at github:crystal-lang/json_mapping.cr)

A total of 1 warnings were found.
Showing last frame. Use --error-trace for full trace.

In lib/discordcr/src/discordcr/websocket.cr:45:18

 45 | @websocket.on_close(&handler)
                 ^-------
Error: wrong number of block argument's arguments (given 1, expected 2)

Exception during parsing all messages from Penguin.bot on all servers

`Missing JSON attribute: mention_roles
parsing Discord::Gateway::MessageUpdatePayload at 1:1 (JSON::MappingError)
from lib/discordcr/src/discordcr/mappings/gateway.cr:0:7 in 'initialize'
from lib/discordcr/src/discordcr/mappings/gateway.cr:302:7 in 'new'
from /usr/lib/crystal/json/from_json.cr:13:3 in 'from_json'
from lib/discordcr/src/discordcr/client.cr:550:19 in 'handle_dispatch'
from lib/discordcr/src/discordcr/client.cr:195:13 in '->'
from /usr/lib/crystal/fiber.cr:255:3 in 'run'
from /usr/lib/crystal/fiber.cr:29:34 in '->'
from ???

(pertaining to previous exception) Raised with packet:
Discord::WebSocket::Packet(@opcode=0_i64 @sequence=266_i64 @DaTa="{"id":"466213529544949765","embeds":[{"url":"https://api.penguin.bot/uploads/cf5b6d46d0cdc253b2adbbbbdc8ea394bc82f2fcaf62f5e18a8fcfa0c6c5f42e.gif","type":"rich","image":{"width":262,"url":"https://api.penguin.bot/uploads/cf5b6d46d0cdc253b2adbbbbdc8ea394bc82f2fcaf62f5e18a8fcfa0c6c5f42e.gif","proxy_url":"https://images-ext-2.discordapp.net/external/oQ6qV-db7ZysEqVOPFXmShu6_Nh5_g_W_maJoRAsRc4/https/api.penguin.bot/uploads/cf5b6d46d0cdc253b2adbbbbdc8ea394bc82f2fcaf62f5e18a8fcfa0c6c5f42e.gif","height":264},"footer":{"text":"BlobCodes @ 2:07 PM - 7/10/2018","proxy_icon_url":"https://images-ext-2.discordapp.net/external/PBDXGfw-puAgmf3B0Ib2tAlchwEPugAlm0XsFg9E3L0/%3Fsize%3D256/https/cdn.discordapp.com/avatars/96967924798992384/fbe3b94ae3db0e099890075f9dbe2cab.png","icon_url":"https://cdn.discordapp.com/avatars/96967924798992384/fbe3b94ae3db0e099890075f9dbe2cab.png?size=256"},"color":2718207}],"channel_id":"362994634349215754","guild_id":"362992013366394880"}" @event_type="MESSAGE_UPDATE")
E, [2018-07-10 14:09:16 +02:00 #2196] ERROR -- discordcr: [Client] An exception occurred during message parsing! Please report this.
Missing JSON attribute: mention_roles
parsing Discord::Gateway::MessageUpdatePayload at 1:1 (JSON::MappingError)
from lib/discordcr/src/discordcr/mappings/gateway.cr:0:7 in 'initialize'
from lib/discordcr/src/discordcr/mappings/gateway.cr:302:7 in 'new'
from /usr/lib/crystal/json/from_json.cr:13:3 in 'from_json'
from lib/discordcr/src/discordcr/client.cr:550:19 in 'handle_dispatch'
from lib/discordcr/src/discordcr/client.cr:195:13 in '->'
from /usr/lib/crystal/fiber.cr:255:3 in 'run'
from /usr/lib/crystal/fiber.cr:29:34 in '->'
from ???

(pertaining to previous exception) Raised with packet:
Discord::WebSocket::Packet(@opcode=0_i64 @sequence=275_i64 @DaTa="{"id":"466214321416962058","embeds":[{"type":"rich","description":"<:_:430096348348547072> <@!96967924798992384>: Your balance is 1,000 gold.\n\nClick here and upvote for 500 free gold every 24h.","color":15844367}],"channel_id":"362994634349215754","guild_id":"362992013366394880"}" @event_type="MESSAGE_UPDATE")`

client.status_update does not seem to work

  game = Discord::GamePlaying.new(name: "Test game")
  client.status_update(status: "idle", game: game, afk: false, since: 0_i64)

This code is not working at all. My bot is not "idle" and the game is not set. What am I doing wrong?

Multiple Heartbeat Fibers

It would appear it is possible for multiple heartbeat fibers to be spawned. It seems as though whenever a client reconnects gracefully (handle a new HELLO), the old heartbeat fiber isn't re-used / a new one isn't put in its place, etc.

Observe the timestamps here on this long-running bot:

W, [2017-08-07 14:14:02 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:02 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:02 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:02 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:02 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:11 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:11 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:11 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:11 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:11 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:11 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:18 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:18 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:18 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}
W, [2017-08-07 14:14:19 +0000 #27020]  WARN -- discordcr: Unsupported message: {"t":null,"s":null,"op":11,"d":null}

Likely relevant code:
https://github.com/meew0/discordcr/blob/master/src/discordcr/client.cr#L228-L250

Unhandled exception: closed socket

dcr has mostly been running really stable for me. The only thing it won't recover from now and then is:

Unhandled exception in spawn: 
Closed socket (IO::Error) 
 from /usr/share/crystal/src/http/web_socket.cr:60:5 in 'check_open' 
 from /usr/share/crystal/src/http/web_socket.cr:64:5 in 'send' 
 from lib/discordcr/src/discordcr/websocket.cr:35:5 in 'send' 
 from lib/discordcr/src/discordcr/client.cr:310:7 in 'status_update' 
 from src/discordtipbot/discordbot.cr:265:5 in 'update_game' 
 from /usr/share/crystal/src/fiber.cr:255:3 in 'run' 
 from /usr/share/crystal/src/concurrent.cr:0:3 in '~proc2Proc(Fiber, (IO::FileDescriptor | Nil))' 
 from ??? 

(TBH I haven't had time to update to latest yet, but AFAICT nothing which could possible relate to this error has changed: greenbigfrog/discordcr@type-fix...meew0:master )

Stuff for parsing mentions

proposed interface:

parse_mentions(str) do |content|
  case content
  when Discordcr::Mention
    # Mention
  when String
    # message hunk
  end
end

Might want a few fancier wrappers around it if required.

Inquiry: Add Ctx as dependency, or stdlib

Ctx is a small library I put together for my own needs, and thinking about it I think it may fit to has it as a standard library feature, or a dependency that can be optionally require'd.

https://github.com/z64/ctx

There are closed issues rejecting a command framework: This isn't one. This is something that can be used to build a "command bot", but ultimately, any serious bot will need this kind of functionality to conditionally run event handlers based on lazily evaluated properties.

In my opinion this is still "lowest common denominator" of any kind of command framework that could be built on top of discordcr, and what initially made me (and others I've talked to) hesitant to start using it - I didn't want to use messy case paths, or break/next out of the blocks on conditionals in a non-DRY way, or not having those conditions able to change lazily, especially since Crystal is compiled.

Here's a snippet of usage from the README:

# Instance a context to use with arbitrary MESSAGE_CREATE events
owner   = Ctx::Context.message_create { |m| m.author.id == 120571255635181568 }
content = Ctx::Context.message_create { |m| m.content.includes? "new fone" }

# Create the handler that matches both contexts
client.message_create(owner, content) do |payload|
  client.create_message(payload.channel_id, "who dis?")
end

Note that I do define a #command method, as it allowed for the fastest creation of the most simple kind of context parsing, and again suited my own needs. I'm fine with removing it, or making any other adjustments as needed.

I do plan on porting more things to Crystal on top of discordcr. At the least, I would like to open a wiki page where community made components / frameworks, or even example bots can be found.

CI is disabled

After the transfer, travisCI doesn't seem to check PRs.
Please re-enable it (or switch to circle)!

New status format

We should update to the new format of sending op3 packets that allow for dnd and invisible statuses.

CHANNEL_PINS_UPDATE dispatch isn't handled

Example err:

W, [2018-04-03 00:56:38 +00:00 #1]  WARN -- discordcr: Unsupported dispatch: CHANNEL_PINS_UPDATE {"last_pin_timestamp":"2018-03-29T04:04:19.394000+00:00", "channel_id":"250460178057527297"}

Add member_count to #get_guild method

It would be useful to have the #get_guild method in the Guild object. I noticed it was present in Discord::Gateway::GuildCreatePayload but I could not access it myself by changing the lib because I am not very familiar with the code base.

Thanks!

Make client_id optional

Currently this is a required Client#initialize parameter, and is not used anywhere in the library that I can see.

It should at least be made optional, and anything added that depends on this value can fall back on GET /oauth2/applications/@me

Time.epoch is not there anymore

Hello,

Trying out examples and got this:

In lib/discordcr/src/discordcr/mappings/channel.cr:16:5

 16 | JSON.mapping(
      ^
Warning: expanding macro


There was a problem expanding macro 'mapping'

Called macro defined in /usr/share/crystal/src/json/mapping.cr:232:3

 232 | macro mapping(**_properties_)

Which expanded to:

 > 1 |     ::JSON.mapping({type: {type: MessageType, converter: MessageTypeConverter}, content: String, id: Snowflake, channel_id: Snowflake, author: User, timestamp: {type: Time, converter: TimestampConverter}, tts: Bool, mention_everyone: Bool, mentions: Array(User), mention_roles: Array(Snowflake), attachments: Array(Attachment), embeds: Array(Embed), pinned: ::Union(Bool, ::Nil), reactions: ::Union(Array(Reaction), ::Nil), activity: ::Union(Activity, ::Nil)})
   2 |   
Warning: Deprecated JSON.mapping. use JSON::Serializable instead (the legacy behaviour is also available in a shard at github:crystal-lang/json_mapping.cr)

A total of 1 warnings were found.
Showing last frame. Use --error-trace for full trace.

In lib/discordcr/src/discordcr/rest.cr:56:31

 56 | reset_time = Time.epoch(response.headers["X-RateLimit-Reset"].to_u64) # gotta prevent that Y2k38
                        ^----
Error: undefined method 'epoch' for Time.class

More examples

It would be nice to have more examples than just the one that shows off ping.

[Mac OS] Unexpected end of http request (Exception)

Hello, I have the following error: Unexpected end of http request (Exception) while using your library.
I tried the examples but I also have this error. I'm using latest "master" version of discorde and crystal 0.22.0 installed with brew.

0x1091b0bf5: *CallStack::unwind:Array(Pointer(Void)) at ??
0x1091b0b91: *CallStack#initialize:Array(Pointer(Void)) at ??
0x1091b0b68: *CallStack::new:CallStack at ??
0x109194cc1: *raise<Exception>:NoReturn at ??
0x109194ca1: *raise<String>:NoReturn at ??
0x1092c0c5f: *HTTP::Client::Response::from_io<(OpenSSL::SSL::Socket::Client | TCPSocket), Bool, Bool>:HTTP::Client::Response at ??
0x1092c0c09: *HTTP::Client::Response::from_io<(OpenSSL::SSL::Socket::Client | TCPSocket)>:HTTP::Client::Response at ??
0x109274c31: *HTTP::WebSocket::Protocol::new<String, String, Int32, Bool>:HTTP::WebSocket::Protocol at ??
0x1092cdbbe: *HTTP::WebSocket::new<String, String, Int32, Bool>:HTTP::WebSocket at ??
0x109295f2f: *Discord::Client#initialize_websocket:HTTP::WebSocket at ??
0x109295e5f: *Discord::Client#initialize:token:client_id<String, UInt64>:Float64 at ??
0x109295d9c: *Discord::Client::new:token:client_id<String, UInt64>:Discord::Client at ??
0x109194788: __crystal_main at ??
0x1091a6288: main at ??

Error: undefined method 'epoch' for Time.class

Error with code of example.

  • Crystal: 0.34.0 [4401e90f0] (2020-04-06)
  • OS: Debian 10.3

`
In lib/discordcr/src/discordcr/rest.cr:56:31

56 | reset_time = Time.epoch(response.headers["X-RateLimit-Reset"].to_u64) # gotta prevent that Y2k38
^----
Error: undefined method 'epoch' for Time.class
`

Unsupported dispatch: GUILD_EMOJIS_UPDATE

This appears to be a typo, or was changed.

W, [2017-04-26 20:49:54 +0000 #20045]  WARN -- discordcr: Unsupported dispatch: GUILD_EMOJIS_UPDATE {"guild_id":"117888867209707524","emojis":[{"roles":[],"require_colons":true,"name":"kappa","managed":false,"id":"245929382151979009"},{"roles":[],"require_colons":true,"name":"contemplatinglife","managed":false,"id":"306894523194408960"}]}

https://github.com/meew0/discordcr/blob/master/src/discordcr/client.cr#L446-L448

Specs

It would be good to set up a policy on specs (CONTRIBUTING.md) and/or adopt a spec suite. I'm partial to trying out minitest.cr, but I'm not fully aware of the other options available, as well as specs practices in Crystal (if they differ in any way from langs like ruby w/ rspec). The crystal stdlib spec API seems a bit limited.

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.