mirror of
https://github.com/arthur-pbty/xiao.git
synced 2026-06-22 18:29:14 +02:00
Face Analyze, Analyze group
This commit is contained in:
@@ -8,7 +8,7 @@ Xiao is a Discord bot coded in JavaScript with
|
|||||||
300 commands, she is one of the most feature-filled bots out there, and formerly
|
300 commands, she is one of the most feature-filled bots out there, and formerly
|
||||||
served over 10,000 servers with a uniquely devoted fanbase.
|
served over 10,000 servers with a uniquely devoted fanbase.
|
||||||
|
|
||||||
## Commands (285)
|
## Commands (286)
|
||||||
### Utility:
|
### Utility:
|
||||||
|
|
||||||
* **prefix**: Shows or sets the command prefix.
|
* **prefix**: Shows or sets the command prefix.
|
||||||
@@ -165,6 +165,14 @@ served over 10,000 servers with a uniquely devoted fanbase.
|
|||||||
* **yu-gi-oh**: Responds with info on a Yu-Gi-Oh! card.
|
* **yu-gi-oh**: Responds with info on a Yu-Gi-Oh! card.
|
||||||
* **zodiac-sign**: Responds with the Zodiac Sign for the given month/day.
|
* **zodiac-sign**: Responds with the Zodiac Sign for the given month/day.
|
||||||
|
|
||||||
|
### Analyzers:
|
||||||
|
|
||||||
|
* **coolness**: Determines a user's coolness.
|
||||||
|
* **face-analyze**: Determines the age, gender, and race of a face.
|
||||||
|
* **gender-guess**: Determines the gender of a name.
|
||||||
|
* **severe-toxicity**: Determines the toxicity of text, but less sensitive to milder language.
|
||||||
|
* **toxicity**: Determines the toxicity of text.
|
||||||
|
|
||||||
### Games:
|
### Games:
|
||||||
|
|
||||||
* **akinator**: Think about a real or fictional character, I will try to guess who it is.
|
* **akinator**: Think about a real or fictional character, I will try to guess who it is.
|
||||||
@@ -316,13 +324,9 @@ served over 10,000 servers with a uniquely devoted fanbase.
|
|||||||
### Other:
|
### Other:
|
||||||
|
|
||||||
* **cleverbot**: Chat with Cleverbot.
|
* **cleverbot**: Chat with Cleverbot.
|
||||||
* **coolness**: Determines a user's coolness.
|
|
||||||
* **gender-guess**: Determines the gender of a name.
|
|
||||||
* **prune**: Deletes up to 99 messages from the current channel.
|
* **prune**: Deletes up to 99 messages from the current channel.
|
||||||
* **severe-toxicity**: Determines the toxicity of text, but less sensitive to milder language.
|
|
||||||
* **strawpoll**: Generates a Strawpoll with the options you provide.
|
* **strawpoll**: Generates a Strawpoll with the options you provide.
|
||||||
* **timer**: Sets a timer for a certain amount of time.
|
* **timer**: Sets a timer for a certain amount of time.
|
||||||
* **toxicity**: Determines the toxicity of text.
|
|
||||||
|
|
||||||
### Roleplay:
|
### Roleplay:
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ client.registry
|
|||||||
['single', 'Single Response'],
|
['single', 'Single Response'],
|
||||||
['events', 'Events'],
|
['events', 'Events'],
|
||||||
['search', 'Search'],
|
['search', 'Search'],
|
||||||
|
['analyze', 'Analyzers'],
|
||||||
['games', 'Games'],
|
['games', 'Games'],
|
||||||
['voice', 'Voice Channel'],
|
['voice', 'Voice Channel'],
|
||||||
['image-edit', 'Image Manipulation'],
|
['image-edit', 'Image Manipulation'],
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ module.exports = class CoolnessCommand extends Command {
|
|||||||
constructor(client) {
|
constructor(client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'coolness',
|
name: 'coolness',
|
||||||
group: 'other',
|
group: 'analyze',
|
||||||
memberName: 'coolness',
|
memberName: 'coolness',
|
||||||
description: 'Determines a user\'s coolness.',
|
description: 'Determines a user\'s coolness.',
|
||||||
args: [
|
args: [
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
const { Command } = require('discord.js-commando');
|
||||||
|
const snekfetch = require('snekfetch');
|
||||||
|
const { KAIROS_KEY, KAIROS_ID } = process.env;
|
||||||
|
const races = ['asian', 'black', 'hispanic', 'other', 'white'];
|
||||||
|
|
||||||
|
module.exports = class FaceAnalyzeCommand extends Command {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'face-analyze',
|
||||||
|
aliases: ['analyze-face', 'face'],
|
||||||
|
group: 'analyze',
|
||||||
|
memberName: 'face',
|
||||||
|
description: 'Determines the age, gender, and race of a face.',
|
||||||
|
args: [
|
||||||
|
{
|
||||||
|
key: 'face',
|
||||||
|
prompt: 'What face do you want to scan?',
|
||||||
|
type: 'image',
|
||||||
|
default: msg => msg.author.displayAvatarURL({ format: 'png', size: 512 })
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(msg, { face }) {
|
||||||
|
try {
|
||||||
|
const { body } = await snekfetch
|
||||||
|
.post('https://api.kairos.com/detect')
|
||||||
|
.set({
|
||||||
|
app_id: KAIROS_ID,
|
||||||
|
app_key: KAIROS_KEY
|
||||||
|
})
|
||||||
|
.send({ image: face });
|
||||||
|
if (!body.images) return msg.say('There are no faces in this image.');
|
||||||
|
if (body.images[0].faces.length > 1) return msg.say('Please provide only one face in the image.');
|
||||||
|
const data = body.images[0].faces[0].attributes;
|
||||||
|
const race = races.sort((a, b) => data[b] - data[a])[0];
|
||||||
|
const gender = data.gender.maleConfidence > data.gender.femaleConfidence ? 'man' : 'woman';
|
||||||
|
return msg.reply(`I think this is a photo of a ${data.age} year old ${race} ${gender}.`);
|
||||||
|
} catch (err) {
|
||||||
|
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -5,8 +5,8 @@ module.exports = class GenderGuessCommand extends Command {
|
|||||||
constructor(client) {
|
constructor(client) {
|
||||||
super(client, {
|
super(client, {
|
||||||
name: 'gender-guess',
|
name: 'gender-guess',
|
||||||
aliases: ['gender', 'guess-gender'],
|
aliases: ['gender', 'guess-gender', 'analyze-gender', 'gender-analyze'],
|
||||||
group: 'other',
|
group: 'analyze',
|
||||||
memberName: 'gender',
|
memberName: 'gender',
|
||||||
description: 'Determines the gender of a name.',
|
description: 'Determines the gender of a name.',
|
||||||
args: [
|
args: [
|
||||||
@@ -7,7 +7,7 @@ module.exports = class SevereToxicityCommand extends Command {
|
|||||||
super(client, {
|
super(client, {
|
||||||
name: 'severe-toxicity',
|
name: 'severe-toxicity',
|
||||||
aliases: ['severe-perspective', 'severe-comment-toxicity'],
|
aliases: ['severe-perspective', 'severe-comment-toxicity'],
|
||||||
group: 'other',
|
group: 'analyze',
|
||||||
memberName: 'severe-toxicity',
|
memberName: 'severe-toxicity',
|
||||||
description: 'Determines the toxicity of text, but less sensitive to milder language.',
|
description: 'Determines the toxicity of text, but less sensitive to milder language.',
|
||||||
args: [
|
args: [
|
||||||
@@ -7,7 +7,7 @@ module.exports = class ToxicityCommand extends Command {
|
|||||||
super(client, {
|
super(client, {
|
||||||
name: 'toxicity',
|
name: 'toxicity',
|
||||||
aliases: ['perspective', 'comment-toxicity'],
|
aliases: ['perspective', 'comment-toxicity'],
|
||||||
group: 'other',
|
group: 'analyze',
|
||||||
memberName: 'toxicity',
|
memberName: 'toxicity',
|
||||||
description: 'Determines the toxicity of text.',
|
description: 'Determines the toxicity of text.',
|
||||||
args: [
|
args: [
|
||||||
@@ -34,7 +34,9 @@ module.exports = class ContrastCommand extends Command {
|
|||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
ctx.drawImage(data, 0, 0);
|
ctx.drawImage(data, 0, 0);
|
||||||
contrast(ctx, 0, 0, data.width, data.height);
|
contrast(ctx, 0, 0, data.width, data.height);
|
||||||
return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'contrast.png' }] });
|
const attachment = canvas.toBuffer();
|
||||||
|
if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.');
|
||||||
|
return msg.say({ files: [{ attachment, name: 'contrast.png' }] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ module.exports = class DistortCommand extends Command {
|
|||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
ctx.drawImage(data, 0, 0);
|
ctx.drawImage(data, 0, 0);
|
||||||
distort(ctx, level, 0, 0, data.width, data.height);
|
distort(ctx, level, 0, 0, data.width, data.height);
|
||||||
return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'distort.png' }] });
|
const attachment = canvas.toBuffer();
|
||||||
|
if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.');
|
||||||
|
return msg.say({ files: [{ attachment, name: 'distort.png' }] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ module.exports = class GlitchCommand extends Command {
|
|||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
ctx.drawImage(data, 0, 0);
|
ctx.drawImage(data, 0, 0);
|
||||||
distort(ctx, 20, 0, 0, data.width, data.height, 5);
|
distort(ctx, 20, 0, 0, data.width, data.height, 5);
|
||||||
return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'glitch.png' }] });
|
const attachment = canvas.toBuffer();
|
||||||
|
if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.');
|
||||||
|
return msg.say({ files: [{ attachment, name: 'glitch.png' }] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ module.exports = class GreyscaleCommand extends Command {
|
|||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
ctx.drawImage(data, 0, 0);
|
ctx.drawImage(data, 0, 0);
|
||||||
greyscale(ctx, 0, 0, data.width, data.height);
|
greyscale(ctx, 0, 0, data.width, data.height);
|
||||||
return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'greyscale.png' }] });
|
const attachment = canvas.toBuffer();
|
||||||
|
if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.');
|
||||||
|
return msg.say({ files: [{ attachment, name: 'greyscale.png' }] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ module.exports = class IfunnyCommand extends Command {
|
|||||||
ctx.fillStyle = '#181619';
|
ctx.fillStyle = '#181619';
|
||||||
ctx.fillRect(0, canvas.height - base.height, canvas.width, base.height);
|
ctx.fillRect(0, canvas.height - base.height, canvas.width, base.height);
|
||||||
ctx.drawImage(base, canvas.width - base.width, canvas.height - base.height);
|
ctx.drawImage(base, canvas.width - base.width, canvas.height - base.height);
|
||||||
return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'ifunny.png' }] });
|
const attachment = canvas.toBuffer();
|
||||||
|
if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.');
|
||||||
|
return msg.say({ files: [{ attachment, name: 'ifunny.png' }] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ module.exports = class InvertCommand extends Command {
|
|||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
ctx.drawImage(data, 0, 0);
|
ctx.drawImage(data, 0, 0);
|
||||||
invert(ctx, 0, 0, data.width, data.height);
|
invert(ctx, 0, 0, data.width, data.height);
|
||||||
return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'invert.png' }] });
|
const attachment = canvas.toBuffer();
|
||||||
|
if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.');
|
||||||
|
return msg.say({ files: [{ attachment, name: 'invert.png' }] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ module.exports = class SepiaCommand extends Command {
|
|||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
ctx.drawImage(data, 0, 0);
|
ctx.drawImage(data, 0, 0);
|
||||||
sepia(ctx, 0, 0, data.width, data.height);
|
sepia(ctx, 0, 0, data.width, data.height);
|
||||||
return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'sepia.png' }] });
|
const attachment = canvas.toBuffer();
|
||||||
|
if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.');
|
||||||
|
return msg.say({ files: [{ attachment, name: 'sepia.png' }] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ module.exports = class SilhouetteCommand extends Command {
|
|||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
ctx.drawImage(data, 0, 0);
|
ctx.drawImage(data, 0, 0);
|
||||||
silhouette(ctx, 0, 0, data.width, data.height);
|
silhouette(ctx, 0, 0, data.width, data.height);
|
||||||
return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'silhouette.png' }] });
|
const attachment = canvas.toBuffer();
|
||||||
|
if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.');
|
||||||
|
return msg.say({ files: [{ attachment, name: 'silhouette.png' }] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ module.exports = class TintCommand extends Command {
|
|||||||
const canvas = createCanvas(data.width, data.height);
|
const canvas = createCanvas(data.width, data.height);
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
drawImageWithTint(ctx, data, color, 0, 0, data.width, data.height);
|
drawImageWithTint(ctx, data, color, 0, 0, data.width, data.height);
|
||||||
return msg.say({ files: [{ attachment: canvas.toBuffer(), name: 'tint.png' }] });
|
const attachment = canvas.toBuffer();
|
||||||
|
if (Buffer.byteLength(attachment) > 8e+6) return msg.reply('Resulting image was above 8 MB.');
|
||||||
|
return msg.say({ files: [{ attachment, name: 'tint.png' }] });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "xiao",
|
"name": "xiao",
|
||||||
"version": "67.0.1",
|
"version": "67.1.0",
|
||||||
"description": "Your personal server companion.",
|
"description": "Your personal server companion.",
|
||||||
"main": "Xiao.js",
|
"main": "Xiao.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ class ImageArgumentType extends ArgumentType {
|
|||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
if (!attachment.height || !attachment.width) return false;
|
if (!attachment.height || !attachment.width) return false;
|
||||||
if (attachment.size > 1000000) return false;
|
if (attachment.size > 8e+6) return 'Please provide an image under 8 MB.';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user