You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Haha-Yes/commands/fun/tweet.js

203 lines
8.0 KiB
JavaScript

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

import { SlashCommandBuilder } from '@discordjs/builders';
import { MessageEmbed } from 'discord.js';
import Twit from 'twit';
import fetch from 'node-fetch';
import os from 'node:os';
import fs from 'node:fs';
import db from '../../models/index.js';
import wordToCensor from '../../json/censor.json' assert {type: 'json'};
import dotenv from 'dotenv';
dotenv.config();
const { twiConsumer, twiConsumerSecret, twiToken, twiTokenSecret, twiChannel, twiLogChannel } = process.env;
const Blacklists = db.Blacklists;
export default {
data: new SlashCommandBuilder()
.setName('tweet')
.setDescription('Send tweet from Haha yes twitter account. Please do not use it for advertisement and keep it english')
.addStringOption(option =>
option.setName('content')
.setDescription('The content of the tweet you want to send me.')
.setRequired(false))
.addAttachmentOption(option =>
option.setName('image')
.setDescription('Optional attachment (Image only.)')
.setRequired(false)),
ratelimit: 3,
cooldown: 3600,
async execute(interaction) {
if (!interaction.options.getString('content') && !interaction.options.getAttachment('image')) {
return interaction.reply({ content: 'Uh oh! You are missing any content for me to tweet!', ephemeral: true });
}
await interaction.deferReply({ ephemeral: false });
let tweet = interaction.options.getString('content');
const attachment = interaction.options.getAttachment('image');
const date = new Date();
// If account is less than 6 months old don't accept the tweet ( alt prevention )
if (interaction.user.createdAt > date.setMonth(date.getMonth() - 6)) {
await interaction.editReply({ content: 'Your account is too new to be able to use this command!' });
return;
}
// Reset the current date so it checks correctly for the 1 year requirement.
date.setTime(Date.now());
// If account is less than 1 year old don't accept attachment
if (attachment && interaction.user.createdAt > date.setFullYear(date.getFullYear() - 1)) {
await interaction.editReply({ content: 'Your account need to be 1 year or older to be able to send attachment!' });
return;
}
// remove zero width space
if (tweet) {
tweet = tweet.replace('', '');
}
if (tweet) {
// Detect banned word (Blacklist the user directly)
if (wordToCensor.includes(tweet) || wordToCensor.includes(tweet.substr(0, tweet.length - 1)) || wordToCensor.includes(tweet.substr(1, tweet.length))) {
const body = { type:'tweet', uid: interaction.user.id, reason: 'Automatic ban from banned word.' };
Blacklists.create(body);
await interaction.editReply({ content: 'Sike, you just posted cringe! Enjoy the blacklist :)' });
return;
}
// Very simple link detection
if (new RegExp('([a-zA-Z0-9]+://)?([a-zA-Z0-9_]+:[a-zA-Z0-9_]+@)?([a-zA-Z0-9.-]+\\.[A-Za-z]{2,4})(:[0-9]+)?(/.*)?').test(tweet) && !tweet.includes('twitter.com')) {
await interaction.editReply({ content: 'You may not tweet links outside of twitter.com' });
return;
}
// Do not allow discord invites
if (tweet.includes('discord.gg') || tweet.includes('discord.com/invite/')) {
await interaction.editReply({ content: 'No discord invite allowed.' });
return;
}
}
const T = new Twit({
consumer_key: twiConsumer,
consumer_secret: twiConsumerSecret,
access_token: twiToken,
access_token_secret: twiTokenSecret,
});
try {
// Make sure there is an attachment and if its an image
if (attachment) {
if (attachment.name.toLowerCase().endsWith('.jpg') || attachment.name.toLowerCase().endsWith('.png') || attachment.name.toLowerCase().endsWith('.gif')) {
fetch(attachment.url)
.then(res => {
const dest = fs.createWriteStream(`${os.tmpdir()}/${attachment.name}`);
res.body.pipe(dest);
dest.on('finish', () => {
const file = fs.statSync(`${os.tmpdir()}/${attachment.name}`);
const fileSize = file.size / 1000000.0;
if ((attachment.name.toLowerCase().endsWith('.jpg') || attachment.name.toLowerCase().endsWith('.png')) && fileSize > 5) {
return interaction.editReply({ content: 'Images can\'t be larger than 5 MB!' });
}
else if (attachment.name.toLowerCase().endsWith('.gif') && fileSize > 15) {
return interaction.editReply({ content: 'Gifs can\'t be larger than 15 MB!' });
}
const b64Image = fs.readFileSync(`${os.tmpdir()}/${attachment.name}`, { encoding: 'base64' });
T.post('media/upload', { media_data: b64Image }, function(err, data) {
if (err) {
console.log('OH NO AN ERROR!!!!!!!');
console.error(err);
return interaction.editReply({ content: 'OH NO!!! AN ERROR HAS occurred!!! please hold on while i find what\'s causing this issue! ' });
}
else {
Tweet(data);
}
});
});
});
}
else {
await interaction.editReply({ content: 'File type not supported, you can only send jpg/png/gif' });
return;
}
}
else {
Tweet();
}
}
catch (err) {
console.error(err);
await interaction.editReply({ content: 'Oh no, an error has occurred :(' });
return;
}
function Tweet(data) {
let options = {
status: tweet,
};
if (data && tweet) {
options = {
status: tweet,
media_ids: new Array(data.media_id_string),
};
}
else if (data) {
options = {
media_ids: new Array(data.media_id_string),
};
}
T.post('statuses/update', options, function(err, response) {
if (err) {
// Rate limit exceeded
if (err.code == 88) return interaction.editReply({ content: err.interaction });
// Tweet needs to be a bit shorter.
if (err.code == 186) return interaction.editReply({ content: `${err.interaction} Your interaction was ${tweet.length} characters, you need to remove ${tweet.length - 280} characters (This count may be inaccurate if your interaction contained link)` });
// Status is a duplicate.
if (err.code == 187) return interaction.editReply({ content: err.interaction });
// To protect our users from spam and other malicious activity, this account is temporarily locked.
if (err.code == 326) return interaction.editReply({ content: err.interaction });
console.error('OH NO!!!!');
console.error(err);
return interaction.editReply({ content: 'OH NO!!! AN ERROR HAS occurred!!! please hold on while i find what\'s causing this issue!' });
}
const tweetid = response.id_str;
const FunnyWords = ['oppaGangnamStyle', '69', '420', 'cum', 'funnyMan', 'GUCCISmartToilet', 'TwitterForClowns', 'fart', 'mcDotnamejeffDotxyz', 'ok', 'hi', 'howAreYou', 'WhatsNinePlusTen', '21'];
const TweetLink = `https://twitter.com/${FunnyWords[Math.floor((Math.random() * FunnyWords.length))]}/status/${tweetid}`;
// Im too lazy for now to make an entry in config.json
let channel = interaction.client.channels.resolve(twiChannel);
channel.send(TweetLink);
const Embed = new MessageEmbed()
.setAuthor({ name: interaction.user.username, iconURL: interaction.user.displayAvatarURL() })
.setDescription(tweet)
.addField('Link', TweetLink, true)
.addField('Tweet ID', tweetid, true)
.addField('Channel ID', interaction.channel.id, true)
.addField('Messsage ID', interaction.id, true)
.addField('Author', `${interaction.user.username} (${interaction.user.id})`, true)
.setTimestamp();
if (interaction.guild) {
Embed.addField('Guild', `${interaction.guild.name} (${interaction.guild.id})`, true);
Embed.addField('message link', `https://discord.com/channels/${interaction.guild.id}/${interaction.channel.id}/${interaction.id}`);
}
else {
Embed.addField('message link', `https://discord.com/channels/@me/${interaction.channel.id}/${interaction.id}`);
}
if (attachment) Embed.setImage(attachment.url);
channel = interaction.client.channels.resolve(twiLogChannel);
channel.send({ embeds: [Embed] });
return interaction.editReply({ content: `Go see ur epic tweet ${TweetLink}` });
});
}
},
};