The Problem

Links from the social media site ifunny.co dont auto embed within discord (a chromium based app). When sharing links to videos it is inconvenient to be redirected to your browser on PC or be forced into a different screen/app on mobile just to view them.

The Solution

Just because ifunny.co doesnt have embed handling for link sharing doesnt stop us from man handling the data for ourselves from their CDN. Hidden inside the data returned from the HTTPS request to ifunny.co is an .mp4 file we can sniff and scrape out.

Inspecting the data

Ifunny doesnt give us any APIs to work with to efficiently retrieve data, so we have to work with the source HTML given through the HTTPS request. Lets take a look at the <video> tag to see what hints we can find.

This looks like visual garbage. Our mp4 is inside the video tag though. The HTML data can be treated as a giant string, and we can search for .mp4. This yields ~5 results per page, some of which are bogus. This isnt a consistent enough approach for me and would require some if/else logic. Luckily this data-src attribute (possibly used for lazy loading) is the only occurence on the page and contains our proper data. This allows us to do only 1 search, and no conditional logic.

Scraping the data

Since we know what were looking for we can use the JS String.search() function to find our substring.
let index = data.search("data-src=");
//data-src="https://img.ifunny.co/videos/ec20...e46b664c3499d820_1.mp4"

for (index += 10; index < data.length; index++) {
    if (data[index] != "\"")
        tempstr += data[index];
    else
         break;
}

Sending the link

DiscordJS makes this easy, we can pass our link data with the original message object. We can use our message object data to reply with our scraped link in the same channel.
message.channel.send ("" + string);


The final product is 39 lines of a simple, but effective code. Software doesnt *have* to be complicated, it just has to serve its purpose.
const { Client, Intents } = require("discord.js");
const client = new Client({
    intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES],
});
const request = require("request");
const ifunnyLink = "https://ifunny.co/video";
client.once("ready", () => {
    console.log("Discord bot operational");
});
client.on("message", message => {
    if (!message.content.startsWith(ifunnyLink) || message.author.bot) return;
    queryAndSend("" + message.content, message);
});
client.login("Super Secret Key");
function queryAndSend(link, message) {
    let tempstr = "";
    request(
        `` + link,
        (err, response, body) => {
            let data = body;
            dataLength = data.length;
            let index = data.search("data-src=");
            for (let i = index + 10; i < data.length; i++) {
                if (data[i] != "\"")
                    tempstr += data[i];
                else
                     break;
                }
                sendMessage(tempstr, message);
            }
        );
}
function sendMessage(string, message) {
    message.channel.send ("" + string);
}