Discord Requests

Hello, I’m wanting to send messages to Roblox via a Discord Bot in Javascript.

Basically when the user sends !message hello it will send the hello message to Roblox and then that message will be used for another purpose etc. I’ve already searched on the forum for topics along the lines of this however none fit what I’m looking for. I’ve already got the Discord Bot side done it’s just sending it to Roblox.

2 Likes

I could try that, although have you got any links or tutorials?

Sudo code for the roblox side:

while true do
-- wait a certain amount of time
-- send a get request to your server
-- use the response which will be json, decode it and everything
-- get the array with the messages, and do whatever you want with that
end

on the discord side:

-- express get a url on your server like /messages or smth
-- send a response of messageArray in json

-- everytime the command is run, push it to an array called messageArray

edit: make sure to filter on roblox using the TextChatService otherwise you will get banned; happened to me once

Are you using nodejs for the discord bot?

he said it is in javascript, so that is assumed

although that is not the main part of this, you would need to use express or any http library in javascript to do this

There are many executors for javascript out there. I wanted to ask so that I could see if I could help on making this http server

Yes I am using nodejs and discord.js with the latest versions.

What you want to do is use the http library. you can setup a server doing so:

let Http = require("http");

let myServer = new Http.Server();
myServer.on("request", function(request, response){  
    request.on("data", function(chunk){
        if(!request.body) request.body = chunk;
        else request.body += chunk;
    });

    request.on("end", function() {
        request.bodyEnded = true;
    });

    request.getBody = function(caller){
        if(request.bodyEnded) caller(request.body);
        else {
            request.on("end", function(){
                caller(request.body);
            });
        };
    };

    /*
        So let me explain, here we are creating a custom property called "body" in request. This will be the body that is sent if
        something like POST is used.
        ALWAYS use getBody, it will yield until a body is returned.
    */

    /*
        Put your shenanigans here
        Tip: For returning values use response.writeHead, response.write and response.end()
    */

    response.writeHead(200, "OK."); //We are saying that everything was fine
    response.write("Very nice"); //This is the body that will be returned
    response.end(); //Ending the request
});

myServer.listen(3000);

/*

NOTE: THIS SERVER IS UNSECURE.

THIS SERVER IS RUNNING ON HTTP and not HTTPS, HTTPS IS THE SECURE METHOD. To use HTTPS however, you need a certificate, key and a bunch of
other stuff.

Another note: You also need a domain. Roblox does not allow secure connections via an IP. You need to use a domain server
that redirects to the port 3000. So something like mydomain.com/api will redirect to the port 3000

If you don't want to deal with these stuff you don't need to. Just be aware that people can check what you are sending to the
servers. So don't send passwords or those things.
*/

I will make a live example soon, I am setting up some files and then I will show you an example

Alright I’ll still be looking at this topic.

Also, meanwhile apache2 decides to work for once. Why are you using this?
As you can see on the comment it is unsecure, so I am warning you since this means anyone could send a message with your robot.

It will be a private use one so there won’t be any risk.

Then, as long as they don’t discover your server’s IP/Domain it’s fine

Sup, I did it. So I opened a temporal web app at (closed) * I updated the code to this:

let Https = require("https");
let Fs = require("fs");

let myServer = new Https.Server({
    cert: Fs.readFileSync(*),
    key: Fs.readFileSync(*)
});
myServer.on("request", function(request, response){  
    request.on("data", function(chunk){
        if(!request.body) request.body = chunk;
        else request.body += chunk;
    });

    request.on("end", function() {
        request.bodyEnded = true;
    });

    request.getBody = function(caller){
        if(request.bodyEnded) caller(request.body);
        else {
            request.on("end", function(){
                caller(request.body);
            });
        };
    };

    /*
        So let me explain, here we are creating a custom property called "body" in request. This will be the body that is sent if
        something like POST is used.
        ALWAYS use getBody, it will yield until a body is returned.
    */

    /*
        Put your shenanigans here
        Tip: For returning values use response.writeHead, response.write and response.end()
    */

    console.log(request.headers);
    request.getBody(function(body){
        console.log(body);
    });

    response.writeHead(200, "OK."); //We are saying that everything was fine
    response.write("Very nice"); //This is the body that will be returned
    response.end(); //Ending the request
});

myServer.listen(3000);

/*

NOTE: THIS SERVER IS UNSECURE.

THIS SERVER IS RUNNING ON HTTP and not HTTPS, HTTPS IS THE SECURE METHOD. To use HTTPS however, you need a certificate, key and a bunch of
other stuff.

Another note: You also need a domain. Roblox does not allow secure connections via an IP. You need to use a domain server
that redirects to the port 3000. So something like mydomain.com/api will redirect to the port 3000

If you don't want to deal with these stuff you don't need to. Just be aware that people can check what you are sending to the
servers. So don't send passwords or those things.
*/

You can test it using the following roblox code:

local HttpService = game:GetService("HttpService");
print("Result:", HttpService:RequestAsync({
	Url = *,
	Method = "POST",

	Headers = {
		IAmAHeader = "nice"
	},

	Body = "very nice!!!"
}));

Result:
image

You should be able to use the new Open Cloud feature that roblox provides. Just setup an API key on the create dashboard, and you can send requests to Roblox’s open cloud with that API key, and listen for the MessagingService in your game, like so:

local MessagingService = game:GetService("MessagingService")

MessagingService:SubscribeAsync("HelloWorld", function(Data)
	print("HelloWorld was fired externally with data: "..Data)
end)

And your JavaScript code on the server:

let Response = await fetch("https://apis.roblox.com/messaging-service/v1/universes/YOURUNIVERSEID/topics/HelloWorld", {
	method: "POST",
	headers: {
		"x-api-key": "YOURAPIKEY",
		"Content-Type": "application/json"
	},
	body: JSON.stringify({
		"message": "Your data here!"
	})
})

This solution is much simpler, faster, and much more secure.

For the new Https.Server({}) what would I put for the cert and key?

How would I sent it from a Discord Bot though

You don’t use HTTPS. Use the normal HTTP code that I sent you before. What I sent you is just what I put in the node script on my server.

You can use the node-fetch npm module, and send a POST request to https://apis.roblox.com/messaging-service/v1/universes/YOURUNIVERSEID/topics/EVENTNAME with your Open Cloud API key and data

@typechecked has a very interesting solution. For this case you need to do it the other way, so you use Long-term poling from the roblox place to the node script.

That just means: Loop a bunch of times until you get a response.

So instead of the place sending a request to the server, it is the server that keeps sending a request each like 1 second to the place.

If the place has a pending “message” it will send it to the server as a response and then the server can use that message and post it.

Alternatively you can do both. Make it so that the place sends an unsecure request to the server that says “Check my data”. Then the server sends a request back to the place using the secure roblox method and then posts the message.

For anyone reading: I was wrong, check the replies for further information (I thought he needed the server to be up-to-date).

Will the http server be my IP then?