Fix R code or translate simple Python function to R
Budget: $10 – $30 USD
I am developing an R code that uses a web-socket to send messages as they arrive from Discord to R (not to be confuse with having R querying Discord constantly for new messages).
Rather than having R asking Discord every certain amount of time for new messages (so you know, Discord does not allows this; Discord has a limit of how many times you can request messages), the websocket allows for Discord to send messages to R only when the arrive.
Python has a well-developed package called discord.py that does this operation flawlessly (Tutorial here: https://builtin.com/software-engineering-perspectives/discord-bot-python); working code below.
In R there are two libraries (websocket and httpuv) that do this, but the code I developed while wroking, closes the connection after some random amount of time from a few minutes to hours (I think Python has a safety reconnecting code, yet to be implemented in R, but not sure). The errors have different names like: "Unhandled promise error: invalid state", etc.
The job at hand is to fix the existing R code (Provided below) so it run non-stop, or translate the Python function to an R function (I need the actual code in R, not just connecting from R to Python like via reticulate package).
All codes I have are below. This could be as simple as adding a line of code I am missing, or creating a safety check to re-start connectivity upon disconnection, or a re-doing the python code in R.
Working Python code:
---------------------------------------------------------------
import discord
intents= discord.Intents.default()
intents.message_content = True
client = discord.Client( intents=intents)
@client.event
async def on_message(message):
print(message.content)
client.run("BotToken")
--------------------------------------------------------------------
The R code:
------------------------------------------------------
library(websocket)
library(jsonlite)
library(async)
Heartbeat =10 #container for heartbite
DiscordSignals <- function(DiscordToken){
#payloads or messages that R has to send to Discord.
Rpayload = list(
op= 2,
d= list(
token= DiscordToken,
intents= 513,
properties=list(
os= "windows",
browser= "firefox",
device= "firefox")
)
)
KeepAlive = list(op= 1, d= "null" )
Jsonpayload = toJSON(Rpayload, auto_unbox = TRUE, pretty = TRUE)
JsonKeepAlive = toJSON(KeepAlive, auto_unbox = TRUE, pretty = TRUE)
ws <<- WebSocket$new("wss://gateway.discord.gg/?v=9&encording=json", errorLogChannels ="warn")
ws$onOpen(function(event) {ws$send(Jsonpayload)}) #Handshake
ws$onMessage(function(event) {
d <- event$data
json = fromJSON(d)
Alert= json$d$content
OP<<-as.numeric(json$op) #Type of message sent from Discord
#https://discord.com/developers/docs/topics/gateway#resuming
#Discord may request additional heartbeats from your app by sending a Heartbeat (opcode OP1) event. Upon receiving the event, .. immediately send back .. Heartbeat ...
#reset heartbeat rate to whatever asked by Discord. Heartbite rate send from Discord in OPs 1 or 10.
if (OP %in% c(1,10)){Heartbeat <<-round(abs(((json$d$heartbeat_interval )/1000)-runif(1)-3),0)}
print (Alert)
})
#send heartbeat every given interval
async({
p=1
while (p==1){
await(delay(Heartbeat))
ws$send(JsonKeepAlive)
}
})
}
DiscordSignals (BotToken)
Rather than having R asking Discord every certain amount of time for new messages (so you know, Discord does not allows this; Discord has a limit of how many times you can request messages), the websocket allows for Discord to send messages to R only when the arrive.
Python has a well-developed package called discord.py that does this operation flawlessly (Tutorial here: https://builtin.com/software-engineering-perspectives/discord-bot-python); working code below.
In R there are two libraries (websocket and httpuv) that do this, but the code I developed while wroking, closes the connection after some random amount of time from a few minutes to hours (I think Python has a safety reconnecting code, yet to be implemented in R, but not sure). The errors have different names like: "Unhandled promise error: invalid state", etc.
The job at hand is to fix the existing R code (Provided below) so it run non-stop, or translate the Python function to an R function (I need the actual code in R, not just connecting from R to Python like via reticulate package).
All codes I have are below. This could be as simple as adding a line of code I am missing, or creating a safety check to re-start connectivity upon disconnection, or a re-doing the python code in R.
Working Python code:
---------------------------------------------------------------
import discord
intents= discord.Intents.default()
intents.message_content = True
client = discord.Client( intents=intents)
@client.event
async def on_message(message):
print(message.content)
client.run("BotToken")
--------------------------------------------------------------------
The R code:
------------------------------------------------------
library(websocket)
library(jsonlite)
library(async)
Heartbeat =10 #container for heartbite
DiscordSignals <- function(DiscordToken){
#payloads or messages that R has to send to Discord.
Rpayload = list(
op= 2,
d= list(
token= DiscordToken,
intents= 513,
properties=list(
os= "windows",
browser= "firefox",
device= "firefox")
)
)
KeepAlive = list(op= 1, d= "null" )
Jsonpayload = toJSON(Rpayload, auto_unbox = TRUE, pretty = TRUE)
JsonKeepAlive = toJSON(KeepAlive, auto_unbox = TRUE, pretty = TRUE)
ws <<- WebSocket$new("wss://gateway.discord.gg/?v=9&encording=json", errorLogChannels ="warn")
ws$onOpen(function(event) {ws$send(Jsonpayload)}) #Handshake
ws$onMessage(function(event) {
d <- event$data
json = fromJSON(d)
Alert= json$d$content
OP<<-as.numeric(json$op) #Type of message sent from Discord
#https://discord.com/developers/docs/topics/gateway#resuming
#Discord may request additional heartbeats from your app by sending a Heartbeat (opcode OP1) event. Upon receiving the event, .. immediately send back .. Heartbeat ...
#reset heartbeat rate to whatever asked by Discord. Heartbite rate send from Discord in OPs 1 or 10.
if (OP %in% c(1,10)){Heartbeat <<-round(abs(((json$d$heartbeat_interval )/1000)-runif(1)-3),0)}
print (Alert)
})
#send heartbeat every given interval
async({
p=1
while (p==1){
await(delay(Heartbeat))
ws$send(JsonKeepAlive)
}
})
}
DiscordSignals (BotToken)