Cannot use Readline with Discord.js - node.js

I'm trying to use the readline for Node.js when working with my Discord bot to make handling inputs easier, however no matter what I do to the code it always runs the bot events only rather than the reader events as well. I'm not sure why this is and I really would like to be able to use both to output messages easier.
My bot:
'use strict';
const Discord = require('discord.js');
const Chalk = require('chalk');
const Readline = require('readline');
const Token;
const Script = require('./data.js');
const rl = Readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question(Chalk.yellow("Enter guild representative's ID: ", (answer) => {
rep = answer;
console.log(Chalk.green("ID Recorded: " + rep));
}));
rl.question(Chalk.magenta("Enter embed color: ", (answer) => {
color = answer;
console.log(Chalk.green("Color recorded: " + color));
}));
rl.question(Chalk.blueBright("Enter guild description: ", (answer) => {
color = answer;
console.log(Chalk.green("Color recorded: " + color));
}));
const bot = new Discord.Client();
bot.on("ready", () => {
console.log("Bot is ready!");
});
bot.on("message", (message) => {
if (message.content == ":addPartner") {
message.guild.channels.find("name", "affiliates").send({ embed });
message.channel.send(":white_check_mark: Affiliate message sent in #affiliates!");
*/
}
});

Related

how to test and mocking nodejs readline with jest?

I'm currently working on a method for a simple console game. And I want to test this method through jest mocking. But I'm having a hard time. Any help would be appreciated.
index.js
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
class App {
play() {
rl.question("Input Numbers ", (userInput) => {
const userNumbers = userInput.split("").map(Number);
if (userNumbers.length !== 3) {
throw new Error("[ERROR] You have to input 3 numbers");
return;
}
});
}
}
module.exports = App;
I tried in index.test.js with jest
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const App = require("../src/App");
test("throws an error if user input 4 numbers", () => {
const mockQuestion = jest.fn().mockImplementation((question, callback) => {
callback("1234");
});
rl.question = mockQuestion;
const app = new App();
expect(() => {
app.play();
}).toThrow("[ERROR] You have to input 3 numbers");
});
But I got this fail message
Expected substring: "[ERROR] You have to input 3 numbers"
Received function did not throw
enter image description here

Nodejs multiple inputs from console - mix of masked and unmasked outputs

I am trying to create a small nodejs utility to produce and consume kafka messages using kafkajs. I want to get the kafka user and password input from the console. I tried different combinations to use the stdoutMuted to true and false at various places, but it doesn't work correctly. If it is set to true before the question is asked then I either get undefined or the question doesn't show up
Using some examples on SO, similar to this and this, I tried to create something like this
var readline = require('readline');
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl._writeToOutput = stringToWrite => {
if (rl.stdoutMuted)
rl.output.write("*");
else
rl.output.write(stringToWrite);
};
rl.stdoutMuted = true;
rl.question('Password: ', password => {
rl.stdoutMuted = false;
console.log('\nPassword is ' + password);
rl.close();
});
This gives below
* *******
Password is mypass
OR
'use strict'
const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
const question1 = () => {
return new Promise((resolve, reject) => {
rl.stdoutMuted = false;
rl.question('Userid : ', (answer) => {
console.log(`Thank you for your valuable feedback: ${answer}`)
resolve()
})
})
}
const question2 = () => {
return new Promise((resolve, reject) => {
rl.stdoutMuted = true;
rl.question('Password : ', (answer) => {
console.log(`Thank you for your valuable feedback: ${answer}`)
resolve()
})
})
}
rl._writeToOutput = function _writeToOutput(stringToWrite) {
if (rl.stdoutMuted)
rl.output.write("\x1B[2K\x1B[200D"+rl.query+"["+((rl.line.length%2==1)?"=-":"-=")+"]");
else
rl.output.write(stringToWrite);
};
const main = async () => {
await question1()
await question2()
rl.close()
}
main()
Gives the below
UserId user
Thank you for your valuable feedback: user
undefined[-=]Thank you for your valuable feedback: password
How can I setup the input such that I can request multiple inputs where some of them will be masked and others plaintext, but all the questions / prompts are visible.
Also, how do I set those as variables that can be used in other parts of the application to connect to Kafka.
Thank you

Sending a message into all servers where bot is

How do I send one message per guild that my bot is in? It doesn't matter which channel it will be, but I don't know how to code it.
I finally came up with that idea:
client.guilds.cache.forEach(guild => {
const Embed = new discord.MessageEmbed();
const Channels = guild.channels.cache.map(channel => `${channel.id} | ${channel.name}`).join(", ")
Embed.setTitle(`Channels for ${guild.name}`);
Embed.setDescription(Channels);
message.channel.send(Embed);
});
but it doesn't work.
I'm working with commands handler so it has to be done with module.exports:
module.exports = {
name: "informacja",
aliases: [],
description: "informacja",
async execute(message) {
client.guilds.cache.forEach(guild => {
const Embed = new discord.MessageEmbed();
const Channels = guild.channels.cache.map(channel => `${channel.id} | ${channel.name}`).join(", ")
Embed.setTitle(`Channels for ${guild.name}`);
Embed.setDescription(Channels);
message.channel.send(Embed);
});
};
My code is not working at all
When I run it - nothing happens, no errors, no messages, just nothing.
tried to logged everything, but still nothing came up.
I also tried to log everything using console.log() but nothing is working
I remind: I need to send one message to all servers where my bot is, but only one channel
You could find a channel on each server where the client can send a message then send:
client.guilds.cache.forEach(guild => {
const channel = guild.channels.cache.find(c => c.type === 'text' && c.permissionFor(client.user.id).has('SEND_MESSAGES'))
if(channel) channel.send('MSG')
.then(() => console.log('Sent on ' + channel.name))
.catch(console.error)
else console.log('On guild ' + guild.name + ' I could not find a channel where I can type.')
})
This is a very simple boilerplate to start with, you can later check channel with id, or smth like that
client.channels.cache.forEach(channel => {
if(channel.type === 'text') channel.send('MSG').then('sent').catch(console.error)
})
v13 code
const Discord = require('discord.js')
const {
MessageEmbed
} = require('discord.js')
const fs = require('fs')
module.exports = {
name: "send",
description: "Send message to all guilds bot joined",
usage: `!send <text>`,
category: "dev",
run: async (client, message, args) => {
client.guilds.cache.map((guild) => {
const channel = guild.channels.cache.find(
(c) => c.type === "GUILD_TEXT" && c.permissionsFor(guild.me).has("SEND_MESSAGES")
);
channel.send('your_text')
})
}}
v12 code
const Discord = require('discord.js')
const {
MessageEmbed
} = require('discord.js')
const fs = require('fs')
module.exports = {
name: "send",
description: "Send message to all guilds bot joined",
usage: `!send <text>`,
category: "dev",
run: async (client, message, args) => {
client.guilds.cache.map((guild) => {
const channel = guild.channels.cache.find(
(c) => c.type === "text" && c.permissionsFor(guild.me).has("SEND_MESSAGES")
);
channel.send('your_text')
})
}}

Node.js readline property doesn't ask for input

Node.js readline property doesn't stop for input, instead continues program, causing app to crash. While trying to solve this I found out that apparently node does the whole code simultaneously and doesn't because of that stop for input. I found out ways to run this code but they didn't work for me.
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var token;
var pass;
rl.question('token: ', (tok) => {
token = tok;
rl.close();
});
rl.question('pass: ', (pas) => {
pass = pas;
rl.close();
});
What can I do to solve this?
I hope you are looking something like below:
const readLine = require('readline');
const util = require('util')
const { promisify } = util;
const readline = readLine.createInterface({
input: process.stdin,
output: process.stdout,
});
// Prepare readline.question for promisification
readline.question[util.promisify.custom] = (question) => {
return new Promise((resolve) => {
readline.question(question, resolve);
});
};
let questionPs = promisify(readline.question);
async function askQuestions (questions,readline) {
let answers= [];
for(let i=0;i<2;i++){
let tmp = await questionPs(q[i]);
answers.push(tmp)
}
console.log(answers);
readline.close();
}
// Usage example:
let q = ['token:','pass:']
askQuestions(q,readline)

Nodejs Telegram bot message receives polling error

I am using
Node Module
https://www.npmjs.com/package/node-telegram-bot-api
error
error: [polling_error] {"code":"ETELEGRAM ","message":"ETELEGRAM : 404 not found"
MyCode
let replyText = "Hi I am Tammy";
const TelegramBot = require('node-telegram-bot-api');
const token = xxxxxxxxx;
const bot = new TelegramBot(token, {polling: true});
bot.onText(/\/echo (.+)/, (msg, match) => {
const chatId = msg.chat.id;
const resp = match[1]; // the captured "whatever"
bot.sendMessage(chatId, resp);
});
bot.on('message', (msg) => {
const chatId = msg.chat.id;
bot.sendMessage(chatId, replyText );
});
Any help or suggestion would be thankful.
try disable or change to other your Telegram proxy.
Also you can see additional info here:
https://github.com/yagop/node-telegram-bot-api/issues/562#issuecomment-382313307
I solved it by removing the "bot" which I added at the beginning of the API_TOKEN.

Resources