geeks
DIAdiscord.js - Imagine an app
•Created by geeks on 5/13/2024 in #djs-questions
Building Embed & 3 Buttons in v14 (use ActionRowBuilder and EmbedBuilder?)
I have a function that 'compiles' and sends an embed and components (which are three buttons) to a text channel:
async function sendEmbed(description) {
try {
const [embedBuilt, buttonRowBuilt] = await Promise.all([
buildEmbed(description),
buildButtonRow()
]);
const textChannel = client.channels.cache.get(textChannelId);
await textChannel.send({ embeds: [embedBuilt.toJSON()], components: [buttonRowBuilt.toJSON()] })
.then((message) => {
lastButtonMessageId = message.id;
}).catch((error) => {
console.error(error);
});
} catch (error) {
console.error(error);
}
}
The embed seems to be OK. But I know there's definitely something wrong with my ActionRowBuilder 😦
async function buildButtonRow() {
const actionRow = new ActionRowBuilder();
actionRow.addComponents(ButtonComponent[[
new ButtonBuilder()
.setLabel('Join Queue')
.setStyle(ButtonStyle.Success)
.setCustomId('join-queue-button'),
new ButtonBuilder()
.setLabel('Leave Queue')
.setStyle(ButtonStyle.Danger)
.setCustomId('leave-queue-button'),
new ButtonBuilder()
.setLabel('Pass Time')
.setStyle(ButtonStyle.Primary)
.setCustomId('pass-time-button')
]]
);
return actionRow
}
Anyone see obvious issues that I need to fix?
Many thanks 🙂7 replies
DIAdiscord.js - Imagine an app
•Created by geeks on 5/9/2024 in #djs-questions
Conditional display of Button Components in Text Channel (based on user role?)
I have a couple of buttons:
const queueButton = new ButtonBuilder()
.setLabel('Join Queue')
.setStyle(ButtonStyle.Primary)
.setCustomId('join-queue-button');
const leaveButton = new ButtonBuilder()
.setLabel('Leave Queue')
.setStyle(ButtonStyle.Secondary)
.setCustomId('leave-queue-button');
const buttonRow = new ActionRowBuilder()
.addComponents(queueButton, leaveButton)
And am sending them to the text chat thus:
async function sendEmbed() {
const textChannel = client.channels.cache.get(textChannelId);
if (textChannel) {
await textChannel.send({components: [buttonRow]})
.then((message) => {
console.log('Embed sent successfully')
})
.catch(console.error);
const collector = textChannel.createMessageComponentCollector({
componentType: ComponentType.Button
});
collector.on('collect', async (interaction) => {
if (interaction.customId === 'join-queue-button') {
await handleJoinButton(interaction)
} else if (interaction.customId === 'leave-queue-button') {
await handleLeaveButton(interaction)
}
});
} else {
console.error('Text channel not found or not text-based');
}
}
But would like only certain users viewing the chat to have the view:
- Join button visible, leave button hidden
Otherwise, users would see:
- Join button hidden, leave button visible
Is this possible maybe by using roles for users or some other way?3 replies
DIAdiscord.js - Imagine an app
•Created by geeks on 5/5/2024 in #djs-voice
Speaking 'start'/'end' events trigger continuously - Caused by while loop?
I have two ts at global level:
let startedSpeakingTimestamp;
let stoppedSpeakingTimestamp;
then as part of my VoiceConnection/VoiceReceiver setup, I have my speaking event listeners below:
botConnection.receiver.speaking.on('start', (userId) => {
if (!startedSpeakingTimestamp) {
client.users.fetch(userId)
.then(user => {
startedSpeakingTimestamp = Date.now();
const startedDate = new Date(startedSpeakingTimestamp)
console.log(
${user.displayName} started speaking at ${startedDate});
})
}
});
botConnection.receiver.speaking.on('end', (userId) => {
if ((!stoppedSpeakingTimestamp || Date.now() > stoppedSpeakingTimestamp) && userActive) {
client.users.fetch(userId)
.then(user => {
stoppedSpeakingTimestamp = Date.now();
const stoppedDate = new Date(stoppedSpeakingTimestamp)
console.log(
${user.displayName} finished speaking at ${stoppedDate});
});
}
});
Continued below29 replies
DIAdiscord.js - Imagine an app
•Created by geeks on 5/5/2024 in #djs-questions
VoiceReceiver - Subscriptions needed before detection of start/end?
I seem to have successfully set up a VoiceReceiver, which is connected to a VoiceConnection:
VoiceReceiver {
voiceConnection: <ref *1> VoiceConnection {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
rejoinAttempts: 0,
_state: { status: 'ready', adapter: [Object], networking: [Networking] },
joinConfig: {
selfDeaf: false,
selfMute: false,
group: 'default',
channelId: '1230241511019515936',
guildId: '1228049526762373284',
adapterCreator: [Function (anonymous)]
},
packets: { server: [Object], state: [Object] },
receiver: VoiceReceiver {
voiceConnection: [Circular *1],
ssrcMap: [SSRCMap],
subscriptions: Map(0) {},
connectionData: [Object],
speaking: [SpeakingMap],
onWsPacket: [Function: bound onWsPacket],
onUdpMessage: [Function: bound onUdpMessage]
},
debug: null,
onNetworkingClose: [Function: bound onNetworkingClose],
onNetworkingStateChange: [Function: bound onNetworkingStateChange],
onNetworkingError: [Function: bound onNetworkingError],
onNetworkingDebug: [Function: bound onNetworkingDebug],
[Symbol(kCapture)]: false
},
ssrcMap: SSRCMap {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
map: Map(0) {},
[Symbol(kCapture)]: false
},
subscriptions: Map(0) {},
connectionData: {},
speaking: SpeakingMap {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
users: Map(0) {},
speakingTimeouts: Map(0) {},
[Symbol(kCapture)]: false
},
onWsPacket: [Function: bound onWsPacket],
onUdpMessage: [Function: bound onUdpMessage]
}
However, my speaking.on('start'/'end') calls are still not firing. I'm thinking I need to add userIds to either the SSRCMap or the Subscriptions Map in the receiver - am I on the right track?
If so, how to do this?
3 replies
DIAdiscord.js - Imagine an app
•Created by geeks on 5/4/2024 in #djs-questions
Using discord.py base with nodejs (discord.js & voice) as addons
If an entire current setup is based around python, but I want to harness the speaking functionalities which only seem to be available in js libraries...
Should I be looking to incorporate the js commands within a container?
Or should I be running a separate set of scripts... ie. have python and js running simultaneously?
I'm running discord.js v14.14.1
And voice v0.16.1
Thx 🙂
18 replies
DIAdiscord.js - Imagine an app
•Created by geeks on 5/1/2024 in #djs-questions
OAuth2 URL + Bot Permissions + Discord Intents
8 replies
DIAdiscord.js - Imagine an app
•Created by geeks on 4/30/2024 in #djs-questions
newState.speaking vs oldState.speaking doesn't seem to be working :(
I want to establish a timestamp both when user starts speaking and also stops speaking.
My startTimer function starts like this:
async function startTimer() {
if (queueActive) {
try {
const currentUser = queue[0];
await unmuteUser(currentUser);
userActive = true;
unmuteTimestamp = Date.now();
const listener = speakingListener(currentUser);
client.on('voiceStateUpdate', listener);
while (userActive) {
The while loop runs some continuous checks on the timestamps.
The speakingListener looks like this (outside of the startTimer function):
const speakingListener = (currentUser) => {
return (oldState, newState) => {
if (newState.member && String(newState.member.id) === String(currentUser.id)) {
if (newState.speaking && !oldState.speaking && !startedSpeakingTimestamp) {
console.log(${currentUser.user.tag} started speaking);
startedSpeakingTimestamp = Date.now();
} else if (!newState.speaking && oldState.speaking) {
console.log(${currentUser.user.tag} stopped speaking);
stoppedSpeakingTimestamp = Date.now();
}
}
};
};
The speakingListener doesn't seem to ever be activated - am I missing something? 😦
9 replies