{"id":26780367,"url":"https://github.com/alani25/oysterbot","last_synced_at":"2026-05-06T22:03:42.544Z","repository":{"id":278425746,"uuid":"935584666","full_name":"Alani25/OysterBot","owner":"Alani25","description":"Discord bot for managing the Monroe Community College Cabbages \u0026 Kings online Discord server.","archived":false,"fork":false,"pushed_at":"2025-03-27T21:45:08.000Z","size":1901,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T22:31:58.638Z","etag":null,"topics":["bot","discord","discordjs","server"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Alani25.png","metadata":{"files":{"readme":"readMe.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-19T17:23:27.000Z","updated_at":"2025-03-27T21:45:12.000Z","dependencies_parsed_at":"2025-02-19T18:40:46.520Z","dependency_job_id":null,"html_url":"https://github.com/Alani25/OysterBot","commit_stats":null,"previous_names":["alani25/oysterbot"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alani25%2FOysterBot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alani25%2FOysterBot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alani25%2FOysterBot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Alani25%2FOysterBot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Alani25","download_url":"https://codeload.github.com/Alani25/OysterBot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246150452,"owners_count":20731419,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","discord","discordjs","server"],"created_at":"2025-03-29T07:16:21.997Z","updated_at":"2026-05-06T22:03:37.513Z","avatar_url":"https://github.com/Alani25.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# King Oyster \n## Bot logs\nCode logs are important things among developers. Since I'm not using github within my workspace this time around (bc I don't need it for hosting and I'm lazy), I'll be outlining the different versions of the bot with all changes made along the way here.\n\n###  v0.1.05 \n- 🐛 **Bug:** Bot doesn't reply to messages send in replies to others\n- 📚 **Libraries:** Google authentication renewal\n- ✨ **Feature:** Bot reacts to keywords, `@ everyone` messages (based on channel), attachments (also based on channel), and etc. \n- ✨ **Feature:** King oyster can now detect haikus (not perfect with syllable counting… it's just a bot afterall ;-; ). Just type a haiku and it'll jump at you if it detects it.\n\n###  v0.1.06:\n- ✨ **Feature:** Syllable counter (count syllables for any poem when prompted), to try out reply to a message and say `@King Oyster#0093 count syllables`\n- ✨ **Feature:** Generate QR code, to try out use slash command or type `qr https://example.com SCALE COLOR-HEX BG-COLOR-HEX` (you can leave anything after the link out of it if you want to)\n- ❌ ~~**Feature:** Add new creative resources to King Oyster~~ ***Bad Idea*** ❌ (would need constant updates)\n- ✨ **Feature *Update:*** Improve the inspirator, figured there's no use for the adverb in there. Use through `/inspire` command or type `@King Oyster#0093 give me some inspiration` (keywords: `inspire`, `inspiration`)\n\n### v0.1.07\n- 🎩 **Hosting:** Improve memory \u0026 hosting\n- ✨ **Feature:** Allow bot to welcome new members\n- 🚔 **Modding:** Spam prevention features with bot. If the same user sends 10+ messages in the same minute, or sends a message that is detected as spam (15+ letters without a space will be detected as spam, ex: uhfkeskfksfnnksefnks), mute them for a minute. If they spam again, bot will mute again for double the time, and so on. Mute info will reset after every hour (meaning if they spam again the next hour, it'll be back to 1 minute mute and goes up from there)\n- ✨ **Feature:** Creating reminders. Ask Oyster to remind you to do something at certain time, and it'll DM you or send a message inside the channel when the time comes.\n- 🔧 **Improvement:** Allowed bot to notice poems in **share channel** (used to only react to posts with embeds)\n- 🔧 **Improvement:** Allow user to view specific or next quote (extra parameter), and make it so that requesting new quote creates a new message rather than editing previous message (this is how it was at first but then I edited it to prevent spam and now I'm putting it back after watching recent user interactions)\n\n### WIP\n- 🎩 **Hosting:** Migrate hosting to a micrcontroller device\n- ✍️ **Data:** Save data from google sheets on separate file, to avoid losing data when API token requires refreshing\n- ~~🔧 **Improvements:** Stop bot from reacting with 📜 on messages \"detected\" as literature anywhere outside the share channel, as it can mistake a lotta things for poems/ lit pieces.~~ ✅ _**DONE**_\n- ☠️ **Oyster's Secret:** Create Oyster's secret, one which no one would know of until the \"time has come.\" Am I insane for adding this in? Yes. I'm a programmer after all.\n- ✨ **Feature:** Allow King Oyster to nicely organize submissions into folders based on their genre, and even create separate threads with every submission posted or linked within (avoid attachments over 200 MB).\n___\n## Code Documentations\nThese documentations are written as of version **`V0.1.06`** of King Oyster Bot, and are currently being updated with version **`V0.1.07`**.\n\nTOC:\n1. [Workspace](#workspace)\n   - \u003ckbd\u003e[src/ commands.js](#src-commandsjs)\u003c/kbd\u003e\n   - \u003ckbd\u003e[src/ index.js](#src-indexjs)\u003c/kbd\u003e\n   - \u003ckbd\u003e[src/ quotes.txt](#src-quotestxt)\u003c/kbd\u003e\n   - \u003ckbd\u003e[src/ reminders.txt](#src-reminderstxt)\u003c/kbd\u003e\n   - \u003ckbd\u003e[src/ welcome.png](#src-welcomepng)\u003c/kbd\u003e\n   - \u003ckbd\u003e[.env](#env)\u003c/kbd\u003e\n   - [\u003ckbd\u003epackage.json\u003c/kbd\u003e \u0026 \u003ckbd\u003epackage-lock.json\u003c/kbd\u003e files + \u003ckbd\u003enode_modules\u003c/kbd\u003e directory](#packagejson--package-lockjson-files--node_modules-directory)\n   - [Setting up Workspace](#setting-up-workspace)\n   - [Renewing Authentication Token](#renewing-authentication-token)\n   - [Node packages](#node-packages)\n2. [Slash commands](#slash-commands)\n   - [\u003ckbd\u003e/report\u003c/kbd\u003e\u003ckbd\u003e`USERNAME`\u003c/kbd\u003e\u003ckbd\u003e`REASON`\u003c/kbd\u003e\u003ckbd\u003e`ATTACHMENTS` (optional)\u003c/kbd\u003e](#report-username-reason-attachments-optional-)\n   - [\u003ckbd\u003e/add-officer\u003c/kbd\u003e\u003ckbd\u003e`USERNAME`\u003c/kbd\u003e](#add-officer-username-)\n   - [\u003ckbd\u003e/deadline\u003c/kbd\u003e\u003ckbd\u003e_\u003c/kbd\u003e](#deadline-)\n   - [\u003ckbd\u003e/requirements\u003c/kbd\u003e\u003ckbd\u003e_\u003c/kbd\u003e](#requirements-)\n   - [\u003ckbd\u003e/submit\u003c/kbd\u003e\u003ckbd\u003e`TITLE`\u003c/kbd\u003e\u003ckbd\u003e`AUTHOR`\u003c/kbd\u003e\u003ckbd\u003e`TYPE`\u003c/kbd\u003e\u003ckbd\u003e`INFO`\u003c/kbd\u003e\u003ckbd\u003e`SUBMISSION`\u003c/kbd\u003e\u003ckbd\u003e`LINK` (optional)\u003c/kbd\u003e](#submit-title-author-type-info-submission-link-optional-)\n   - [\u003ckbd\u003e/schedule\u003c/kbd\u003e\u003ckbd\u003e_\u003c/kbd\u003e](#schedule-)\n   - [\u003ckbd\u003e/officehours\u003c/kbd\u003e\u003ckbd\u003e_\u003c/kbd\u003e](#officehours-)\n   - [\u003ckbd\u003e/appointment\u003c/kbd\u003e\u003ckbd\u003e`MONTH`\u003c/kbd\u003e\u003ckbd\u003e`DATE`\u003c/kbd\u003e\u003ckbd\u003e`HOUR`\u003c/kbd\u003e\u003ckbd\u003e`DESCRIPTION` (optional)\u003c/kbd\u003e](#appointment-month-date-hour-description-)\n   - [\u003ckbd\u003e/rules\u003c/kbd\u003e\u003ckbd\u003e_\u003c/kbd\u003e](#rules-)\n   - [\u003ckbd\u003e/linkperm\u003c/kbd\u003e\u003ckbd\u003e`LINK`\u003c/kbd\u003e](#linkperm-link-)\n   - [\u003ckbd\u003e/suggest\u003c/kbd\u003e\u003ckbd\u003e`ACTIVITY`\u003c/kbd\u003e\u003ckbd\u003e`INFO`\u003c/kbd\u003e](#suggest-activity-info-)\n   - [\u003ckbd\u003e/roll\u003c/kbd\u003e\u003ckbd\u003e`MAX` (optional)\u003c/kbd\u003e](#roll-max-optional-)\n   - [\u003ckbd\u003e/INSPIRE\u003c/kbd\u003e\u003ckbd\u003e_\u003c/kbd\u003e](#inspire-)\n   - [\u003ckbd\u003e/QUOTE\u003c/kbd\u003e\u003ckbd\u003e`NUMBER` (optional)\u003c/kbd\u003e](#quote-)\n   - [\u003ckbd\u003e/QR-CODE\u003c/kbd\u003e\u003ckbd\u003e`URL`\u003c/kbd\u003e\u003ckbd\u003e`SCALE` (optional)\u003c/kbd\u003e\u003ckbd\u003e`COLOR` (optional)\u003c/kbd\u003e\u003ckbd\u003e`COLOR-BG` (optional)\u003c/kbd\u003e](#qr-code-url-scale-optional-color-optional-color-bg-optional-)\n   - [\u003ckbd\u003e/REMIND-ME\u003c/kbd\u003e\u003ckbd\u003eREMINDER\u003c/kbd\u003e\u003ckbd\u003eMONTH\u003c/kbd\u003e\u003ckbd\u003eDAY\u003c/kbd\u003e\u003ckbd\u003eYEAR (optional)\u003c/kbd\u003e\u003ckbd\u003eTIME (optional)\u003c/kbd\u003e\u003ckbd\u003ePRIVATE (optional)\u003c/kbd\u003e](#remind-me-reminder-month-day-year-optional-time-optional-private-optional-)\n3. [Non-Slash Commands](#non-slash-commands)\n   - \u003ckbd\u003e[Custom Welcome Image](#custom-welcome-image)\u003c/kbd\u003e \u003csub\u003e(v0.1.07)\u003c/sub\u003e\n   - \u003ckbd\u003e[Haiku Detection](#haiku-detection)\u003c/kbd\u003e \u003csub\u003e(v0.1.05)\u003c/sub\u003e\n   - \u003ckbd\u003e[Count Syllables](#count-syllables)\u003c/kbd\u003e \u003csub\u003e(v0.1.06)\u003c/sub\u003e\n   - \u003ckbd\u003e[Reactions](#reactions)\u003c/kbd\u003e \u003csub\u003e(v0.1.05+)\u003c/sub\u003e\n4. [Moderating](#moderating)\n   - [Spam Prevention](#spam-prevention)\n   - [Link Permission](#link-permissions)\n\n___\n\n# Workspace\nThe directory is organized as follows:\n\u003cbr\u003e\u003cimg width=\"187\" alt=\"image\" src=\"https://github.com/user-attachments/assets/af4a53b3-2484-40c8-a566-39e88b3f8862\" /\u003e\n\n## src/ commands.js\nRegisters slash commands.\n\u003cbr\u003eRun the following command _once_ to register commands with a server:\n```curl\nnode src/commands.js\n```\nMake sure to adjust the server ID in `.env` file.\n\u003cbr\u003e[See Slash Commands section for more info on slash commands.](#slash-commands)\n\n## src/ index.js\nThe heart of King Oyster, the brain— this file contains main code for bot. \n\u003cbr\u003eThis file includes Google authentication, working with Google Drive \u0026 Spreadhseets (see [renewing authentication token](#renewing-authentication-token) section), imports dependencies (see [Node Packages](#node-packages)), sets bot status, connects to `quotes.txt` file, listens to interactions and created messages.\n\n## src/ quotes.txt\nLists quotes to be used in `index.js`.\n\u003cbr\u003e[See `/quote` slash command.](#quote-)\n\n## src/ reminders.txt\nA text file to save all reminders.\n\u003cbr\u003eIn the case that Oyster Bot restarts, all the reminders won't be lost since they'd be saved in this file.\n\u003cbr\u003eTODO link reminders command here\n\n## src/ welcome.png\nBase for custom welcome image. Image below to the left is \u003ckbd\u003esrc/ welcome.png\u003c/kbd\u003e, and image to the right is an example of the base image being used to create a welcome message with a user's avatar, as a test. The image to the right is also saved as \u003ckbd\u003ewelcome-image.png\u003c/kbd\u003e within the directory, and adjusts accordingly based on each user.\n\u003cbr\u003e\u003cimg width=\"200\" alt=\"Welcome Image Base\" src=\"https://github.com/user-attachments/assets/4b3aeac4-b93d-4c18-a420-fc0d61332e87\" /\u003e \u003cimg width=\"200\" alt=\"Welcome Image USED\" src=\"https://github.com/user-attachments/assets/6c222a2a-955b-48ef-bbd5-91d8482fe10b\" /\u003e\n\u003cbr\u003e[See `Custom Welcome Image` section.](#custom-welcome-image)\n\n\n\u003e **Note:** The \u003ckbd\u003esrc/ welcome.wick\u003c/kbd\u003e is the Wick project file where I created the custom image, and can be opened with [Wick Editor](https://www.wickeditor.com/#/) and edited from there.\n\n## .env\nContains all secrets. \n\u003cbr\u003eThis file contains:\n- `TOKEN`: The bot token, aka the Oyster's password.\n- `GUILD_ID`: The Discord server ID. Useful when registering slash commands with a new server.\n- `CLIENT_ID`: Oyster's user ID, not very important and I probably don't use.\n- `DRIVE_API_KEY`: Google Authentication API key. \n- `DRIVE_CLIENT_ID`: Google authentication client ID. \n- `DRIVE_CLIENT_SECRET`: Google authentication secret, aka the password for the authentication process.\n- `DRIVE_REDIRECT_URI`: Redirecting URI to authentication link for handling API request\n- `DRIVE_REFRESH_TOKEN`: Authentication token. May need to refresh after updating bot. See [src/index.js](#src-indexjs)\n- `DRIVE_FOLDER_ID`: ID for google drive folder. We don't use this one really in the code– but might be useful in later versions. ID derived from directory url.\n- `DRIVE_FOLDER_ID_1`: **Writing** submissions folder ID; derived from directory url.\n- `DRIVE_FOLDER_ID_2`: **Visual** submissions folder ID; derived from directory url.\n- `DRIVE_FOLDER_ID_3`: **Audio** submissions folder ID; derived from directory url.\n- `DRIVE_FOLDER_ID_4`: **Video** submissions folder ID; derived from directory url.\n- `DRIVE_FOLDER_ID_5`: **Other** submissions folder ID; derived from directory url.\n- `SPREADSHEET_ID`: Spreadsheet file ID, used for information on room number, meeting times, office hours, deadline, etc. Derived from spreadsheet url.\n\n## package.json \u0026 package-lock.json files + node_modules directory\n`package.json` contains version number of dependencies, while `package-lock.json` includes more info on packages used, connecting back to `node_modules` directory, which includes all the packages used in the project.\n\n\u003cbr\u003eSetting up NPM steps included in [Setting up Workspace](#setting-up-workspace) section.\n\u003cbr\u003e[See Node Packages section.](#node-packages)\n\n___\n# Setting up Workspace\nSee [Workspace](#workspace) to get an idea of how to setup the directory. This tutorial assumes that you have NPM v22+ and git installed on your device. \n\u003cbr\u003eIf not, you can [follow this quick guide to install git](https://github.com/git-guides/install-git) and clone this respitory with this command\n```curl\ngit clone https://github.com/Alani25/OysterBot.git\n```\nor you can manually download the files from this respitory (which would be a better option if you don't have expierence with git).\n\u003cbr\u003e\u003cimg width=\"481\" alt=\"Screenshot 2025-02-25 at 11 46 48 AM\" src=\"https://github.com/user-attachments/assets/47c3c8db-0c02-407f-9107-709574cfca3a\" /\u003e\n\n\u003cbr\u003eHowever, you will still _need_ to [install Node JS](https://nodejs.org/en/download) to use the [DiscordJS library](https://discord.js.org/) and other [required packages](#node-packages).\n\n\u003cbr\u003eAn IDE (Integrated Development Environment, aka a code editor) would also be required to edit the code, in which case I would recommend [VS Code](https://code.visualstudio.com/). \n\n\u003cbr\u003eAfter install the code, either using `git clone` or by manually installing the zip file and unzipping it, you should find these files inside of the version folder.\n\u003cbr\u003eNote that the version used in this tutorial is `v0.1.06`, but you might be working off of a different version. If there are any other files or versions outside of the directory feel free to remove them. \n\u003cbr\u003e\u003cimg width=\"903\" alt=\"image\" src=\"https://github.com/user-attachments/assets/8816e4ce-f60d-434d-a92a-89187f1c042b\" /\u003e\n\n\u003cbr\u003eNext step should be simple— first make sure your Node version is up to date by running\n```curl\nnode --version\n```\nNode version v17+ is recommended. \n\u003cbr\u003eNext, change directory into the version you would like to use. Would recommend doing a quick `ls` to view all version installed, in this tutorial we'll be going into `V0.1.06` but I would recommend working with the latest version of the bot available. Same steps would apply for all versions.\n```\ncd V0.1.06\nnpm install\n```\n\nPreview in terminal:\n\u003cbr\u003e\u003cimg width=\"403\" alt=\"image\" src=\"https://github.com/user-attachments/assets/123ac481-23a8-4c8e-b88b-c392caed2788\" /\u003e\n\n\u003cbr\u003eNow if you've never touched a terminal before you might be confused. In which case, I would recommend you to install the VS Code IDE I mentioned earlier, and open the version folder there instead. After opening the bot folder there, you should find a terminal at the bottom. \n\n\u003cimg width=\"1019\" alt=\"Screenshot 2025-02-25 at 12 04 05 PM\" src=\"https://github.com/user-attachments/assets/82d415e4-922f-47da-b30a-555bda0b3819\" /\u003e\n\nIf you don't see the terminal, move your cursor closer to the bottom of the editor, and try to drag up the terminal window.\n\u003cbr\u003eYou should be able to run `npm install` inside of the terminal window, without needing to change directory with `cd V0.1.06` if you opened the version folder inside VS Code.\n\n\u003cbr\u003eYour main code should be inside of the [\u003ckbd\u003eindex.js\u003c/kbd\u003e file](#src-indexjs). You will also need to create a [\u003ckbd\u003e.env\u003c/kbd\u003e file](#env), see the [\u003ckbd\u003e.env\u003c/kbd\u003e file](#env) section for an idea on what to include inside of the file.\n\n\u003cbr\u003e**Note:** you will need to know how to aquire the different tokens that are used in the `.env` file in order to create your own.\n\u003cbr\u003eIf you're planning on updating King Oyster's code… well, first off hey there future C\u0026K officers, I can't believe you're actually reading this!! And second off… you can either contact me for the files or see if I've left it behind for you somewhere, unless if you have expierence programming bots and would like to get them on your own, in which case head over to the [Google authentication playground for developers](https://developers.google.com/oauthplayground), [Google Cloud Console](https://console.cloud.google.com/), both which I'll explain later on, Google Drive \u0026 Sheets (obviously) and the [Discord Developer Portal](https://discord.com/developers/applications).\n\n\u003cbr\u003eFor the Google Spreasheet, make sure to also use [this Spreadsheet](https://docs.google.com/spreadsheets/d/1ppkEjOB4EYGmxIexfEBU_mMoCqp8vWpwRIgj6Cr9zjw/edit?usp=sharing) as reference. Most of everything else would rely on the code, and in which case if you are trying to update things I would hope that you understand some coding… if you don't, then god help you cause you'll sure be in for a lotta fun.\n\n\u003cbr\u003eBack on topic, once you're all set with everything, you should be able to start the bot by running the command\n```curl\nnode src/index.js\n```\nAlternatively, I'd like to also recommend running the bot with either [nodemon](https://www.npmjs.com/package/nodemon) while testing, or [pm2](https://www.npmjs.com/package/pm2) if you'd like to keep the bot alive 24/7 in the background of your computer. There are additional steps to that in the case that you'd want to keep the bot alive while the computer is sleeping, in which for I'd recommend using [Amphetamine](https://apps.apple.com/us/app/amphetamine/id937984704?mt=12) or a real bot hosting service if you're not a psycho, such as [lunes](https://lunes.host/). I will give you a warning though, when using a bot hosting service, the service providers might be within a different time zone, which could mess up dates and such. This is not always the case, but do watch out for that.\n\n### Renewing Authentication Token\n\u003cbr\u003eIf you run the bot, and get something in the console that says\n```curl\nError reading spreadsheet: invalid_grant\nGoogle APIs won't work. In other words, google drive \u0026 spreadsheet connections won't happen…\nplz visit https://developers.google.com/oauthplayground using approved google account and see codes inside of .env file\n```\nFirst thing you should do is thank me for the detailed warning. Next up, follow the steps given.\n\u003cbr\u003eHead over to the [OAuth 2.0 Playground](https://developers.google.com/oauthplayground), and under step 1, search for and check `https://www.googleapis.com/auth/drive` for Google Drive authentication (under \u003ckbd\u003eApps Script API V1\u003c/kbd\u003e or \u003ckbd\u003eDrive API v3\u003c/kbd\u003e), and `https://www.googleapis.com/auth/spreadsheets.readonly` for Speadsheets authentication (under \u003ckbd\u003eArea120 Tables API v1alpha1\u003c/kbd\u003e or \u003ckbd\u003eGoogle Sheets API v4\u003c/kbd\u003e).\n\n\u003cbr\u003eSecond step, select the gear icon and make sure to add in your OAuth Client ID and Secret ID.\n\u003cimg width=\"644\" alt=\"Screenshot 2025-02-25 at 5 59 32 PM\" src=\"https://github.com/user-attachments/assets/edec66ac-e2c4-45a7-8a76-1fb16cd0a029\" /\u003e\n\u003cbr\u003eI cannot show these tokens publicly as they can be misused, but you can obtain them from the [Google Cloud Console](https://console.cloud.google.com/), which if you're a part of C\u0026K then I recommend logging in through the C\u0026K Gmail to obtain these codes without much trouble. If you're not, then I would recommend following [this youtube tutorial](https://www.youtube.com/watch?v=1y0-IfRW114) to connect your bot to Google's APIs. \n\n\u003cbr\u003eLastly, select \u003ckbd\u003eAuthorize APIs\u003c/kbd\u003e\n\u003cbr\u003e\u003cimg width=\"547\" alt=\"Screenshot 2025-02-25 at 6 57 19 PM\" src=\"https://github.com/user-attachments/assets/41bf3d6a-0e56-46e7-bc5e-7c2edc7c798a\" /\u003e\n\u003cbr\u003eYou would be prompted to log into a google account, and allowing certain permissions.\n\u003cbr\u003eYou should use the C\u0026K google account, or an account that has been set up under [Google Cloud Console](https://console.cloud.google.com/).\n\n\u003cbr\u003eOnce you complete the process, you should find yourself on step 2 of the OAuth 2.0 Playground (if it skips to step 3, then click step 2). \n\u003cbr\u003eClick \u003ckbd\u003eExchange authroization code for tokens\u003c/kbd\u003e, and then copy the **refresh token**. This is the token that you will define inside the [.env](#env) file, under the variable name `DRIVE_REFRESH_TOKEN`.\n\n\u003cbr\u003eAnd now, once you run the bot again, you should not see the `invalid_grant` error.\n\n___\n\n## Node Packages\nNode Packages are outside libraries imported into our code to assist with specific tasks. The libraries have been installed through NPM. You may run `npm ls` to get a list of all current node packages, or `npm outdated` to search for any outdated packages. \n\n**DiscordBot**\n\u003cbr\u003e\u003ckbd\u003e\n\u003cbr\u003e├── \u003ckbd\u003eaxios@1.7.9\u003c/kbd\u003e Creating HTTP requests \n\u003cbr\u003e├── \u003ckbd\u003ecanvas@3.1.0\u003c/kbd\u003e Used for creating custom images.\n\u003cbr\u003e├── \u003ckbd\u003ediscord.js@14.18.0\u003c/kbd\u003e Main Discord bot library. \n\u003cbr\u003e├── \u003ckbd\u003edotenv@16.4.7\u003c/kbd\u003e Working with environmental variables. \n\u003cbr\u003e├── \u003ckbd\u003efetch@1.1.0\u003c/kbd\u003e Fetching url contents (UNUSED PACKAGE?) \n\u003cbr\u003e├── \u003ckbd\u003efs@0.0.1\u003c/kbd\u003e Used for reading file within directory. \n\u003cbr\u003e├── \u003ckbd\u003egoogleapis@144.0.0\u003c/kbd\u003e Used for Google authentication \u0026 connecting to Google tools. \n\u003cbr\u003e├── \u003ckbd\u003enode-cron@3.0.3\u003c/kbd\u003e Used for running commands at specific times.\n\u003cbr\u003e├── \u003ckbd\u003epath@0.12.7\u003c/kbd\u003e Assists with tracking file paths. \n\u003cbr\u003e└── \u003ckbd\u003eqrcode@1.5.4\u003c/kbd\u003e Generate \u0026 work with QR codes. \n\u003c/kbd\u003e\n\n___\n# Slash Commands\nSlash commands are a list of pre-defined commands that can be used to interact with the bot. \u003cbr\u003e \nThese commands can also come with different input parameters accordingly (see [src/commands.js](#src-commandsjs)).\u003cbr\u003e\n\nTo start using commands, all you need to do is start typing a message with the character `/`, then you can select the command you wish to use.\n\u003cbr\u003e\u003cimg width=\"795\" alt=\"image\" src=\"https://github.com/user-attachments/assets/aea8cd47-814b-452c-a80d-1ffdc8fb9291\" /\u003e\n\nThe purpose of each command is listed below.\n\n___\n## \u003ckbd\u003e`/report` \u003ckbd\u003eUSERNAME\u003c/kbd\u003e \u003ckbd\u003eREASON\u003c/kbd\u003e \u003ckbd\u003eATTACHMENTS (optional)\u003c/kbd\u003e \u003c/kbd\u003e\nReport \u003ckbd\u003eUSERNAME\u003c/kbd\u003e for \u003ckbd\u003eREASON\u003c/kbd\u003e, and optionally attach \u003ckbd\u003eATTACHMENTS\u003c/kbd\u003e as proof.\n\u003cbr\u003eIf the \u003ckbd\u003eUSERNAME\u003c/kbd\u003e (being reported) is an **officer**, then the bot will let the user know that they might've made a mistake.\n\n\u003cbr\u003e\u003cimg width=\"499\" alt=\"image\" src=\"https://github.com/user-attachments/assets/16c13543-8bfa-49e6-98af-bc6e38d1a542\" /\u003e\n\n\u003cbr\u003eDespite this, the report is _still send._ When a report is send, the bot will search for a channel with the name `bot-reports`. If this channel doesn't exist, the bot is smart enough to create it, while restricting access to it by regular members (allowing only officers to view it).\n\u003cbr\u003eThe report will include the \u003ckbd\u003eUSERNAME\u003c/kbd\u003e display name and user ID, along with the user's username, their \u003ckbd\u003eREASON\u003c/kbd\u003e, and an \u003ckbd\u003eATTACHMENT\u003c/kbd\u003e if provided.\n\n\u003cbr\u003eIn the case that the user (sending the report) was an officer, then the \u003ckbd\u003eUSERNAME\u003c/kbd\u003e will be automatically muted for **10 minutes** after the report is send.\n\n___\n## \u003ckbd\u003e`/add-officer` \u003ckbd\u003eUSERNAME\u003c/kbd\u003e \u003c/kbd\u003e\nCommand to give the officer role to a member. User must be an officer to be able to use this command.\n\u003cbr\u003e✅ If the user is an officer, then \u003ckbd\u003eUSERNAME\u003c/kbd\u003e will be assigned an officer role. \n\u003cbr\u003e❌ If the user is NOT an officer, they will be notified that only officers are able to run this command.\n\n___\n## \u003ckbd\u003e`/deadline` \u003c/kbd\u003e\nThis command will inform the user of the C\u0026K magazine submissions deadline, along with a countdown.\n\u003cbr\u003eButton interactions can lead user to [submission requirements](#requirements-), or the submissions form.\n\n\u003cbr\u003e\u003cimg width=\"789\" alt=\"image\" src=\"https://github.com/user-attachments/assets/30d5814a-7abb-4e22-8bc0-a0ecbf9eb721\" /\u003e\n\n\u003e Can be activated through chat messages by replying to or mentioning `@King Oyster#0093`, using keywords: \n\u003e \u003cbr\u003e\u003ckbd\u003edeadline\u003c/kbd\u003e or \u003ckbd\u003esubmission\u003c/kbd\u003e AND EITHER \u003ckbd\u003etime\u003c/kbd\u003e OR \u003ckbd\u003ewhen\u003c/kbd\u003e\n\n___\n## \u003ckbd\u003e`/requirements` \u003c/kbd\u003e\nThis command will inform the user of the C\u0026K magazine submissions' requirements.\n\u003cbr\u003eButton interactions can lead user to [deadline](#deadline-), or the submissions form.\n\n\u003e Can be activated through chat messages by replying to or mentioning `@King Oyster#0093`, using keywords: \n\u003e \u003cbr\u003e\u003ckbd\u003esubmission\u003c/kbd\u003e or \u003ckbd\u003erequirements\u003c/kbd\u003e\n\n___\n## \u003ckbd\u003e`/submit` \u003ckbd\u003eTITLE\u003c/kbd\u003e \u003ckbd\u003eAUTHOR\u003c/kbd\u003e \u003ckbd\u003eTYPE\u003c/kbd\u003e \u003ckbd\u003eINFO\u003c/kbd\u003e \u003ckbd\u003eSUBMISSION\u003c/kbd\u003e \u003ckbd\u003eLINK (optional)\u003c/kbd\u003e \u003c/kbd\u003e\nSubmit a piece to the magazine.\n\u003cbr\u003eThe \u003ckbd\u003eSUBMISSION\u003c/kbd\u003e file will be sent to Google drive, along with other submissions (if Drive isn't working, see [Renewing Authentication Token](#renewing-authentication-token) section).\n\u003cbr\u003eBefore being send into the drive, the submission will be sorted into different folders based on the chosen \u003ckbd\u003eTYPE\u003c/kbd\u003e:\n1. Writing\n2. Visual\n3. Video\n4. Audio\n5. Other\n\nThe \u003ckbd\u003eSUBMISSION\u003c/kbd\u003e file will also be renamed into the title of the piece, followed by an underscore and the default file name.\n\u003cbr\u003eNevertheless, in case our bot faces issues submitting the piece to the drive, and as a backup, Oyster automatically sends all submissions in a separate, private channel, called \"bot-submissions.\" This will include the user's username, the piece's \u003ckbd\u003eTITLE\u003c/kbd\u003e and \u003ckbd\u003eAUTHOR\u003c/kbd\u003e (name published under), all hidden behind spoilers, along with the submission \u003ckbd\u003eTYPE\u003c/kbd\u003e, extra \u003ckbd\u003eINFO\u003c/kbd\u003e, a \u003ckbd\u003eLINK\u003c/kbd\u003e if included, and obviously the \u003ckbd\u003eSUBMISSION\u003c/kbd\u003e if attached.\n\nIt's unlikely that the bot would ever have issues with uploading the \u003ckbd\u003eSUBMISSION\u003c/kbd\u003e, unless if the \u003ckbd\u003eSUBMISSION\u003c/kbd\u003e is very large in size. To prevent issues, we stop the bot from sending an attachment of the \u003ckbd\u003eSUBMISSION\u003c/kbd\u003e in the **bot-submissions** channel if it's _**over 200 MB in size!**_ The bot would still attempt to upload the file to google drive, in which it should succeed but at a slower rate. This is a rare case in which we'd advise to use the \u003ckbd\u003eLINK\u003c/kbd\u003e option to share your piece (and for \u003ckbd\u003eSUBMISSION\u003c/kbd\u003e you can submit a simple thumbnail).\n\n\u003csup\u003e**Note:** If the **bot-submissions** channel doesn't exist, the bot is smart enough to create it and set permissions accordingly.\u003c/sup\u003e\n\n___\n## \u003ckbd\u003e`/schedule` \u003c/kbd\u003e\nThis command will inform the user of the meeting time and location of our regular C\u0026K member meetings, along with the exact meeting time of the next meeting.\n\n\n\u003e Can be activated through chat messages by replying to or mentioning `@King Oyster#0093`, using keywords: \n\u003e \u003cbr\u003e\u003ckbd\u003eschedule\u003c/kbd\u003e or \u003ckbd\u003emeet\u003c/kbd\u003e AND \u003ckbd\u003etime\u003c/kbd\u003e or \u003ckbd\u003ewhen\u003c/kbd\u003e or \u003ckbd\u003ewhere\u003c/kbd\u003e \n\n\n\u003e \u003csup\u003e 🐛 **Note:** Sometimes the hosting service could have a different timezone and mess up deadline times and such since I'm working with literal timestamps, which sucks. I'm currently hosting locally but that's an issue to look out for. Now I can see why most discord bots don't use timestamps, I guess I made more work for myself.\n___\n## \u003ckbd\u003e`/officehours` \u003c/kbd\u003e\nGet the location and time of our office hours for the semester.\n\u003cbr\u003eThis command connects to a Google spreadsheet, where officers can input their office hours times without needing to touch the code.\n\u003cbr\u003eSame case for infortmation included in the [deadline](#deadline-) and [schedule](#schedule-) commands.\n\n\u003e Can be activated through chat messages by replying to or mentioning `@King Oyster#0093`, using keywords: \n\u003e \u003cbr\u003e\u003ckbd\u003eofficehours\u003c/kbd\u003e or \u003ckbd\u003eoffice hours\u003c/kbd\u003e or \u003ckbd\u003eoffice-hours\u003c/kbd\u003e\n\n___\n## \u003ckbd\u003e`/appointment` \u003ckbd\u003eMONTH\u003c/kbd\u003e \u003ckbd\u003eDATE\u003c/kbd\u003e \u003ckbd\u003eHOUR\u003c/kbd\u003e \u003ckbd\u003eDESCRIPTION\u003c/kbd\u003e \u003c/kbd\u003e\nSet an appointment to meet with an officer in \u003ckbd\u003eMONTH\u003c/kbd\u003e, \u003ckbd\u003eDATE\u003c/kbd\u003e, at \u003ckbd\u003eHOUR\u003c/kbd\u003e. The appointment is then treated as a report, and will be send to the reports channel for an officer to check (see `/REPORT ...` command). Along with the user info and appointment time, the report will also include the \u003ckbd\u003eDESCRIPTION\u003c/kbd\u003e. As a matter of fact, the bot response send privately to the user is identical to the report the officers recieve (see image below).\n\n\u003cbr\u003e\u003cimg width=\"816\" alt=\"image\" src=\"https://github.com/user-attachments/assets/59d2295c-26e3-4485-a2a3-5e9efd792eb7\" /\u003e\n\n\n___\n## \u003ckbd\u003e`/rules` \u003c/kbd\u003e\nCommand will help the user find the server rules. \n\u003cbr\u003eThe bot will also give the user the option to navigate to the [Discord Guidelines]([url](https://discord.com/guidelines)) or view [MCC Policies]([url](https://www.monroecc.edu/depts/policy/)) with the click of a button.\n\n\u003cbr\u003e\u003cimg width=\"651\" alt=\"image\" src=\"https://github.com/user-attachments/assets/3ac8424e-3ecc-405f-a791-b3ccb5b9bf81\" /\u003e\n\n\u003e Can be activated through chat messages by replying to or mentioning `@King Oyster#0093`, using keywords: \n\u003e \u003cbr\u003e\u003ckbd\u003erules\u003c/kbd\u003e\n\n___\n## \u003ckbd\u003e`/linkperm` \u003ckbd\u003eLINK\u003c/kbd\u003e \u003c/kbd\u003e\nRequest permission to post links.\n\u003cbr\u003eThis will send a report to the same **bot-report** channel used by the `/report...` and `/appointment...` commands.\n\u003cbr\u003eThe request will look as follows:\n\n\u003cbr\u003e\u003cimg width=\"812\" alt=\"image\" src=\"https://github.com/user-attachments/assets/88226795-59b4-44fb-97bf-2a36932901ed\" /\u003e\n\n\u003cbr\u003eTo accept, after reviewing the link, a mod, aka officer, can give the user a __**@link perm**__ role. \n\u003cbr\u003eThis role will allow the user to post links without being stopped by the bot.\n\n\u003cbr\u003ePlease note that certain links, such as youtube and tenor urls (GIFs) are allowed without needing link perms (see `allowedLinks` array in code).\n\n\u003cbr\u003e[See link permissions section.](#link-permissions)\n___\n## \u003ckbd\u003e`/suggest` \u003ckbd\u003eACTIVITY\u003c/kbd\u003e \u003ckbd\u003eINFO\u003c/kbd\u003e \u003c/kbd\u003e\nSuggest an \u003ckbd\u003eACTIVITY\u003c/kbd\u003e for us to do during our weekly member meetings, along with extra \u003ckbd\u003eINFO\u003c/kbd\u003e on how the activity works.\n\u003cbr\u003eSimilar to `report...`, `/appointment ...`, and `/linkperm ...` commands, this command will send the suggestion as a report in the **bot-reports** channel in the format shown below.\n\n\u003cbr\u003e\u003cimg width=\"817\" alt=\"image\" src=\"https://github.com/user-attachments/assets/d9ce1105-07a8-4d46-994f-d844714adaec\" /\u003e\n\n\n## \u003ckbd\u003e`/roll` \u003ckbd\u003eMAX (optional)\u003c/kbd\u003e \u003c/kbd\u003e\nRoll a dice and get a random number. Optionally, you can adjust the range of possible values from the roll by adjusting the \u003ckbd\u003eMAX\u003c/kbd\u003e sides of the die.\n\n\u003cbr\u003e\u003cimg width=\"661\" alt=\"image\" src=\"https://github.com/user-attachments/assets/a0dc9e37-6766-4b1f-bc5d-065ec48004bc\" /\u003e\n\n\n___\n## \u003ckbd\u003e`/inspire` \u003c/kbd\u003e\nGet a random adjective and noun to help spark some inspiration ✨\n\n\u003cbr\u003e\u003cimg width=\"300\" alt=\"image\" src=\"https://github.com/user-attachments/assets/2712716a-51e4-40b1-819d-e1230435acda\" /\u003e\n\u003cbr\u003eDon't like what you see? Click \u003ckbd\u003eSprinkle More Inspiration\u003c/kbd\u003e and King Oyster will edit the message to add more inspiration on top of what's already there.\n\n\u003csup\u003e**Note:** See `getRandomInspiration(...)` function in code, `noun` and `adjective` variables.\u003c/sup\u003e\n\n\u003e Can be activated through chat messages by replying to or mentioning `@King Oyster#0093`, using keywords: \n\u003e \u003cbr\u003e\u003ckbd\u003einspire\u003c/kbd\u003e or \u003ckbd\u003einspiration\u003c/kbd\u003e\n\n___\n## \u003ckbd\u003e`/quote` \u003ckbd\u003eNUMBER (optional)\u003c/kbd\u003e \u003c/kbd\u003e\nWanna feel some wisdom? Then get a random quote from a set of 40+ pre-selected quotes (saved in [quotes.txt](#src-quotestxt) file, quotes are separated by three new lines).\n\u003cbr\u003eIf you choose to input a \u003ckbd\u003eNUMBER\u003c/kbd\u003e then you'll get a quote that corresponds to that number rather than a random one.\n\n\u003cbr\u003e\u003cimg width=\"451\" alt=\"image\" src=\"https://github.com/user-attachments/assets/7ba96f4e-b587-4911-97e8-06c7003940c2\" /\u003e\n\u003cbr\u003eEach generated quote is followed with three buttons. Two arrows to cycle through previous and next quote, and a \u003ckbd\u003eRandom Quote\u003c/kbd\u003e button, which gives you a new random quote in a new message.\n\n\u003e Can be activated through chat messages by replying to or mentioning `@King Oyster#0093`, using keywords: \n\u003e \u003cbr\u003e\u003ckbd\u003equote\u003c/kbd\u003e\n\n___\n## \u003ckbd\u003e`/qr-code` \u003ckbd\u003eURL\u003c/kbd\u003e \u003ckbd\u003eSCALE (optional)\u003c/kbd\u003e \u003ckbd\u003eCOLOR (optional)\u003c/kbd\u003e \u003ckbd\u003eCOLOR-BG (optional)\u003c/kbd\u003e \u003c/kbd\u003e\nHave Oyster generate you a QR code that redirects to \u003ckbd\u003eURL\u003c/kbd\u003e, along with a few optional inputs, such as \u003ckbd\u003eSCALE\u003c/kbd\u003e of the QR code image (default: 20), and the \u003ckbd\u003eCOLOR\u003c/kbd\u003e of the QR code (HEX code recommended), and \u003ckbd\u003eCOLOR-BG\u003c/kbd\u003e for the QR code background (transparent by default). \n\n\u003cbr\u003eSee image below for an example of how QR code can be generated WITHOUT using the slash command, but rather by sending a text message.\n\n\u003cbr\u003e\u003cimg width=\"496\" alt=\"image\" src=\"https://github.com/user-attachments/assets/88cd37bb-86d2-4278-a34d-38d2ee4cc9c5\" /\u003e\n\n\u003csup\u003e**Note:** In the image above, I could've also included the \u003ckbd\u003eCOLOR-BG\u003c/kbd\u003e at the end, but chose not to so the background defaulted to transparent. \u003c/sup\u003e\n\nThe slash command works the same way as the text command, except if you generate a QR code with the slash commands, the message is hidden and can only be viewed by you.\n\n\u003e Can be activated through chat messages by sending a message that\n\u003e \u003cbr\u003eSTARTS WITH \u003ckbd\u003e`qr `\u003c/kbd\u003e\n\n___\n## \u003ckbd\u003e`/remind-me` \u003ckbd\u003eREMINDER\u003c/kbd\u003e \u003ckbd\u003eMONTH\u003c/kbd\u003e \u003ckbd\u003eDAY\u003c/kbd\u003e \u003ckbd\u003eYEAR (optional)\u003c/kbd\u003e \u003ckbd\u003eTIME (optional)\u003c/kbd\u003e \u003ckbd\u003ePRIVATE (optional)\u003c/kbd\u003e \u003c/kbd\u003e\nAsk King Oyster to reminder you about \u003ckbd\u003eREMINDER\u003c/kbd\u003e, in the given \u003ckbd\u003eMONTH\u003c/kbd\u003e / \u003ckbd\u003eDAY\u003c/kbd\u003e. \n\u003cbr\u003eYou can also optionally specify \u003ckbd\u003eYEAR (optional)\u003c/kbd\u003e and \u003ckbd\u003eTIME (optional)\u003c/kbd\u003e.\n\n\u003cbr\u003eYou can also set \u003ckbd\u003ePRIVATE (optional)\u003c/kbd\u003e to `True` to make Oyster send you a private reminder in your DMs.\n\n\u003csup\u003e**Note:** This slash command was added recently in v0.1.07, and is likely to be updated in later versions.\u003c/sup\u003e\n\n___\n# Non-Slash Commands\nTo make the bot feel more lively and noticed, we need it to react and interact with the community without being tasked to.\n\u003cbr\u003eFor this reason, I have added a set of interactions for the bot. Some of these interactions might still be considered commands, but most could happen unexpectedly.\n\n## Custom Welcome Image\nKing Oyster greets all new members with a welcome message, and the new user's avatar as part of a custom welcome image. \n\u003cbr\u003e [See `src/ welcome.png` file.](#src-welcomepng)\n\u003cbr\u003e![image](https://github.com/user-attachments/assets/46214741-946a-45a6-bfc0-e023b8013227)\n\n\n## Haiku Detection\nKing Oyster automatically checks all send messages in search of a 5-7-5 syllables haiku pattern. If it finds a message that meets this critera, it'll reply with the following message:\n\n\u003cimg width=\"313\" alt=\"image\" src=\"https://github.com/user-attachments/assets/91232b0b-c548-45a7-a02a-ee32331e8ae0\" /\u003e\n\n\u003e \u003csup\u003e**Note:** You don't need to send a massage with multiple lines for Oyster to find the haiku\n\n\u003cbr\u003eOf course, the syllable counter method by King Oyster isn't perfect since it's only a bot. For us humans, it's as simple as counting how many times our chin drops when saying a word, but for a bot… well… it's more difficult to program the logic for that, so expect some flaws here and there. I'd say it's close to accurate but not fully there yet.\n\n## Count Syllables\nWhen asked to, King Oyster will count the syllables inside of a poem.\n\u003cbr\u003eSee image below for usage.\n\n\u003cbr\u003e\u003cimg width=\"800\" alt=\"image\" src=\"https://github.com/user-attachments/assets/e7b37c9a-d2b8-476f-8641-655ea2d98572\" /\u003e\n\n\u003e **Keywords:** \u003ckbd\u003ecount\u003c/kbd\u003e AND \u003ckbd\u003esyllables\u003c/kbd\u003e\n\n## Reactions\nI was considering making a whole new section for this part but figured might as well keep it a part of this. \n\u003cbr\u003eKing Oyster will react to different messages based on keywords, name of the channel they're send, mentions, and such.\n\nFor example, if you say **\"important\"** in your message then king oyster will try to emphasize your message\n\u003cimg width=\"489\" alt=\"image\" src=\"https://github.com/user-attachments/assets/88085403-142d-4fa3-9141-e847f7b78bfc\" /\u003e\n\nPersonally, I would advise against reading the rest of this section, as knowing when and what Oyster reacts to would ruin the magic, but I won't stop you if you're curious. \n\u003cbr\u003eEnough blabber, here's a table—\n\n| Emoji    | ID      | Keywords | CHANNEL KEYWORD | INCLUDES     |\n| -------- | ------- | -------- | --------------- | ------------ |\n| 💚       | X       | X        | \"announce\"      |`@everyone`   |\n| 💚       | X       | \"love\" or \u003cbr\u003e\"thank\" AND \"oyster\"|X| X   |\n| 💚       | X       | \"thank\"  | X               |`@King Oyster`|\n| ‼️       | X       | \"important\"| X             | X            |\n| 📜       | X       | X          | X             | *5+ LINES    |\n| ![image](https://github.com/user-attachments/assets/2b34f20d-5fae-4442-9cfe-c69875ccfced) | 1334234382772207696 | X   | NOT \"anounce\"     |`@everyone`              |\n| ![image](https://github.com/user-attachments/assets/2b34f20d-5fae-4442-9cfe-c69875ccfced) | 1334234382772207696 | X   | \"share\"           | ATTACHMENT or *5+ LINES |\n| ![image](https://github.com/user-attachments/assets/0583e696-fc09-40fa-9578-a5e7d098a9bd) | 1334609229599739976 | X   | NOT \"share\"       | ATTACHMENT              |\n| ![image](https://github.com/user-attachments/assets/17199945-c2f1-45d3-9876-ecb43e58c398) | 1334609056421249186 | \"boba\"     | X          | X                       |\n| \u003ckbd\u003e![image](https://github.com/user-attachments/assets/4e23e73d-c06f-467e-983b-b1f6957cd7e5)\u003c/kbd\u003e | 1334608848513798155 | \"origami\"| X | X                       |\n| ![image](https://github.com/user-attachments/assets/78a53c5a-e309-42d0-9027-5811894dc1c9) | 1334609780097945733 | \"oops\" OR \"uhoh\"| X     | X                       |\n\n\u003e 📜 ***5+ lines:** check if message has 4+ line breaks, meant to help detect poems.\n\n___\n# Moderating\nThis is fun and all, but gotta remember that a main reason for Oyster's creation was to help in moderating the server in cases where the mods might not be online. \n\n\n\u003e \u003csup\u003eThis section has been added in version v0.1.07.\u003c/sup\u003e\n\n## Spam Prevention\nIf the same user sends 10+ messages in the same minute, or 15+ letters without a space will (ex: uhfkeskfksfnnksefnks), Oyster will mute them for a minute. \n\u003cbr\u003eIf they spam again, Oyster will mute again for 2 minutes, and the time will keep doubling. Mute info will reset after every hour (meaning if they spam again the next hour, it'll be back to 1 minute mute and goes up from there)\n\n\u003cimg width=\"607\" alt=\"image\" src=\"https://github.com/user-attachments/assets/d878a9da-3dc3-4d18-9f95-573da4f2b47d\" /\u003e\n\n\u003e **Note:** King Oyster cannot mute users with equal or higher permissions than him. Meaning if I'm an admin, then Oyster cannot mute me. Of course, if I'm an admin, spamming is the least dangerous thing I could do 😅\n\n## Link Permissions\nIf a user without an officer or link role attempts to post a link that is not a tenor (GIF) or youtube URL, then Oyster deletes the message immediately and sends a private message to the user, telling them to ask for permission before sharing a link in the club.\n\u003cbr\u003e\u003cimg width=\"500\" alt=\"Oyster D-M-ing someone about their deleted link and how to request link permission\" src=\"https://github.com/user-attachments/assets/f9069f80-3614-41d8-9eae-23ed6cf6af78\" /\u003e\n\u003cbr\u003eTo allow someone to post links, you'll just need to give them the \u003ckbd\u003elink perm\u003c/kbd\u003e, or a role in the server with the word \"link\" (make sure you don't have multiple link roles in the channel).\n\u003cbr\u003eAs long as someone has the link role, they should be able to post links without Oyster stopping them.\n\n\u003cbr\u003e You can also edit the URLs that Oyster allows by defeault by editing the `allowedLinks` array inside of the \u003ckbd\u003e[src/ index.js](#src-indexjs)\u003c/kbd\u003e file.\n\n\u003cbr\u003e [See `/linkperm [...]` command.](#linkperm-link-)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falani25%2Foysterbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falani25%2Foysterbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falani25%2Foysterbot/lists"}