Skip to content

Instantly share code, notes, and snippets.

@miraris
Last active December 17, 2017 14:16
Show Gist options
  • Save miraris/c70cf30a86e2ca49d7718fc2c0c7c24d to your computer and use it in GitHub Desktop.
Save miraris/c70cf30a86e2ca49d7718fc2c0c7c24d to your computer and use it in GitHub Desktop.
Terrible code using idk what paradigm to interact with the Discord API..
module Juldi
using Requests
using DandelionWebSockets
import Requests: get, post, put, delete, options
import DandelionWebSockets: on_text, state_connecting, state_open, state_closing, state_closed
import JSON
mutable struct DiscordHandler <: WebSocketHandler
client::WSClient
stop_channel::Channel{Any}
end
# Global variables?..
TOKEN = "secret"
GATEWAY_OPCODES = Dict("DISPATCH" => 0,
"HEARTBEAT" => 1,
"IDENTIFY" => 2,
"STATUS_UPDATE" => 3,
"VOICE_STATE_UPDATE" => 4,
"VOICE_SERVER_PING" => 5,
"RESUME" => 6, "RECONNECT" => 7,
"REQUEST_GUILD_MEMBERS" => 8,
"INVALID_SESSION" => 9,
"HELLO" => 10,
"HEARTBEAT_ACK" => 11
)
SEQUENCE = nothing
HEARTBEAT_INTERVAL = nothing
IDENTIFY_DATA = Dict(
"op" => GATEWAY_OPCODES["IDENTIFY"],
"d" => Dict(
"token" => TOKEN,
"properties" => Dict(
"\$os" => "linux",
"\$browser" => "Discord.jl",
"\$device" => "Discord.jl"
),
"compress" => true,
"large_threshold" => 250,
"presence" => Dict(
"game" => Dict(
"name" => "Miraris' DMs",
"type" => 0
),
"status" => "online",
"afk" => false
)
)
)
HEADERS = Dict(
"Authorization" => "Bot $TOKEN",
"User-Agent" => "DiscordBot (Julia is a meme, 0.0.1)",
"Content-Type" => "application/json"
)
GATEWAY = Requests.json(get("https://discordapp.com/api/gateway/bot"; headers = HEADERS))
USER = nothing
# Set sequence and other global variables..
function set_globals(response)
global SEQUENCE
if response["op"] != 10
SEQUENCE = response["s"]
end
end
# Basic send message function..
function send_message(response)
if isassigned(response["d"]["mentions"], 1) && response["d"]["mentions"][1]["username"] == "Julia"
channel_id = response["d"]["channel_id"]
post("https://discordapp.com/api/channels/$channel_id/messages"; headers = HEADERS,
json = Dict("content" => "no u"))
end
end
# Process the incoming payload..
function process_payload(response)
global USER
global HEARTBEAT_INTERVAL
if response["op"] == GATEWAY_OPCODES["DISPATCH"]
event_name = response["t"]
data = response["d"]
if event_name == "READY"
user = data["user"]
println("WE ARE FUCKING READY!! I am " * user["username" * user["discriminator"]])
elseif event_name == "MESSAGE_CREATE"
send_meme(response)
else
println("Unhandled Event.")
end
elseif response["op"] == GATEWAY_OPCODES["HELLO"]
HEARTBEAT_INTERVAL = response["d"]["heartbeat_interval"]
println("Setting HEARTBEAT_INTERVAL to $HEARTBEAT_INTERVAL")
else
println("Unhandled OP Code.")
end
end
function on_text(::DiscordHandler, s::String)
println("Response: $s")
response = JSON.parse(s)
# Set globals..
set_globals(response)
# Process the data
process_payload(response)
end
# Closing state..
state_closing(::DiscordHandler) = println("State: CLOSING")
# Connecting state..
state_connecting(::DiscordHandler) = println("State: CONNECTING")
# Identify ourselves using OP Code 2
function identify()
global IDENTIFY_DATA
println("SENDING IDENTIFY")
return JSON.json(IDENTIFY_DATA)
end
# On open connection..
function state_open(handler::DiscordHandler)
println("State: OPEN")
function send_heartbeat(timer)
println("SENDING HEARTBEAT")
heartbeat_packet = "{\"op\": 1, \"d\": $SEQUENCE}"
send_text(handler.client, heartbeat_packet)
println(heartbeat_packet)
println("HEARTBEAT SENT")
end
@schedule begin
# Identify packet
send_text(handler.client, identify())
# Timer for heartbeating
Timer(send_heartbeat, HEARTBEAT_INTERVAL/1000, HEARTBEAT_INTERVAL/1000)
end
end
function state_closed(::DiscordHandler)
println("State: CLOSED")
# signal that ocnnection is closed..
put!(stop_chan, true)
end
stop_chan = Channel{Any}(3)
client = WSClient()
handler = DiscordHandler(client, stop_chan)
# Uh, wow - building the ws URI
uri = URI(GATEWAY["url"] * "?v=6&encoding=json")
println("Connecting to $uri.. ")
wsconnect(client, uri, handler)
println("Connected.")
# First message means all messages have been sent and we should close?
take!(stop_chan)
stop(client)
# 2nd means close and we need to exit..
take!(stop_chan)
end # module
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment