0

I'm learning NodeJS, Express via Replit.com with a small project. The goal is to create a simple input field that when submitted posts to various channels, such as Discord, Twitter, etc.

The below code runs on replit.com, loads the necessary packages and successfully connects to the Discord Channel.

I can run javascript code in app.js from the html. (Such as send()) Placing such function inside of index.js does not work. How do I access code from index.js (such as the methods from the discord js) to trigger/execute them from the html?

Directory Structure:

index.js
public/
  indx.html
  css/
    app.css
  js/
    app.js

index.js:

const express = require("express");
const path = require('path');
const app = express();

app.listen(3000, () => {
  console.log("project is running");
})

app.use(express.static(path.join(__dirname, 'public')));

app.get('/', function(req, res) {
    res.redirect('index.html');
});

const { Client, GatewayIntentBits, Intents } = require('discord.js');
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
  ]
})

client.on("ready", () => {
  console.log("Bot is ready.");
  client.channels.cache.get('1056649564532252XXX').send('yo');
});

client.login(process.env.token);

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sample Site</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <style>
    body { padding-top: 50px; }
  </style>
</head>
<body>

  <div class="container">
    <input />
    <button onclick="send()">Send</button>
  </div>

   <script src="js/app.js"></script>

</body>
</html>

app.js:

function send() {
  console.log('sent');
  // this won't work here: client.channels.cache.get('1056649564532252XXX').send('yo');
}
1
  • You need to make an ajax call back to the server. And send the data. The server will run the message sending. Commented Jul 12, 2023 at 15:21

2 Answers 2

1

You cannot use client variable because it's defined in the server and send function is running on client browser.

So you need to make an ajax call back to the server and send the input data.

The server will run the message send process.

In index.js you need to add new endpoint to accept the ajax

app.post('/send', function(req, res) {
  client.channels.cache.get('1056649564532252XXX').send('yo')

  res.json({ success: true })
});

In app.js

function send() {
  console.log('sending');

  fetch('/send', { method: 'POST' })
    .then(response => response.json())
    .then(data => console.log('sent', data))
    .catch(error => console.error(error))
}

Accepting body from client

If you want to accept body data sent from the client you need to use express.json middleware.

express.json is same as body-parser.json.

You can read the full docs here.

To use a middleware you need to add new use before the routes that need the middleware.

app.use(express.json())

Add this before the send route.

This will throw error if the client send malformed json string.

In the send route you need to get the value from the client. You can get it from req.body.

To handle this you can read here

Here I the name is message

app.post('/send', function(req, res) {
  // You need to check here if the message is sent and it's a string
  if (!req.body.message && typeof req.body.message === 'string')
    res.status(400).json({ success: false, message: 'No message found'}) // `.status()` is used to set the status of the response if not set the default is `200`.

 client.channels.cache.get('1056649564532252XXX')
   .send(req.body.message)

  res.json({ success: true })
});

In the client or app.js

Add the body when using the fetch.

Change the fetch to

fetch('/send', { method: 'POST', body: JSON.stringify({ message: 'yo this message is from the client' }) })
  .then(response => response.json())
  .then(data => console.log('sent', data))
  .catch(error => console.error(error))

You need to stringify the object because the fetch body accept string

References

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @kennarddh - this works well. Can you append the answer and/or point me to where to learn more about how to pass data through the fetch correctly in app.js, and retrieve it in the index.js? (To send messages other than 'yo')
0

My guess is that it's due to the redirect in your app.js and the call order of your server function.

First thing when you're running this app, ensure that you're calling via via node app.js to ensure you're serving the application via the server.

Then you'll want to update the express portion of your app.js to resemble the code below:

const express = require("express");
const path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'public')));

app.get('/', function(req, res) {
    res.sendFile(path.join(__dirname, "./public/index.html"));
});

app.listen(3000, () => {
      console.log("project is running");
    })

I haven't personally worked with the discord client, but if you'd like it to load before the page it may also be worth putting that above the app.listen method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.