Skip to content

SkinPeek Admin Guide

Giorgio edited this page Oct 25, 2022 · 13 revisions

This is a more-or-less comprehensive guide to all the features I've added to make hosting and managing the bot easier.

config.json

As you might have noticed. config.json has many other fields than just the bot token. Here's what each of them does.

Cron syntax

First, I need to explain cron syntax.

Cron comes from Unix-like OSs (Linux, Mac & others). It's a way of making a task repeat regularly. So for example, if you wanted to do something every day at 2:15PM, or every 45 minutes, or every 3 hours but only on the 5th day of the month, you would use cron. And cron syntax is a simple way of describing when/how often you want your task to run.

If you're not familiar with cron, you can probably just google cron every day at 2PM or whatever you want. And you can use crontab.guru to double check your expressions.

Now for the tricky bit. The bot uses node-cron to schedule the tasks. Any cron expression will work as intended, but it's got another trick up it's sleeve: seconds. With normal cron, you can only specify minutes. Node-cron lets you add an extra part at the front to specify seconds as well.

If a cron expression has 5 "parts", it's a normal cron expression. If it has 6 parts, it's a node-cron expression, and the first part is seconds, the second is minutes, etc. I'm pointing this out because if you paste any of the cron expressions in the default config.json into crontab.guru, it won't work because that website doesn't understand seconds.

The option list

  • fetchSkinPrices: Whether to fetch and show the skin prices alongside the names.
  • fetchSkinRarities: Same as above but for rarities.

These two options were the very first two that I added to the bot, because I wasn't sure whether everybody wanted to see the skin price/rarity. Nowadays, I can't really think of a reason you might want to turn them off. You have the option to I guess.

  • localiseSkinNames: Whether to translate the skin names to the language of whoever's using the bot.

This works because when you use a command (like /shop), discord sends what language your application is set to. So if your discord is set to Spanish, the bot will send you the Spanish skin names. This is toggleable because some of the gun translations might be weird in some languages, and some people might prefer the english names.

  • linkItemImage: Make the gun name clickable to view the skin image

On mobile, the embed image is cropped down to a square, and you can't see the whole weapon (great UI design, discord). This option makes the skin name clickable to be able to see the whole image. Added by muckelba.

  • useEmojisFromServer: Server ID. When looking for an emoji to use (skin rarity & VP icon), look in this server first.

If you use /shop in server A, the bot will first look for the emoji in that server. Then, if this option is set, it will look in that server. Otherwise, it will go through all the servers it's in to find one usable emoji. If it's not available anywhere, it will try to create the emoji in server A. And if it can't, it just won't use any emojis.
Note: Discord bots can use external emojis without having to pay for Nitro btw.

  • refreshSkins: Cron syntax describing when to check for alerts.

This one is in UTC. It's the only one though, the other cron syntaxes will work using your local timezone. By default the bot checks at 15 seconds after midnight UTC.

  • checkGameVersion: How often to check for a Valorant update. By default, it's every 15 minutes.

  • updateUserAgent: How often to check for a new Riot Client user-agent, helps prevent cloudflare error 1020 (see below). Every 15mins by default.

  • delayBetweenAlerts: How much time in milliseconds to wait between each person while checking alerts. Defaults to 0.5s.

  • emojiCacheExpiration: The bot fetches a server's emoji list, and keeps it in memory for this much time. Defaults to 10s.

  • loadoutCacheExpiration: Only update someone's skin collection this often at most. Defaults to 10mins.

  • alertsPerPage: When using /alerts, how many to display on one page. Watch out, discord doesn't allow more than 25 embed fields.

  • useShopCache: Whether to use shop cache.

If we assume that someone's daily shop, bundles and night market will not change during the day, there's no reason to fetch their shop twice if they do /shop twice. So if the bot fetches someone's daily shop, it saves it to disk for the day, and if they do /shop again, it won't have to fetch the shop from Valorant servers since it already knows what it is.
Note: Valorant returns your daily shop, bundles and night market all in the same request. So if someone does /nightmarket then /shop, it will only have to fetch it once if shop cache is turned on. Checking for someone's alerts will also add their shop to cache.
Also fun fact, did you know that bundles expire at 9PM UTC instead of midnight? Well now you know I guess.

  • useLoginQueue, loginQueue, loginRetryTimeout: Read about these in the shop queue part down below.
  • authFailureStrikes: How many times to fail to authenticate before giving up on checking alerts.

Imagine someone uses the bot only a couple of times, and then doesn't delete their account. If they change their password later on, their cookies will be invalidated, but the bot doesn't know that yet. Then once the bot tries to check for alerts for that user, it will fail. By default, the bot will only accept 2 failures before labelling the cookies as invalid and skipping alerts checking for them.

  • maxAccountsPerUser: How many different accounts a user can have. Defaults to 5, as discord only allows 5 buttons in a row.

  • rateLimitBackoff: When rate limited without an ETA, wait for this many seconds before retrying. Defaults to 1 minute.

  • rateLimitCap: Don't wait for a rate limit to expire for longer than this. Defaults to 10 minutes.

If too many accounts try to authenticate in a short amount of time, Riot will rate limit the bot's IP address. This means that no one can authenticate for a little while.
I don't know how many requests per minute it takes to get rate limited, and Riot will only sometimes tell the bot how long the rate limit lasts.
When there's no info on how long the bot is blocked for, the bot will wait 60 seconds by default. That's what rateLimitBackoff is for.
Sometimes, Riot servers will tell the bot that it's rate limited for an hour, but silently unblocks the bot sooner than that. So by default, if the bot is told to wait more than 10 minutes, it will actually only wait 10 minutes. That's what rateLimitCap is for.
If you find yourself getting rate limited a lot, try turning on the auth and shop queues.

  • useShopQueue, shopQueue: Read about these in the auth queue part down below.
  • useMultiqueue: Read about this in the sharding part down below.
  • storePasswords: Store people's usernames/passwords instead of cookies.

I don't think I need to tell you that this is a bad idea. Passwords are not stored for people with 2FA on (because just their password is not enough to log in).

  • trackStoreStats: Track how many times each skin appears in someone's shop.

  • statsExpirationDays: How many days to keep the stats of a certain day. The higher the number, the more new skins will have less presence compared to other skins. Set to 0 to never clear them.

  • statsPerPage: How many skins to display per page when using /stats. Won't work with more than 9 due to the discord limit of 10 embeds per message (one is used for the title bar).

  • shardReadyTimeout: How long to wait for each shard to become ready before giving up and crashing. Read more about sharding below.

  • ownerId: The Discord ID of who's allowed to use admin commands. See the admin commands part below.

  • ownerName: What to put as the owner when using /info.

  • status: What to put as the status when using /info.

  • logToChannel: Channel ID. Send the output of the bot to a discord channel, so you can check the logs from your phone.

  • logFrequency: How often to send the logs. Defaults to every 10 seconds.

  • logUrls: For debugging. Log every URL the bot sends a request to.

Admin commands

You can use these admin commands to manage the bot from any discord channel.

You should set the ownerId in config.json to your discord ID first, otherwise anyone can use these commands. ownerId can be the ID of a user, a role (everyone with that role) or a guild (any message in that guild). You can put multiple IDs separated by a comma: 123456789,987654321.

Admin commands are used by sending a message that starts with !, for example !config, in any channel that the bot can see. With Discord recently changing message content to become a privileged intent, the bot can only receive messages that it is tagged in. So if your bot is verified, you will need to tag your bot before every admin command like this: @bot !config ....

Here is the list of admin commands:

  • !deploy: used to tell discord what slash commands the bot has. You can either deploy in just one guild or to all guilds with !deploy guild and !deploy global.

  • !undeploy: remove all slash commands from the bot. You'll need to deploy again if you want to use the bot. Useful if you deployed both in a guild and globally, and you see every command twice.

  • !config [name] [value]: change an option in config.json. Most configs will change immediately, but config.json won't be saved and any scheduled cron tasks won't be rescheduled until you do !config reload.

  • !config reload: see above.

  • !config load: If you manually changed config.json, use this to read the config from disk again. Also useful if you changed some values with !config by mistake and want to undo your changes.

  • !config read: Reads and sends you the contents of config.json on discord.

  • !message [message]: (not recommended) send a message to all guilds the bot is in.

For each guild, the bot will look for the channel with the most alerts. If a guild has no alerts set up, it will not send a message there, since they're probably not using the bot. I don't recommend you use this, especially if the bot is in many servers. The bot will lock up while it goes through everyone's alerts and sends a message to all the guilds. Doesn't work with sharding enabled.

  • !status [status]: change the bot's status in /info.
  • !forcealerts: manually trigger checking for everyone's alerts. Useful if you disabled automatic checking, or the bot wasn't on at midnight UTC.
  • !stop skinpeek: immediately stop and shut down the bot.
  • !update: auto-update the bot to the latest version. Only works if you set it up correctly, read more about it below.

Auto updating the bot using !update

This is useful to be able to update the bot with a simple command, although it requires you to have cloned the repo using git.

First, download and install git. On windows, it's here.

Then, open a command line, and type the following command:

git clone https://github.com/giorgi-o/SkinPeek

It should automatically download the bot into a new folder. Transfer the config.json and data folder from where the bot used to be.

To launch the bot, either use the SkinPeek.sh/SkinPeek.bat scripts, or (recommended) use the pm2. This is to ensure that when the bot stops, it's automatically restarted.

Then you should be able to use !update just like any other admin command.

Note that due to how git works, if you change any of the bot's code, git will refuse to update the bot.

Cloudflare error 403/1020

Last we heard, Riot had a problem with many people trying to crack Riot accounts. They do this by getting a list of passwords that got leaked from another website, and trying all those usernames/passwords on riotgames.com, hoping that people reused the same password on multiple websites.

So, they implemented a Cloudflare firewall to try and stop these account crackers by preventing them from logging in if Riot thinks that they are an account cracker. If Riot thinks that someone is not logging in from the official website or the Riot client, it will send them Cloudflare error 1020.

So far, the valorant third-party community has managed to somewhat escape the dreaded error 1020, but every now and then they update their firewall, and we need to find a new way of bypassing it.

So if you get 1020'd, here's what you can do:

  • Riot are known to ban IPs from popular VPS hosting providers (e.g. Hetzner). If the bot works on your home computer but not on your VPS, the IP has probably been banned.
  • Restart the bot. The bot now automatically tries to fetch the latest user-agent when starting up, and refreshes it every 15 minutes.
  • Update the bot. If you haven't updated in a while, now's the time. I probably already fixed it in the latest update.
  • Wait for an update. If everyone is affected, you can be sure that the community is hard at work trying to find another bypass.

Login and Shop queue

The login and shop queues are a way to try and reduce the bot getting rate limited by only fetching someone's auth or shop every X seconds. By default it's 2 seconds for the auth queue, and 1 second for the shop queue.

This means that if you turned on the auth queue, and two people try and authenticate at the same time, it will process one, wait two seconds, and then process the other. Same for the shop queue.

If your bot is a small bot used by only a handful of people, there's no point in enabling the queues, since all they will do is add an unnecessary delay. However, if you are hosting a large bot, and you get rate limited often, I recommend you turn them on.

If you still get rate limited with the auth and shop queues on, try increasing the seconds in loginQueue and shopQueue.

VPS recommendation

Many people have asked me which VPS I recommend to host the bot on.

The truth is that the bot is quite optimised, so it doesn't use many resources if it's not used by many people, so there isn't a wrong option per se. It comes down to which VPS provider you trust the most, and has the most features.

As to which VPS provider you should use, here is the list of recommendations from both the discord.js and discord.py servers:

Discord.js list of affordable hosting providers:
OVH Starting at $3.35/mo for 1 core, 2GB RAM, 20GB SSD
DigitalOcean Starting at $5/mo for 1 core, 1GB RAM, 25GB SSD
Linode Starting at $5/mo for 1 core, 1GB RAM, 25GB SSD
Vultr Starting at $2.50/mo for 1 core, 512MB RAM, 10GB SSD
AWS Lightsail Starting at $3.50/mo (first month free) for 1 core, 512MB RAM, 20GB SSD
Time4VPS Starting at €3.99/month for 1 core, 2GB RAM, 20GB SSD
VIRMACH Full Windows and Linux Desktop VPS starting at $7/mo and $1/mo respectively
Netcup Starting at €2.62/mo for 1 core, 2GB RAM, 20GB SSD
GitHub education Free credit and other offers for students
Microsoft students Free credit for students
Google Cloud free tier

Discord.py: Need to run your bot 24/7? Get a cheap VPS.
https://www.scaleway.com/ EU
https://www.linode.com/ US/EU/Asia
https://www.digitalocean.com/ US
https://www.vultr.com/ US
https://www.ovh.co.uk/ EU/Canada
https://www.hetzner.com/ Germany/US
https://www.time4vps.eu/ Lithuania.
Self-hosting: Any computer.
Free hosting: No. Not even heroku.
Kinda free: GCP, AWS have one year free micros.

Sharding

If your bot gets added to 2500 servers, discord won't let you start it without sharding. Sharding is basically a way of splitting up a discord bot into multiple processes to make it more efficient. Discord says you should enable sharding as soon as 2000 servers.

However, I recommend you leave sharding off for bots in less than 1000 severs, and definitely for those in less than 500. All it will do is use extra ram for nothing, and add an overhead to any cross-shard operation.

To use sharding, you launch the bot using sharding.js instead of SkinPeek.js... and that's it. The bot should automatically take care of the rest.

You will see that every log message will have a number before it, this indicates the shard number that the log is coming from.

Multiqueue

(multiqueue is still in beta. at the moment it seems to not work under pressure. enable it if you're feeling ballsy, and keep an eye on it.)

One problem with sharding is that the auth/shop queues don't work across shards. So if, on every shard, someone does /shop at the exact same time, the bot might get rate limited, and there's nothing it can do about it.

Introducing, multiqueue. Multiqueue is a system where all auth and shop operations are done on shard 0. This way, shard 0 can handle the login and shop queues, and prevent the bot from getting rate limited.

Get in touch!

If you're hosting an instance of the bot with many (1000+) users, don't hesitate to contact me on discord! I want to add a list of public bots to the readme at some point, plus if you have some questions about the bot, I can probably answer them.

Clone this wiki locally