Skip to content

Instantly share code, notes, and snippets.

@simoniz0r
Last active November 13, 2024 22:25
Show Gist options
  • Save simoniz0r/31a446f319494c6210eb0e1fbe9a6f14 to your computer and use it in GitHub Desktop.
Save simoniz0r/31a446f319494c6210eb0e1fbe9a6f14 to your computer and use it in GitHub Desktop.
blargbot tags
some blargbot tags
{//;prevent direct use}
{if;{commandname};==;dapi;
{throw;This command cannot be used directly. Use {lb}exec{semi}dapi{rb} instead.}
{return}
}
{//;check if @bot.token set}
{if;{get;@bot.token};!=;{null};
{jset;~dapi.head;headers.Authorization;Bot{space}{replace;{get;@bot.token};Bot{space};};c};
{throw;Variable '@bot.token' not set. Use {lb}set{semi}@bot.token{semi}YourTokenHere{rb} to set your token.}
{return}
}
{//;get method}
{switch;{upper;{args;0}};
["GET","POST","PUT","PATCH","DELETE"];
{jset;~dapi.head;method;{upper;{args;0}};c};
[""];
{jset;~dapi.head;method;GET;c};
{throw;Invalid method. Expected 'GET', 'POST', 'PUT', 'PATCH', or 'DELETE'.}
{return}
}
{//;check endpoint input}
{if;{args;1};startswith;`;
{throw;Missing endpoint input.}
{return}
}
{//;check for body input}
{if;{length;{argsarray}};>;2;
{set;!~dapi.body;{args;2;n}}
}
{if;{jget;~dapi.body};!=;{lb}{rb};
{jset;~dapi.head;headers.content-type;application/json;c}
{request;https://discord.com/api/v10/{lower;{args;1}};{jget;~dapi.head};{jget;~dapi.body}};
{request;https://discord.com/api/v10/{lower;{args;1}};{jget;~dapi.head};{get;~dapi.body}}
}
{//;function to output help}
{function;githelp;
{embed;{embedbuild;
title:Help for git;
color:yellow;
footer.text:{usernick} ({userid});
footer.icon_url:{useravatar};
timestamp:{time};
description:__**Usage**__: `git <setrepo <github repo url> [-b branch] [-d directory] | status | pull [commit sha] | cc <command name> | ratelimit`
Use a Github repository to store commands and `pull` their contents to guild variables that can be used via `{escapebbtag;{inject}}`. Allows others to easily contribute to your commands, commands to be kept up to date with the remote repo by `pull`ing them, and mistakes to be undone quickly by reverting to a previous commit.
See https://github.com/discordlinux/blargbot-commands for an example setup.
Please note that guild variables are used for storing commands. If you would like to use git with custom commands, it must be ran as a cc.
Example:
{repeat;`;3}
b!cc set git {escapebbtag;{exec;git;{args}}}
{repeat;`;3}
**Arguments**
{repeat;`;3}
setrepo - Set the Github repo. Optionally set the branch (defaults to 'main') ('-b') and directory where the manifest.json and commands are stored ('-d'). Must be staff to use this argument.
Ex: 'setrepo github.com/user/repo'
Ex: 'setrepo github.com/user/repo -b somebranch'
Ex: 'setrepo github.com/user/repo -d somedir'
status - View status including configuration, current commit, and commands.
Ex: 'status'
pull - Pull a commit. Defaults to latest commit. If specifying commit, must be full commit sha.
Ex: 'pull'
Ex: 'pull 048d8327b3fcd9231ca43cbdd47164b43eca82b0'
cc - Output an example of how to use a given command in a custom command using '{escapebbtag;{inject}}'. Must be a command found in 'manifest.json'.
Ex: 'cc feedback'
ratelimit - View current Github API rate limit usage.
Ex: 'ratelimit'
{repeat;`;3}
{zws};
fields.name:Initial Setup;
fields.value:Before use, the `setrepo` argument must be ran by a staff member. See the arguments list above for help and examples.
Your repo **must** contain a `manifest.json` with an array of commands as the value of the `commands` key. Each object in the array must contain the `name` and `file_path` keys. `manifest.json` must be stored either in the same directory as your commands or in a directory above them. `file_path` must be relative to the location of `manifest.json`. Ex, if the file for our command `feedback` is `feedback.bbtag` and is in the same directory as `manifest.json`, the value of `file_path` will be `feedback.bbtag`. If the file for our command `info` is `info.bbtag` and is stored in the `info` directory below `manifest.json`, the value of `file_path` will be `info/info.bbtag`.
[Click here for an example manifest.json](https://github.com/discordlinux/blargbot-commands/blob/main/commands/manifest.json);
fields.name:Using Pulled Commands;
fields.value:Although git can automatically inject commands for you by using `{escapebbtag;{exec;git;{args}}}` as the contents of a command with the same `name` as one the commands in `manifest.json`, the most reliable way would be to `{escapebbtag;{inject}}` the command yourself with its stored variable: `{escapebbtag;{inject;{get;_gitcmd.name}}}`. All commands are stored in the variable format `_gitcmd.name`. Ex, if the `name` in `manifest.json` for your command is `info`, the variable name will be `_gitcmd.info`.
Example:
{repeat;`;3}
b!cc set info {escapebbtag;{inject;{get;_gitcmd.info}}}
{repeat;`;3}
git can also automagically generate code that can be copy and pasted for creating custom commands. See `cc` in the list of arguments above for more info.;}}
}
{//;function to set git repo}
{function;gitsetrepo;
{//;only staff can set repo}
{if;{isstaff;{userid}};!=;true;
{throw;Only staff can setup the Github repo!}
{return}}
{//;split github url by /}
{set;!~giturlar;{split;{params;0};/}}
{//;check if valid repo input}
{if;{logic;||;
{bool;{replace;{jget;~giturlar;0};www.;};!=;github.com};
{bool;{length;{get;~giturlar}};!=;3}};
{output;Invalid github repo. Expected format: `github.com/user/repo`}
{return}}
{//;set user}
{set;!~gituser;{jget;~giturlar;1}}
{//;set repo}
{set;!~gitrepo;{jget;~giturlar;2}}
{//;set branch}
{if;{params;1};!=;{null};
{set;!~gitbranch;{params;1}};
{set;!~gitbranch;main}}
{//;set directory}
{if;{params;2};!=;{null};
{set;!~gitdir;/{params;2}}}
{//;set raw url}
{set;!~gitrawurl;https://raw.githubusercontent.com/{get;~gituser}/{get;~gitrepo}/{get;~gitbranch}{get;~gitdir}}
{//;check if manifest.json exists}
{set;!~gitmanifest;{request;{get;~gitrawurl}/manifest.json}}
{if;{jget;~gitmanifest;status};!=;200;
{output;File `manifest.json` not found at '<{get;~gitrawurl}/manifest.json>'.
If your `manifest.json` is in a directory within your repo, use the `-d` flag to specify the directory.
The branch may also be set with the `-b` flag (defaults to `main`).
See <https://github.com/discordlinux/blargbot-commands/blob/main/commands/manifest.json> for an example `manifest.json`}
{return}}
{//;check if manifest is proper format}
{if;{logic;||;
{bool;{jget;~gitmanifest;body.commands.0.name};==;{null}};
{bool;{jget;~gitmanifest;body.commands.0.name};startswith;`};
{bool;{jget;~gitmanifest;body.commands.0.file_path};==;{null}};
{bool;{jget;~gitmanifest;body.commands.0.file_path};startswith;`}};
{output;Invalid `manifest.json` format found at '<{get;~gitrawurl}/manifest.json>'.
See <https://github.com/discordlinux/blargbot-commands/blob/main/commands/manifest.json> for an example `manifest.json`}
{return}}
{//;checks passed, set variables}
{set;!@{guildid}.gituser;{get;~gituser}}
{set;!@{guildid}.gitrepo;{get;~gitrepo}}
{set;!@{guildid}.gitbranch;{get;~gitbranch}}
{set;!@{guildid}.gitdir;{get;~gitdir}}
{output;{repeat;`;3}
Repo: {get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}
Branch: {get;@{guildid}.gitbranch}
Directory: {replace;{get;@{guildid}.gitdir};/;}
Commands:
{foreach;~f;{jget;~gitmanifest;body.commands};{space}{space}• '{jget;~f;name}' - '{jget;~f;file_path}'{newline}}
Run 'git pull' to pull available commands from this repo.
{repeat;`;3}}
}
{//;function to get latest commit from github API}
{function;gitlatest;
{//;check variables}
{if;{logic;||;
{bool;{get;@{guildid}.gituser};==;{null}};
{bool;{get;@{guildid}.gitrepo};==;{null}};
{bool;{get;@{guildid}.gitbranch};==;{null}}};
{throw;Missing required configuration. Run 'git setrepo' before use.}
{return}}
{//;just set url if git commit already set}
{if;{get;~gitcommit};!=;{null};
{set;!~giturl;https://raw.githubusercontent.com/{get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}/{get;~gitcommit}{get;@{guildid}.gitdir}}
{//;get commit message from metadata}
{set;!~gitcommitmsg;{htmldecode;{jget;{split;{jget;{exec;metadata;https://github.com/{get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}/commit/{get;~gitcommit}};meta.og:title};{space}·};0}}}
{//;else};
{//;get latest commit from atom feed}
{//;check if page exists}
{set;!~gitcommitcheck;{request;https://github.com/{get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}/commits.atom}}
{if;{jget;~gitcommitcheck;status};!=;200;
{throw;Error getting latest commit from 'https://github.com/{get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}/commits.atom'}
{return}}
{//;convert XML to JSON}
{set;!~gitcommitjson;{exec;xml2json;https://github.com/{get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}/commits.atom}}
{set;!~gitcommit;{jget;{split;{jget;~gitcommitjson;feed.entry.0.id};/};1}}
{//;{set;!~gitcommit;{jget;~gitcommitjson;body.payload.commitGroups.0.commits.0.oid}}}
{set;!~gitcommitmsg;{reverse;{replace;{reverse;{regexreplace;{jget;~gitcommitjson;feed.entry.0.content.#text};/(<[^>]*>|\n\s+)/g;}};{newline}{space}{space}{space};}}}
{//;{set;!~gitcommitmsg;{jget;~gitcommitjson;body.payload.commitGroups.0.commits.0.shortMessage}}}
{set;!~giturl;https://raw.githubusercontent.com/{get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}/{get;~gitcommit}{get;@{guildid}.gitdir}}
}
}
{//;function to 'pull' from ~giturl to author variable}
{function;gitpull;
{set;!~gitpull;{request;{get;~giturl}/{params;0}}}
{if;{jget;~gitpull;status};!=;200;
{throw;'{get;~giturl}/{params;0}' returned: {regexreplace;{get;~gitpull};/`/g;;}}
{return}}
{//;only update if hashes do not match}
{if;{hash;{get;_gitcmd.{params;1}}};!=;{hash;{jget;~gitpull;body}};
{set;!_gitcmd.{params;1};{jget;~gitpull;body}}
{push;~pullmsg;• '{params;1}' pulled from '{params;0}'}
}
}
{//;function to update all stored commands}
{function;gitpullall;
{//;if input given, set as ~gitcommit}
{if;{params;0};!=;{null};
{set;!~gitcommit;{params;0}}}
{//;get latest commit}
{func.gitlatest}
{//;make sure manifest exists}
{set;!~gitmanifest;{request;{get;~giturl}/manifest.json}}
{if;{jget;~gitmanifest;status};!=;200;
{throw;No stored commands to update. Add a 'manifest.json' to your repo. See https://github.com/discordlinux/blargbot-commands/blob/main/commands/manifest.json for an example.}
{return}}
{//;create start of pull message}
{set;!~pullmsg;[]}
{push;~pullmsg;Repo: {get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}{newline}Branch: {get;@{guildid}.gitbranch}{if;{get;@{guildid}.gitdir};!=;{null};{newline}Directory: {replace;{get;@{guildid}.gitdir};/;}}{newline}Current commit: {get;_gitcommit}}
{//;if ~gitcommit matches _gitcommit, output message and return}
{if;{hash;{get;~gitcommit}};==;{hash;{get;_gitcommit}};
{push;~pullmsg;{newline}Up to date with commit '{get;~gitcommit}'{if;{get;~gitcommitmsg};!=;{null};:{newline}{get;~gitcommitmsg}}}
{output;{repeat;`;3}
{join;{get;~pullmsg};{newline}}
{repeat;`;3}}
{return}}
{//;update _gitcommit variable and output pull message}
{set;!_gitcommit;{get;~gitcommit}}
{push;~pullmsg;{newline}Pulling commit '{get;~gitcommit}'{if;{get;~gitcommitmsg};!=;{null};:{newline}{get;~gitcommitmsg}}{newline}}
{set;!~pullmsgid;{output;{repeat;`;3}
{join;{get;~pullmsg};{newline}}
{repeat;`;3}}}
{//;loop through commands and pull each one}
{foreach;~gitcmd;{jget;~gitmanifest;body.commands};
{func.gitpull;{jget;~gitcmd;file_path};{jget;~gitcmd;name}}
}
{//;if no files updated, add up to date message}
{if;{length;{get;~pullmsg}};==;2;
{push;~pullmsg;Pull finished. All commands already up to date.}
}
{//;edit pull message with results}
{edit;{channelid};{get;~pullmsgid};{repeat;`;3}
{join;{get;~pullmsg};{newline}}
{repeat;`;3}}
}
{//;function to show github rate limit and reset time}
{function;gitratelimit;
{if;{get;@gittoken};!=;{null};
{jset;~head;headers.Authorization;token {get;@gittoken};c}}
{set;!~gitratelimit;{jget;{request;https://api.github.com/rate_limit;{get;~head}};body.resources.core}}
**Remaining**: {jget;~gitratelimit;remaining}
**Reset**: <t:{jget;~gitratelimit;reset}:R>
}
{//;function to generate an inject that can be copy and pasted when creating commands}
{function;gitgeninject;
{if;{params;0};==;{null};
{throw;Missing required argument command name.}
{return}}
{//;get manifest.json}
{set;!~gitmanifest;{request;https://raw.githubusercontent.com/{get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}/{get;@{guildid}.gitbranch}{get;@{guildid}.gitdir}/manifest.json}}
{if;{jget;~gitmanifest;status};!=;200;
{throw;'manifest.json' not found. Add a 'manifest.json' to your repo. See https://github.com/discordlinux/blargbot-commands/blob/main/commands/manifest.json for an example.}
{return}}
{//;filter list of commands to match input}
{set;!~gitcmdar;{filter;~c;{jget;~gitmanifest;body.commands};{bool;{jget;~c;name};==;{params;0}}}}
{//;error if no matches}
{if;{length;{get;~gitcmdar}};==;0;
{throw;No matches for '{params;0}' found in 'manifest.json'.}
{return}}
{//;get name and path from ~gitcmdar}
{set;!~gitcmdname;{jget;~gitcmdar;0.name}}
{set;!~gitcmdpath;{jget;~gitcmdar;0.file_path}}
{output;This command can be used to create a custom command for `{get;~gitcmdname}`:
{repeat;`;3}
b!cc set {get;~gitcmdname} {lb}//{semi}View or edit the code for this command: https://github.com/{get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}/blob/{get;@{guildid}.gitbranch}{get;@{guildid}.gitdir}/{get;~gitcmdpath}{rb}
{lb}inject{semi}{lb}get{semi}_gitcmd.{get;~gitcmdname}{rb}{rb}
{repeat;`;3}}
}
{//;function to show status}
{function;gitstatus;
{if;{logic;||;
{bool;{get;@{guildid}.gituser};==;{null}};
{bool;{get;@{guildid}.gitrepo};==;{null}};
{bool;{get;@{guildid}.gitbranch};==;{null}}};
{throw;Missing required configuration. Run 'git setrepo' before use.}
{return}}
{//;get manifest.json}
{set;!~gitmanifest;{request;https://raw.githubusercontent.com/{get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}/{if;{get;_gitcommit};!=;{null};{get;_gitcommit};{get;@{guildid}.gitbranch}}{get;@{guildid}.gitdir}/manifest.json}}
{if;{jget;~gitmanifest;status};!=;200;
{throw;'manifest.json' not found. Add a 'manifest.json' to your repo. See https://github.com/discordlinux/blargbot-commands/blob/main/commands/manifest.json for an example.}
{return}}
{output;{repeat;`;3}
Repo: {get;@{guildid}.gituser}/{get;@{guildid}.gitrepo}
Branch: {get;@{guildid}.gitbranch}{if;{get;@{guildid}.gitdir};!=;{null};{newline}Directory: {replace;{get;@{guildid}.gitdir};/;}}
Current commit: {get;_gitcommit}
Commands:
{foreach;~f;{jget;~gitmanifest;body.commands};{space}{space}• '{jget;~f;name}' - '{jget;~f;file_path}'{newline}}
{repeat;`;3}}
}
{//;function to show raw code for commands}
{function;gitraw;
{if;{get;_gitcmd.{params;0}};==;{null};
❌ The `{params;0}` command doesn't exist!
{return}
}
{if;{length;{get;_gitcmd.{params;0}}};<;2000;
ℹ️ The raw code for `{params;0}` is:
{repeat;`;3}
{get;_gitcmd.{params;0}}
{repeat;`;3};
{get;_gitcmd.{params;0}}
}
}
{//;if commandname is not git, try to inject var with commandname}
{if;{commandname};!=;git;
{if;{get;~command};==;{null};
{set;!~command;{commandname}}}
{if;{get;_gitcmd.{get;~command}};==;{null};
{throw;Command '{get;~command}' not found. Have you ran 'setrepo' and 'pull'?};
{inject;{get;_gitcmd.{get;~command}}}};
{//;if commandname is git, detect arguments}
{switch;{lower;{args;0}};
["setrepo"];
{func.gitsetrepo;{args;1};{flag;b};{flag;d}};
["status"];
{func.gitstatus};
["pull"];
{func.gitpullall;{regexreplace;{flag;_};/^pull\s?/i;}};
["inject","cc","ccommand"];
{func.gitgeninject;{regexreplace;{flag;_};/^(inject|cc|ccommand)\s?/i;}};
["ratelimit","rate_limit"];
{func.gitratelimit};
["raw"];
{func.gitraw;{args;1}};
{func.githelp}
}}
{function;help;
{embed;{embedBuild;
title:Pokémon Info;
color:yellow;
footer.text:Current default generation: {if;{get;@{guildid}.default.gen};==;{null};9;{get;@{guildid}.default.gen}};
description:__**Usage**__: `{commandname} <query [-g <gen>] | setgen <gen>>`
Gets info about Pokémon/abilities/items/moves/natures/types.
**Examples**:
{repeat;`;3}
Search for Pokémon, etc:
{commandname} squirtle
{commandname} squirtle -g 4
Set the default generation:
{commandname} setgen 4
{zws}
{repeat;`;3};
}}
}
{function;pokes;
{exec;searchmsg;Searching for `{params;0}`...}
{if;{flag;g};!=;{null};
{set;!~gen;{flag;g}};
{set;!~gen;{get;@{guildid}.default.gen}}
}
{switch;{lower;{get;~gen}};
["1","i","rb"];
{set;!~url;https://raw.githubusercontent.com/simoniz0r/smogon-dump/main/rb.json};
["2","ii","gs"];
{set;!~url;https://raw.githubusercontent.com/simoniz0r/smogon-dump/main/gs.json};
["3","iii","rs"];
{set;!~url;https://raw.githubusercontent.com/simoniz0r/smogon-dump/main/rs.json};
["4","iv","dp"];
{set;!~url;https://raw.githubusercontent.com/simoniz0r/smogon-dump/main/dp.json};
["5","v","bw"];
{set;!~url;https://raw.githubusercontent.com/simoniz0r/smogon-dump/main/bw.json};
["6","vi","xy"];
{set;!~url;https://raw.githubusercontent.com/simoniz0r/smogon-dump/main/xy.json};
["7","vii","sm"];
{set;!~url;https://raw.githubusercontent.com/simoniz0r/smogon-dump/main/sm.json};
["8","viii","ss"];
{set;!~url;https://raw.githubusercontent.com/simoniz0r/smogon-dump/main/ss.json};
{set;!~url;https://raw.githubusercontent.com/simoniz0r/smogon-dump/main/sv.json}
}
{set;!~raw;{jget;{request;{get;~url}};body.pokemon}}
{set;!~result;{filter;~p;{jget;~raw};{bool;{lower;{replace;{jget;~p;name};.;}};==;{lower;{replace;{params;0};.;}}}}}
{set;!~rtype;pokemon}
{if;{length;{jget;~result}};==;0;
{set;!~raw;{jget;{request;{get;~url}};body.abilities}}
{set;!~result;{filter;~p;{jget;~raw};{bool;{lower;{replace;{jget;~p;name};.;}};==;{lower;{replace;{params;0};.;}}}}}
{set;!~rtype;abilities}
}
{if;{length;{jget;~result}};==;0;
{set;!~raw;{jget;{request;{get;~url}};body.items}}
{set;!~result;{filter;~p;{jget;~raw};{bool;{lower;{replace;{jget;~p;name};.;}};==;{lower;{replace;{params;0};.;}}}}}
{set;!~rtype;items}
}
{if;{length;{jget;~result}};==;0;
{set;!~raw;{jget;{request;{get;~url}};body.moves}}
{set;!~result;{filter;~p;{jget;~raw};{bool;{lower;{replace;{jget;~p;name};.;}};==;{lower;{replace;{params;0};.;}}}}}
{set;!~rtype;moves}
}
{if;{length;{jget;~result}};==;0;
{set;!~raw;{jget;{request;{get;~url}};body.natures}}
{set;!~result;{filter;~p;{jget;~raw};{bool;{lower;{replace;{jget;~p;name};.;}};==;{lower;{replace;{params;0};.;}}}}}
{set;!~rtype;natures}
}
{if;{length;{jget;~result}};==;0;
{set;!~raw;{jget;{request;{get;~url}};body.types}}
{set;!~result;{filter;~p;{jget;~raw};{bool;{lower;{replace;{jget;~p;name};.;}};==;{lower;{replace;{params;0};.;}}}}}
{set;!~rtype;types}
}
{if;{length;{jget;~result}};==;0;
{edit;{channelid};{get;~searchmsgid};_delete;{embedBuild;
title:Could Not Find Info For '{params;0}';
color:red;
description:No info found for `{params;0}`.;
footer.text:Info From Generation {get;~gen};}}
{return}
}
{switch;{get;~rtype};
["pokemon"];
{func.pokemon};
["abilities"];
{func.abilities};
["items"];
{func.items};
["moves"];
{func.moves};
["natures"];
{func.natures};
["types"];
{func.types}
}
}
{function;pokemon;
{set;!~pokeapi;{request;https://pokeapi.co/api/v2/pokemon-species/{jget;~result;0.oob.dex_number}}}
{set;!~bulbjson;{exec;getjson;https://bulbapedia.bulbagarden.net/w/api.php?action=query&format=json&prop=extracts%7Cinfo%7Cpageimages&iwurl=1&generator=search&redirects=1&formatversion=2&exintro=1&explaintext=1&exsectionformat=plain&inprop=url&piprop=original&pilimit=1&pilicense=any&gsrsearch={uriencode;{jget;~result;0.name}}&gsrlimit=1&gsrwhat=nearmatch}}
{set;!~desc;{regexreplace;{jget;~bulbjson;query.pages.0.extract};/(\s\(Japanese.*[a-z].?\)\s|\n)/g;{space}}}
{if;{length;{split;{get;~desc};.}};>;8;
{set;!~desc;{join;{slice;{split;{get;~desc};.};0;7};.}. [[...]](https://bulbapedia.bulbagarden.net/wiki/{regexreplace;{jget;~result;0.name};/\s/g;_}_(Pok%C3%A9mon))}
}
{set;!~flavoren;{filter;~e;{jget;~pokeapi;body.flavor_text_entries};{bool;{jget;~e;language.name};==;en}}}
{set;!~flavor;{regexreplace;{jget;~flavoren;0.flavor_text};/(\n|\f)/g;{space}}}
{set;!~color;{jget;~pokeapi;body.color.name}}
{set;!~evochain;{request;{jget;~pokeapi;body.evolution_chain.url}}}
{set;!~evoarray;[]}
{push;~evoarray;{capitalize;{regexreplace;{jget;~evochain;body.chain.species.name};/-/g;{space}}}}
{if;{length;{jget;~evochain;body.chain.evolves_to}};>;0;
{set;!~firstevo;[]}
{foreach;~e;{jget;~evochain;body.chain.evolves_to};
{push;~firstevo;{capitalize;{regexreplace;{jget;~e;species.name};/-/g;{space}}}}
}
{push;~evoarray;{join;~firstevo;/}}
{if;{length;{jget;~evochain;body.chain.evolves_to.0.evolves_to}};==;1;
{push;~evoarray;{capitalize;{regexreplace;{jget;~evochain;body.chain.evolves_to.0.evolves_to.0.species.name};/-/g;{space}}}}
}
{if;{length;{jget;~evochain;body.chain.evolves_to.0.evolves_to.0.evolves_to}};==;1;
{push;~evoarray;{capitalize;{regexreplace;{jget;~evochain;body.chain.evolves_to.0.evolves_to.0.evolves_to.0.species.name};/-/g;{space}}}}
}
}
{if;{length;{jget;~evoarray}};==;1;
{set;!~evos;No Evolutions};
{set;!~evos;{join;~evoarray;{space}->{space}}}
}
{edit;{channelid};{get;~searchmsgid};_delete;{embedBuild;
title:Pokémon - {jget;~result;0.name} #{jget;~result;0.oob.dex_number};
url:https://bulbapedia.bulbagarden.net/wiki/{regexreplace;{jget;~result;0.name};/\s/g;_}_(Pok%C3%A9mon);
thumbnail.url:https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/{jget;~result;0.oob.dex_number}.png;
color:{get;~color};
description:{get;~desc};
fields.name:{zws};
fields.value:**HP**: {jget;~result;0.hp}
**ATK**: {jget;~result;0.atk}
**DEF**: {jget;~result;0.def}
**SPA**: {jget;~result;0.spa}
**SPD**: {jget;~result;0.spd}
**SPE**: {jget;~result;0.spe}
**BST**: {math;+;{jget;~result;0.hp};{jget;~result;0.atk};{jget;~result;0.def};{jget;~result;0.spa};{jget;~result;0.spd};{jget;~result;0.spe}}
**Weight**: {jget;~result;0.weight}
**Height**: {jget;~result;0.height};
fields.inline:true;
fields.name:{zws};
fields.value:**Types**:{newline}{join;{jget;~result;0.types};,{space}}
**Abilities**:{newline}{join;{jget;~result;0.abilities};,{space}}
**Evolutions**:{newline}{get;~evos}
**Generations**:{newline}{join;{jget;~result;0.oob.genfamily};,{space}};
fields.inline:true;
fields.name:{zws};
fields.value:*{get;~flavor}*;
fields.inline:false;
footer.text:Info From Generation {get;~gen};
}}
}
{function;abilities;
{edit;{channelid};{get;~searchmsgid};_delete;{embedBuild;
title:Ability - {jget;~result;0.name};
url:https://bulbapedia.bulbagarden.net/wiki/{regexreplace;{jget;~result;0.name};/\s/g;_}_(Ability);
color:lightgreen;
description:{jget;~result;0.description};
footer.text:Generations: {join;{jget;~result;0.genfamily};,{space}};
}}
}
{function;items;
{edit;{channelid};{get;~searchmsgid};_delete;{embedBuild;
title:Item - {jget;~result;0.name};
url:https://bulbapedia.bulbagarden.net/wiki/{regexreplace;{jget;~result;0.name};/\s/g;_};
thumbnail.url:https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/items/{regexreplace;{lower;{jget;~result;0.name}};/\s/g;-}.png;
color:lightblue;
description:{jget;~result;0.description}
{zws}
*Generations: {join;{jget;~result;0.genfamily};,{space}}*;
footer.text:Info From Generation {get;~gen};
}}
}
{function;moves;
{edit;{channelid};{get;~searchmsgid};_delete;{embedBuild;
title:Move - {jget;~result;0.name};
url:https://bulbapedia.bulbagarden.net/wiki/{regexreplace;{jget;~result;0.name};/\s/g;_}_(move);
color:lightred;
description:{jget;~result;0.description}
**Category**: {jget;~result;0.category}
**Power**: {jget;~result;0.power}
**Accuracy**: {jget;~result;0.accuracy}
**Priority**: {jget;~result;0.priority}
**PP**: {jget;~result;0.pp}
**Type**: {jget;~result;0.type}
**Generations**: {join;{jget;~result;0.genfamily};,{space}};
footer.text:Info From Generation {get;~gen};
}}
}
{function;natures;
{edit;{channelid};{get;~searchmsgid};_delete;{embedBuild;
title:Nature - {jget;~result;0.name};
url:https://bulbapedia.bulbagarden.net/wiki/Nature;
color:lightyellow;
description:{jget;~result;0.summary}
**HP**: {jget;~result;0.hp}
**ATK**: {jget;~result;0.atk}
**DEF**: {jget;~result;0.def}
**SPA**: {jget;~result;0.spa}
**SPD**: {jget;~result;0.spd}
**SPE**: {jget;~result;0.spe}
**Generations**: {join;{jget;~result;0.genfamily};,{space}};
footer.text:Info From Generation {get;~gen};
}}
}
{function;types;
{edit;{channelid};{get;~searchmsgid};_delete;{embedBuild;
title:Type - {jget;~result;0.name};
url:https://bulbapedia.bulbagarden.net/wiki/{jget;~result;0.name}_(type);
color:lightpink;
description:{if;{jget;~result;0.description};!=;{null};{jget;~result;0.description}{newline}}
{foreach;~atk;{jget;~result;0.atk_effectives};**{jget;~atk;0}**: {jget;~atk;1}x{newline}}**Generations**: {join;{jget;~result;0.genfamily};,{space}};
footer.text:Info From Generation {get;~gen};
}}
}
{function;setgen;
{set;!~gen;{lower;{params;0}}}
{switch;{lower;{params;0}};
["1","i","rb"];
{set;!~starter;150};
["2","ii","gs"];
{set;!~starter;250};
["3","iii","rs"];
{set;!~starter;384};
["4","iv","dp"];
{set;!~starter;487};
["5","v","bw"];
{set;!~starter;643};
["6","vi","xy"];
{set;!~starter;717};
["7","vii","sm"];
{set;!~starter;792};
["8","viii","ss"];
{set;!~starter;889};
{set;!~starter;1008}
{set;!~gen;9}
}
{set;!@{guildid}.default.gen;{get;~gen}}
{embed;{embedBuild;
title:Set Default Generation;
color:green;
thumbnail.url:https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/{get;~starter}.png;
description:{zws}
Set default generation to `{get;~gen}`.;
}}
}
{fallback;}
{switch;{args;0};
["help",""];
{func.help};
["setgen"];
{func.setgen;{args;1}};
{fallback}
{func.pokes;{flag;_}}
}
{exec;reqnu}{apply;func.nureq;{argsarray}}
{//;{set;!~url;{args;0}}
{if;{logic;||;{bool;{get;~url};==;{null}};{bool;{get;~url};startswith;`}};{throw;Missing required arguments {get;~url}}{return}}
{set;!~headers;{args;1}}
{if;{logic;||;{bool;{get;~headers};startswith;`};{bool;{get;~headers};==;{null}}};
{set;!~headers;}}
{if;{logic;||;{bool;{jget;~headers;headers.user-agent};startswith;`};{bool;{jget;~headers;headers.user-agent};==;{null}}};
{jset;~headers;headers.user-agent;syretia;c}}
{set;!~method;{jget;~headers;method}}
{if;{logic;||;{bool;{get;~method};==;{null}};{bool;{get;~method};startswith;`}};
{set;!~method;GET}}
{jset;~headers;method;POST;c}
{set;!~body;{args;2;n}}
{if;{logic;||;{bool;{get;~body};startswith;`};{bool;{get;~body};==;{null}}};
{set;!~body;}}
{jget;{request;https://syretia.xyz/req?url={uriencode;{get;~url}}&x={get;~method}&raw={flagset;r}&f={flag;f};{get;~headers};{get;~body}};body}}
{function;nureq;
{//;head for request}
{if;{jget;{params;1};method};!=;{null};
{set;!~nuhead;{jget;{params;1}}};
{jset;~nuhead;method;GET;c}
}
{if;{jget;~nuhead;headers};==;{null};
{jset;~nuhead;headers.user-agent;blargbot (blargbot.xyz);c}
}
{//;setup headers aray}
{set;!~headers;[]}
{foreach;~key;{jkeys;~nuhead;headers};
{if;{lower;{get;~key}};!=;x-authorization;
{push;~headers;{get;~key};{jget;~nuhead;headers.{get;~key}}}
}
}
{jset;~nuhead;headers.x-headers;{uriencode;{jget;~headers}};c}
{//;request}
{if;{length;{paramsarray}};>;2;
{set;!~nureq;{request;https://syretia.xyz/api/v1/req?url={uriencode;{params;0}};{jget;~nuhead};{params;2;n}}};
{set;!~nureq;{request;https://syretia.xyz/api/v1/req?url={uriencode;{params;0}};{jget;~nuhead}}}
}
{//;check status}
{if;{jget;~nureq;status};!=;200;
{jset;~nureq;body;{get;~nureq};c}
}
{jget;~nureq;body}
}
{//;scans urls using phish.sinking.yachts, phisherman.gg, Google Safe Browsing, metadata, and loaded scripts to check for malicious links}
{//;example command to add autoresponse:}
{//;b!ar add /https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,}/gi -R}
{//;function to check urls using phish endpoint on syretia.xyz}
{function;phish;
{//;set desc array to empty array}
{if;{get;~us.desc.ar};==;{null};
{set;!~us.desc.ar;[]}}
{//;check if local domain array exists}
{if;{isarray;{get;_us.malicious.ar}};!=;true;
{set;!_us.malicious.ar;[]}}
{//;set malicious to false}
{set;!~maliciousurl;false}
{//;check local list}
{if;{indexof;{jvalues;_us.malicious.ar};{get;~us.domain}};!=;-1;
{set;!~maliciousurl;true}
{push;~us.desc.ar;This domain was found in urlscanner's list of malicious domains.}}
{if;{get;~maliciousurl};!=;true;
{//;get results from anti-fish endpoint}
{jset;~head;method;POST;c}
{jset;~head;headers.User-Agent;blargbot;c}
{set;!~antifish;{jget;{exec;req;https://anti-fish.bitflow.dev/check;{jget;~head};{jset;;message;{get;~us.furl};c}};body}}
{if;{logic;&&;
{bool;{jget;~antifish;match};==;true};
{bool;{jget;~antifish;matches.0.trust_rating};==;1.0}};
{jset;~us.phish;phish;true;c}
{set;!~us.domain;{jget;~antifish;matches.0.domain}}
{jset;~us.phish;source;{jget;~antifish;matches.0.source};c}
}
{//;get results from google safe browsing if above check not true
{if;{get;~yachts};!=;true;
{set;!~gsb.results;{jget;{pop;{split;{jget;{exec;req;https://transparencyreport.google.com/transparencyreport/api/v3/safebrowsing/status?site={get;~us.domain}};body};{newline}}};0}}
{if;{jget;~gsb.results;1};==;4;
{jset;~us.phish;phish;true;c}
{jset;~us.phish;source;Google Safe Browsing;c}
}
}
}
{//;check results}
{if;{jget;~us.phish;phish};==;true;
{set;!~maliciousurl;true}
{set;!~us.source;{jget;~us.phish;source}}
{push;~us.desc.ar;This domain was found in {get;~us.source}{if;{get;~us.source};endswith;s;';'s} list of phishing domains.}
}}
{//;check whitelist}
{switch;{get;~us.base.domain};
{concat;{exec;us.whitelist};{get;_us.whitelist.ar}};
{set;!~maliciousurl;false}
}
{if;{get;~maliciousurl};==;true;
{//;unsafe}
{//;set variables for rest of embed}
{set;!~us.name;This website is unsafe}
{set;!~us.icon;https://www.colorcombos.com/combomaker_image.php?design=squares.png&colors={exec;discordcolors;red}&background_color={exec;discordcolors;red}&output_width=400}
{set;!~us.eurl;https://urlscan.io/domain/{get;~us.domain}}
{set;!~us.color;{exec;discordcolors;red}}
{push;~us.desc.ar;*[`urlscan.io/domain/{get;~us.domain}`](https://urlscan.io/domain/{get;~us.domain})*}
}}
{//;function to check if url loads javascript that all nitro scam sites seem to load}
{function;scriptscan;
{//;set desc array to empty array}
{if;{get;~us.desc.ar};==;{null};
{set;!~us.desc.ar;[]}}
{set;!~maliciousurl;false}
{//;get array of elements in head of site}
{set;!~us.head.ar;{exec;headar;{get;~us.furl}}}
{//;check website for script that all nitro scam sites seem to load}
{set;!~script.check;{filter;~sc;{get;~us.head.ar};{regextest;{get;~sc};/(src="\/assets\/discord\/js\/app\.js\?v=3fea243fdd"|"\/\.well-known\/ddos-guard\/check\?context=free_splash"|src="__API_PATH__"|src="\/assets\/bruh\.js")/gi}}}
{if;{length;{get;~script.check}};>;0;
{//;contains script, most likely nitro scam url}
{set;!~maliciousurl;true}
{set;!~us.name;This website is unsafe}
{set;!~us.icon;https://www.colorcombos.com/combomaker_image.php?design=squares.png&colors={exec;discordcolors;red}&background_color={exec;discordcolors;red}&output_width=400}
{set;!~us.eurl;https://urlscan.io/domain/{get;~us.domain}}
{set;!~us.color;{exec;discordcolors;red}}
{push;~us.desc.ar;This website loads JavaScript that is commonly used on Nitro scam websites.{newline}*[`urlscan.io/domain/{get;~us.domain}`](https://urlscan.io/domain/{get;~us.domain})*}
}}
{//;function to scan urls by checking title from metadata}
{function;metascan;
{//;set desc array to empty array}
{if;{get;~us.desc.ar};==;{null};
{set;!~us.desc.ar;[]}}
{fallback;}
{set;!~maliciousurl;false}
{//;get array of elements in head of site if not already set}
{if;{get;~us.head.ar};==;{null};
{set;!~us.head.ar;{exec;headar;{get;~us.furl}}}}
{//;get metadata for url}
{set;!~us.meta.ar;{filter;~ms;{get;~us.head.ar};{bool;{get;~ms};startswith;meta}}}
{//;get title and description from metadata}
{set;!~meta.title;{htmldecode;{pop;{slice;{split;{jget;{filter;~mst;{get;~us.meta.ar};{bool;{get;~mst};includes;title"}};0};"};0;-1}}}}
{set;!~meta.desc;{htmldecode;{pop;{slice;{split;{jget;{filter;~msd;{get;~us.meta.ar};{bool;{get;~msd};includes;description"}};0};"};0;-1}}}}
{set;!~meta.creator;{pop;{slice;{split;{jget;{filter;~msc;{get;~us.meta.ar};{bool;{get;~msc};includes;twitter:creator:id"}};0};"};0;-1}}}
{if;{get;~meta.creator};==;{null};
{set;!~meta.creator;{pop;{slice;{split;{jget;{filter;~msc;{get;~us.meta.ar};{bool;{get;~msc};includes;twitter:creator"}};0};"};0;-1}}}}
{set;!~meta.locale;{pop;{slice;{split;{jget;{filter;~msc;{get;~us.meta.ar};{bool;{get;~msc};includes;locale"}};0};"};0;-1}}}
{//;check metadata for words/phrases commonly used by nitro scams}
{if;{logic;||;
{logic;&&;
{bool;{get;~meta.creator};==;@discord};
{bool;{get;~meta.locale};==;ru}};
{logic;&&;
{bool;{get;~meta.title};==;Discord - A New Way to Chat with Friends & Communities};
{bool;{get;~meta.desc};==;Discord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.};
{bool;{get;~meta.creator};==;@discord}};
{logic;&&;
{regextest;{get;~meta.title};/discord/gi};
{regextest;{get;~meta.title};/nitro/gi};
{regextest;{get;~meta.title};/free/gi};
{regextest;{get;~meta.title};/steam/gi}};
{logic;&&;
{regextest;{get;~meta.desc};/discord/gi};
{regextest;{get;~meta.desc};/nitro/gi};
{regextest;{get;~meta.desc};/free/gi};
{regextest;{get;~meta.desc};/steam/gi}}};
{//;most likely nitro scam link}
{set;!~maliciousurl;true}
{set;!~us.name;This website is unsafe}
{set;!~us.icon;https://www.colorcombos.com/combomaker_image.php?design=squares.png&colors={exec;discordcolors;red}&background_color={exec;discordcolors;red}&output_width=400}
{set;!~us.eurl;https://urlscan.io/domain/{get;~us.domain}}
{set;!~us.color;{exec;discordcolors;red}}
{push;~us.desc.ar;This website's metadata triggered Nitro Scam Protection.{newline}**Title**: {htmldecode;{get;~meta.title}}{newline}**Description**: {htmldecode;{get;~meta.desc}}{newline}**Twitter Creator ID**: {get;~meta.creator}{newline}**Locale**: {get;~meta.locale}{newline}*[`urlscan.io/domain/{get;~us.domain}`](https://urlscan.io/domain/{get;~us.domain})*}
}}
{//;function to output results}
{function;results;
{output;{if;{commandname};startswith;_autoresponse;{usermention}}
{embed;{embedbuild;
author.name:{get;~us.name};
author.icon_url:{get;~us.icon};
author.url:{get;~us.eurl};
title:{get;~us.title};
url:{get;~us.eurl};
color:{get;~us.color};
footer.text:Posted by {usernick} ({userid});
footer.icon_url:{useravatar};
timestamp:{time};
description:{join;{get;~us.desc.ar};{newline}};}}}
}
{//;function to show stats about malicious domains}
{function;stats;
{embed;{embedbuild;
color:{exec;discordcolors;blurple};
title:urlscanner stats;
description:• {numformat;{get;*us.global.scans};;;,} URLs scanned
• {numformat;{get;*us.global.count};;;,} phishing URLs caught
• {numformat;{exec;syretia;json_db?pretty=true&token={get;@json_db}&op=get&bin=domains&id=blacklist&path={uriencode;length}};;;,} phishing domains blocked through phish.sinking.yachts:
https://raw.syretia.xyz/json_db/domains/blacklist{if;{logic;&&;{isarray;{get;_us.malicious.ar}};{bool;{length;{get;_us.malicious.ar}};>;0}};{newline}• {length;{get;_us.malicious.ar}} locally blocked domain{if;{length;{get;_us.malicious.ar}};>;1;s}:{newline}{dump;{jvalues;_us.malicious.ar}}.txt}
• {length;{exec;us.whitelist}} globally whitelisted domains:
https://raw.syretia.xyz/json_db/domains/whitelist{if;{logic;&&;{isarray;{get;_us.whitelist.ar}};{bool;{length;{get;_us.whitelist.ar}};>;0}};{newline}• {length;{get;_us.whitelist.ar}} locally whitelisted domain{if;{length;{get;_us.whitelist.ar}};>;1;s}:{newline}{dump;{jvalues;_us.whitelist.ar}}.txt}
• Last 10 caught URLs:
{reverse;{get;*us.caught.ar}}{repeat;`;3}
{join;{slice;{get;*us.caught.ar};0;10};{newline}}
{repeat;`;3}{reverse;{get;*us.caught.ar}}{if;{logic;&&;
{isarray;{get;*us.malicious.ar}};
{bool;{length;{get;*us.malicious.ar}};>;0}};
• New malicious domains:
{repeat;`;3}
{join;{jvalues;*us.malicious.ar};{newline}}
{repeat;`;3}};}}
}
{//;function to sync list of new domains to blocked list}
{function;sync;
{switch;{userid};
["86201442112671744"];
{//;do nothing};
{func.error;You are not authorized to modify the malicious domains list!}
{return}}
{set;!~mlist;{exec;firebase;get;-p discord/domains/blacklist}}
{if;{logic;||;
{bool;{isarray;{get;*us.malicious.ar}};==;true};
{bool;{length;{get;*us.malicious.ar}};!=;0}};
{exec;syretia;phish_bl_sync?key={get;@sybash.key};-d {jvalues;*us.malicious.ar}}
}
{set;!*us.malicious.ar;[]}
{void;{exec;firebase;set;-p discord/domains/whitelist;-a {jget;@firebase;1};-d {exec;us.whitelist}}}
{func.stats}
}
{//;function to pop a domain from the new domain array}
{function;pop;
{switch;{userid};
["86201442112671744"];
{//;do nothing};
{func.error;You are not authorized to modify the malicious domains list!}
{return}}
{pop;*us.malicious.ar}
}
{//;function to shift a domain from the new domain array}
{function;shift;
{switch;{userid};
["86201442112671744"];
{//;do nothing};
{func.error;You are not authorized to modify the malicious domains list!}
{return}}
{shift;*us.malicious.ar}
}
{//;function to clear the new domain array}
{function;clear;
{switch;{userid};
["86201442112671744"];
{//;do nothing};
{func.error;You are not authorized to modify the malicious domains list!}
{return}}
{set;!*us.malicious.ar;[]}
}
{//;function to add new domains to the local block array and global array}
{function;add;
{//;only staff can add domains}
{if;{isstaff;{userid}};!=;true;
{func.error;You are not authorized to modify the malicious domains list!}
{return}}
{//;check if local domain array exists}
{if;{isarray;{get;_us.malicious.ar}};!=;true;
{set;!_us.malicious.ar;[]}}
{//;check if url was provided}
{if;{regextest;{params;0};/^https?://.*/};!=;true;
{func.error;`{params;0}` is not a URL.}
{return}}
{//;get actual url if redirect and get domain}
{set;!~us.url;{exec;redirect.t;{params;0}}}
{set;!~us.domain;{jget;{split;{get;~us.url};/};2}}
{//;check if domain is whitelisted}
{if;{indexof;{exec;us.whitelist};{get;~us.domain}};!=;-1;
{func.error;`{get;~us.domain}` is in the list of globally whitelisted domains.}
{return}}
{//;check if already in NSP domain array}
{if;{indexof;{get;~us.firebase};{get;~us.domain}};!=;-1;
{func.error;`{get;~us.domain}` is already in Nitro Scam Protection's list of malicious domains.}
{return}}
{//;check if already in local domain array}
{if;{indexof;{get;_us.malicious.ar};{get;~us.domain}};!=;-1;
{func.error;`{get;~us.domain}` is already in local list of malicious domains.}
{return}}
{//;add to global array}
{if;{isarray;{get;*us.malicious.ar}};!=;true;
{set;!*us.malicious.ar;[]}}
{if;{indexof;{get;*us.malicious.ar};{get;~us.domain}};==;-1;
{void;{push;*us.malicious.ar;{get;~us.domain}}}}
{//;add to local array}
{void;{push;_us.malicious.ar;{get;~us.domain}}}
{//;run stats function to show domain was added}
{func.stats}
}
{//;function to remove domains from the local block array}
{function;remove;
{//;only staff can remove domains}
{if;{isstaff;{userid}};!=;true;
{func.error;You are not authorized to modify the malicious domains list!}
{return}}
{//;check if url was provided}
{if;{regextest;{params;0};/^https?://.*/};!=;true;
{func.error;`{params;0}` is not a URL.}
{return}}
{//;get actual url if redirect and get domain}
{set;!~us.url;{exec;redirect.t;{params;0}}}
{set;!~us.domain;{jget;{split;{get;~us.url};/};2}}
{//;check if local domain array exists}
{if;{isarray;{get;_us.malicious.ar}};!=;true;
{set;!_us.malicious.ar;[]}
{func.error;`{get;~us.domain}` is not in the local list of malicious domains.}
{return}}
{//;check if in local domain array}
{if;{indexof;{get;_us.malicious.ar};{get;~us.domain}};==;-1;
{func.error;`{get;~us.domain}` is not in the local list of malicious domains.}
{return}}
{//;remove from local array}
{set;!_us.malicious.ar;{filter;~d;{jvalues;_us.malicious.ar};{bool;{get;~d};!=;{get;~us.domain}}}}
{//;run stats function to show domain was removed}
{func.stats}
}
{//;function to handle local whitelisting}
{function;whitelist;
{//;only staff can handle whitelisting}
{if;{isstaff;{userid}};!=;true;
{func.error;You are not authorized to modify the whitelisted domains list!}
{return}}
{//;check arguments}
{switch;{lower;{params;0}};
["add"];
{func.whitelistadd;{params;1}};
["remove","rm"];
{func.whitelistremove;{params;1}};
{func.error;No valid argument found.
__**Usage**__: `{commandname} whitelist <add|remove> <URL>`}
}}
{//;function to add domains to local whitelist array}
{function;whitelistadd;
{//;check if local domain array exists}
{if;{isarray;{get;_us.whitelist.ar}};!=;true;
{set;!_us.whitelist.ar;[]}}
{//;check if url was provided}
{if;{regextest;{params;0};/^https?://.*/};!=;true;
{func.error;`{params;0}` is not a URL.}
{return}}
{//;get actual url if redirect and get domain}
{set;!~us.url;{exec;redirect.t;{params;0}}}
{set;!~us.domain;{jget;{split;{get;~us.url};/};2}}
{set;!~us.base.domain;{join;{reverse;{slice;{reverse;{split;{get;~us.domain};.}};0;2}};.}}
{//;check if domain is whitelisted}
{if;{indexof;{exec;us.whitelist};{get;~us.base.domain}};!=;-1;
{func.error;`{get;~us.base.domain}` is already in the list of globally whitelisted domains.}
{return}}
{//;check if already in NSP domain array}
{if;{indexof;{get;~us.firebase};{get;~us.base.domain}};!=;-1;
{func.error;`{get;~us.base.domain}` is already in Nitro Scam Protection's list of malicious domains.}
{return}}
{//;check if already in local domain array}
{if;{indexof;{get;_us.whitelist.ar};{get;~us.base.domain}};!=;-1;
{func.error;`{get;~us.base.domain}` is already in local list of whitelisted domains.}
{return}}
{//;add to local array}
{void;{push;_us.whitelist.ar;{get;~us.base.domain}}}
{//;run stats function to show domain was added}
{func.stats}
}
{//;function to remove domains from the local whitelist array}
{function;whitelistremove;
{//;check if url was provided}
{if;{regextest;{params;0};/^https?://.*/};!=;true;
{func.error;`{params;0}` is not a URL.}
{return}}
{//;get actual url if redirect and get domain}
{set;!~us.url;{exec;redirect.t;{params;0}}}
{set;!~us.domain;{jget;{split;{get;~us.url};/};2}}
{set;!~us.base.domain;{join;{reverse;{slice;{reverse;{split;{get;~us.domain};.}};0;2}};.}}
{//;check if local domain array exists}
{if;{isarray;{get;_us.whitelist.ar}};!=;true;
{set;!_us.whitelist.ar;[]}
{func.error;`{get;~us.base.domain}` is not in the local list of whitelisted domains.}
{return}}
{//;check if in local domain array}
{if;{indexof;{get;_us.whitelist.ar};{get;~us.base.domain}};==;-1;
{func.error;`{get;~us.base.domain}` is not in the local list of whitelisted domains.}
{return}}
{//;remove from local array}
{set;!_us.whitelist.ar;{filter;~d;{jvalues;_us.whitelist.ar};{bool;{get;~d};!=;{get;~us.base.domain}}}}
{//;run stats function to show domain was removed}
{func.stats}
}
{//;function to output help}
{function;help;
{embed;{embedbuild;
title:Help for urlscanner;
color:{exec;discordcolors;yellow};
description:__**Useage**__: `{commandname} <URL{if;{isstaff;{userid}};|add <URL>|remove <URL>|whitelist <add|remove> <URL>}|stats> | {escapebbtag;{exec;urlscanner;{escapebbtag;[bbtag]}}}`
Scans URLs for malicious content. `{commandname}` is intended to be used in an autoresponse. When `{commandname}` is ran in an autoresponse and a malicious URL is detected, the message containing the URL will be deleted, `[bbtag]` will be ran if present, and a message about why the URL is malicious will be outputed.
To add an autoresponse that will detect URLs, the following example can be used:
{repeat;`;3}
{escapebbtag;b!ar add /https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,}/gi -R}
{repeat;`;3}
After adding the autoresponse as shown above, edit it to contain the following:
{repeat;`;3}
{escapebbtag;{exec;urlscanner;{escapebbtag;[bbtag]}}}
{repeat;`;3}
Where `[bbtag]` is any valid BBTag that you wish to have executed when a malicious URL is detected.
***Please remember to wrap the code you wish to have executed in `{escapebbtag;{escapebbtag}}` otherwise it will be executed every time a URL is posted!***
Example:
{repeat;`;3}
{escapebbtag;{exec;urlscanner;{escapebbtag;{warn;{userid};1;Posted malicious URL}}}}
{repeat;`;3}
To silence the message that is outputted when a malicious URL is posted, simply use `{escapebbtag;{return}}` as the `[bbtag]`.
Examples:
{repeat;`;3}
{escapebbtag;{exec;urlscanner;{escapebbtag;{return}}}}
{escapebbtag;{exec;urlscanner;{escapebbtag;{warn;{userid};1;Posted malicious URL}{return}}}}
{repeat;`;3}
**Arguments when not ran in autoresponse**:
{repeat;`;3}
{if;{isstaff;{userid}};add - Add a domain to the local blocked domains array{newline}remove - Remove a domain from the local blocked domains array{newline}whitelist - Add/remove a domain to/from the local whitelisted domains array}
stats - View stats about urlscanner use
{repeat;`;3};}}
}
{//;detect if being ran in autoresponse}
{switch;{jget;{split;{commandname};_};1};
["autoresponse"];
{//;being ran in autoresponse}
{//;get array of matching urls in message text}
{set;!~urls;{regexmatch;{messagetext};/https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,}/gi}}
{//;check if array contains urls}
{if;{length;{get;~urls}};>;0;
{//;check each url in the array}
{foreach;~url;{get;~urls};
{//;set full url to variable}
{set;!~us.furl;{regexreplace;{replace;{get;~url};www.;};/(<|>|"|'|\(|\))/g;}}
{set;!~us.domain;{jget;{split;{get;~us.furl};/};2}}
{set;!~us.base.domain;{join;{reverse;{slice;{reverse;{split;{get;~us.domain};.}};0;2}};.}}
{//;check redirects}
{//;{set;!~redirect;{jget;{split;{regexreplace;{exec;redirect.t;{get;~us.furl}};/(https?:\/\//|^`.*);};/};0}}
{if;{get;~redirect};!=;{null};
{set;!~us.domain;{get;~redirect}}
{set;!~us.base.domain;{join;{reverse;{slice;{reverse;{split;{get;~us.domain};.}};0;2}};.}}
}}
{//;count number of urls scanned globally}
{if;{numformat;{get;*us.global.scans};};==;NaN;
{set;!*us.global.scans;0}}
{if;{guildid};!=;204061452707954688;
{set;!*us.global.scans;{math;+;1;0{get;*us.global.scans}}}}
{if;{isarray;{get;*us.guilds.{time;MMDDYYYY}}};!=;true;
{set;!*us.guilds.{time;MMDDYYYY};["{hash;{lower;{regexreplace;{guildname};/\s/g;}}}"]};
{if;{indexof;{get;*us.guilds.{time;MMDDYYYY}};{hash;{lower;{regexreplace;{guildname};/\s/g;}}}};==;-1;
{push;*us.guilds.{time;MMDDYYYY};{hash;{lower;{regexreplace;{guildname};/\s/g;}}}}}}
{fallback;}
{//;check if local domain array exists}
{if;{isarray;{get;_us.whitelist.ar}};!=;true;
{set;!_us.whitelist.ar;[]}}
{//;do not run checks on whitelisted domains}
{switch;{get;~us.base.domain};
{concat;{exec;us.whitelist};{get;_us.whitelist.ar}};
{//;whitelisted domain, do nothing};
{//;not whitelisted, run checks}
{//;foreach loop that runs each function}
{foreach;~method;["phish"];
{//;check whitelist again after getting redirect}
{switch;{get;~us.base.domain};
{concat;{exec;us.whitelist};{get;_us.whitelist.ar}};
{//;whitelisted domain, do nothing};
{//;run function}
{func.{get;~method}}
{//;check results}
{if;{get;~maliciousurl};==;true;
{//;malicious url posted}
{delete}
{//;add domain to global array if not present}
{if;{isarray;{get;*us.malicious.ar}};!=;true;
{set;!*us.malicious.ar;[]}}
{if;{logic;&&;
{switch;{get;~us.source};["phish.sinking.yachts","Phishing.Database"];false;true};
{bool;{indexof;{get;*us.malicious.ar};{get;~us.domain}};==;-1}};
{void;{push;*us.malicious.ar;{get;~us.domain}}}}
{//;add URL to global array if not present}
{if;{isarray;{get;*us.caught.ar}};!=;true;
{set;!*us.caught.ar;[]}}
{if;{logic;&&;
{bool;{guildid};!=;204061452707954688};
{bool;{indexof;{get;*us.caught.ar};{get;~us.furl}};==;-1}};
{void;{push;*us.caught.ar;{get;~us.furl}}}}
{//;count number of malicious urls posted globally}
{if;{numformat;{get;*us.global.count};};==;NaN;
{set;!*us.global.count;0}}
{if;{guildid};!=;204061452707954688;
{set;!*us.global.count;{math;+;1;0{get;*us.global.count}}}}
{//;return if quiet passed}
{switch;{lower;{flag;_}};
["quiet"];
{return}}
{//;check if custom code exists}
{if;{flag;_};!=;{null};
{inject;{args}}}
{//;output warning}
{func.results}
{//;end loop after code executed in case multiple urls posted}
{return}
}}
}}}};
{//;not being ran in autoresponse}
{exec;errorfunc}
{fallback;}
{//;detect arguments}
{switch;{lower;{args;0}};
["sync"];
{func.sync};
["pop"];
{func.pop};
["shift"];
{func.shift};
["clear"];
{func.clear};
["add"];
{func.add;{args;1}};
["remove","rm"];
{func.remove;{args;1}};
["whitelist","wl"];
{func.whitelist;{args;1};{args;2}};
["list","stats"];
{func.stats};
["","help"];
{func.help};
{//;get urls from input}
{set;!~urls;{split;{flag;_};{space}}}
{//;check urls}
{foreach;~url;{get;~urls};
{fallback;}
{//;set full url to variable}
{set;!~us.furl;{get;~url}}
{set;!~us.domain;{jget;{split;{get;~us.furl};/};2}}
{//;check redirects}
{//;{set;!~redirect;{jget;{split;{regexreplace;{exec;redirect.t;{get;~us.furl}};/(https?:\/\//|^`.*);};/};0}}
{if;{get;~redirect};!=;{null};
{set;!~us.domain;{get;~redirect}}
}}
{//;foreach loop that runs each function}
{foreach;~method;["phish"];
{//;run function}
{func.{get;~method}}
{//;check results}
{if;{get;~maliciousurl};==;true;
{//;output results}
{func.results}
{//;return}
{return;false}
}}
{//;output results if not done above}
{//;setup embed}
{set;!~us.name;No unsafe content found}
{set;!~us.eurl;https://urlscan.io/domain/{get;~us.domain}}
{set;!~us.icon;https://www.colorcombos.com/combomaker_image.php?design=squares.png&colors={exec;discordcolors;green}&background_color={exec;discordcolors;green}&output_width=400}
{push;~us.desc.ar;This website has passed all checks and was not found to be malicious.}
{push;~us.desc.ar;*[`urlscan.io/domain/{get;~us.domain}`](https://urlscan.io/domain/{get;~us.domain})*}
{set;!~us.color;{exec;discordcolors;green}}
{func.results}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment