#development

1 messages ยท Page 1941 of 1

jaunty dune
#

how do i convert flags to badges like this on screenshot? ^

pale vessel
#

393472 & 1 << 18 for example

#

If it doesn't return 0, then they have that flag/badge

jaunty dune
#

math moment

jaunty dune
#

Thank you

pale vessel
#

Have a read

jaunty dune
#

Okay

jaunty dune
wheat mesa
#

Bitwise operations

boreal iron
#

PHP ๐Ÿค

sick agate
#

how do i proxy tcp connections in nodejs with node:net

quartz kindle
#

read from source socket and write to destination socket

tardy hornet
#

when ever I use this menu it returns this error:

earnest phoenix
#

is there any max document limit for mongoose fetch (since i already have 150k in mongo db)

cinder patio
#

I don't think so

#

buuut you shouldn't load them all into memory

earnest phoenix
#

I cache them, so i load all into the memory mmLol ,but the documents are really small. All documents are about 11mb and 3mb leaned

neat ingot
neat ingot
#

like, afaik, as long as a document matches the query, it will be returned in the documents array

#

but i dont normally use fetch tbf, i normally find or findone

earnest phoenix
#

Caching is the best solution for me, since retrieving from cache is 100-500 times faster then fetching from mongo db

whole glen
#
    console.log(`Logged in as ${client.user.tag}!`);
  console.log('Ready!');
  console.log('In ' + client.guilds.cache.size + ' servers')
  client.user.setPresence({
   status: "online"
  });
    client.user.setActivity('Servers: ' + client.guilds.cache.size + ' (work in progress)', { type: 'STREAMING', url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' });
  const restartlog = new MessageEmbed();
    restartlog.setTitle('DaBaby bot has been restarted')
    restartlog.setColor('#ffff00')
    restartlog.setTimestamp()
 client.channels.cache.get('838264759899652137').send(restartlog)
  //shows stats on my bot on my server
});
``` throw new DiscordAPIError(data, res.status, request);
            ^

DiscordAPIError: Cannot send an empty message
neat ingot
#

i've had a custom wrapper around mongoose for years that i use. its my 'cachebase' module, which is then further extended by my project specific database module ๐Ÿ˜„

cinder patio
whole glen
#

newest one i think

neat ingot
#

.send({embeds:[restartlog]});

whole glen
#

oh right

#

they changed it im used to old one

neat ingot
#

lol yea i was too. i've come to prefer the new ways of doing things. slash commands are real nice ๐Ÿ™‚

whole glen
#

yes

neat ingot
#

todays mission: implement a choice select menu thingy

solemn latch
#

they are quite easy

#

the djs guide does an amazing job at explaining it

earnest phoenix
neat ingot
#

ye i dont imagine it will take long, but i havent tried those yet. been too busy rewriting my minigame system to accomodate buttons and remove its reaction based system

solemn latch
#

heya

neat ingot
#

what would be the best channel to get feedback on the design/layout of an image my bot sends?

earnest phoenix
#

I would assume this one is fine since its sorta dev related right @solemn latch ?

neat ingot
#

ye i was thinking the same, but always best to double check ๐Ÿ˜„

solemn latch
#

probably here yeah

earnest phoenix
#

How can I not make HTML look so packed? Or how can I increase a chrome extensions box?

split hazel
#

tf did you do to make it look like that

spark flint
#

its a chrome extension

#

so

earnest phoenix
earnest phoenix
spark flint
#

thats for a popup

earnest phoenix
#

oh okay

spark flint
earnest phoenix
#

okay

spark flint
#

its got the whole popup code

earnest phoenix
#

okay

neat ingot
#

^ graphing network data for my server

#

all my junk runs in docker containers, so there is a netdata container, bot container, website, db, etc. they use their own network under the hood to only expose the site to the world. but i got my bot doing api calls to the netdata container to get server stats โค๏ธ

#

obviously it looks ass atm. but im happy about being able to do that ๐Ÿ˜„

sudden geyser
#

looks like weed

neat ingot
#

oh yea, thats my temp bg image lol

#

my bots a drug trading minigame type thing, has a weed bg ๐Ÿ˜›

#

can buy and sell and pvp and junk ๐Ÿ˜›

#

but im super happy about being able to graph network data (and other server stats accurately, like ram usage). then i can easily check up on things ๐Ÿ˜„

red venture
#

Hey guys,
I am relatively new to programming with Discord bots, but I wanted to try it out and learn how to work with an API as well. I am currently a bit confused whether I need my Token and an OAuth2 link or only one of them.
I appreciate any response, thank you :)

sudden geyser
#

You'll need both of them usually.

#

An OAuth2 link is for users to invite your bot

#

While your bot token is like a password only your bot should know

#

Unless you're referring to a different kind of token

red venture
#

I did mean the bot token :)

neat ingot
#

you would use the token for the bot to login. the oauth link would be used for folks to invite the bot to their server

red venture
#

Okay, thanks. That answered the first thing I didn't completely understand xD

neat ingot
#

your allowed to share the oauth link. never share your token, or you need to reset and change it

red venture
#

Makes sense

#

Referring to "Application" in that context

neat ingot
#

yes, you first create an application, and then that can have a bot associated with it

#

you must have an app to make a bot

#

but i think there are other type of applications? like, games and such that integrate with discord. not 100% on that though

red venture
neat ingot
#

yea but, you might create an app like a game with a 'rich presence' so that your app gets recognized by discord in a users profile, so it tells others what app they are using, for example

#

like that

red venture
#

Ah, yes right

neat ingot
#

but yea, kind of off topic for your question lol. sorry ๐Ÿ˜„

red venture
#

No problem xD

#

Another question is, do I need to connect permanently to the API, WebSocket, or are, for commands at the moment, GET & Post enough?
||And how would I do GET & POST, as I am a bit confused in regards to "asking" something from the API||

lament rock
spark flint
#

how would i order in descending order using mongodb on nodejs

lament rock
#

SELECT * FROM table ORDER BY column DESC

spark flint
#

mongodb

lament rock
#

oh my b. My brain was like mysql

spark flint
#

i usually use mysql

#

but in this case i have too much data to move

lament rock
#

postgres is strong in that regard and requires less refactoring. Maria couldn't keep up for me

red venture
lament rock
#

VC is just an example. There are other events like guild create and delete which are required for getting client guild count, but if you don't require states of resources in your app, then just rest is completely sufficient

neat ingot
spark flint
#

i fixed it now

#

const data = await users.find({}).limit(16).sort( { score: -1 }).toArray();

#

that worked

red venture
#

Thank you :)

neat ingot
#

oh your making a highscore list? fun! โค๏ธ

spark flint
#

yep

neat ingot
#

i usually do something like this for highscore lists:

#
model.instanceMethods.addNewEntry = async function(name, score, extra) {
    const new_entry = new ListEntry.model({
        uname: sanitize(name).trim(),
        extra: sanitize(extra).trim(),
        score: Number(sanitize(score)),
    });
    this.entries.push(new_entry);
    this.sortInOrder();
    while (this.max_entries > 0 && this.max_entries < this.entries.length) {
        this.entries.pop();
    }    
    await this.save();
    // fix for this.entries.indexOf(new_entry);
    // as it wasnt working properly
    const filtr = e => e.id === new_entry.id;
    const entry = this.entries.find(filtr);
    return this.entries.indexOf(entry);
};```
#

^ where by, i sort the list upon adding a new score

#

and then remove the additional entries

#

that way i can ensure the dataset doesnt grow too large

#

like, i have a highscore model that has an entries array, so like, each server might have its own highscore list, or each game, or each project, w.e

drowsy flume
#

yo

spark flint
#

hi

drowsy flume
#

do you think I should add more info on the bot, or will people not actually read all of it

spark flint
#

Make it detailed but not too detailed

#

there is a chance users would want to know what it is

#

but make sure to have a simple sum up at the top for those who don't want to

drowsy flume
#

yeah that makes sense

#

maybe I should photoshop a picture or something

sudden geyser
drowsy flume
sudden geyser
#

ah

drowsy flume
#

how hard is it to add a image to it

earnest phoenix
#

    let user = interaction.options.getMember('user')
  let role = '921560627909099561';
  let role2 = interaction.guild.roles.cache.get('921560627909099561')
  console.log(role2)
const row = new MessageActionRow()
            .addComponents(
                new MessageSelectMenu()
                    .setCustomId('select')
                    .setPlaceholder('Nothing selected')
                    .addOptions([
                        {
                            label: 'Human Resources',
                            description: 'Hire user as Human Resources',
                            value: 'hr',
                        },
                    ]),
            );

const embed  = new MessageEmbed()
    .setAuthor(interaction.user.tag, interaction.user.displayAvatarURL({ dynamic:true }))
    .setDescription(`Select a Department to hire a User Into.`)
    
        await interaction.reply({ embeds: [embed], components: [row], ephemeral:true });

const filter = (interaction) => {
if(interaction.user.id === interaction.member.id) return true;
return interaction.reply({ content: "You can't use this button" })}
    const collector = interaction.channel.createMessageComponentCollector({ filter, time: 15000 });

collector.on('collect', async i => {
    if (!i.isSelectMenu()) return;


if (i.customId === 'hr') {

        await i.deferUpdate();
  await user.roles.add(role2)
        await i.channel.send({ content: 'Selected **Human Resources**! Roles Given', components: [] });
    }
});
    }
}```
> **`This interaction failed`** is what it keeps saying but I see nothing wrong ![whyGod](https://cdn.discordapp.com/emojis/830101616760717322.webp?size=128 "whyGod") .
quartz kindle
#

you didnt specify exactly which part fails, the command interaction or the select menu interaction

#

but i can see many things wrong in that code

earnest phoenix
#

Select menu lol my bad.

#

It sends the first embed and stuff, but doesn't do anything when I click "hr"

#

o-o

quartz kindle
#

well, first of all, you are overriding the name interaction inside your filter

#

so your filter is using the wrong interaction

#

use a different name

#

and also, dont return interaction.reply inside the filter, because interaction.reply returns a promise, which is a truthy value (it exists and its not null/undefined)

#

so your filter will still pass even if the "cant use this button" message is sent

earnest phoenix
#

Done.

#

Still a interaction failed.

spark flint
#

so

#

(new URL(url), function(url.hostname == "i.imgur.com"))

#
<% if (user.banner || (new URL(url), function(url.hostname == "i.imgur.com")) { %>
  <img class="w-full" src="<%= user.banner %>" alt="" />
<% } else { %>
  <img class="w-full" src="https://static.capy.host/i/8zqNRkdr.png" alt="" />
<% } %>```
#

how would i make it check that the url hostname is i.imgur.com

#

SyntaxError: Unexpected token '.'

solemn latch
#

does this need to be done inside ejs?

#

could it be done in js on the webpage?

spark flint
#

well

#

it lists users using users.forEach

#

so its probably not possible (or easy)

sudden geyser
solemn latch
#

^

spark flint
#

oh good point

solemn latch
#

yeah

spark flint
#

forgot about that facepalm

sudden geyser
#

Actually .hostname would be better

#

since it'd exclude ports

spark flint
#

i did .hostname

sudden geyser
#

nice

hidden gorge
#

Hey guys Im having an error

wheat mesa
#

Update node

#

v16 or higher

hidden gorge
#

ok

#

@wheat mesa How do i Update?

wheat mesa
#

Iโ€™m assuming youโ€™re using replit

hidden gorge
#

Yep

wheat mesa
#

Thereโ€™s some sort of replit guide out there for updating

hidden gorge
#

Me and my friend are coding it togther

wheat mesa
#

I donโ€™t have the link though

hidden gorge
#

@wheat mesa it wont let me install node

#

We keep getting

wheat mesa
#

Look up a tutorial on how to update node in replit

#

Thereโ€™s tons out there

earnest phoenix
#
npm init -y && npm i --save-dev node@16 && npm config set prefix=$(pwd)/node_modules/node && export PATH=$(pwd)/node_modules/node/bin:$PATH

In your shell

#

Then create a .replit file in the main branch and put

run="npm start"
``` in it
lament rock
#

wtf

#

npmjs is hosting node?

#

it is

earnest phoenix
#

What did you create your project as?

hidden gorge
earnest phoenix
#

This might not make any differences but I always have this on my replit projects:

 },
  "engines": {
    "node": "16.x"
  }```
#

This is also what the command above creates when you run that:

 "devDependencies": {
    "node": "^16.13.1"
  }``` *or should*
lament rock
#

some envs respect engines like heroku

hot whale
#

heloo

#

i use djs

#

does anyone know how to make an avatar command i have seen a few tutorials but it does not work

earnest phoenix
hot whale
#

hold on

#
if (message.content ==='.av')
    const user = message.mentions.users.first() || message.author;
    const avatarEmbed = new Discord.RichEmbed()
        .setColor(0x333333)
        .setAuthor(user.username)
        .setImage(user.avatarURL);
    message.channel.send(avatarEmbed);
}
);```
#

btw i am a beginner

earnest phoenix
#

That code snippet uses an old version of discord.js

hot whale
#

i see

#

can u send the updated version

#

of the avatar command

#

if thats fine

#

with you

earnest phoenix
#

We don't spoon-feed, but we can help you change a few things for it to work:

  1. The message event is deprecated and removed, use the messageCreate event instead
  2. The RichEmbed class was renamed to MessageEmbed
  3. I recommend creating slash-commands instead of normal message commands
hot whale
#

ah ok

#

ye i use that sometimes

#

do they have the avatar command guide there

earnest phoenix
#

Nope, but it gives you an idea of what you can do to get started, you can have a look at the documentation to see what you can use to get the avatar of the user and do whatever you want with it

hot whale
#

alr thanks

#

const user = message.mentions.users.first() || message.author;
^^^^^

#

this is the error i am getting

#

unexpected token

earnest phoenix
#

You're missing the { after the if statement

marble juniper
#

Also don't follow outdated youtube tutorials

#

cuz to me it seems like u do

#

lol

hot whale
#

ahha yes

#

i am new to this so i didnt really know what to do

marble juniper
#

Before making a bot you should defenitly know the basics and how to debug properly

hot whale
#

yeah

earnest phoenix
#

in v13 message => messageCreate RichEmbed() => MessageEmbed() avatarURL => avatarURL() send({ embeds: [embed] });

proven lantern
#

i am using aws lambdas for each of my bot commands. some of the lambdas have duplicate code so i'm moving that logic to "layers" so that it can be shared between the lambdas. I'm not sure how i should organize the common logic. should each shared function be it's own layer? should i make 1 large layer with all the common logic? Each lambda is limited to 5 layers so i'm worried about making each layer 1 function because i might run out of layer slots for the lambda, but each lambda is so small that it shouldn't have too many needed layers so i dont really know what to do yet

tardy hornet
#

how can I make that the bot wont react to interactions in its dms?
with:

        if (interaction.channel.type === 'dm') return;

????

earnest phoenix
#

dude you have returned to dm

#

wtf

#
  // your code 
}```
tardy hornet
#

I dont want it to return anything

earnest phoenix
#

what

neat ingot
#

@tardy hornet

#

if not a guild, then do nothin

tardy hornet
#

k ty

earnest phoenix
#

i don't understand didn't he want to reply to dm messages

tardy hornet
#

no

#

"how can I make that the bot wont react to interactions in its dms?"

neat ingot
#

if its slash commands, they can also reply in channels they cant see

#

so you might want to check bot permissions for the channel after that

earnest phoenix
#

i thought won lmao

tardy hornet
#

lol yeah my bad forgot to add a t

#

well it did not work, its a slash command @neat ingot but ty for trying to help

#

it still responded

neat ingot
#

dang, you rich

earnest phoenix
neat ingot
#

idk why it doesnt work, i use those 3 checks for all my commands, and they dont respond in dms or channels it doesnt see (i also have checks for channel access)

earnest phoenix
tardy hornet
#

yes

earnest phoenix
#

show your code

neat ingot
#
    if (interaction.user.bot) return; // if command user is a bot, return
    if (!interaction.guild.available) return; // if there is no guild available, return
    if (interaction.channel.type !== 'GUILD_TEXT') return; // if the command channel isnt a guild text channel, do the hokey kokey
#

^ is all i use for the dm check, and for stopping bots ofc

tardy hornet
neat ingot
#

you can also get bot perms by: js const bot_permissions = guild.me.permissionsIn(channel).toArray();

earnest phoenix
#

messageCreate Thonk

tardy hornet
#

fuck

#

ty lol

neat ingot
#

i dont like that code, sorry

earnest phoenix
neat ingot
#

you should store your mods in a config or env file

#

and idk what bls and blms are, but they are quite clearly discord snowflakes

tardy hornet
#

I will save their ids in a db

neat ingot
#

start as you mean to go on โค๏ธ

tardy hornet
#

ty

tardy hornet
#

fixed

neat ingot
#

which event are you listening to now? interactionCreate?

earnest phoenix
neat ingot
#

is how i handle that particlar event in my nub code ๐Ÿ™‚

slender wagon
#
function toDiscord() {
var username = document.getElementById("name").value;
var age = document.getElementById("age").value;
var discordWebhook = "https://discord.com/api/webhooks/whatever";
var request = new XMLHttpRequest();
request.open("POST", discordWebhook);
request.setRequestHeader('Content-type', 'application/json');
var params = {
    username: "username",
    content: "hi"
};
request.send(JSON.stringify(params));
}
#

ok so i am working on this little thing here and trying to get data from a form (it works)

#

but the issue is it doesn't send it to my webhook

#

unless i paste it on the console, idk if a webhook is supposed to work that way

tardy hornet
slender wagon
#
var discordWebhook = "https://discord.com/api/webhooks/whatever";
var request = new XMLHttpRequest();
request.open("POST", discordWebhook);
request.setRequestHeader('Content-type', 'application/json');
var params = {
    username: "username",
    content: "hi"
};
request.send(JSON.stringify(params));
}

this part works just fine tested it on the console, but when i do it inside my webpage it wont work

slender wagon
#

no i am making my own form

#

it does call the thing

#

i console loged the username and everything

#

it just doesn't push it to the webhook

foggy heath
#

Does your button have type="submit"?

slender wagon
#

yup

neat ingot
#

your form* might be trying to submit before the function call?

#

idk, random guess

foggy heath
#

Add your script after body

slender wagon
#

okay

#

same shit

#

what could this be

foggy heath
#

Your localhost shutdown I guess

neat ingot
#

if you comment out the request, when you click to submit your form, does the page reload or anything?

earnest phoenix
slender wagon
#

and adds this

neat ingot
foggy heath
neat ingot
#

try remove the () from your onsubmit= declaration ?

#

i'd personally just get the js object and rewrite the function from there, but give that a bash first ๐Ÿ˜„

slender wagon
#

same thing

slender wagon
#

found

neat ingot
#

well, i rolled the dice and failed, who's up next? ๐Ÿ˜›

foggy heath
#

Create codesandbox link

#

I will check xD

neat ingot
#

i just spent like 2 hours debugging why paypal wasnt working for my localhost site, to discover i hadnt enabled the button to open the freakin paypal window...

foggy heath
neat ingot
#

yea, a big one ๐Ÿ˜„

#

it happens though

foggy heath
slender wagon
neat ingot
#

wth

#

in your umm

#

pass the event

slender wagon
#

which event am i supposed to call here

neat ingot
#

^ that shows a form that when event isnt passed, it doesnt log

#

check the fiddle link i sent, it may help ๐Ÿ™‚

#

like, if you either dont pass the event to the toDiscord(), then the event.preventDefault() cant be triggered

#

if that isnt there, the form will trigger a reload when submitted

#

or, try to load another page ~ w.e

gentle condor
#

how can I undisable a disabled button in discord.py (discord-componemts)

slender wagon
#

@neat ingot YOOO THANKS

#

that fixed itt

neat ingot
#

random guess for the win

foggy heath
neat ingot
#

๐Ÿ˜›

spark flint
#

ID is undefined

#

Wait no

#

It means that Channel is undefined, so where can it get ID from?

sudden geyser
crimson pike
neat ingot
#

synthwave 84 (vs code extension)

#

you can make it glow like neon and stuff too, but thats too distracting imo ๐Ÿ˜›

earnest phoenix
#

Need help if my bot dont have presnece intent and i want to use this code

intents = discord.Intents.all()
intents.members = True

How to use this

earnest phoenix
spark flint
#

ah

#

is it returning an error

earnest phoenix
#

Yes

spark flint
#
intents = discord.Intents.default()
intents.members = True```
#

that

#

change to that

earnest phoenix
#

This work not properly

spark flint
#

default instead of all

earnest phoenix
#

On deafult
Bot not ban user

spark flint
#

thats why you then specify underneath which intents

earnest phoenix
#

This works?

#

Or not

spark flint
#

Should do

#

but its not good practice requesting all intents

#

thats why you do default and request the ones you need

earnest phoenix
#

@spark flint what is meant by presence intent

spark flint
#

see if a user is online, do not disturb, offline, idle etc

#

and see what game theyre playing etc

earnest phoenix
spark flint
#

well do you need to?

earnest phoenix
#

That user is idle or

#

Dnd

earnest phoenix
spark flint
#

do you need to track their status

#

always think ahead, is it a good enough feature for Discord to verify you for

spark flint
#

is your bot verified

earnest phoenix
#

Yes

spark flint
#

then apply for it in developer dashboard

earnest phoenix
#

Or online

spark flint
#

member.status

earnest phoenix
spark flint
#

thats it

#

that would return the members status

#

Yes

earnest phoenix
solemn latch
#

thats pretty hard to answer, but in the location you need it, which also has the member variable defined.

spark flint
#

yep

solemn latch
#

๐Ÿ‘€ why do you have random capital letters in variable names

spark flint
solemn latch
#

it makes readability go out the window ๐Ÿ˜„

#

I've never used discord-buttons, always just used the ones inbuilt in js.
not sure how much help I can give.
and it seems the owner of the library no longer supports it.

#

probably best to not use deprecated libraries.

#

someone else might be able to help though, you never know.

earnest phoenix
#

On click button next page show

solemn latch
#

Not a py programmer, not sure how to do that, but the py docs cover it

spark flint
#

Its a module called discord-components

tardy hornet
#

when I try to start the bot

#

it never done this before

lament rock
plucky cairn
#

Has anyone had problems with the BOT skipping music before finishing the current one?

#

with ytdl

earnest phoenix
#

don't use youtube for music bots

#

discord doesn't verify them

#

meaning your bot can never be in more than 100 servers

plucky cairn
#

for some reason, i saw that the bot is playing a song, and for no reason it stops and goes to the next

plucky cairn
earnest phoenix
#

is in the support server of a website that lets you grow your bot

plucky cairn
#

what are you guys using for the bot? spotify?

earnest phoenix
#

nothing

#

don't have one

plucky cairn
earnest phoenix
#

Is it possible to check if a link is a redirect to an ip grabber for a chrome extension?

sudden geyser
#

easier said than done

earnest phoenix
#

maybe this css selector works

quartz kindle
lament rock
#

Also, you should look into using LavaLink instead of writing your own voice code

#

voice is super difficult

#

I wrote my own LavaLink so I would know

tardy hornet
gilded olive
quartz kindle
tardy hornet
earnest phoenix
#

app.enable("trust proxy"); is this required, if i use apache 2 reverse proxy?

quartz kindle
#

and you still didnt explain what "does not work" means

#

nobody can help you if you dont tell us whats going on

tardy hornet
quartz kindle
#

?

#

what error?

tardy hornet
# quartz kindle ?

it does not matter it was a problem on the host side, they just told me and its good now, sorry for spending your time for nothing

quartz kindle
#

lol ok

earnest phoenix
quartz kindle
earnest phoenix
#

normal http requests ig,
basic web server with endpoints /slash/gid:/create
I have used this package https://www.npmjs.com/package/express-rate-limit ,but when it hits the rate limit it is global and not ip specific

quartz kindle
#

according to the docs, "trust proxy" basically unhides headers set by a proxy, for example X-Forwarded-For

#

these headers are used to obtain the original requester IP address

#

otherwise express can only see apache's ip address, since all requests are coming from apache

earnest phoenix
#

so i need to enable it and are there any sideeffects?

quartz kindle
#

yes, and no there are no side effects

tepid warren
#

Can someone teach me how to develop my own bot?

wheat mesa
#

Do you know any programming languages?

tepid warren
wheat mesa
#

Youโ€™re going to need to learn a programming language first

tepid warren
#

Where can I learn that? ๐Ÿ˜ญ

sudden geyser
#

I recommend starting off with JavaScript

wheat mesa
#

Thereโ€™s tons of tutorials online, javascript and python are beginner friendly

tepid warren
#

What about on phone-

wheat mesa
#

(Though personally Iโ€™d recommend javascript)

sudden geyser
#

noop

tepid warren
#

Ok

lament rock
#

no operation

tepid warren
#

Hopefully I get a laptop soon

tepid warren
sudden geyser
#

You can develop on a mobile device, but it's very limiting compared to desktop. I recommend you search up tutorials on JavaScript

#

You can then build a bot with Discord.js

lament rock
#

there is a web version of vscode

#

probably the best bet if mobile is only option

tepid warren
wheat mesa
#

Itโ€™s not a great experience, but if youโ€™re really motivated then go for it

tepid warren
#

I found my iPad

lament rock
#

I got node on my jailbroken iphone, but poor experience

tepid warren
#

Is any bot developers available to hop in VC and teach me how to use JavaScript?

wheat mesa
#

Iโ€™d recommend looking at some stuff online first, like W3Schools or something similar

tepid warren
#

Ok.

tepid warren
wheat mesa
#

Javascript

#

More specifically node.js if youโ€™re looking into bot development

tepid warren
#

I am gonna go into YouTube and find some videos. Is also Programming Language

lament rock
#

YouTube tutorials for JavaScript are weird awoowtf

#

if you're a visual learner though, might be something

tepid warren
#

I will see yโ€™all soon

sudden geyser
#

There are a lot of ways to learn JavaScript, and specifically Discord bots.

tepid warren
#

After viewing this video

quaint rampart
#

hey guys so i have an array full of player objects and i wanna sort the array by their team value there are only 2 team values 'Red' and 'Blue' how can i achieve this? (js) array: https://sourceb.in/NLmaBRFXPL

heavy stirrup
#

Hi

#

Me bot and top.gg verivay @spark flint

spark flint
#

please stop pinging me

wheat mesa
#

But itโ€™s important

wheat mesa
modest maple
#

10/10 would do again

lyric mountain
#

No way, yall verivay?

novel jetty
#

This by default, returns true or false. How can i make it so it returns tickYes or โŒ?

**MANAGE_CHANNELS** - ${message.member?.guild.me?.permissions.has('MANAGE_CHANNELS')}
sudden geyser
#

since it returns a boolean, wrap it in a condition

#

For example,

if {message.member?.guild.me?.permissions.has('MANAGE_CHANNELS')) {
  return "tickYes"
} else {
  return "tickNo"
}
novel jetty
# sudden geyser For example, ```js if {message.member?.guild.me?.permissions.has('MANAGE_CHANNEL...

This is what my code looks like and how you showed to do it, i will have to rewrite and hard code im pretty sure

const embed = new MessageEmbed()
      .setAuthor('Permission Checker')
      .setDescription(`This is all the permissions that i have\n\n
      __**General Server Permissions**__
      **VIEW_CHANNELS** - ${message.member?.guild.me?.permissions.has('VIEW_CHANNEL')}
      **MANAGE_CHANNELS** - ${message.member?.guild.me?.permissions.has('MANAGE_CHANNELS')}
      **MANAGE_ROLES** - ${message.member?.guild.me?.permissions.has('MANAGE_ROLES')}
      **MANAGE_EMOJIS_AND_STICKERS** - ${message.member?.guild.me?.permissions.has('MANAGE_EMOJIS_AND_STICKERS')}
      **VIEW_AUDIT_LOG** - ${message.member?.guild.me?.permissions.has('VIEW_AUDIT_LOG')}
      **MANAGE_WEBHOOKS** - ${message.member?.guild.me?.permissions.has('MANAGE_WEBHOOKS')}
      **MANAGE_SERVER** - ${message.member?.guild.me?.permissions.has('MANAGE_GUILD')}

      __**Membership Permissions**__
      **CREATE_INVITE** - ${message.member?.guild.me?.permissions.has('CREATE_INSTANT_INVITE')}
      **CHANGE_NICKNAME** - ${message.member?.guild.me?.permissions.has('CHANGE_NICKNAME')}
      **MANAGE_NICKNAMES** - ${message.member?.guild.me?.permissions.has('MANAGE_NICKNAMES')}
      **KICK_MEMBERS** - ${message.member?.guild.me?.permissions.has('KICK_MEMBERS')}
      **BAN_MEMBERS** - ${message.member?.guild.me?.permissions.has('BAN_MEMBERS')}

      __**Text Channel Permissions**__
      **SEND_MESSAGES** - ${message.member?.guild.me?.permissions.has('SEND_MESSAGES')}
      **SEND_MESSAGES_IN_THREADS** - ${message.member?.guild.me?.permissions.has('SEND_MESSAGES_IN_THREADS')}
      **CREATE_PUBLIC_THREADS** - ${message.member?.guild.me?.permissions.has('CREATE_PUBLIC_THREADS')}
      **CREATE_PRIVATE_THREADS** - ${message.member?.guild.me?.permissions.has('CREATE_PRIVATE_THREADS')}
      **EMBED_LINKS** - ${message.member?.guild.me?.permissions.has('EMBED_LINKS')}
      **ATTACH_FILES** - ${message.member?.guild.me?.permissions.has('ATTACH_FILES')}
      **ADD_REACTIONS** - ${message.member?.guild.me?.permissions.has('ADD_REACTIONS')}
      **USE_EXTERNAL_EMOJIS** - ${message.member?.guild.me?.permissions.has('USE_EXTERNAL_EMOJIS')}
      **USER_EXTERNAL_STICKERS** - ${message.member?.guild.me?.permissions.has('USE_EXTERNAL_STICKERS')}
      **MENTION_EVERYONE** - ${message.member?.guild.me?.permissions.has('MENTION_EVERYONE')}
      **MANAGE_MESSAGES** - ${message.member?.guild.me?.permissions.has('MANAGE_MESSAGES')}
      **MANAGE_THREADS** - ${message.member?.guild.me?.permissions.has('MANAGE_THREADS')}
      **READ_MESSAGE_HISTORY** - ${message.member?.guild.me?.permissions.has('READ_MESSAGE_HISTORY')}
      **USE_APPLICATION_COMMANDS** - ${message.member?.guild.me?.permissions.has('USE_APPLICATION_COMMANDS')}
      
      **ADMINISTRATOR** - ${message.member?.guild.me?.permissions.has('ADMINISTRATOR')}
      `)

    message.reply({ embeds: [embed]})
sudden geyser
#

You could simplify that with a function

#
function permissionEmoji(message, p) {
  if (message.member?.guild.me?.permissions.has(p)) {
    return "tickYes";
  } else {
    return "tickNo";
  }
}
#

And now you can just

`**VIEW_CHANNELS** - ${permissionEmoji(message, "VIEW_CHANNEL")}`
#

You could go even farther and get the permission names from somewhere else

#

Since hard coding them isn't fun

novel jetty
#

Yea

#

Thanks

#

@sudden geyser

sudden geyser
#

A string is a valid permission resolvable.

#

So maybe TypeScript is just trying to be annoying

#

Does running your bot still work?

novel jetty
#

This is whats its giving me

novel jetty
#
return new TSError(diagnosticText, diagnosticCodes);
           ^
TSError: โจฏ Unable to compile TypeScript:
src/commands/test/audit.ts:18:53 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'PermissionResolvable'.

18       if (message.member?.guild.me?.permissions.has(p)) {
                                                       ~

    at createTSError (C:\Users\great\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:750:12)
    at reportTSError (C:\Users\great\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:754:19)
    at getOutput (C:\Users\great\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:941:36)
    at Object.compile (C:\Users\great\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:1243:30)
    at Module.m._compile (C:\Users\great\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:1370:30)
    at Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Object.require.extensions.<computed> [as .ts] (C:\Users\great\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:1374:12)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:94:18)
    at Object.<anonymous> (C:\Users\great\OneDrive\Desktop\Angelus\src\index.ts:101:17)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Module.m._compile (C:\Users\great\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:1371:23)
    at Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Object.require.extensions.<computed> [as .ts] (C:\Users\great\AppData\Roaming\npm\node_modules\ts-node\src\index.ts:1374:12) {
  diagnosticText: "\x1B[96msrc/commands/test/audit.ts\x1B[0m:\x1B[93m18\x1B[0m:\x1B[93m53\x1B[0m - \x1B[91merror\x1B[0m\x1B[90m TS2345: \x1B[0mArgument of type 'string' is not assignable to parameter of type 'PermissionResolvable'.\r\n" +
    '\r\n' +
    '\x1B[7m18\x1B[0m       if (message.member?.guild.me?.permissions.has(p)) {\r\n' +
    '\x1B[7m  \x1B[0m \x1B[91m                                                    ~\x1B[0m\r\n',
  diagnosticCodes: [ 2345 ]
}
[nodemon] app crashed - waiting for file changes before starting...
#

Nope

sudden geyser
#

sadge

#

Try setting the type of p to PermissionResolvable

#

I don't use TypeScript so I could be wrong

novel jetty
#

It works now!

#

Thanks for the help!

lament rock
#

type string is not assignable to literal string union

#

const s = "string";
const s2: "string" = s; // type string is not assignable to type "string"

#

string literal types are weird but helpful

round cove
#

That doesn't sound right.

#

That should work.

#

What TS version are you running?

proven lantern
#

are types causing a problem

#

im so sorry

#

but you can only blame typescript

round cove
#

Not true

proven lantern
#

typescript is great for solving problems it creates

earnest phoenix
#

TS doesn't really create issues

#

its the people who uses it

proven lantern
#

The theory about types is that it allows the compiler to find bugs at compile time, but you still have to test. the bugs that the type system find are useless. types system causes bugs that keep you up at night because you need to get around the type system
https://youtu.be/XFTOG895C7c?t=3258

cinder patio
#

yeah that should work

lament rock
# round cove That doesn't sound right.

it is correct. This occurs on any ts version. assigning something to a string without explicitly typing it as a string literally will be type string.

const s: "string" = "string";

will work, but my previous example will not because the constant was just of type string when the variable assigned to expects string literal

round cove
#

Your version or config must be the reason.

#

I'm also using strict.

#

So I would assume it's your config.

lament rock
#

I am using strict type checking

proven lantern
#

oof

round cove
#

Nothing else at all in your config?

cinder patio
lament rock
#

Probably a lot of other stuff but idk what all I've changed

#

it would be type string unless the as const modifier is present on my end

cinder patio
#

Or should I say a string type with value "string"

#

const b: "string" also has a string type with value "string"

#

so the two types are compatible

lament rock
#

my settings are really strict

#

super strict

round cove
#

Okay, show it then.

#

strict: true

#

lol

lament rock
#

at work rn

sudden geyser
# earnest phoenix TS doesn't really create issues

It does, imo. It adds so much complexity, valuing correctness over flexibility, and is, at best, good at verifying the type of something is correctโ€”not whether its value actually makes sense (which is common). Even if you find a clever way to make the type system check the "value", there's a good chance the complexity of it is so astronomically high that a test/assert would've done better.

proven lantern
#

types are like training wheels. it's easy to do easy stuff, but then it gets in the way when you do complex stuff

round cove
sudden geyser
#

Yes.

round cove
sudden geyser
#

I use both static and dynamic and prefer dynamic.

proven lantern
#

i usually design a system at the start before i know everything about the system

#

but if you are really doing waterfall model development then it wont hurt too much to use types

cinder patio
#

If types get in your way of doing complex stuff then you just don't know how to use types

cinder patio
#

ยฏ_(ใƒ„)_/ยฏ

proven lantern
#

weird, i know how to use types though

round cove
#

Going back to the string literals, TS is infering that my const string is just the string literal string, but I'm also on TS 4.5.

proven lantern
#

๐Ÿฟ

round cove
#

const str: string = "string"

I can type guys

proven lantern
#

that's a lot of typing

round cove
#

at least 20 characters

proven lantern
#

can you do object destruction while giving the variables a type?

round cove
#

It's inferred, why?

cinder patio
proven lantern
#

i'm not sure how the syntax would look

cinder patio
#

const {a, b}: Record<string, string> = {};

proven lantern
#

are the keys in objects ordered?

#

const {a, b}: Record<string, number> = {};

#

would a be a string and b be a number?

round cove
#
interface Person {
  name: string;
  age: number;
}

const dylan: Person = {
  name: "Dylan",
  age: 24
}

const { name, age } = dylan; // string, number```
cinder patio
#

string is the key type

#

number is the value type

proven lantern
#

is it possible to destruct two different types while doing strict typing?

lament rock
#

yes

cinder patio
#

const {a, b}: { a: string, b: number } = {};

round cove
#

Like what I gave above?

proven lantern
#

like what googlefeud is showing

round cove
#

Literally what I sent above

proven lantern
#

oh wait

#

i mean left side of the assignment

#

no neither of what you did

round cove
#

What about the left side?

proven lantern
#

const str: string = "string"

#

const str: string

round cove
#

const str: string = "string" The type is inferred here you don't need to type it.

proven lantern
#

you never need to type it

round cove
#
const str: string = "string"
const str = "string"``` are the same
proven lantern
#

it's js

#

with ts garbage added

round cove
#

what

#

lol

#

lol

#

lol

#

Alright I'm not going into this one.

#

Have fun

wheat mesa
#

The TS compiler (as with most other modern compilers at this point) can infer type literals

wheat mesa
#

Types are not a bad thing

#

They prevent errors before they happen

proven lantern
#

ts is a superset of js

#

so it has all the good parts of js

wheat mesa
#

Because js has flaws where types need to be known

proven lantern
#

js does have flaws

pale vessel
#

Is it really a flaw?

proven lantern
#

but there should be a subset of js used, not a superset with all the flaws

#

and more

wheat mesa
#

I donโ€™t want to have a function like js function addTwoNumbers(a, b) { return a+b; } when a or b might not be number types

round cove
#

hurrdurr only pass numbers to it then !!!1 1 11 11

#

js devs be like

#

๐Ÿ™„

wheat mesa
#

I used js for a while then I got into TS and realized how much nicer it was

round cove
#

why is my program running into a runtime error

sudden geyser
#

So maybe adding a number and a string is an error in this version

wheat mesa
#

Iโ€™d rather have my compiler yell at me than run into errors at runtime tbh

proven lantern
wheat mesa
#

Why write tests when I could just use types and make everything more clear?

proven lantern
sudden geyser
proven lantern
#

the simplest of problems

wheat mesa
#

I understand that unit testing is useful in both situations but the fact still stands that typing can catch a lot of overlook-able errors

sudden geyser
#

they only catch a small set of bugs imo

#

the dumb mistakes like spelling

#

or the type not being specific enough

#

or you know what

#

but when you need something more specific/advanced, ts tends to fall flat

#

what I was saying before about even if you could get a type checker to catch them

#

I was recently looking into Ramda (JS functional library) and wondered why it wasn't typed, and it was for these similar reasons

cinder patio
#

types not only help with simple stupid errors but they also improve readability by a lot, and also make your code more straightforward and predictable

sudden geyser
#

at the expense of complexity? sure

#

it's nice with documenters too

#

auto generate these types/syntax

#

I get that stuff

cinder patio
#

yup. And also I don't think it really introduces that much complexity

#

it increases file size yes but it's worth it

round cove
#

What are you on about when you say complexity, it's not making sense.

#

Please explain.

spark flint
#

How would I check if a record already existed in a mongodb database? I'm using Nodejs.

round cove
spark flint
#

oh epic

#

then i could do if (!database.find({userid:userid})) right?

round cove
#

You need to await the process.

cinder patio
#

pretty sure it returns a promise

spark flint
#

oh shit yeah

round cove
#

Returns a "query" which is their version of a promise.

sudden geyser
#

If you're saying things like "function x takes inputs a int and b int and returns int", it doesn't sound complex. But then you want to draw a relationship between the two inputs and the output, and then you have Addition and Subtraction types that are structurally equivalent but have different types and therefore incompatible (TypeScript doesn't have this since it's structural, but people want it sadly), and then you want your type checker to do something really specific, like verify that two numbers don't overflow when combined (Xetera wrote an article about user permissions like this), and when you want to add a new field to your type but it turns out that was a breaking change despite it being optional

And then you sit back and ask, "is this really what I want?" A lot would say yes, but me? Nah.

#

I've only talked a bit about scenarios where I think static typing like TS isn't beneficial, but I don't think types are all bad. Lower-level and mission-critical projects that use types for correctness or performance (like Rust) benefit from static typing. And the rest? Well, at least you can have your IDE auto-complete when you type dot.

#

but fighting a static vs. dynamic war is boring

#

So what's the weather like outside

proven lantern
#

I am still trying to think of the best way to refactor the common logic for my lambda into layers

#

the first function i'm planning to move into a shared layer is one that creates the matchmaking lobby embed object based on an array of players in the lobby

neat ingot
#

how does using lambdas work for bot development?

proven lantern
#

i use the interactions endpoint to route to the lambda

#

interaction endpoint -> api gateway -> router lambda -> command lambda

neat ingot
#

so like

#
module.exports = {
    event_name: 'interactionCreate',
    execute_once: false,
    async execute(interaction) {
        // api call to lambda(interaction)
    },
};```
#

or am i way off? ๐Ÿ˜„

#

i've never used lambdas before, but i thought it was just for like, singular functions. so having a bot running in one confuses me

proven lantern
#

i just register a url here that points to my api gateway

neat ingot
#

oh interesting

proven lantern
#

i dont use a library

neat ingot
#

do you still need a bot to be running/logged in?

proven lantern
#

you dont need it, but you can have one running

#

i have one running so it appears online

#

and for the legacy commands

#

they were talking about better support for https only bots during the last event on the Discord Developers server

round cove
#

What does your lambda look like?

proven lantern
#

the team

#

the slash project is one big lambda with all the command handlers. the tu prefix projects are the individual commands that im refactoring all the logic into

neat ingot
#

i find the concept of a bot using lambdas quite intreaguing tbh

proven lantern
neat ingot
#

node is on v16 now btw for lts

proven lantern
#

aws lambda only supports 14 currently

neat ingot
#

so does a lambda have to like, spin up the node env each time it is called?

proven lantern
#

nope

#

it stays on after a cold start

#

and cold starts are very fast when the lambda is < 10mb

#

like 10-50 ms

neat ingot
#

o0

#

thats insanely fast

proven lantern
#

aws is much faster than firebase

neat ingot
#

i have internal network api calls that dont go as quick as that, and they technically run locally on the machine lol

proven lantern
#

nice, lol

modest maple
proven lantern
#

yeah, firebase does a lot more than just serverless functions

modest maple
#

Also if you think 10ms is good for cold start cloudflare does sub 1ms cold starts on the paid teirs

neat ingot
#

well, my server is warm. take that! SnorlaxDab

proven lantern
#

i need to play with cloudflare workers

#

they seem pretty cool

#

maybe that's the next step

#

once all the commands are separated i can easily move one command over at a time

proven lantern
neat ingot
#

it legit does since i started mining crypto ๐Ÿ˜„

proven lantern
#

make sure to only do gpu mining and not cpu mining.

neat ingot
#

lol yea

#

i use my cpu

proven lantern
#

the server will be very slow if you did

boreal iron
#

I wonder about how cheap your electricity bill must be if you go for miningโ€ฆ

neat ingot
#

old gtx 1060 6gb, earns around 50p a day after eletric fees

#

i mean, its not much, but im not tryna flex it or anythin' ๐Ÿ˜›

boreal iron
#

Hmm itโ€™s not worth it over hereโ€ฆ

proven lantern
#

energy here starts at $0.09 and then goes up to a little less than $0.11

#

per kwh

neat ingot
#

texas?

#

texas energy is cheap af

#

i legit pay 20p per kw/h, which is like, 30+ cents

woeful pike
# sudden geyser If you're saying things like "function x takes inputs a int and b int and return...

So the thing you're referring to is probably related to this https://blog.merovius.de/2017/09/12/diminishing-returns-of-static-typing.html but I don't understand the idea of throwing the baby out with the bathwater. Yes you can technically describe your entire program within just a type system in a theorem prover or something and it would be a gigantic pain and not worth it 99.9% of the time, but static types become useful way earlier than that. Just because structural typing can be a pain doesn't mean the entire concept of static types are not worth it

boreal iron
#

Yeah Iโ€™m around 40cents too

#

EU is just a big joke

woeful pike
#

like I just personally don't understand people who prefer dynamic typing to some kind of static typing. Writing js was such an unbelievable pain for me that I was gonna quit it entirely before I found TS

proven lantern
#

we get offsets here from hydro power plants

neat ingot
#

raw js 4 lyfe!

woeful pike
#

writing js is so much easier than typescript yes but you very rarely write something and never touch it again

#

changing things in js tho. The biggest pain I have ever experienced

proven lantern
#

training wheels are good for starters, but you can do a lot more when you take them off

woeful pike
#

same story with python or any dynamically typed language

#

there are cool languages I want to use like clojure and elixir but I can't because dynamic typing is so unusable lol

modest maple
woeful pike
#

ye but strong and dynamic are different traits

neat ingot
#

i mean, just because you can write dynamic code, it doesnt mean you have to

woeful pike
#

well yeah but a type system that allows dynamic typing is unsound

neat ingot
#

only if the user is

#

but yea, having forced typings do make it easier for the user

woeful pike
#

typescript does an ok job at preventing implicit any and stuff like that

proven lantern
#

like ts

woeful pike
#

I mean.. that depends

proven lantern
#

there are some reason for typed languages

woeful pike
#

assembly is also dynamically typed lol

#

it's more about escape hatches

neat ingot
#

to be fair, type how you feel comfortable. if you like the featureset that ts offers, stick with it. its obviously a popular choice for a reason as many people feel the same way

proven lantern
#

types belong in languages that are system languages not application languages

woeful pike
#

For example Elm has basically 0 escape hatches. You can't circumvent the type system so even though you compile to JS you simply don't get runtime errors

proven lantern
#

elm is awesome

neat ingot
#

using one language to convert to another is always going to be behind the main language tho

proven lantern
#

parts of it

woeful pike
#

no? try handwriting writing assembly that's better than the C++ compiler lol

#

unless you mean high level transpiling

proven lantern
#

primary distinguishing characteristic of systems programming when compared to application programming is that application programming aims to produce software which provides services to the user directly (e.g. word processor), whereas systems programming aims to produce software and software platforms which provide services to other software, are performance constrained, or both (e.g. operating systems, computational science applications, game engines, industrial automation, and software as a service applications).

woeful pike
#

which could still be faster than handwritten js like compiling with asm.js

woeful pike
#

types make sure your program is sound, why would it matter who the end user is

proven lantern
#

i think of driver software when i think of systems programming

#

one provides an api to other programmers

#

the other makes a product

woeful pike
#

ok but you have running code at the end of the day. Doesn't really matter what the purpose is

#

unless you mean it's more acceptable for application code to be unsound and crash/stop working etc

proven lantern
#

they can use more memory and be more sound

#

less error prone

#

you can build features faster for the customers

#

you can make changes faster

woeful pike
#

making changes in dynamically typed languages is always ALWAYS much slower and more painful

#

you have no idea what you broke

#

unless you have flawless test coverage

#

which makes you build features slower

proven lantern
#

depends on how you program

#

if you write coupled code then you will have the problem

woeful pike
#

there's a sweet spot where you know exactly what stops working when you break the contract between types but without needing to encode every type of information at the type level

#

yeah you can write decoupled code but when you make one breaking change somewhere you don't know what parts of your code relies on that broken change without either running your code or having perfect code coverage like I said

#

I absolutely hate running my code, I love having a compiler tell me what exactly broke

proven lantern
#

you never mutate

#

so things never break

woeful pike
#

what does mutations have to do with anything

proven lantern
#

you make new functions

#

contracts cant change

woeful pike
#

that sounds like a nightmare. You don't need to keep the internals of your own codebase opaque to yourself

proven lantern
#

in my case whenever i make a new command i create a new codebase

#

i dont change another codebase

woeful pike
#

and how do you find where you use a specific function without type information

proven lantern
#

if there is going to be a breaking change then i make a new command and cutover to that

woeful pike
#

when it's time to migrate

#

I don't see how this is in any way more productive than getting instant feedback when you break things lol

proven lantern
#

you cant break things like you can when they are coupled

#

its very liberating

#

you dont have to think about the entire state and flow of the project to make a feature

woeful pike
#

I mean I don't have to think about it, I just change something and look at what broke

proven lantern
#

i just make a new thing that cant break anything

woeful pike
#

so much more work

#

idk it just seems like a painful way of working around the lack of safety rather than "move fast with dynamic typing" people like to talk about

proven lantern
#

less error prone is a big feature of programming this way

modest maple
proven lantern
#

decoupling things means you can focus at the task at hand and not worry about other stuff

modest maple
#

how is decoupling at all linked to dynamic languages again?

woeful pike
#

yeah I don't see the connection here

#

you can write decoupled code with any kind of type system

#

it sounds more to me like you're forced to version your own internal code to prevent accidentally breaking things because of dynamic typing more than anything

proven lantern
#

the issue caused by tight coupling are relieved a bit with a strong type system

modest maple
#

As someone who maintains a roughly 500k loc python code base, you really dont save any time with it being written dynamically, infact the client has definitely lost not only performance but also alot of development time which has been spent debugging bugs coming out of the lack of strict rules.

woeful pike
#

most python people end up using type hinting at that point everywhere anyways so why not just use a proper type system idk

sudden geyser
# woeful pike So the thing you're referring to is probably related to this https://blog.merovi...

That article does share a lot of my views on static vs. dynamic typing, but I'm not suggesting we all throw out static typing. In fact, I said static typing is good in certain environments (e.g. systems where "real" performance can be extracted from knowing the type), but I don't see it useful in most, such as the browser or any "JS" environment (Node.js). In the browser, verifying the type is for your own safety. It doesn't care if you made the type checker happy, so its benefits extend to the developer at best. But that is why people use stuff like TypeScript, right? So I can be sure that argument I passed was an integer rather than a double? Like I said before, I don't see the benefit in these scenarios as types just add a lot of complexity to projects. It creates many puzzles for developers to solve and make sure their code is "correct" (which it's not, often). I can make sure that argument is an integer without one.

In some codebases, you can have static here and dynamic here (e.g. Dart), but, in general, I prefer dynamic typing. It has a lot of perks that I like, such as being very flexible. If static typing works for you (Haskellers), go do it.

woeful pike
#

what are the downsides of static typing tho? Like to me complexity of types come from the complexity of the code

modest maple
#

also ecosystem generally determines the choice of language used more so the typing system tbh

woeful pike
#

like for example, if you can't represent something like this returned by a function in a type system, that complexity doesn't just go away. You just forget about the contract because you don't have to write it down and it feels simpler until you make a mistake

type Result<T> =
  | { status: "success", data: T }
  | { status: "fail", reason: string }
#

and yeah there are benefits to dynamic typing for things like plugin systems from what I remember but that's fairly niche

proven lantern
#

like this?

const { status, reason, data} = response.data;```
woeful pike
#

yeah, but data only exists if status is "success" you have to remember to put an if statement before you access it

#

why would you want to remember that detail when you could force the compiler to remember it for you

proven lantern
#

why do you want the data if it failed?

#

and errors usually have data

woeful pike
#

and yeah learning how to grasp a type system takes a little bit more time but I don't see the point in picking a language based on how easy it is for a beginner who doesn't know the language to use it

woeful pike
#

that was just an example

proven lantern
#
const { status, reason, data} = response.data;
if (status === "fail"){
  throw new Error("bad");
}
return data.reduce(...);
woeful pike
#

I think you're missing the point

proven lantern
#

type checking is the point

modest maple
#

yes

woeful pike
#

you can only have so many conditions and rules in your head as a developer

proven lantern
#

i dont need that help

modest maple
woeful pike
#

you have other more important things to be thinking about than rules of your program

proven lantern
#

write small pure functions as 90% of your code

modest maple
#

man you would not be fun to be with on a large code base lol

proven lantern
#

then a simple imperative shell that uses those functions

woeful pike
#

ah yes here I was as a FP fanatic writing impure functions

modest maple
#

also, there's a difference between handling the cases you expect vs being forced to handle all cases that a possible.

proven lantern
#

i know how to work on large codebases and all the problems that come with it

woeful pike
#

I can deal with it too, I just don't want to and shouldn't have to either. Why do the work of a computer

modest maple
#

also, you're acting like types are a bad thing?

proven lantern
#

dynamic types are great

#

i love types

woeful pike
#

don't mind me I'm just using dynamic typing JUSTLOL

quartz kindle
#

js is best in za vorld

modest maple
#

itsu_shock k

proven lantern
modest maple
#

tbh I generally use JS over type script in alot of personal projects

#

and just... avoid using anything JS related lol

proven lantern
#

just use an spec object like i posted

quartz kindle
#

h8rs gonna h8 :^)

woeful pike
#

if you're gonna go through the trouble of writing types why not make sure the compiler actually checks them

#

same thing with elixir, good spec support but idk why it's not enforced

quartz kindle
#

because you're supposed to drink elixir, not code in it

#

:^)

orchid fox
orchid fox
modest maple
#

have you attempted searching?

orchid fox
#

No

#

But I know discord.js and BDFD only

modest maple
#

might be a good idea to try

orchid fox
#

Yeah

sudden geyser
# woeful pike what are the downsides of static typing tho? Like to me complexity of types come...

I outlined some reasons in the first quoted message (<#development message>). The biggest ones in my view are flexibility and correctness. I've already talked about correctness before, like this.

function double<T: Number>(n: T): T {
  return n + n;
}

Of course, I don't write TypeScript, so this implementation could be wrong, but what if doubling that number was actually too large? Or too small (somehow)? Most type checkers will just let this throw at runtime, but hopefully TypeScript catches this at compile time (don't know if this does). We want our types to prove that something is correct, but implementing it explodes in complexity.

For flexibility, think about a string. "Yay!" https://google.com/ /Users/Klay/Downloads/yay.txt cd ... We're all guilty of shoving what could be represented in specific structures instead as strings because they're flexible. I see this especially with classes where a map would've served better. It sounds small, but this is where I think dynamic typing is flexible as it encourages this kind of thing. Rather than representing each of these as String, URL, File, Command, etc. and trying to talk to each other through their rigid interfaces, I can just use a String/Map/etc. and inherit all its properties.

I still like to verify the structure of certain things in dynamic languages, so schemas can be useful (especially since they're just data, you can manipulate the schema dynamically), but these are just part of my decision to use dynamic. If you like your different structures and correctness, go use them. I won't judge you (a bit long, sorry).

quartz kindle
hidden gorge
#

Hey guys How do I update my version of Node im using discord.js V13 and im trying to update node but it just gives me errors

sudden geyser
#

what's the error

quartz kindle
hidden gorge
#
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
exit status 1```
#

is the error

quartz kindle
hidden gorge
#

ok

quartz kindle
hidden gorge
#

Ok

#

do i put my old code in too?

quartz kindle
#

you can after you check the version is working

hidden gorge
#

ok

#

node -v? right

quartz kindle
#

just press the run button

hidden gorge
#

v16

#

Thanks

quartz kindle
#

alright, so now you can bring your old code to this new project

hidden gorge
#

ok

#

Thanks So much @quartz kindle My bot is running now

proven lantern
#

Tim saves the day

woeful pike
# sudden geyser I outlined some reasons in the first quoted message (<https://discord.com/channe...

Right, being able to catch overflow errors in compile time would require using a language with dependent typing, and that gets into the territory of unproductive type systems (for most applications). But I don't see why this drawback means all type systems aren't worth using.

So you're saying that it with static typing, in order to fully benefit from a type system, it would be better to use opaque types (not necessarily classes) over strings that represent incompatible ideas to fully benefit from having static types. And that because that's somewhat tedious to do, it's better to keep it all as a string? I mean I could see the reasoning behind that but to me the incompatible interfaces is the whole point and worth the extra couple seconds of tedious work. You shouldn't be able to pass a Command into a File even though they're both strings.

Like I know I always reach for stuff like python and js when I need to test a quick thing so dynamic typing definitely has its place but yeah. I guess if it works for you it works for you

quartz kindle
#

most dynamic types are pretty much an abstraction layer on top of static types in one way or another, unless you somehow design a language from ground up that doesnt run on top of C or something

#

in that sense, typescript kinda makes you go full circle lul

proven lantern
#

i wonder what types will look like for quantum processor drivers

#

qbit type

#

a qubit is basically a map with infinite keys right?

woeful pike
#

qubits actually work somewhat similarly to rusts ownership concept

#

I haven't read any research on this but just the vague idea seems similar. Seems to me like you can borrow a qubit and pass it around but once you observe it you have to move the value and it collapses to a new type (bit)

#

and the underlying qubit is destroyed, you can't do anything with it after observation

#

I know next to nothing about quantum physics obviously so that's just based on what I've heard

neat ingot
#

yo tim. im curious. whats your bot infrastructure look like as a whole? if you dont mind sharing, feel free to tell me to take a hike ๐Ÿ˜›

proven lantern
#

here's some q# quantum code

@EntryPoint()
operation MeasureOneQubit() : Result {
    // The following using block creates a fresh qubit and initializes it
    // in the |0โŒช state.
    use qubit = Qubit();
    // We apply a Hadamard operation H to the state, thereby preparing the
    // state 1 / sqrt(2) (|0โŒช + |1โŒช).
    H(qubit);
    // Now we measure the qubit in Z-basis.
    let result = M(qubit);
    // As the qubit is now in an eigenstate of the measurement operator,
    // we reset the qubit before releasing it.
    if result == One { X(qubit); }
    // Finally, we return the result of the measurement.
    return result;
    
}```
#

simple example is the following program, which allocates one qubit in the |0โŸฉ state, then applies a Hadamard operation H to it and measures the result in the PauliZ basis.

#

i have no idea what this simple example is doing

woeful pike
#

lol they're using F#'s entrypoint attribute but with a @

eternal osprey
#
 const embed = new Discord.MessageEmbed()
  .setColor("RANDOM")
  .setFooter("Vouch Services!")
  .setTimestamp()
  .setThumbnail(message.author.avatarURL)
  .addField("Total vouches: ", `${g1}`)
  .setTitle(`All vouches of ${m.user.username}(${m})`)
  .setDescription(messages)```why is my setThumbnail not working?
#

I am running on v12

proven lantern
#

you need to construct the url

#

from the avatar

eternal osprey
#

hmm wait what

proven lantern
#

message.author.avatar

eternal osprey
#

oowhh

quartz kindle
#

and https for communicating with my astronomy api

eternal osprey
neat ingot
quartz kindle
#

i like to keep things simple

neat ingot
#

like, my nub bot requires docker, nginx, certbot, two node js containers, and a mongodb container

#

๐Ÿ˜„

eternal osprey
#
 .setThumbnail(message.author.avatar.avatarURL)```This sent the embed without the thumbnail
#

running on v12.5.3

quartz kindle
#

yeah im not a fan of splitting it across so many things

proven lantern
#
.setThumbnail(`https://cdn.discordapp.com/avatars/${userId}/${avatar}.webp?size=80`)
quartz kindle
#

my api uses nginx and acme.sh instead of sertbot

neat ingot
#

yea, less things = less potential conflicts

quartz kindle
#

and node runs on pm2

#

but thats about it

neat ingot
#

thats like forever?

quartz kindle
#

yeah i guess

neat ingot
#

so does that host a site for your bot too?

quartz kindle
#

i dont have a website for my bot right now

#

thinking about making one next year

neat ingot
#

๐Ÿ˜ฎ

eternal osprey
#
DiscordAPIError: Invalid Form Body
embed.description: This field is required
embeds[0].description: This field is required``` no way
quartz kindle
#

after the mega rework im gonna do

#

lul

neat ingot
#

i just added a subdomain to my dev domain that ive had for years for my bots

#

(its offline atm)

neat ingot
#

thats part of why my setup is so complex, cause i have more than just my bots running, i have a few websites/api endpoints running in various containers, with nginx routing everything internally through a dockerized network

quartz kindle
#

cool

#

i split my stuff over different vps'es instead lul

#

i have 4 vps's rn, one of them is not actually doing anything, i forgot to cancel it

neat ingot
#

lol, which company you with for vps?

quartz kindle
#

experimenting with multiple companies, so each is in a different one

neat ingot
#

a few years ago i got recommendations for contabo from someone in here, havent looked back

quartz kindle
#

google compute engine, galaxygate, kamatera, hetzner

neat ingot
#

o0

#

i've not used any of those lol

#

they any good?

quartz kindle
#

im planning to moving everything into the hetzner vps

#

its by far the best one

#

(for my needs)

neat ingot
#

their pricing seems fairly similar to contabo

quartz kindle
#

oh an i have a couple websites hosted on interserver, a shared hosting thing

proven lantern
#

ever used vercel?

quartz kindle
#

nop

#

heard about it

spark flint
#

vercel is good

#

apart from daily spam saying my domain is not configured

quartz kindle
#

lul

neat ingot
#

oh actually tim you might actually know this. what would an average amount of ram be per 100 servers for a typical discord js bot?

proven lantern
spark flint
quartz kindle
neat ingot
#

default

#

my bots in 740 servers and chewing 3 and a half gig of ram lol

#

i tried to drop in your light version, but it threw errors about idk what so i stopped ๐Ÿ˜„

proven lantern
#

you gotta replace all cache hits with fetches

quartz kindle
#

i'd say about 100mb per 1k guilds, plus 100mb for some base stuff idk

#

but like

#

i've seen 500mb for 100 servers and i've seen 500mb for 10k servers

proven lantern
#

let me check the memory usage of my bot

quartz kindle
#

so it varies a lot

proven lantern
#

it's 2k servers with Tims library

quartz kindle
#

last time i checked logging into my bot with default djs v13, it went up to about 800mb on ready event

neat ingot
#

hmm

quartz kindle
#

at 9k servers

#

i didnt let it run, so it doesnt account for message caching, etc

neat ingot
#

yea, im probably gonna just rewrite the bot at some point tbh

#

i feel like it might be leaky somewhere

quartz kindle
#

im currently still running it on djs-light with djs v12

neat ingot
#

but at boot it uses easily 600+mb every time

quartz kindle
#

using about 140mb ram

proven lantern
#

60mb of ram with 1800 servers

neat ingot
#

side note: it wasnt that bad before we updated to djs 13

quartz kindle
quartz kindle
proven lantern
quartz kindle
#

my bot could go lower, but i cache a lot of stuff from my api as well

proven lantern
#

after 23 days

neat ingot
quartz kindle
#

or is that internal sharding?

#

or no sharding

proven lantern
#

i do sharding things

neat ingot
#

thats no sharding, but its setup to move to internal shard manager when required

quartz kindle
#

if you use the sharding manager, then pm2 will only show the ram usage of the manager, not of the whole thing

proven lantern
#

oh

quartz kindle
#

check ram usage with top or htop

#

there should be multiple processes for your bot, each with its own ram usage

sudden geyser
#

But I don't see why this drawback means all type systems aren't worth using.
I don't think all type systems are bad. I think, for many applications, type systems are not as useful as people stress they are.

So you're saying that it with static typing, in order to fully benefit from a type system, it would be better to use opaque types (not necessarily classes) over strings that represent incompatible ideas to fully benefit from having static types.
My only experience with opaque types is Swift, which I never fully understood, so sorry if I misinterpret this. In general, I'm saying that, to fully benefit from a type system, you need "correctness", which you can't get efficiently. With a dynamic type system, you trade correctness for flexibility, and that flexibility usually comes with using simpler types, like strings, maps, arrays, etc. and caring about the structure of something. A Person and User class can have identical structures but different typesโ€”whether this is rejected depends on if the type system is nominal or structural. This gets worse as you introduce more classes, as every class in a statically typed language is "special" and can't be used interchangeably or generically without some interface/protocol. If a new version of Person comes out, will you be able to reuse any of the fields and methods that accept the original one? No! When you try using simpler types in a statically typed language, that correctness goes out of the window.

Writing function identity<T>(x: T): T { return x; } is not hard, but as the requirements of types and application increase, what once was tedious has become problematic for some people.

neat ingot
#

i can make my bot poll netdata for all system information via an internal network ๐Ÿ˜„