1.0.2 • Published 1 year ago

discordv13-giveaways v1.0.2

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

Discord Giveaways (DiscordJS v13/v14)

Característicos

  • ⏱️ Facil de usar!
  • 🔄 Reinicialização automática após travamento do bot!
  • 🇫🇷 Suporte para traduções: adapte as strings para seu próprio idioma!
  • 📁 Suporte para todos os bancos de dados! (padrão json)
  • ⚙️ Muito customizável! (prêmio, duração, vencedores, permissões ignoradas, entradas de bônus etc...)
  • 🚀 Super poderoso: comece, edite, role novamente, termine, exclua premios!
  • 💥 Eventos: giveawayEnded, giveawayRerolled, giveawayDeleted, giveawayReactionAdded, giveawayReactionRemoved, endedGiveawayReactionAdded
  • 🕸️ Suporte para shards!
  • e muito mais...

Instalação

npm i discordv13-giveaways

Inicialização

const Discord = require('discord.js'),
    client = new Discord.Client({intents: []}),
    settings = {
        token: 'Token do seu bot'
    };

const { GiveawaysManager } = require('discordv13-giveaways'); // chamando a dependencia
// agora vamos definir as configurações basicas:
const manager = new GiveawaysManager(client, {
    storage: './giveaways.json', // local para salvar os dados
    updateCountdownEvery: 10000, // atualização do sorteio
    hasGuildMembersIntent: false, // interação dos membros do servidor
    default: {
        botsCanWin: false, // o bot tbm pode ganhar?
        exemptPermissions: ['MANAGE_MESSAGES', 'ADMINISTRATOR'], // permissões para executar o comando ou gerenciar eventos
        embedColor: '#FF0000', // cor da embed quando começar o sorteio
        embedColorEnd: '#000000', // cor da embed quando terminar o sorteio
        reaction: '🎉' // emoji para o pessoal reagir
    }
});

client.giveawaysManager = manager; // importando configurações

// eventos do discord?
client.on('ready', () => {
    console.log('I\'m ready!');
});
client.login(settings.token);

Depois disso, os sorteios que ainda não foram concluídos começarão a ser atualizados novamente e novos sorteios poderão ser iniciados. Você pode passar um objeto de opções para customizar os sorteios. Aqui está uma lista deles:

  • client: o client discord (sua instância do bot discord).
  • options.storage: o arquivo json que será usado para armazenar os sorteios.
  • options.updateCountdownEvery: o número de milissegundos que levará para atualizar os temporizadores.
  • options.endedGiveawaysLifetime: duração pela qual os sorteios encerrados permanecem no banco de dados após o término.
  • options.hasGuildMembersIntent: se o bot tem acesso à intenção GUILD_MEMBERS. Funciona sem, mas será mais rápido com.
  • options.default.botsCanWin: se os bots podem ganhar um sorteio.
  • options.default.exemptPermissions: uma série de permissões de discord. Os membros que tiverem pelo menos uma dessas permissões não poderão ganhar um sorteio, mesmo que reajam a ele.
  • options.default.embedColor: uma cor hexadecimal para as incorporações de sorteios.
  • options.default.embedColorEnd: uma cor hexadecimal para as incorporações de sorteios quando eles terminam.
  • options.default.reaction: a reação à qual os usuários terão que reagir para participar.
  • options.default.lastChance: os parâmetros do sistema de última chance. Exemplo de uso para o objeto giveaway

Iniciando

client.on('message', (message) => {
    const ms = require('ms'); // npm install ms
    const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
    const command = args.shift().toLowerCase();

    if (command === 'start-giveaway') {
        // <comando> 2d 1 Prêmio incrível!
        // Irá criar um giveaway com a duração de dois dias, com um vencedor e o prémio será "Prêmio incrível!"

        client.giveawaysManager.start(message.channel, {
            time: ms(args[0]), // tempo
            winnerCount: parseInt(args[1]), // total de ganhadores
            prize: args.slice(2).join(' ') // prêmio
        }).then((gData) => {
            console.log(gData); // {...} (messageID, data final e mais)
        });
        // E o sorteio começou!
    }
});
  • options.time: a duração do sorteio.
  • options.prize: o prêmio de sorteio.
  • options.hostedBy: o usuário que hospeda o sorteio.
  • options.winnerCount: o número de ganhadores do sorteio.
  • options.winnerIDs: os IDs dos vencedores do sorteio. ⚠ Você não precisa e nem poderá definir isso como uma opção inicial! A matriz só é preenchida quando um sorteio termina ou é refeito!
  • options.botsCanWin: se os bots podem ganhar o sorteio.
  • options.exemptPermissions: uma série de permissões de discord. Os membros do servidor que tiverem pelo menos uma dessas permissões não poderão ganhar uma oferta, mesmo que reajam a ela.
  • options.embedColor: uma cor hexadecimal para as incorporações de sorteio.
  • options.embedColorEnd: uma cor hexadecimal incorpora os sorteio quando eles terminam.
  • options.reaction: a reação à qual os usuários terão que reagir para participar.
  • options.extraData: Dados extras que você deseja salvar em relação a este sorteio. Você pode acessá-lo a partir do objeto de oferta usando giveaway.extraData.

Isso permite que você comece uma nova oferta. Uma vez o start() função é chamada, o giveaway começa, e você só tem que observar o resultado, o pacote faz o resto!

⚠ ATENÇÃO!

Os exemplos de comando abaixo (reroll, edit delete, end) podem ser executados em qualquer servidor do qual seu bot seja membro se uma pessoa tiver o prêmio ou o messageIDde um sorteio. Para evitar abusos, recomendamos verificar se o prêmio ou o messageID que foi fornecido pelo usuário do comando é para sorteio no mesmo servidor, caso não seja, cancele a execução do comando.

let giveaway = 
// Pesquisa com prêmio de sorteio
client.giveawaysManager.giveaways.find((g) => g.guildID === message.guild.id && g.prize === args.join(' ')) ||
// Pesquise com messageID
client.giveawaysManager.giveaways.find((g) => g.guildID === message.guild.id && g.messageID === args[0]);

// Se nenhum sorteio foi encontrado
if (!giveaway) return message.channel.send('Não foi possível encontrar uma oferta para `'+ args.join(' ') +'`.');

Role novamente um sorteio

client.on('message', (message) => {
    const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
    const command = args.shift().toLowerCase();

    if (command === 'reroll') {
        const messageID = args[0];
        client.giveawaysManager.reroll(messageID).then(() => {
            message.channel.send('Sucesso! Sorteio relançado!');
        }).catch((err) => {
            message.channel.send('Nenhum sorteio encontrado para ' + messageID + ', Por favor verifique e tente novamente.');
        });
    }
});
  • options.winnerCount: o número de vencedores para escolher.
  • options.messages: um objeto com a mensagem "congrat" e "error".

Edit o sorteio

client.on('message', (message) => {
    const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
    const command = args.shift().toLowerCase();

    if (command === 'edit') {
        const messageID = args[0];
        client.giveawaysManager.edit(messageID, {
            addTime: 5000,
            newWinnerCount: 3,
            newPrize: 'New Prize!'
        }).then(() => {
            // Aqui, podemos calcular o tempo após o qual temos certeza de que a lib atualizará o giveaway
            const numberOfSecondsMax = client.giveawaysManager.options.updateCountdownEvery / 1000;
            message.channel.send('Sucesso! Sorteio será atualizado em menos de ' + numberOfSecondsMax + ' segundos.');
        }).catch((err) => {
            message.channel.send('Nenhum sorteio encontrado para ' + messageID + ', Por favor verifique e tente novamente.');
        });
    }
});
  • options.newWinnerCount: o novo número de vencedores.
  • options.newPrize: o novo prêmio.
  • options.addTime: o número de milissegundos a serem adicionados à duração do giveaway.
  • options.setEndTimestamp: o carimbo de data/hora da nova data de término (por exemplo, para o sorteio terminar em 1 hora, defina-o como Date.now() + 60000).
  • options.newMessages: as novas mensagens de sorteio
  • options.newExtraData: o novo valor de dados extras para o sorteio
  • options.newBonusEntries: os novos objetos BonusEntry (por exemplo, para alterar a quantidade de entradas).

⚠️ Nota: para reduzir o tempo de doação, defina addTime com um número negativo! Por exemplo addTime: -5000 reduzirá o tempo de doação em 5 segundos!

Delete um sorteio

client.on('message', (message) => {
    const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
    const command = args.shift().toLowerCase();

    if (command === 'delete') {
        const messageID = args[0];
        client.giveawaysManager.delete(messageID).then(() => {
            message.channel.send('Sucesso! Sorteio deletado!');
        }).catch((err) => {
            message.channel.send('Nenhum sorteio encontrado para ' + messageID + ', Por favor verifique e tente novamente.');
        });
    }
});
  • doNotDeleteMessage: se a mensagem de sorteio não deve ser deletada.

⚠️ Nota: quando você usa a função de exclusão, os dados do sorteio e por padrão a mensagem do sorteio são excluídos. Você não pode restaurar um sorteio depois de excluí-lo!

Terminar um sorteio

client.on('message', (message) => {
    const args = message.content.slice(settings.prefix.length).trim().split(/ +/g);
    const command = args.shift().toLowerCase();

    if (command === 'end') {
        const messageID = args[0];
        client.giveawaysManager.end(messageID).then(() => {
            message.channel.send('Sucesso! Sorteio encerrado!');
        }).catch((err) => {
            message.channel.send('Nenhum sorteio encontrado para ' + messageID + ', Por favor verifique e tente novamente.');
        });
    }
});

Buscar sorteios

// Uma lista de todos os sorteios
const allGiveaways = client.giveawaysManager.giveaways; // [ {Giveaway}, {Giveaway} ]

// Uma lista de todos os sorteios no servidor com ID "1909282092"
const onServer = client.giveawaysManager.giveaways.filter(g => g.guildID === '1909282092');

// Uma lista dos sorteios ativos atuais (não finalizados)
const notEnded = client.giveawaysManager.giveaways.filter(g => !g.ended);

Membros isentos

client.giveawaysManager.start(message.channel, {
    time: 60000,
    winnerCount: 1,
    prize: 'Chave gratuita do Steam',
    // Apenas os membros que têm a função "Nitro Boost" podem ganhar
    exemptMembers: (member) => !member.roles.cache.some((r) => r.name === 'Nitro Boost')
})

⚠️ Nota: Se a função deve ser personalizável

const roleName = 'Nitro Boost';

client.giveawaysManager.start(message.channel, {
    time: 60000,
    winnerCount: 1,
    prize: 'Chave gratuita do Steam',
    // Apenas os membros que têm a função atribuída a "roleName" podem ganhar
    exemptMembers: new Function('member', `return !member.roles.cache.some((r) => r.name === \'${roleName}\')`),
})

Última chance

client.giveawaysManager.start(message.channel, {
    time: 60000,
    winnerCount: 1,
    prize: 'Discord Nitro!',
    lastChance: {
        enabled: true,
        content: '⚠️ **ÚLTIMA CHANCE DE PARTICIPAR!** ⚠️',
        threshold: 5000,
        embedColor: '#FF0000'
    }
})

Entradas de bônus

client.giveawaysManager.start(message.channel, {
    time: 60000,
    winnerCount: 1,
    prize: 'Chave gratuita do Steam',
    bonusEntries: [
        // Os membros que têm a função "Nitro Boost" recebem 2 entradas de bônus
        {
            bonus: (member) => member.roles.cache.some((r) => r.name === 'Nitro Boost') ? 2 : null,
            cumulative: false
        }
    ]
})

⚠️ Nota: Se a função bonus deve ser personalizável

const roleName = 'Nitro Boost';
const roleBonusEntries = 2;

client.giveawaysManager.start(message.channel, {
    time: 60000,
    winnerCount: 1,
    prize: 'Chave gratuita do Steam',
    bonusEntries: [
        // Os membros que têm a função atribuída a "roleName" obtêm a quantidade de entradas de bônus atribuídas a "roleBonusEntries"
        {   
            bonus: new Function('member', `return member.roles.cache.some((r) => r.name === \'${roleName}\') ? ${roleBonusEntries} : null`),
            cumulative: false 
        }
    ]
})

🇫🇷 Tradução

Você também pode passar um messages parâmetro para start() função, se você quiser traduzir o texto do bot:

  • options.messages.giveaway: a mensagem que será exibida acima das incorporações.
  • options.messages.giveawayEnded: a mensagem que será exibida acima das incorporações quando o sorteio terminar.
  • options.messages.timeRemaining: a mensagem que exibe o tempo restante (o cronômetro).
  • options.messages.inviteToParticipate: a mensagem que convida os usuários a participar.
  • options.messages.winMessage: a mensagem que será exibida para parabenizar o(s) ganhador(es) quando o sorteio terminar.
  • options.messages.embedFooter: a mensagem exibida na parte inferior das incorporações.
  • options.messages.noWinner: a mensagem que é exibida se nenhum vencedor puder ser sorteado.
  • options.messages.winners: simplesmente a palavra "vencedor" em seu idioma.
  • options.messages.endedAt: simplesmente as palavras "Terminou em" em seu idioma.
  • options.messages.units.seconds: simplesmente a palavra "segundos" em seu idioma.
  • options.messages.units.minutes: simplesmente a palavra "minutos" em seu idioma.
  • options.messages.units.hours: simplesmente a palavra "horas" em seu idioma.
  • options.messages.units.days: simplesmente a palavra "dias" em seu idioma.

Nota: as unidades devem estar no plural.

Por exemplo:

client.giveawaysManager.start(message.channel, {
    time: ms(args[0]),
    winnerCount: parseInt(args[1]),
    prize: args.slice(2).join(' '),
    messages: {
        giveaway: '@everyone\n\n🎉🎉 **GIVEAWAY** 🎉🎉',
        giveawayEnded: '@everyone\n\n🎉🎉 **GIVEAWAY TERMINOU** 🎉🎉',
        timeRemaining: 'Tempo restante: **{duration}**',
        inviteToParticipate: 'Reaja com 🎉 para participar!',
        winMessage: 'Parabéns, {winners}! Você ganhou **{prize}**!\n{messageURL}',
        embedFooter: 'Alimentado pelo pacote discordv13-giveaways',
        noWinner: 'Sorteio cancelado, sem participações válidas.',
        hostedBy: 'Hospedado por: {user}',
        winners: 'Ganhador(es)',
        endedAt: 'Terminou em',
        units: {
            seconds: 'segundos',
            minutes: 'minutos',
            hours: 'horas',
            days: 'dias',
            pluralS: false // Não é necessário, porque as unidades terminam com um S, então ele será removido automaticamente se o valor da unidade for menor que 2
        }
    }
});

E para a função reroll():

client.giveawaysManager.reroll(messageID, {
        messages: {
            congrat: ':tada: Novo(s) ganhador(es): {winners}! Parabéns você venceu **{prize}**!\n{messageURL}',
            error: 'Nenhuma participação válida, nenhum novo vencedor(es) pode ser escolhido!'
        }
    }).catch((err) => {
        message.channel.send('Nenhum sorteio encontrado para ' + messageID + ', verifique e tente novamente.');
    });
  • options.messages.congrat: a mensagem de felicitações.
  • options.messages.error: a mensagem de erro se não houver nenhum participante válido.

Custom Database

Você pode usar seu banco de dados personalizado para salvar sorteios, em vez dos arquivos json (o "banco de dados" por padrão para discordv13-giveaways). Para isso, você precisará estender a classe GiveawaysManager e substituir alguns métodos pelos seus personalizados. Existem 4 métodos que você precisará substituir:

  • getAllGiveaways: esse método retorna uma matriz de sorteios armazenados.
  • saveGiveaway: este método armazena um novo giveaway no banco de dados.
  • editGiveaway: este método edita um sorteio já armazenado no banco de dados.
  • deleteGiveaway: este método exclui um giveaway do banco de dados (permanentemente).

⚠️ Todos os métodos devem ser assíncronos para retornar uma promessa!

Outros exemplos:

Aqui está um exemplo, usando quick.db, ​​um banco de dados SQLite. Os comentários no código abaixo são muito importantes para entender como ele funciona!

const Discord = require('discord.js'),
    client = new Discord.Client(),
    settings = {
        token: 'Your Discord Bot Token'
    };

// Load quick.db - é um exemplo de banco de dados personalizado, você pode usar MySQL, PostgreSQL, etc...
const db = require('quick.db');
if (!Array.isArray(db.get('giveaways'))) db.set('giveaways', []);

const { GiveawaysManager } = require('discord-giveaways');
const GiveawayManagerWithOwnDatabase = class extends GiveawaysManager {
    // Esta função é chamada quando o gerente precisa obter todos os sorteios que estão armazenados no banco de dados.
    async getAllGiveaways() {
        // Obtenha todos os sorteio do banco de dados
        return db.get('giveaways');
    }

    // Esta função é chamada quando um sorteio precisa ser salvo no banco de dados.
    async saveGiveaway(messageID, giveawayData) {
        // Adicione o novo sorteio ao banco de dados
        db.push('giveaways', giveawayData);
        // Não se esqueça de devolver alguma coisa!
        return true;
    }

    // Esta função é chamada quando um sorteio precisa ser editado no banco de dados.
    async editGiveaway(messageID, giveawayData) {
        // Obtenha todos os sorteio do banco de dados
        const giveaways = db.get('giveaways');
        // Remova a oferta não editada da matriz
        const newGiveawaysArray = giveaways.filter((giveaway) => giveaway.messageID !== messageID);
        // Empurre o sorteio editado para a matriz
        newGiveawaysArray.push(giveawayData);
        // Salve a matriz atualizada
        db.set('giveaways', newGiveawaysArray);
        // Não se esqueça de devolver alguma coisa!
        return true;
    }

    // Essa função é chamada quando um sorteio precisa ser excluído do banco de dados.
    async deleteGiveaway(messageID) {
        // Obtenha todos os sorteio do banco de dados
        const giveaways = db.get('giveaways');
        // Remova o sorteio da matriz
        const newGiveawaysArray = giveaways.filter((giveaway) => giveaway.messageID !== messageID);
        // Salve a matriz atualizada
        db.set('giveaways', newGiveawaysArray);
        // Não se esqueça de devolver alguma coisa!
        return true;
    }
};

// Crie uma nova instância de sua nova classe
const manager = new GiveawayManagerWithOwnDatabase(client, {
    updateCountdownEvery: 10000,
    default: {
        botsCanWin: false,
        exemptPermissions: ['MANAGE_MESSAGES', 'ADMINISTRATOR'],
        embedColor: '#FF0000',
        embedColorEnd: '#000000',
        reaction: '🎉'
    }
});
// Agora temos uma propriedade giveawaysManager para acessar o gerenciador em qualquer lugar!
client.giveawaysManager = manager;

client.on('ready', () => {
    console.log('I\'m ready!');
});

client.login(settings.token);

Suporte para shards:

Fazer discord-giveaways trabalhando com shards, você precisará estender o GiveawaysManager classe e atualizar o refreshStorage() método. Este método deve chamar o getAllGiveaways() método para cada fragmento, então todos GiveawaysManager sincronizar seu cache com o banco de dados atualizado.

const Discord = require('discord.js'),
    client = new Discord.Client(),
    settings = {
        token: 'Your Discord Bot Token'
    };

// Estende a classe GiveawaysManager e atualiza o método refreshStorage
const { GiveawaysManager } = require('discord-giveaways');
const GiveawayManagerWithShardSupport = class extends GiveawaysManager {
    // O método de armazenamento de atualização é chamado quando o banco de dados é atualizado em um dos estilhaços
    async refreshStorage() {
        // Isso deve fazer com que todos os estilhaços atualizem seu cache com o banco de dados atualizado
        return client.shard.broadcastEval(() => this.giveawaysManager.getAllGiveaways());
    }
};

// Crie uma nova instância de sua nova classe
const manager = new GiveawayManagerWithShardSupport(client, {
    storage: './storage.json',
    updateCountdownEvery: 10000,
    default: {
        botsCanWin: false,
        exemptPermissions: ['MANAGE_MESSAGES', 'ADMINISTRATOR'],
        embedColor: '#FF0000',
        embedColorEnd: '#000000',
        reaction: '🎉'
    }
});
// Agora temos uma propriedade giveawaysManager para acessar o gerenciador em qualquer lugar!
client.giveawaysManager = manager;

client.on('ready', () => {
    console.log('I\'m ready!');
});

client.login(settings.token);