Coder Social home page Coder Social logo

adamt20054 / djscaptcha Goto Github PK

View Code? Open in Web Editor NEW
12.0 2.0 1.0 2.14 MB

A NPM module for Discord.js made to easily create CAPTCHAs to present to your Discord servers members.

Home Page: https://www.npmjs.com/package/djscaptcha

License: GNU General Public License v3.0

JavaScript 100.00%
verification djscaptcha captcha djs discord-verification discord-verification-bot security discord-js djsv14 bot

djscaptcha's Introduction

License Repo Size TOP_LANGUAGE FORKS Stars Dependency Review CodeQL DevSkim njsscan sarif

DJS Captcha

Table of Contents

Description

DJSCaptcha sets out to generate on-the-fly CAPTCHAs based off your desired inputs to present to members of your server. The module both creates the CAPTCHA, listens for a result and then acts on the result by removing and/or adding roles to users in your server.

The module was designed to primarily be used as a welcome CAPTCHA verification system.

Getting Started

This bot is designed for DiscordJS@V14, you may run into issues using it in earlier versions as DiscordJS switched to EmbedBuilder().

Prerequisites

DiscordJS@V14 requires [email protected] or higher to run.

If you are using an Ubuntu and other Debian based systems, you may need to install some Prerequisites for Canvas to run. You can install these by running the following in the CLI:

sudo apt-get update
sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev

For more information on installing see the Canvas Ubuntu and other Debian based systems installation page


Installation

To install this module, type the command shown below into your Terminal.

npm i djscaptcha

Example Code

const { EmbedBuilder, Collection, PermissionsBitField, Embed, Colors } = require('discord.js');
const { Captcha } = require("djscaptcha");
const client = (`..`) // Import client here

// Triggered by the guildMemberAdd event.

client.on('guildMemberAdd', async (member) => {
    const captcha = new Captcha(client, {
        roleAddID: "803853753357959189", // [Optional if addRoleOnSuccess = false] The ID of the role to add to the user.
        roleRemoveID: "807093688466800712", // [Optional if removeRoleOnSuccess = false] The ID of the role to remove from the user.
        channelID: "803763753429762100", // [Optional if sendToTextChannel = false] The ID of the channel to send the CAPTCHA to.
        sendToTextChannel: false, // [Optional | defaults to false] Whether to send the CAPTCHA to a text channel.
        addRoleOnSuccess: true, // [Optional | defaults to true] Whether you want the bot to add the role to the user if the captcha is solved.
        removeRoleOnSuccess: true, // [Optional | defaults to false] Whether you want the bot to remove the role from the user if the captcha is solved.
        kickOnFailure: true, // [Optional | defaults to false] Whether you want the bot to kick the user if the captcha is failed. Kicks happen 7.5seconds after the captcha has timedout/failed.
        kickIfRoleAdded: false, // [Optional | defaults to false | kickOnFailure must be true] Whether to kick the user if they have the role added to them without the captcha being completed.
        kickIfRoleRemoved: false, // [Optional | defaults to false | kickOnFailure must be true] Whether to kick the user if they have the role removed from them without the captcha being completed
        caseSensitive: true, // [Optional | defaults to true] Whether you want the captcha responses to be case-sensitive.
        attempts: 3, // [Optional | defaults to 3] The number of attempts before captcha is considered to be failed.
        timeout: 300000, // [Optional | defaults to 60000] The time the user has to solve the captcha on each attempt in milliseconds.
        showAttemptCount: true, // [Optional | defaults to true] Whether to show the number of attempts left in embed footer.
        customPromptEmbed: new EmbedBuilder() // [Optional] Customise the embed that will be sent
            .setTitle(`Welcome to ${member.guild.name}!`)
            .addFields({
                name: "I'm Not a Robot",
                value: `${member.user}, to gain access to **${member.guild.name}**, please solve the CAPTCHA below!\n\nThis is done to protect the server from raids consisting of spam bots.`
            })
            .setColor('#0099ff') // Set a custom color for the Prompt Embed
            .setThumbnail(member.guild.iconURL({dynamic: true})),
        customSuccessEmbed: new EmbedBuilder() // [Optional] Customise the embed that will be sent
            .setTitle("✅ CAPTCHA Solved!")
            .setDescription(`${member.user}, you completed the CAPTCHA successfully, and you have been given access to **${member.guild.name}**!`)
            .setTimestamp()
            .setColor('#29ff00')
            .setColor(Colors.Aqua)
            .setThumbnail(member.guild.iconURL({dynamic: true})),
        customFailureEmbed: new EmbedBuilder() // [Optional] Customise the embed that will be sent
            .setTitle("❌ You Failed to Complete the CAPTCHA!")
            .setDescription(`${member.user}, you failed to solve the CAPTCHA!`)
            .setTimestamp()
            .setColor('#c71515')
            .setThumbnail(member.guild.iconURL({dynamic: true})),
    });

    captcha.present(member);


});

To use the default embeds, simply use the following code:

    customPromptEmbed: new EmbedBuilder(),
    customSuccessEmbed: new EmbedBuilder(),
    customFailureEmbed: new EmbedBuilder()

To learn more about creating your own embeds, refer to the Discord.js EmbedBuilder documentation.



channelID Option Explained

The channelID option is the ID of the Discord Text Channel to Send the CAPTCHA to if the user's Direct Messages are locked. If no ID is provided then the CAPTCHA will not be sent at all if the users DMs are locked.

Use the option sendToTextChannel, and set it to true to always send the CAPTCHA to the Text Channel.

sendToTextChannel Option Explained

The sendToTextChannel option determines whether you want the CAPTCHA to be sent to a specified Text Channel instead of Direct Messages, regardless of whether the user's DMs are locked.

Use the option channelID to specify the Text Channel.

kickIfRoleAdded Option Explained

The kickIfRoleAdded option determines whether you want the bot to kick the user if they have the role added to them without the captcha being completed. If this option is set to true, the bot will kick the user if they have the role added to them without the captcha being completed. kickOnFailure must be set to true for this option to work. If you are using this bot alongside other verification methods, or you want to manually verify some people, keep this option as false

Use the option false to not kick the user if they have the role added to them without the captcha being completed.

kickIfRoleRemoved Option Explained

The kickIfRoleRemoved option determines whether you want the bot to kick the user if they have the role removed from them without the captcha being completed. If this option is set to true, the bot will kick the user if they have the role removed them without the captcha being completed. kickOnFailure must be set to true for this option to work. If you are using this bot alongside other verification methods, or you want to manually verify some people, keep this option as false

Use the option false to not kick the user if they have the role added to them without the captcha being completed.


Presenting a CAPTCHA to a Member With Built-In CAPTCHA Creation


Discord.js Captcha can automatically create a CAPTCHA for you, if you don't want to create one yourself.

Note: Built-In CAPTCHA Creation requires you to install the canvas package which should be preinstalled as part of the prerequisites. If canvas is not installed, you can install it with

npm i canvas
client.on("guildMemberAdd", async member => {
    //in your bot application in the dev portal, make sure you have intents turned on!
    captcha.present(member); //captcha is created by the package, and sent to the member
});


Presenting a CAPTCHA to a Member With Custom CAPTCHA Image Data


Don't like how the automatically created CAPTCHA looks? Simply pass in your own CaptchaImageData to the present method!

// noinspection JSAnnotator

client.on("guildMemberAdd", async member => {
  //in your bot application in the dev portal, make sure you have intents turned on!
  const captchaImageBuffer = //custom image as buffer
  const captchaImageText = //answer to the captcha as string
          captcha.present(member, {image: captchaImageBuffer, text: captchaImageText});
});

Note: When displaying a CAPTCHA to the user, the CAPTCHA image will automatically be attached to the customPromptEmbed for you.

In addition, if you have the showAttemptCount option enabled, any embed footer text on the customPromptEmbed will be overwritten with the number of attempts left.

Manually Creating a CAPTCHA


You can use the createCaptcha method to easily create your own CAPTCHA using Discord.js Catch's Built-In CAPTCHA Creation. It also comes with broader control over the length of the CAPTCHA, and the characters you would like to use by using a blacklist.

Note: Built-In CAPTCHA Creation uses A-Z, a-z and 0-9.

const { createCaptcha } = require("discord.js-captcha");

(async () => {
    //creating a CAPTCHA with 4 characters, and EXCLUDING numbers
    const myCaptcha = await createCaptcha(4, "0123456789");
    console.log(myCaptcha);
    // => { image: Buffer, text: "aBCd" }
})();


CAPTCHA Events

There are five events that you can use to log CAPTCHA actions, responses, and other details. They are:

  • prompt - Emitted when a CAPTCHA is presented to a user.
  • answer - Emitted when a user responds to a CAPTCHA.
  • success - Emitted when a CAPTCHA is successfully solved.
  • failure - Emitted when a CAPTCHA is failed to be solved.
  • timeout - Emitted when a user does not solve the CAPTCHA in time.

All of these events are emitted by the Captcha class. Here's an example of how to use them:

captcha.on("success", data => {
    console.log(`A Member has Solved a CAPTCHA!`);
    console.log(data);
});

Note: These events are used alongside the options passed in. For example, if kickOnFailure is set to true, the bot will kick the user on the timeout (or failure if the user has no attempts left), as well as what your manual event contains.

Screenshots

Image of Captcha Image of Captcha Image of Captcha

License

GNU GPLv3 License

Acknowledgements

This is a modification from discord.js-captcha for DJS@v14 with modifications and additions suited towards personal projects.

Contact me

djscaptcha's People

Contributors

adamt20054 avatar dependabot[bot] avatar imgbotapp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

kcchdev

djscaptcha's Issues

Option to send captcha in ephemeral messages through the buttons

Given Discord's new Ephemeral messaging feature, one could use this method to send the Embed containing the captcha and via the buttons (also recently introduced), one could reply with the code so as to be verified.
Doing so also solves the problem for users who do NOT have Direct Messages active for the Server in question (since the whole verification procedure will take place in the verification channel on the Server itself).

Crashes when cant DM user[BUG]

Describe the bug
Bot crashes when trying to DM a user that it cant

To Reproduce
Steps to reproduce the behavior:

  1. Make the bot DM a user it cant

Expected behavior
It should try the fallback channel if provided, or just not send a captcha

Screenshots

throw new DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData);
              ^

DiscordAPIError[50007]: Cannot send messages to this user
    at SequentialHandler.runRequest (C:\Users\Elijah\Desktop\bots\vf\node_modules@discordjs\rest\dist\index.js:659:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async SequentialHandler.queueRequest (C:\Users\Elijah\Desktop\bots\vf\node_modules@discordjs\rest\dist\index.js:458:14)
    at async REST.request (C:\Users\Elijah\Desktop\bots\vf\node_modules@discordjs\rest\dist\index.js:902:22)
    at async DMChannel.send (C:\Users\Elijah\Desktop\bots\vf\node_modules\discord.js\src\structures\interfaces\TextBasedChannel.js:175:15)
    at async C:\Users\Elijah\Desktop\bots\vf\node_modules\djscaptcha\src\index.cjs:331:25
    at async handleAttempt (C:\Users\Elijah\Desktop\bots\vf\node_modules\djscaptcha\src\index.cjs:311:17)
    at async C:\Users\Elijah\Desktop\bots\vf\node_modules\djscaptcha\src\index.cjs:511:13
    at async Captcha.present (C:\Users\Elijah\Desktop\bots\vf\node_modules\djscaptcha\src\index.cjs:258:9) {
  requestBody: {
    files: [],
    json: {
      content: undefined,
      tts: false,
      nonce: undefined,
      embeds: [
        {
          title: '❌ You failed to solve the Captcha!!',
          description: "» <@741601107310018560>, you've failed to solve the Captcha, we know these can be hard sometimes.\n" +
            'Please rejoin the server if you want to try again!',
          timestamp: '2022-10-23T16:29:11.678Z',
          color: 13047061,
          thumbnail: {
            url: 'https://cdn.discordapp.com/icons/1025748794245132328/745b42c9a7d4a860380109928b799e35.webp'
          }
        }
      ],
      components: undefined,
      username: undefined,
      avatar_url: undefined,
      allowed_mentions: undefined,
      flags: undefined,
      message_reference: undefined,
      attachments: undefined,
      sticker_ids: undefined,
      thread_name: undefined
    }
  },
  rawError: { message: 'Cannot send messages to this user', code: 50007 },
  code: 50007,
  status: 403,
  method: 'POST',
  url: 'https://discord.com/api/v10/channels/1033779135950110750/messages'
}

Error handling gaps [BUG]

Describe the bug
The bot crashes when it tries to delete messages that dont exist

To Reproduce
Steps to reproduce the behavior:
Delete a message the bot was going to delete and it'll crash

Expected behavior
It shouldn't crash

Screenshots

C:\Users\Elijah\Desktop\bots\vf\node_modules@discordjs\rest\dist\index.js:659
        throw new DiscordAPIError(data, "code" in data ? data.code : data.error, status, method, url, requestData);
              ^

DiscordAPIError[10008]: Unknown Message
    at SequentialHandler.runRequest (C:\Users\Elijah\Desktop\bots\vf\node_modules@discordjs\rest\dist\index.js:659:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async SequentialHandler.queueRequest (C:\Users\Elijah\Desktop\bots\vf\node_modules@discordjs\rest\dist\index.js:458:14)
    at async REST.request (C:\Users\Elijah\Desktop\bots\vf\node_modules@discordjs\rest\dist\index.js:902:22)
    at async MessageManager.delete (C:\Users\Elijah\Desktop\bots\vf\node_modules\discord.js\src\managers\MessageManager.js:254:5)
    at async Message.delete (C:\Users\Elijah\Desktop\bots\vf\node_modules\discord.js\src\structures\Message.js:765:5)
    at async C:\Users\Elijah\Desktop\bots\vf\node_modules\djscaptcha\src\index.cjs:328:25
    at async handleAttempt (C:\Users\Elijah\Desktop\bots\vf\node_modules\djscaptcha\src\index.cjs:311:17)
    at async C:\Users\Elijah\Desktop\bots\vf\node_modules\djscaptcha\src\index.cjs:511:13
    at async Captcha.present (C:\Users\Elijah\Desktop\bots\vf\node_modules\djscaptcha\src\index.cjs:258:9) {
  requestBody: { files: undefined, json: undefined },
  rawError: { message: 'Unknown Message', code: 10008 },
  code: 10008,
  status: 404,
  method: 'DELETE',
  url: 'https://discord.com/api/v10/channels/1033239641387716658/messages/1033524618738282496'
}

Additional context
Add error handling throughout

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.