discord export buttton array - node.js

in my /report command, a channel is created, into which the button and embed are sent. I need to store the id of the new channel the button was sent to in order to interact with that channel later on. I tried to create an array and use exports to export it to my InteractionCreater file in which I have written: const reportArr = require('../commands/Report/report')
module.exports = {
name: 'interactionCreate',
async execute(interaction,client) {
if(interaction.isCommand()){
// if (!interaction.isCommand()) return;
const command = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction,client);
} catch (error) {
console.error(error);
await interaction.reply({content: 'There was an error while executing this command!', ephemeral: true});
}
}
else if(interaction.isButton()){
if(interaction.customId.includes('acceptB')){
console.log(reportArr.reports)
}
}
but in InteractionCreater i get undefeated even though if i try to output the array in command then they are output. Tell me how can I put my channel in the InteractionCreater file, which is created when the /report command is sent. This is what sending embed\button looks like:
(Creating new channel).then(async reportChannel => {const acceptButton = new MessageActionRow()
.addComponents(
new MessageButton()
.setCustomId(`acceptB`)
.setLabel('Accept')
.setStyle('SUCCESS')
.setEmoji('✅')
);
await client.channels.cache.get(`${settings["tickets-log"]}`).send({
content: `<#&${settings.moder}>`
}).then(idmessage => {
idmessage.delete()
})

To create a channel and then send a message and button into it:
const channelName = `Channel Name Here` // Change this
const channel = await interaction.guild.channels.create(channelName, {
parent: 'parentID', // Change this
type: 'GUILD_TEXT',
permissionOverwrites: [{ // For if you want it private, otherwise delete this whole section from here
id: interaction.guild.id,
deny: [
'VIEW_CHANNEL'
]
}, {
id: interaction.user.id, // id of person who started the channel creation process
allow: [
'SEND_MESSAGES', 'VIEW_CHANNEL', 'EMBED_LINKS', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY'
]
}, {
id: 'adminRoleID', // Change this
allow: [
'SEND_MESSAGES', 'VIEW_CHANNEL', 'EMBED_LINKS', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY'
]
}, {
id: 'anyAdditionalRoleID', // Change this
allow: [
'SEND_MESSAGES', 'VIEW_CHANNEL', 'EMBED_LINKS', 'ATTACH_FILES', 'READ_MESSAGE_HISTORY'
]
}] // For if you want it private, otherwise delete this whole section up to here
})
const acceptButton = new MessageActionRow()
.addComponents(
new MessageButton()
.setCustomId(`acceptB`)
.setLabel('Accept')
.setStyle('SUCCESS')
.setEmoji('✅')
)
await channel.send({
content: `<#&${settings.moder}>`,
components: [acceptButton]
})
Then to make that button do something:
module.exports = {
name: 'interactionCreate',
async execute(interaction, client) {
if (interaction.isCommand()) {
const command = client.commands.get(interaction.commandName);
if (!command) return;
try {
await command.execute(interaction, client);
} catch (error) {
console.error(error);
await interaction.reply({
content: 'There was an error while executing this command!',
ephemeral: true
});
}
} else if (interaction.isButton()) {
if (interaction.customId === 'acceptB') {
console.log('button clicked') // Do what you want to do here
}
}
}
}

Related

How can I change the message to replying embeds in play.js

I am creating a discord music bot. I want the bot to give output messages with embeds and reply to the user who used the command. Here's my code:
const { QueryType } = require('discord-player');
module.exports = {
name: 'play',
aliases: ['p'],
utilisation: '{prefix}play [song name/URL]',
voiceChannel: true,
async execute(client, message, args) {
if (!args[0]) return message.channel.send(`Please enter a valid search.`);
const res = await player.search(args.join(' '), {
requestedBy: message.member,
searchEngine: QueryType.AUTO
});
if (!res || !res.tracks.length) return message.channel.send(`No results found.`);
const queue = await player.createQueue(message.guild, {
metadata: message.channel
});
try {
if (!queue.connection) await queue.connect(message.member.voice.channel);
} catch {
await player.deleteQueue(message.guild.id);
return message.channel.send(`I can't join the voice channel.`);
}
await message.channel.send(`Loading your ${res.playlist ? 'playlist' : 'track'}...`);
res.playlist ? queue.addTracks(res.tracks) : queue.addTrack(res.tracks[0]);
if (!queue.playing) await queue.play();
},
};
I want to make it look like this

how to execute more than thousand requests in parallel by axios using node.js

When I try to make axios.get request(url) for a small number of URLs it works successfully but when the number of URLs is large I get an errors from axios ( socket hang up - Client network socket disconnected before secure TLS connection was established - read ECONNRESET - connect ETIMEDOUT).
my code
I try to loop through this array
const links = [
{
title: 'title two',
newsLink: 'https://al-omana.net/details.php?id=158277',
imageLink: 'https://al-omana.net/media/imgs/news/25-09-2021-04-18-26.jpeg',
category: 'news',
rssId: 321,
selector: '.story_text p'
},
{
title: 'title one',
newsLink: 'https://al-omana.net/details.php?id=158277',
imageLink: 'https://al-omana.net/media/imgs/news/25-09-2021-04-18-26.jpeg',
category: 'news',
rssId: 123,
selector: '.story_text p'
},
... 1415 more items
]
and I try to extract the content by this function
async function scrapeContent(item) {
try {
let content = "";
const { data } = await axios.get(item.newsLink);
const $ = cheerio.load(data);
const listItems = $(item.selector);
listItems.each((_, item) => {
content += $(item).text();
});
return {
...item,
content: content.replace(/[\r\n\"\t]+/gm, "")
};
} catch (error) {
console.log({ in: "scrapeContent", message: error.message });
}
}
and this my execute function
async function scraper(links) {
try {
const promises = links.map(scrapeContent); // this loop axios requests
const newsContent = await Promise.all(promises);
console.log(newsContent);
} catch (error) {
console.log({ in: "scraper", message: error.message });
}
scraper(links);
Please help me

API Only sends 1 chunk of metadata when called

I have a problem with my API that sends metadata when called from my smart contract of website. Its NFT tokens and my database is postgres and API is node.js
The problem is when I mint 1 NFT metadata works perfect, but if I mint 2 or more it will only ever send 1 chunk of data? So only 1 NFT will mint properly and the rest with no data?
Do I need to set a loop function or delay? Does anyone have any experience with this?
Any help would be much appreciated.
Below is the code from the "controller" folder labeled "nft.js"
const models = require("../../models/index");
const path = require("path");
const fs = require("fs");
module.exports = {
create_nft: async (req, res, next) => {
try {
const dir = path.resolve(__dirname + `../../../data/traitsfinal.json`);
const readCards = fs.readFileSync(dir, "utf8");
const parsed = JSON.parse(readCards);
console.log("ya data ha final ??", parsed);
parsed.forEach(async (item) => {
// return res.json(item)
let newNft = await models.NFT.create({
name: item.Name,
description: item.Description,
background: item.Background,
body: item.Body,
mouth: item.Mouth,
eyes: item.Eyes,
head_gear: item.Head_Gear,
tokenId: item.tokenId,
image: item.imagesIPFS,
});
});
return res.json({
data: "nft created",
error: null,
success: true,
});
} catch (error) {
console.log("server error", error.message);
next(error);
}
},
get_nft: async (req, res, next) => {
try {
const { id } = req.params;
// console.log("id ?????????",id)
// console.log("type of ",typeof(id))
// const n=Number(id)
// console.log("type of ",typeof(id))
const nft = await models.NFT.findByPk(id);
if (!nft) {
throw new Error("Token ID invalid");
}
if (!nft.isMinted) {
throw new Error("Token not minted");
}
console.log(nft);
// }
const resObj = {
name: nft.name,
description: nft.description,
image: `https://gateway.pinata.cloud/ipfs/${nft.image}`,
attributes: [
{ trait_type: "background", value: `${nft.background}` },
{ trait_type: "body", value: `${nft.body}` },
{ trait_type: "mouth", value: `${nft.mouth}` },
{ trait_type: "eyes", value: `${nft.eyes}` },
{ trait_type: "tokenId", value: `${nft.tokenId}` },
{
display_type: "number",
trait_type: "Serial No.",
value: id,
max_value: 1000,
},
],
};
return res.json(resObj);
} catch (error) {
console.log("server error", error.message);
next(error);
}
},
get_nft_all: async (req, res, next) => {
try {
// console.log("id ?????????",id)
// console.log("type of ",typeof(id))
// const n=Number(id)
// console.log("type of ",typeof(id))
const nft = await models.NFT.findAndCountAll({
limit: 10
});
// console.log(nft);
if (!nft) {
throw new Error("Token ID invalid");
}
// if (nft.isMinted) {
// throw new Error("Token not minted");
// }
// console.log(nft);
// }
var resObjarr = [];
for (var i = 0; i < nft.rows.length; i++) {
resObj = {
name: nft.rows[i].name,
description: nft.rows[i].description,
image: `https://gateway.pinata.cloud/ipfs/${nft.rows[i].image}`,
attributes: [
{ trait_type: "background", value: `${nft.rows[i].background}` },
{ trait_type: "body", value: `${nft.rows[i].body}` },
{ trait_type: "mouth", value: `${nft.rows[i].mouth}` },
{ trait_type: "eyes", value: `${nft.rows[i].eyes}` },
{ trait_type: "tokenId", value: `${nft.rows[i].tokenId}` },
{
display_type: "number",
trait_type: "Serial No.",
value: nft.rows[i].id,
max_value: 1000,
},
],
};
resObjarr.push(resObj);
}
console.log(JSON.stringify(resObjarr))
return res.json(resObjarr);
} catch (error) {
console.log("server error", error.message);
next(error);
}
},
mint: async (req, res, next) => {
try {
const { id } = req.params;
const updated = await models.NFT.findByPk(id);
if (!updated) {
throw new Error("NFT ID invalid");
}
if (updated.isMinted) {
throw new Error("NFT Already minted");
}
updated.isMinted = true;
updated.save();
return res.json({
data: "Token minted successfully",
error: null,
success: true,
});
} catch (error) {
console.log("server error", error.message);
next(error);
}
},
};
Below is from the routes folder.
const router = require("express").Router();
const auth=require("../middleware/auth")
const {
create_nft,
get_nft,
get_nft_all,
mint
} = require("../controller/nft");
router.post(
"/create",
create_nft
);
router.get(
"/metadata/:id",
get_nft
);
router.get(
"/metadata",
get_nft_all
);
router.put(
"/mint/:id",
mint
);
module.exports = router;
Looking your code,you may having some kind of asyncrhonous issue in this part:
parsed.forEach(async (item) => {
// return res.json(item)
let newNft = await models.NFT.create({
name: item.Name,
description: item.Description,
background: item.Background,
body: item.Body,
mouth: item.Mouth,
eyes: item.Eyes,
head_gear: item.Head_Gear,
tokenId: item.tokenId,
image: item.imagesIPFS,
});
});
Because .forEach is a function to be used in synchronous context and NFT.create returns a promise (that is async). So things happens out of order.
So one approach is to process the data first and then perform a batch operation using Promise.all.
const data = parsed.map(item => {
return models.NFT.create({
name: item.Name,
description: item.Description,
background: item.Background,
body: item.Body,
mouth: item.Mouth,
eyes: item.Eyes,
head_gear: item.Head_Gear,
tokenId: item.tokenId,
image: item.imagesIPFS,
})
})
const results = await Promise.all(data)
The main difference here is Promise.all resolves the N promises NFT.create in an async context in paralell. But if you are careful about the number of concurrent metadata that data may be too big to process in parallel, then you can use an async iteration provided by bluebird's Promise.map library.
const Promise = require('bluebird')
const data = await Promise.map(parsed, item => {
return models.NFT.create({
name: item.Name,
description: item.Description,
background: item.Background,
body: item.Body,
mouth: item.Mouth,
eyes: item.Eyes,
head_gear: item.Head_Gear,
tokenId: item.tokenId,
image: item.imagesIPFS,
})
})
return data

mtproto/core Telegram replay to another Channel

i want collect news from different channels and echo them in a second channel, with the code i can read channels(not all but most).
I stuck now on the echo problem and have no clue about how i can do this, mtproto is completely new to me, thanks.
Im using the following code i have from another stackoverflow question.
const { MTProto, getSRPParams } = require('#mtproto/core');
const prompts = require('prompts');
const api_id = 'xxxxx';
const api_hash = 'xxxxx';
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()
});
})

Bot framework continueDialog not popping off the stack

I create chatbot by Bot Framework and use LINE API Developers on node.js
Problem on my work was continueDialog not continue waterfallDialog next step.
and the stack didn't change when it's done with continueDialog
before continueDialog
stack1 [ { id: 'xxxDialog',
state: { options: {}, values: [Object], stepIndex: 0 } } ]
after continueDialog
stack2 [ { id: 'xxxDialog',
state: { options: {}, values: [Object], stepIndex: 0 } } ]
on index.js
server.post('/api/line',jsonParser, async (req, res)=> {
const conversationReference = {
type: "message",
text: "Hello world" ,
channelData: { clientActivityID: "id-xxxx" },
channelId: 'api/line/id-xxxx',
recipient:
{ id: lineID`,
name: 'line',
role: 'botLine' },
serviceUrl: 'https://localhost:3978' ,
from:
{ id: lineId`,
name: 'User',
role: 'user' },
conversation: { id: lineId },
};
const context = await adapter.createContext(conversationReference);
await bot.onTurn(context);
});
on bot.js
class Bot extends ActivityHandler {
/**
*
* #param {ConversationState} conversationState
* #param {UserState} userState
* #param {Dialog} dialog
*/
constructor(conversationState, userState) {
super();
this.conversationState = conversationState;
this.userState = userState;
this.dialogStateAccessor = conversationState.createProperty('dialogStateAccessor');
this.dialogAccessor= conversationState.createProperty('testAccessor');
this.dialog = new DialogSet(this.dialogStateAccessor);
this.dialog.add(new WaterfallDialog('testDialog', [
this.step1.bind(this),
this.step2.bind(this)
]));
}
async step1(stepContext){
linesent("step 1") ;
return {status : DialogTurnStatus.waiting} ;
}
async step2(stepContext){
linesent("step 2") ;
return await stepContext.endDialog();
}
async onTurn(turnContext) {
const reservation = await this.dialogAccessor.get(turnContext, null);
// Generate a dialog context for our dialog set.
const dc = await this.dialog.createContext(turnContext);
if (!dc.activeDialog){
// If there is no active dialog, check whether we have a reservation yet.
if (!reservation) {
// If not, start the dialog.
await dc.beginDialog(`testDialog`);
}
}
else {
//Continue the dialog.
const dialogTurnResult = await dc.continueDialog();
}
return await this.conversationState.saveChanges(turnContext, false);
}
but it did not show any error.
Any help would be appreciated.
found the continueDialog method be
async continueDialog(dc) {
// Don't do anything for non-message activities
if (dc.context.activity.type !== botbuilder_core_1.ActivityTypes.Message) {
return dialog_1.Dialog.EndOfTurn;
}
// Run next step with the message text as the result.
return await this.resumeDialog(dc, dialog_1.DialogReason.continueCalled, dc.context.activity.text);
}
the bot always do if condition.
Changed continueDialog to resumeDialog on your activeDialog id the waterfall will working on next step.

Resources