sn0wcrack / saucybot-discord Goto Github PK
View Code? Open in Web Editor NEWA discord bot that fills in the gaps for art sites without proper inline embeds.
License: MIT License
A discord bot that fills in the gaps for art sites without proper inline embeds.
License: MIT License
Describe the bug
This is more of a feature ask - but I wanted to start a discussion on if there's a way to make fixing twitter embeds more reliable. Right now if I'm looking at the check right, it seems it only replaces the embed if Discord failed to create one. Can we have an option for it to fix them in all instances so it achieves fixing broken Twitter embeds like vxtwitter, twxtter, or other similiar parent services?
To Reproduce
Any twitter link with a video. The embed may be successful in discord, but the video frequently fails to play from the twitter embed.
Expected behavior
An embedded video is created that can reliably be played in Discord.
Additional context
Open to other suggestions - I was just hoping this remained a reliable way to automatically convert twitter links to ones that played correctly in discord embeds.
Context: PluralKit is another Discord bot which allows single users to send messages under multiple names through use of webhook messages, which it does by first reading the plain message sent by a user, then deleting that message and instantly recreating it with the webhook name.
Previously (before today), using this bot and SaucyBot in conjunction created no issues. If a user using PluralKit sent a message with a link to a supported website, SaucyBot would briefly attempt to create an embed for the user's initial message in the intervening second or two when the message existed, but would stop doing so after Pluralkit deleted said message. It would then continue onto create an embed for the webhook message Pluralkit had created to replace it. Screenshot of past instance when this previously worked:
However, for some unknown reason, the bot does not (at the time of writing) do this any longer. It instead attempts to create an embed for the initial message, and then stops when Pluralkit deletes the message. Pluralkit then continues onto recreate the message with the webhook name and profile, but SaucyBot does not attempt to create an embed from this message, as it did previously. Here is an example screen recording of the bot's current behavior:
I have granted SaucyBot the administrator permission in the relevant server, so there should be no permissions issue stopping it from interacting with Pluralkit's messages as it did before.
Describe the bug
When more than one link is posted by a user at the same time in one post, SaucyBot only pulls and uploads picture from one of those links.
To Reproduce
Paste at least two links in one message and send them. Those may be from the same or different sites.
Expected behavior
SaucyBot pulls and uploads images from every link posted.
Additional context
The original saucebot had that feature, therefore I figured I'd report it as a bug.
Issue was checked by posting double or mixed links from DeviantArt, FurAffinity and Pixiv
The bot seems to prioritize DeviantArt
Describe the bug
Bot removes Twitter embeds after posting its own embed, but is only able to do so when Manage Webhooks is enabled for the bot.
To Reproduce
Disable "Manage Webhooks" for @everyone
and leave it off for SaucyBot, then post a Twitter link.
Expected behavior
SaucyBot should request Manage Webhooks permissions when added to a server to prevent this issue. Ideally, if the permission was denied and Saucy is unable to delete an embed because of it, the bot should indicate somehow that it needs this permission to function properly. Even more ideally, the embed deletion feature should be toggleable.
Additional context
Image of example behavior. SaucyBot deletes the Twitter default embed if Manage Webhooks is on.
Is it possible to make Saucybot delete the users message after fetching the file(s) and posting the embed?
because otherwise, it's just doubling the amount of messages and clogging up the channels, especially since it works now without even using the command prompt so it's doing it's thing even when people don't intentionally use it.
Describe the bug
When bot tries to process a tweet that is a quote retweet reply to another post, if the replied to tweet includes a video, the bot will embed the quoted tweet instead of linked tweet media
To Reproduce
Example of tweet where the issue occurs (NSFW, not porn, but still nsfw): https://twitter.com/303_taroo/status/1763652002482188613
Expected behavior
Embeded media should be the images of the quote reply.
The original Saucebot supports DeviantArt, but this one doesn't. I was planning to migrate to this bot and lack of this one feature is a problem for me. Can it be added?
While waiting to see if an embed works or not SaucyBot posts a message like this,
If you aren't looking at the channel at the moment this message is posted and then deleted, it leaves you with a 'ghost' unread message notification on the channel until you right click the channel and mark it as read.
If there's any way to silence this single message in the process per-server that'd be rad
Describe the bug
When SaucyBot creates an embed for a FurAffinity post, it adds an extra blank line between every line in the description.
To Reproduce
Paste this into a Discord message: https://www.furaffinity.net/view/51719696/
Expected behavior
The description should look like what fxfurafinity embeds:
Additional context
It looks like the parser is just accidentally adding a blank line after every single line in the original description. Should be a fairly simple fix.
Hi Sn0wCrack, the community I'm a part of recently added saucybot-discord to our Discord. While we love finally being able to play Twitter videos in Discord again (thank you for your work on it!), it's kind of clunky to have Discord embed the tweet with the video thumbnail and then have the video below it.
The workflow that some people end up doing is:
As someone in the community I'm in so elegantly put it, "what if i wanna see the mf's tweet ๐"
If you have the time to work on this, would you be able to have saucybot delete the user's original post and then include the link to the tweet in question with the newly-embedded video?
been looking through the bot and was wondering if there's a command to change the amount of images it embeds directly on discord. Is it a feature ? or do i have to deploy the bot myself and edit the file on my pc?
Since yesterday Saucy isn't embedding Pixiv links, pasting the link gets the message that Saucybot is matching the links but then it doesn't do anything and only leaves the link as typed. Saucy works normally with Devianart, Twitter, Newgrounds, and Artstation.
Oddly enough, I tried adding it to a dummy server I have to test bots and it works there perfectly, I tried matching the permissions between the two, and still doesn't work in my main server.
twitter is switching their links to x.com. can the bot fix the embeds for x the same way it has for twitter? the vx creator has made fixv to work with x so it should all work the same way. aka
twitter.com -> vxtwitter.com
x.com -> fixvx.com
Describe the bug
When it comes to Devient art links, the bot doesn't seem to work anymore. There will be flash of it trying, but then nothing. It still works with other links like Twitter or FurAffinity, its just DA it seems to not work with
To Reproduce
Just post a devient art link
Expected behavior
there will be a flash of it replying, and then nothing
Additional context
Now that I'm hoping I've got the bugs ironed out on that one.
I'd like to hear from people over the next couple of weeks as to what they think of this feature and how useful it seems to them.
I'm personally thinking of disabling this, but if enough people find this more useful than annoying, I'm more than willing to keep it enabled on the live version of SaucyBot.
Please let me know what you think in a reply here or by joining the SaucyBot Support Discord Server
Our server already uses BDSMbed to link twitter video uploads directly so they play inline on mobile and web discord, and it makes no distinction between NSFW or not (since it doesn't matter for the library they use to fetch the video links). This in combination with Saucybot causes double uploads when the URL in question is detected as NSFW.
A setting to disable video uploads from the bot would be a simple way to work around this scenario.
At rare occasions the link will be embedded properly, but the bot will still add a second embed, pretty much duplicating the message.
At other situations, the user specifically posts a link not wanting it to embed (for example nsfw content in a safe channel), but there is no way to stop the bot from embedding.
More commonly a user will post a link in the wrong channel, and even if they delete their message, the embed will remain.
In situations like this, only a mod can delete the mistake and mods are simply not always available.
There needs to be a way for all users to delete embeds of their own links. A suggestion is to use a specific reaction emote (for example โ) that instructs the bot to delete the message if it's triggered by the message author.
Site Name: Misskey.design
Site URL: https://misskey.design/
Example URLs:
From what I have seen, misskey.design URLs will embed properly on Discord if they contain one or multiple images, one or multiple animated GIFs, but not a video. This is what motivates this request.
As far as I know, misskey.design is based on Misskey, so I would assume at least some of the work for misskey.io support could prove useful for misskey.design.
Site Name:
Misskey
Site URL:
https://misskey.io/
Example URLs:
Misskey API Docs:
https://misskey-hub.net/en/docs/api/
Further information:
misskey.io is a site where a lot of JP artists migrated to, part of the fediverse. It doesn't provide NSFW embeds.
I'm currently running the very simple Discord embed helper for this site where you replace the .io with .wtf, and it creates vxtwitter-like embeds for Discord, which allows embeds of NSFW content.
The example output is pretty much 1:1 the HTML output of vxtwitter, you can check it by going to view-source:https://misskey.wtf/notes/9lbmhln1jb
for example. The note ID is always an alphanumeric string between 10 and 16 characters (so far).
This is in PHP, nothing special, very barebones but gets the job done.
I thought about just making a PR with the site added but since I don't know C# and haven't worked with actual software before, I lack the skills to do it myself.
I hope this helps!
Basically fetching the API result of a /api/notes/show
request:
// If the renoteId key exists, this is a renote of a note
if (isset($result->renoteId) && !empty($result->renoteId)) {
// grab the information of the renoted note and reassign the ID, we don't care about the renote info
$result = $result->renote;
$noteID = $result->id;
}
// Grab some basic information with fallbacks where appropriate
$displayName = $result->user->name ?? $result->user->username;
$userName = $result->user->username;
$avatar = $result->user->avatarUrl ?? '/noavatar.jpg';
$text = $result->text ?? "no text";
$date = $result->createdAt;
if (!isset($result->files)) die("Note missing files");
$files = $result->files;
if (sizeof($files) === 0) die("No files");
// if only 1 file of type image/gif, grab its url. There's also a thumbnailUrl key containing a reduced size webp version of a gif but discord does not support webps
if (sizeof($files) === 1 && $files[0]->type === 'image/gif') {
$imageURL = $files[0]->url;
// same for video, but the HTML output changes accordingly
} elseif (sizeof($files) === 1 && $files[0]->type === 'video/mp4') {
$videoURL = $files[0]->url;
goto video;
} else {
// Check if the thumbnail hasn't been stored before, store a reduced version when not
if (!file_exists("./thumbnails/".$noteID.".jpg")) {
// Similar to vxtwitter, create a mosaic of all images in the note, but not as fancy
try {
$imagick = new Imagick();
$count = 0;
foreach ($files as $file) {
$imagick->addImage(new imagick($file->thumbnailUrl));
$count++;
}
$cols = (int)sqrt($count);
$rows = (int)ceil($count / (float)$cols);
$result = $imagick->montageImage(new ImagickDraw(), $rows."x".$cols."+0+0", "", Imagick::MONTAGEMODE_UNFRAME, "0x0+0+0");
$result->setImageFormat('jpg');
$result->setImageCompressionQuality(80);
file_put_contents("./thumbnails/".$noteID.".jpg", $result);
} catch (Exception $exception) {
die($exception);
}
}
$imageURL = "/thumbnails/".$noteID.".jpg";
}
// Then here the HTML headers get created containing all the information from the note
The oembed.json
in the HTML is a PHP file in a folder called oembed.json
which just passes back the info we give it as a json:
<link rel="alternate" href="/oembed.json?author_name=<?= urlencode($displayName ?? "") ?>%20(@<?= urlencode($userName ?? "") ?>)&author_url=<?= urlencode("https://misskey.io/notes/".($noteID ?? "")) ?>&provider_name=Misskey.io&provider_url=https://misskey.io" type="application/json+oembed" title="<?= urlencode($userName ?? "") ?>">
// /oembed.json/index.php
if (empty($_GET)) die();
$data = [];
foreach ($_GET as $param => $value) {
$data[$param] = $value;
}
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data);
die();
Site Name: Nitter
Site URL: https://nitter.net/
Example URLs:
Nitter links don't seem to embed in discord so this could be a nice addition.
So Saucy bot stopped download and embed Twitter videos to server because of Twitter god awful API. have u been able to work around this yet? ๐ฅบ
When posting links from Furaffinity the bot replies with
"Matched link to FurAffinity, please wait..."
But it gets stuck there and never posts the image.
The issue has been present for over a week now.
All other sites work as expected.
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
This repository currently has no open or pending branches.
SaucyBot/docker-compose.dev.yml
mariadb 11@sha256:e59ba8783bf7bc02a4779f103bb0d8751ac0e10f9471089709608377eded7aa8
redis 7-alpine@sha256:0bc09d9f486508aa42ecc2f18012bb1e3a1b2744ef3a6ad30942fa12579f0b03
SaucyBot/docker-compose.prod.yml
mariadb 11@sha256:e59ba8783bf7bc02a4779f103bb0d8751ac0e10f9471089709608377eded7aa8
redis 7-alpine@sha256:0bc09d9f486508aa42ecc2f18012bb1e3a1b2744ef3a6ad30942fa12579f0b03
SaucyBot/Dockerfile
mcr.microsoft.com/dotnet/runtime 8.0-alpine3.19@sha256:6c3def5f3ab3f1f1cdf9320f351b15e200dca527212733dab7eb404bff1dbb21
mcr.microsoft.com/dotnet/sdk 8.0-alpine3.19@sha256:b1275049a8fe922cbc9f1d173ffec044664f30b94e99e2c85dd9b7454fbf596c
.github/workflows/continuous-deployment.yml
actions/checkout v4@692973e3d937129bcbf40652eb9f2f61becf3332
docker/metadata-action v5@8e5442c4ef9f78752691e2d8f8d19755c6f78e81
docker/setup-qemu-action v3@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf
docker/setup-buildx-action v3@aa33708b10e362ff993539393ff100fa93ed6a27
docker/login-action v3@9780b0c442fbb1117ed29e0efdff1e18412f7567
docker/build-push-action v6@5176d81f87c23d6fc96624dfdbcd9f3830bbe445
appleboy/ssh-action v1.0.3@029f5b4aeeeb58fdfe1410a5d17f967dacf36262
.github/workflows/continuous-integration.yml
actions/checkout v4@692973e3d937129bcbf40652eb9f2f61becf3332
actions/setup-dotnet v4@6bd8b7f7774af54e05809fcc5431931b3eb1ddee
actions/cache v4@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9
SaucyBot.Tests/SaucyBot.Tests.csproj
coverlet.collector 6.0.2
xunit.runner.visualstudio 2.8.2
xunit 2.9.0
NSubstitute 5.1.0
Microsoft.NET.Test.Sdk 17.10.0
SaucyBot/SaucyBot.csproj
Xabe.FFmpeg 5.2.6
StackExchange.Redis 2.8.0
Serilog.Sinks.Console 6.0.0
Serilog.Settings.Configuration 8.0.2
Serilog.Extensions.Hosting 8.0.0
Serilog 4.0.1
Pomelo.EntityFrameworkCore.MySql 8.0.2
Polly.Core 8.4.1
Microsoft.Extensions.Hosting 8.0.0
Microsoft.Extensions.Caching.StackExchangeRedis 8.0.7
Microsoft.Extensions.Caching.Memory 8.0.0
Microsoft.EntityFrameworkCore.Tools 8.0.7
Microsoft.EntityFrameworkCore.Sqlite 8.0.7
Microsoft.EntityFrameworkCore.Design 8.0.7
Microsoft.EntityFrameworkCore 8.0.7
EFCore.NamingConventions 8.0.3
Discord.Net 3.15.3
AngleSharp 1.1.2
global.json
dotnet-sdk 8.0.303
Bot reposts twitter posts when the picture embed takes "too long" (half a second), resulting in multiple reposts. It also only posts a single image from a multi-image tweet.
Site Name: Reddit media embed
Site URL: https://reddit.com/media/
Example URLs:
https://www.reddit.com/media?url=https%3A%2F%2Fi.redd.it%2F8pnbi675wsqb1.png
https://www.reddit.com/media?url=https%3A%2F%2Fi.redd.it%2Fhaamnx8disqb1.png
https://www.reddit.com/media?url=https%3A%2F%2Fi.redd.it%2Fdkmhkykrhtqb1.png
I'm trying to change the limit for pixiv image on my server but can't seem to find it
Saucy isn't embedding Pixiv links, pasting the link gets the message that Saucybot is matching the links but then it doesn't do anything and only leaves the link as typed. Saucy works normally with Devianart, Twitter, Newgrounds, and Artstation.
I already tried kicking the bot and inviting it back and changing permissions, but the issue persists. and unlike the previous time something like this happened, changing the server's name didn't fix the issue.
Describe the bug
Bit of a noob, especially with docker, so I'm sure this is probably my fault in some way, but I'm stuck trying to deploy this thing and googling errors hasn't been much help.
The fields in the .env file I've left blank are either websites I don't want to include with the bots functionality, or not being sure what value should be applied.
After running docker compose up
, everything seems to start up as expected, but when it tries to connect to a shard, I get a 403.
I've invited the bot to my server with the bot
and applications.commands
scopes, as well as all Privileged Gateway Intents enabled and Text Permissions Send Messages
, Embed Links
, Attach Files
and Read Message History
.
To Reproduce
Create .env file like below, run docker compose up
.
Expected behavior
Bot coming online and functioning.
Additional context
.env file:
NODE_ENV=production
DISCORD_API_KEY=[CENSORED]
DISCORD_SHARD_RESPAWN=true
DISCORD_SHARD_SPAWN_TIMEOUT=30000
DISCORD_GUILD_ID= # For development only
DISCORD_CLIENT_ID= # For development only
MAXIMUM_EMBEDS=8
DISABLED_SITES=
SENTRY_DSN=
REDIS_URL=
PIXIV_LOGIN=
PIXIV_PASSWORD=
PIXIV_COOKIE=
PIXIV_POST_LIMIT=5
PIXIV_UGOIRA_FORMAT=mp4
PIXIV_UGOIRA_BITRATE=2000
ARTSTATION_POST_LIMIT=5
FA_COOKIE_A=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx [OBFUSCATED TO SHOW SYNTAX BEING USED]
FA_COOKIE_B=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx [OBFUSCATED TO SHOW SYNTAX BEING USED]
EHENTAI_IPB_ID=
EHENTAI_IPB_PASS=
TWITTER_API_KEY=[CENSORED]
TWITTER_API_SECRET=[CENSORED]
TWITTER_ACCESS_TOKEN=[CENSORED]
TWITTER_ACCESS_SECRET=[CENSORED]
TWITTER_BEARER_TOKEN=[CENSORED]
TWITTER_READ_DELAY=1350
DEVIANTART_CLIENT_ID=
DEVIANTART_CLIENT_SECRET=
Log output:
saucybot-discord-cache-1 | 1:M 18 Sep 2022 15:39:53.364 * Ready to accept connections
saucybot-discord-bot-1 | [2022-09-18 15:39:55] [Manager] [INFO] Launched Shard 0
saucybot-discord-bot-1 | node:internal/process/promises:279
saucybot-discord-bot-1 | triggerUncaughtException(err, true /* fromPromise */);
saucybot-discord-bot-1 | ^
saucybot-discord-bot-1 |
saucybot-discord-bot-1 | [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Response code 403 (Forbidden)".] {
saucybot-discord-bot-1 | code: 'ERR_UNHANDLED_REJECTION'
saucybot-discord-bot-1 | }
saucybot-discord-bot-1 | [2022-09-18 15:40:00] [Manager] [ERROR] Shard 0's process exited before its Client became ready.
saucybot-discord-bot-1 | node:internal/process/promises:279
saucybot-discord-bot-1 | triggerUncaughtException(err, true /* fromPromise */);
saucybot-discord-bot-1 | ^
saucybot-discord-bot-1 |
saucybot-discord-bot-1 | [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Response code 403 (Forbidden)".] {
saucybot-discord-bot-1 | code: 'ERR_UNHANDLED_REJECTION'
saucybot-discord-bot-1 | }
saucybot-discord-bot-1 | /bot/node_modules/discord.js/src/sharding/Shard.js:162
saucybot-discord-bot-1 | reject(new Error(ErrorCodes.ShardingReadyDied, this.id));
saucybot-discord-bot-1 | ^
saucybot-discord-bot-1 |
saucybot-discord-bot-1 | Error [ShardingReadyDied]: Shard 0's process exited before its Client became ready.
saucybot-discord-bot-1 | at Shard.onDeath (/bot/node_modules/discord.js/src/sharding/Shard.js:162:16)
saucybot-discord-bot-1 | at Object.onceWrapper (node:events:628:26)
saucybot-discord-bot-1 | at Shard.emit (node:events:513:28)
saucybot-discord-bot-1 | at Shard.emit (node:domain:489:12)
saucybot-discord-bot-1 | at Shard._handleExit (/bot/node_modules/discord.js/src/sharding/Shard.js:408:10)
saucybot-discord-bot-1 | at ChildProcess.emit (node:events:513:28)
saucybot-discord-bot-1 | at ChildProcess.emit (node:domain:489:12)
saucybot-discord-bot-1 | at Process.ChildProcess._handle.onexit (node:internal/child_process:291:12)
saucybot-discord-bot-1 | Emitted 'error' event on Shard instance at:
saucybot-discord-bot-1 | at /bot/node_modules/discord.js/src/sharding/Shard.js:416:56
saucybot-discord-bot-1 | at processTicksAndRejections (node:internal/process/task_queues:96:5) {
saucybot-discord-bot-1 | code: 'ShardingReadyDied'
saucybot-discord-bot-1 | }
saucybot-discord-bot-1 exited with code 1
Attempted to invite the bot to multiple servers I am an admin in, or I own, and the invite failed, presenting this screen:
I am an adminstrator in all of the discords, and I tried making a role with the specific requested permission enabled and that also failed to work. Figured I should report this since this bot's functionality would be very useful.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.