Getting UUID’s by providing only the crypto coins name/ticker - javascript

I’m building a Discord bot using the Discord.JS module, and using NodeJS. I’m trying to add a simple crypto-price feature to my bot.
For now, I’m using the following code:
const unirest = require("unirest");
const req = unirest("GET", "https://coinranking1.p.rapidapi.com/coin/Qwsogvtv82FCd/price");
req.query({
"referenceCurrencyUuid": "yhjMzLPhuIDl"
});
req.headers({
"X-RapidAPI-Host": "coinranking1.p.rapidapi.com",
"X-RapidAPI-Key": "X",
"useQueryString": true
});
req.end(function (res) {
if (res.error) throw new Error(res.error);
console.log(res.body);
});
So basically, you have to provide the UUID of the desired crypto coin to request information, but I want my users to be able to do (for example) !price bitcoin or !price btc, but this requires the command to be like !price Qwsogvtv82FCd.
How do I resolve this issue?

If you check the API documentation, you can see that instead of using the coin price endpoint, you could use the search suggestion (https://coinranking1.p.rapidapi.com/search-suggestions), where you can search for a coin by its name or symbol. It returns an object like the one below. If you check the objects in data.coins, they have keys like uuid, name, symbol, and price:
{
"status":"success",
"data":{
"coins":[
{
"uuid":"Qwsogvtv82FCd",
"iconUrl":"https://cdn.coinranking.com/gNsKAuE-W/bitcoin_btc.svg",
"name":"Bitcoin",
"symbol":"BTC",
"price":"65955.43592725793773050345"
},
{...}
],
"exchanges":[
{...},
{...}
],
"markets":[...]
}
}
Your current code doesn't really do anything and it doesn't even have discord.js code. Here is a sample code with some explanation:
const { Client, Intents } = require('discord.js');
// I'm using node-fetch instead of unirest
// make sure you install it using npm i node-fetch
const fetch = require('node-fetch');
const RAPID_API_KEY = 'YOUR RAPID API KEY';
const TOKEN = 'YOUR DISCORD API TOKEN';
const client = new Client({
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES],
});
const prefix = '!';
client.on('messageCreate', async (message) => {
if (message.author.bot || !message.content.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
if (command !== 'price') return;
if (!args[0]) return message.reply('Please provide a coin!');
try {
// get the search query
let query = args[0].toLowerCase();
// call the API
let coins = await searchCoin(query);
// if there is no search result, or something went wrong, exit w/ a message
if (!coins || coins.length === 0)
return message.reply(`No result for \`"${query}"\``);
// check the first result only
let coin = coins[0];
// if there is an exact match, send the price returned from the API
if (
coin.name.toLowerCase() === query ||
coin.symbol.toLowerCase() === query
)
return message.reply(
`The current price of **${coin.name} (${coin.symbol})** is **${coin.price} USD**`,
);
// if there is no exact match, just send the coin name and symbol in a message
message.reply(
`No exact result found. Did you mean **${coin.name} (${coin.symbol})**?`,
);
} catch (err) {
console.error(err);
message.reply('Oops, there was an error. Please try again later.');
}
});
client.once('ready', () => {
console.log('Bot is connected...');
});
client.login(TOKEN);
async function searchCoin(query) {
const url = `https://coinranking1.p.rapidapi.com/search-suggestions?query=${query}`;
const options = {
method: 'GET',
headers: {
'X-RapidAPI-Host': 'coinranking1.p.rapidapi.com',
'X-RapidAPI-Key': RAPID_API_KEY,
},
};
try {
const response = await fetch(url, options);
const json = await response.json();
return json.status === 'success' ? json.data?.coins : null;
} catch (err) {
console.error(err);
return null;
}
}
And here is the result:

Related

MongoServerSelectionError: getaddrinfo ENOTFOUND at Timeout._onTimeout

So you may have seen this question type somewhere else. but the thing here is I tried all of the things we need to do according to docs and saw other posts with similar errors but still my error is not fixed. So I use keyv and use MongoDB atlas as storage adapter in this code, but the error is from MongoDB. Also, there is no error in the "keyv" because it works for other people, there is error in the MongoDB
So now I will list whatever I tried:
1. Made sure there is IP access
2. The userid and passcode are correct
3. The MongoDB atlas is running
4. Read the docs and code multiple times
5. If u think adding the +srv with the code will fix the error, it won't, it doesn't work with keyql idk why also it is not present in many codes, I already tried it
So this is the code
const { Client, Intents, MessageEmbed, Collection } = require('discord.js');
let client = new Client({ intents: [Intents.FLAGS.GUILDS,Intents.FLAGS.GUILD_MESSAGES] });
const dotenv = require('dotenv');
const Keyv = require('keyv');
const keyv = new Keyv('mongodb://Discord:password#cluster0.auifa.mongodb.net/Cluster0');
dotenv.config();
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('messageCreate', async (msg) => {
if (msg.author.bot) return;
let number = msg.content.split(' ')[1];
if (msg.content === '!ping') {
msg.channel.send('ping!')
}
// Use like const prefix = await getGuildPrefix(); `
const getGuildPrefix = async () => {
const prefixMap = await keyv.get('prefix');
return prefixMap ?. [msg.guild.id] || "!"
}
// Sets the prefix to the current guild.
const setGuildPrefix = async (prefix) => {
let prefixMap = await keyv.get('prefix');
if (!prefixMap)
{
prefixMap = "!";
}
prefixMap[msg.guild.id] = prefix;
await keyv.set('prefix', `${prefixMap}`);
}
let prefix = await getGuildPrefix();
// Get prefix command.
if ((msg.content === `${process.env.prefix}prefix`) || (msg.content === `${prefix}prefix`)) {
msg.channel.send(`Your server prefix is ${prefix}`)
}
// Change prefix command
const commandPrefix = await getGuildPrefix();
if ((msg.content.startsWith(`${process.env.prefix}setprefix`)) || (msg.content.startsWith(`${commandPrefix}setprefix`))) {
const newPrefix = number;
if (newPrefix.length === 0) {
msg.channel.send(`Please enter a valid prefix`);
}
await setGuildPrefix(newPrefix)
msg.channel.send(`Your server prefix is now '${newPrefix}'`);
}
})
client.login(process.env.token);
And this is the error message
Keyv connection error: MongoServerSelectionError: getaddrinfo ENOTFOUND cluster0.auifa.mongodb.net
at Timeout._onTimeout (D:\javascript\node_modules\mongojs\node_modules\mongodb\lib\core\sdam\topology.js:438:30)
at listOnTimeout (node:internal/timers:557:17)
at processTimers (node:internal/timers:500:7) {
reason: TopologyDescription
Connection string does not look like an Atlas one.
It has to be something like: mongodb+srv://<username>:<password>#cluster0.auifa.mongodb.net/YOUR-DB
Login to your Atlas account then:
Go to Databases page
Click on Connect button
Choose "Connect your application"
Copy your connection string
Docs about Mongo Atlas connection: https://docs.atlas.mongodb.com/connect-to-cluster/#connect-to-a-cluster

Updating the prefix for a guild doesent require a full restart to apply but adding a new guild to my database does for some reason

so i have code setup so when a guild joins they are added to the database with default settings i setup. if they decide to change the prefix it works fine they can change the prefix and it will update and they can immediately start using it.
BUT for some reason when a guild is added i have to restart the bot or use nodemon and make it auto restart upon changes for that new guild before they can use ANY commands. is there a difference in how im adding this info to the database compared to adding the prefix?
below is the code i use to add the server to the database and below that is the code i use to let them change prefix. im trying to get the commands to work for the server that just invited the bot without having to restart the bot to avoid bugs down the line when its trying to do something and is then restarted cause someone invited the bot.
/// adding a guild to the database upon invite
bot.on('guildCreate', async (guild) => {
// Guild the user needs to have the role in
let myGuild = await bot.guilds.fetch(process.env.BOT_GUILD);
console.log(myGuild);
// Role that the user needs
let requiredRole = process.env.PAID_ROLE;
console.log(requiredRole);
// find default channel
let defaultChannel = "";
guild.channels.cache.forEach((channel) => {
if(channel.type == "text" && defaultChannel == "") {
if(channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {
defaultChannel = channel;
console.log(defaultChannel);
}
}
});
// Member object of the user in guildA
try{
let guildOwner = await myGuild.members.fetch(guild.ownerID);
console.log(guildOwner);
if (!guildOwner)
return console.log(`Oops, ${guild.owner} is not a member of your server.`);
}catch(error) {
return console.log(`Oops, ${guild.owner} is not a member of your server.`),
defaultChannel.send('Please kick the bot, have the guild owner join this discord https://discord.gg/tDTjBAaCAn, Then you can reinvite the bot and you will be properly added to the database and can use the bot! dont forget to check out the premium features while your there if you decide you want more features from Gate Bot!');
}
//Check if they have the role
let guildOwner = await myGuild.members.fetch(guild.ownerID);
let ownerHasPaidRole = guildOwner.roles.cache.has(process.env.PAID_ROLE);
if (ownerHasPaidRole){
console.log(`Woohoo, ${guildOwner} has the required role`);}
try {
/// insert serverid and serverownerid into servers db
await connection.query(
`INSERT INTO Servers (serverId, serverOwnerId, paidRole) VALUES ('${guild.id}', '${guild.ownerID}', 1)`
);
/// insert server id into serverconfig db
await connection.query(
`INSERT INTO ServerConfig (serverId) VALUES ('${guild.id}')`
);
}catch(err){
console.log(err);
}});
Message handler to use the change prefix command
///allowing the script to see files from the commands folder
bot.commands = new Discord.Collection();
const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for(const file of commandFiles){
const command = require(`./commands/${file}`);
bot.commands.set(command.name, command);
}
///Message Handler
bot.on('message', async (message) => {
const prefix = guildCommandPrefixes.get(message.guild.id);
console.log('caught message');
if(!message.content.startsWith(prefix) || message.author.bot) return;
const args = message.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase();
///basic ping pong test command
if(command === 'help'){
bot.commands.get('help').execute(message);
}
///basic ping pong test command
else if(command === 'ping'){
bot.commands.get('ping').execute(message);
}
///change the servers prefix
else if(command === 'changeprefix'){
bot.commands.get('changeprefix').execute(message, connection, prefix, guildCommandPrefixes);
}
///arguments test
else if (command === 'argsinfo'){
bot.commands.get('argsinfo').execute(message, command, args)
}
///message command list
else if (command === 'autoungate'){
bot.commands.get('autoungate').execute(message, args, Discord);
}});
command used to change prefix.
module.exports= {
name: 'changeprefix',
description: "this will change the prefix in the database for the set guild id",
execute: async (message, connection, prefix, guildCommandPrefixes) =>{
setTimeout(() => {message.delete();}, 3000);
if (message.content.toLowerCase().startsWith(prefix + 'changeprefix')){
if (message.member.id === message.guild.ownerID) {
var guild = message.guild
paidRole = await connection.query(`SELECT paidRole FROM Servers Where '${guild}' === serverId`);
const [cmdName, newPrefix ] = message.content.split(" ");
if (paidRole === '1'){
if (newPrefix) {
try {
await connection.query(
`UPDATE ServerConfig SET cmdPrefix = '${newPrefix}' WHERE serverId= '${message.guild.id}'`
);
guildCommandPrefixes.set(message.guild.id, newPrefix);
message.channel.send(`Updated guild prefix to ${newPrefix}`).then(sentMessage => {sentMessage.delete({ timeout: 3000}); });
}catch(err) {
console.log(err);
message.channel.send(`Failed to update guild prefix to ${newPrefix}`).then(sentMessage => {sentMessage.delete({ timeout: 3000}); });
}}
else {
message.channel.send('You need to input a prefix to change to!').then(sentMessage => {sentMessage.delete({ timeout: 3000}); });
}}
else {
message.channel.send('You need to purchase the premium version for prefix customization.').then(sentMessage => {sentMessage.delete({ timeout: 3000}); });
}}
else {
message.channel.send('You do not have permissions to do this command!').then(sentMessage => {sentMessage.delete({ timeout: 3000}); });
}
}
}}
I made sure my paidRole variable in my database could be set to null.
Upon guild creation the guild is marked null for a split second to get it in the database. I used UPDATE to update the role to either 1 or 0 in the database based on their role in my Discord.
When you use UPDATE it will "refresh" the bot and apply automatically some changes without making it restart possibly causing some issues.
Here's the code I ended up using:
/// adding a guild to the database upon invite
bot.on('guildCreate', async (guild) => {
// Guild the user needs to have the role in
let myGuild = await bot.guilds.fetch(process.env.BOT_GUILD);
try {
/// insert serverid and serverownerid into servers db
await connection.query(
`INSERT INTO Servers (serverId, serverOwnerId, paidRole) VALUES ('${guild.id}', '${guild.ownerID}', NULL)`
);
/// insert server id into serverconfig db
await connection.query(
`INSERT INTO ServerConfig (serverId) VALUES ('${guild.id}')`
);
}catch(err){
console.log(err);
// find default channel
let defaultChannel = "";
guild.channels.cache.forEach((channel) => {
if(channel.type == "text" && defaultChannel == "") {
if(channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {
defaultChannel = channel;
console.log(defaultChannel);
}
}
});
// Member object of the user in guildA
try{
let guildOwner = await myGuild.members.fetch(guild.ownerID);
if (!guildOwner)
return console.log(`Oops, ${guild.owner} is not a member of your server.`);
}catch(error) {
return console.log(`Oops, ${guild.owner} is not a member of your server.`),
defaultChannel.send('Please kick the bot, have the guild owner join this discord https://discord.gg/tDTjBAaCAn, Then you can reinvite the bot and you will be properly added to the database and can use the bot! dont forget to check out the premium features while your there if you decide you want more features from Gate Bot!');
}
//Check if they have the role
let guildOwner = await myGuild.members.fetch(guild.ownerID);
let ownerHasPaidRole = guildOwner.roles.cache.has(process.env.PAID_ROLE);
if (ownerHasPaidRole){
console.log(`Woohoo, ${guildOwner} has the required role`);
await connection.query(
`UPDATE Servers SET paidRole = '1' WHERE serverId = ${guild.id}`
);
}
else {
await connection.query(
`UPDATE Servers SET paidRole = '0' WHERE serverId = ${guild.id}`
);
}
}});

Discord.js Embed error Cannot send an empty message

so I'm trying to make a help command with list of commands showed in embed. My code kinda works but it throws an error "DiscordAPIError: Cannot send an empty message" and I've tried already everything I know and what I've found but I can't fix it.
Here's the code
const Discord = require('discord.js');
const { prefix } = require('../config.json');
module.exports = {
name: 'help',
description: 'List all of my commands or info about a specific command.',
aliases: ['commands', 'cmds'],
usage: '[command name]',
cooldown: 5,
execute(msg, args) {
const data = [];
const { commands } = msg.client;
if (!args.length) {
const helpEmbed = new Discord.MessageEmbed()
.setColor('YELLOW')
.setTitle('Here\'s a list of all my commands:')
.setDescription(commands.map(cmd => cmd.name).join('\n'))
.setTimestamp()
.setFooter(`You can send \`${prefix}help [command name]\` to get info on a specific command!`);
msg.author.send(helpEmbed);
return msg.author.send(data, { split: true })
.then(() => {
if (msg.channel.type === 'dm') return;
msg.reply('I\'ve sent you a DM with all my commands!');
})
.catch(error => {
console.error(`Could not send help DM to ${msg.author.tag}.\n`, error);
msg.reply('it seems like I can\'t DM you! Do you have DMs disabled?');
});
}
const name = args[0].toLowerCase();
const command = commands.get(name) || commands.find(c => c.aliases && c.aliases.includes(name));
if (!command) {
return msg.reply('that\'s not a valid command!');
}
data.push(`**Name:** ${command.name}`);
if (command.aliases) data.push(`**Aliases:** ${command.aliases.join(', ')}`);
if (command.description) data.push(`**Description:** ${command.description}`);
if (command.usage) data.push(`**Usage:** ${prefix}${command.name} ${command.usage}`);
data.push(`**Cooldown:** ${command.cooldown || 3} second(s)`);
msg.channel.send(data, { split: true });
},
};
You should try replace this line :
msg.channel.send(data, { split: true });
with
msg.channel.send(data.join(' '), { split: true }); since your data variable is an array and not a string
The problem is as the error states. You are trying to send an empty message somewhere.
You can try replacing msg.channel.send(data) with msg.channel.send(data.join('\n')), since the data variable is an array.
I don't see why sending an array doesn't work though.

Having some trouble with weather-js and args

I have a command in my bot, called weather, it works fine, but i want to send an error message if the user writes it without any arguments.
It works if the arguments are not a place, but if you write it without any args, it doesnt reply anything
Here's the code (Updated with entire code)
const Discord = require('discord.js');
const weather = require('weather-js');
exports.run = async (client, message, args) => {
weather.find({search: args[0], degreeType: "C"}, function(err, result){
if (err) message.channel.send(err);
const noargs = new Discord.RichEmbed()
.setDescription(`Input a valid location, please`)
.setColor(0xfd5454)
if(!result.length) {
message.channel.send(noargs);
return;
}
var current = result[0].current;
var location = result[0].location;
It works if you write ",weather nonexistingcity" but if you write ",weather" without any args, it doesnt work.
PD: noargs is a discord embed, is declared but not included in this post.
const weather = require('weather-js');
const Discord = require('discord.js');
module.exports = {
name: "weather",
description: "Checks a weather forecast",
async execute(client, message, cmd, args, Discord){
weather.find({search: args.join(" "), degreeType: 'F'}, function (error, result){
// 'C' can be changed to 'F' for farneheit results
if(error) return message.channel.send(error);
if(!args[0]) return message.channel.send('Please specify a location')
if(result === undefined || result.length === 0) return message.channel.send('**Invalid** location');
var current = result[0].current;
var location = result[0].location;
const weatherinfo = new Discord.MessageEmbed()
.setDescription(`**${current.skytext}**`)
.setAuthor(`Weather forecast for ${current.observationpoint}`)
.setThumbnail(current.imageUrl)
.setColor(0x111111)
.addField('Timezone', `UTC${location.timezone}`, true)
.addField('Degree Type', 'Celsius', true)
.addField('Temperature', `${current.temperature}°`, true)
.addField('Wind', current.winddisplay, true)
.addField('Feels like', `${current.feelslike}°`, true)
.addField('Humidity', `${current.humidity}%`, true)
message.channel.send(weatherinfo)
})
}
}
If you want to check if no args where provoided you can do :
if(args.length == 0) return message.channel.send('You need to provide a city');
...weather-js is programmed to answer the user if he didn't provide args with a default message. I want to know how to change that message.
If you really want to change this message instead of checking your arguments yourself like #PLASMA chicken has suggested, the message is located on line 31 of weather-js/index.js.

Creating an application that will listen to a telegram channel

First of all please note that this is not about creating a bot.
My goal is to create an application that will simply listen to any number of telegram channels that the account I will provide it with is subscribed to and retrieve all messages sent to those channels (as if I was a normal user). My guess is that I will need to
Authenticate myself using my account's phone number
Be able to setup a callback listener either per channel or a general listener for all incoming messages
I've been looking around the telegram api for a couple of days now and I am extremely confused as to how it works. After giving up on it, I started looking at readymade implementations, mostly for NodeJS but was still not able to find a concrete solution. I'm testing some things with the telegram-js api but running it directly using node didn't work. Does it need to run in a browser? Is there any more streamlined approach to this? Preferably something with good documentation.
PS: I'm fluent in Java and Javascript mostly so I've prioritized libraries based on those languages.
EDIT:
Here is the code that I've written (essentially copied an example)
var { Telegram } = require("../libs/telegram");
var TypeLanguage = require("telegram-tl-node") ;
var MTProto = require("telegram-mt-node");
var schema = require("../libs/api-schema.json");
const APP_ID = "111111";
const APP_HASH = "fb6da8f6abdf876abd6a9d7bf6";
const SERVER = { host: "111.111.111.11", port: "443" };
const config = {
id: APP_ID,
hash: APP_HASH,
version: '0.0.1',
lang_code: 'en',
authKey: null
};
let telegram = new Telegram(MTProto, TypeLanguage);
telegram.useSchema(schema);
addPublicKeys(telegram);
let connection = new MTProto.net.HttpConnection(SERVER);
let client = telegram.createClient();
client.setConnection(connection);
connection.connect(function() {
let ready = client.setup(config);
ready.then(function(client) {
// it never resolves this promise
function callback(response) {
console.log(response);
}
client.callApi("help.getConfig").then(callback, callback);
});
});
It uses those 2 libs:
telegram-mt-node
telegram-tl-node
Late answer but might help others.
You can utilize mtproto-core to authenticate with a regular telegram account and listen to updates (or do anything you can with telegram clients, really)
Here is a sample script I've written that listens to new messages from channels/supergroups the user is subscribed to:
const { MTProto, getSRPParams } = require('#mtproto/core');
const prompts = require('prompts');
const api_id = ...; // insert api_id here
const api_hash = ' ... '; // insert api_hash here
async function getPhone() {
return (await prompts({
type: 'text',
name: 'phone',
message: 'Enter your phone number:'
})).phone
}
async function getCode() {
// you can implement your code fetching strategy here
return (await prompts({
type: 'text',
name: 'code',
message: 'Enter the code sent:',
})).code
}
async function getPassword() {
return (await prompts({
type: 'text',
name: 'password',
message: 'Enter Password:',
})).password
}
const mtproto = new MTProto({
api_id,
api_hash,
});
function startListener() {
console.log('[+] starting listener')
mtproto.updates.on('updates', ({ updates }) => {
const newChannelMessages = updates.filter((update) => update._ === 'updateNewChannelMessage').map(({ message }) => message) // filter `updateNewChannelMessage` types only and extract the 'message' object
for (const message of newChannelMessages) {
// printing new channel messages
console.log(`[${message.to_id.channel_id}] ${message.message}`)
}
});
}
// checking authentication status
mtproto
.call('users.getFullUser', {
id: {
_: 'inputUserSelf',
},
})
.then(startListener) // means the user is logged in -> so start the listener
.catch(async error => {
// The user is not logged in
console.log('[+] You must log in')
const phone_number = await getPhone()
mtproto.call('auth.sendCode', {
phone_number: phone_number,
settings: {
_: 'codeSettings',
},
})
.catch(error => {
if (error.error_message.includes('_MIGRATE_')) {
const [type, nextDcId] = error.error_message.split('_MIGRATE_');
mtproto.setDefaultDc(+nextDcId);
return sendCode(phone_number);
}
})
.then(async result => {
return mtproto.call('auth.signIn', {
phone_code: await getCode(),
phone_number: phone_number,
phone_code_hash: result.phone_code_hash,
});
})
.catch(error => {
if (error.error_message === 'SESSION_PASSWORD_NEEDED') {
return mtproto.call('account.getPassword').then(async result => {
const { srp_id, current_algo, srp_B } = result;
const { salt1, salt2, g, p } = current_algo;
const { A, M1 } = await getSRPParams({
g,
p,
salt1,
salt2,
gB: srp_B,
password: await getPassword(),
});
return mtproto.call('auth.checkPassword', {
password: {
_: 'inputCheckPasswordSRP',
srp_id,
A,
M1,
},
});
});
}
})
.then(result => {
console.log('[+] successfully authenticated');
// start listener since the user has logged in now
startListener()
});
})
You can find the values for api_id and api_hash from https://my.telegram.org.
On the first run the script prompts the user for phone_number, code, and password.
[+] You must log in
√ Enter your phone number: ... <phone_number>
√ Enter the code sent: ... <code>
√ Enter Password: ... <2FA password>
and after the authentication is over
a sample run outputs:
[+] starting listener
[13820XXXXX] Ja
[13820XXXXX] Bis bald guys��
[13820XXXXX] Ja. �
[13820XXXXX] Bis später
[13820XXXXX] Jaaa�
The way I've checked the authentication status was taken from here.
Alternative libraries worth checking out that are active the time of writing (and can be used to create the same behavior with): Airgram (tdlib) and GramJs
I used gram.js library and essentially did this:
import { TelegramClient } from 'telegram'
TelegramClient().addEventHandler(handler, { chats: [1234567890] })
The bot does NOT need to be a member of the channel you want to listen to.
My code runs as a Node.js app.
You need to first create a token by talking to #BotFather with Telegram.
here is my working code by using gramjs and its purely on nodejs.
Getting all the messages from all the channels without any delay's.
import {
TelegramClient
} from "telegram";
import {
NewMessage,
NewMessageEvent
} from "telegram/events";
import {
StringSession
} from "telegram/sessions";
const input = require("input");
const apiId = 1233456677;
const apiHash = "xxxxxxxxxxxxxxxxx";
let stringSession = new StringSession("xxxxxxxxxxxxxxxxx");
(async() => {
console.log("Loading interactive example...");
const client = new TelegramClient(stringSession, apiId, apiHash, {
connectionRetries: 5,
});
await client.start({
phoneNumber: async() => await input.text("Please enter your number: "),
password: async() => await input.text("Please enter your password: "),
phoneCode: async() =>
await input.text("Please enter the code you received: "),
onError: (err) => console.log(err),
});
console.log("You should now be connected.");
const session: any = client.session.save();
stringSession = new StringSession(session); // Save this string to avoid logging in again - specially in nodemon
console.log(client.session.save()); // --> you can also copy this session from your console once you get it and paste it in line number 8 - new StringSession("XXXXXXXXXXXXXX")
// once you saved add the JWT Token on line no. 8 as mention above next time you will getting directly connected.
await client.sendMessage("me", {
message: "Hello!"
});
async function handler(event: NewMessageEvent) {
console.log("[newmessage]", event);
}
client.addEventHandler(handler, new NewMessage({}));
})();
Note - Ignore the "Run Code Snippet" as found it best way to add whole code instead of formatting.
You can use the gram.js library in the following way:
Install these:
npm install properties-reader
npm install telegram
npm install input
Then get your apiId and apiHash from Telegram Auth in the App Configuration section.
Create a file config.properties with a content similar to that:
[telegram]
apiId=12345678
apiHash=12345678901234567890123456789012
Inside of your nodejs code you can listen to a specific chat like this (see chatId inside of the code below):
const PropertiesReader = require('properties-reader');
const configs = PropertiesReader('config.properties');
getProp = (bundle, key) => {return configs.get(`${bundle}.${key}`);}
const { TelegramClient } = require("telegram");
const { StoreSession } = require("telegram/sessions");
const { NewMessage } = require("telegram/events");
const { EditedMessage } = require("telegram/events/EditedMessage");
const input = require("input");
const apiId = getProp("telegram", "apiId")
const apiHash = getProp("telegram", "apiHash")
const storeSession = new StoreSession("telegram_session"); // see: https://painor.gitbook.io/gramjs/getting-started/authorization#store-session
(async () => {
console.log("Loading interactive example...");
const client = new TelegramClient(storeSession, apiId, apiHash, {
connectionRetries: 5,
});
await client.start({
phoneNumber: async () => await input.text("Please enter your number: "),
password: async () => await input.text("Please enter your password: "),
phoneCode: async () =>
await input.text("Please enter the code you received: "),
onError: (err) => console.log(err),
});
console.log("You should now be connected.");
client.session.save(); // Save the session to avoid logging in again
async function eventPrint(event) {
// see 'node_modules/telegram/tl/custom/message.d.ts'
const message = event.message
const isNew = message.editDate === undefined
const text = message.text
const date = new Date(message.date*1000)
console.log(`The message is ${isNew ? 'new' : 'an update'}`)
console.log(`The text is: ${text}`)
console.log(`The date is: ${date}`)
}
// to get the chatId:
// option 1: open telegram on a web browser, go to the chat, and look the url in the address bar
// option 2: open telegram app, copy link to any message, it should be something like: https://t.me/c/1234567890/12345, the first number after "/c/" is the chatId
const chatId = 1234567890
client.addEventHandler(eventPrint, new NewMessage({ chats: [chatId] }));
client.addEventHandler(eventPrint, new EditedMessage({ chats: [chatId] }));
})();

Categories