DiscordChatExporter
DiscordChatExporter copied to clipboard
Lottie-based stickers cannot be rendered in HTML due to CORS
Version
v2.33
Flavor
GUI (Graphical User Interface)
Export format
HTML
Details
Note: this is an issue related to an unreleased feature (as of v2.32 being latest stable release).
Lottie-based stickers are rendered using the lottie-web
library, which requests the animation manifest stored in JSON from the provided URL (e.g. https://discord.com/stickers/749054660769218631.json), parses it, and then transforms into an SVG.
The problem is that Discord's CDN has a CORS policy on GET https://discord.com/stickers/*.json
which allows only requests from discord.com
origin. In an export, since it's running technically on localhost
, it fails.
Additionally, even if this is solved, another CORS issue manifests when the chat is exported with "download media" feature. When doing that, aforementioned json
files are placed on local filesystem, which is a problem because browsers do not allow JS code to resolve content from the filesystem.
As it stands, stickers are currently not being rendered in HTML. We need to find a workaround.
Steps to reproduce
- Export a channel with lottie-based stickers
- See that none of the stickers are showing up
- Inspecting the Network tab in devconsole will show that requests fail due to CORS
I was thinking that maybe the JSON data could be embedded somewhere into the HTML file itself, but it looks like they can be pretty massive. That would probably introduce a huge amount of bloat.
I was thinking that maybe the JSON data could be embedded somewhere into the HTML file itself, but it looks like they can be pretty massive. That would probably introduce a huge amount of bloat.
Indeed, they are quite massive. An alternative would be to save them as JS files. So instead of:
{"v":"5.6.2","fr":60,"ip":0, ... }
Do:
window.lottieAnimationData['749054660769218631'] = {'v':'5.6.2','fr':60,'ip':0, ...}
This would allow us to do <script src="path/to/js/file">
and then fetch animation data from a global object. It's non-trivial to implement, but should probably work.
However, this would only work with "download media" turned on because otherwise we shouldn't download anything locally.
Perhaps downloading that data could be added as an additional option, so that in effect:
- If downloading media, @Tyrrrz's suggestion of embedding inside JS files would be used
- If not downloading media, the user can optionally download just this data and embed it inside the HTML file, as suggested by @96-LB
Closing as there's no real way to fix it with the current architecture