import { Composer } from "grammy"; import type { Context } from "#root/bot/context.js"; import { logHandle } from "#root/bot/helpers/logging.js"; import metaLinkCheck from "#root/lib/metaLinkCheck.js"; import twitterLinkCheck from "#root/lib/twitterLinkCheck.js"; import { urql } from "#root/main.js"; import increment from "#root/lib/graphql/mutations/incrementMutation.js"; import addGroup from "#root/lib/graphql/mutations/addGroupMutation.js"; import incrementGroup from "#root/lib/graphql/mutations/incrementGroupMutation.js"; import tiktokLinkCheck from "#root/lib/tiktokLinkCheck.js"; const composer = new Composer(); const feature = composer.chatType(["group", "supergroup"]); /** * What triggers this feature and adds to the log when it has been triggered. * The trigger is anytime an embedded url is detected. */ feature.on("message::url", logHandle("embed-check"), async (ctx: Context) => { const mutationKey = process.env.GRAPHQL_MUTATION_KEY || ""; await urql.mutation(increment, { trigger: true, mutationKey }); if (ctx.chat && ctx.msg) { const groupName = ctx.chat?.title || ""; const groupID = ctx.chat?.id.toString() || ""; const groupUsername = ctx.chat?.username || ""; let detectedLinks = 0; const username = ctx.msg.from?.username; // Filters every message/caption entity that is a url into a new array. const embeds = ctx.msg.entities ? ctx.msg.entities.filter(e => e.type === "text_link") : []; const captionEmbeds = ctx.msg.caption_entities ? ctx.msg.caption_entities.filter(e => e.type === "text_link") : []; const allEmbeds = embeds.concat(captionEmbeds); // If the all embeds array isn't empty filter through them to check for every type of disallowed link. if (allEmbeds.length) { const metaLinks = allEmbeds.filter(({ url }) => metaLinkCheck(url)); const twitterLinks = allEmbeds.filter(({ url }) => twitterLinkCheck(url)); const tiktokLinks = allEmbeds.filter(({ url }) => tiktokLinkCheck(url)); // Handles Meta & Facebook Links if (metaLinks.length) { detectedLinks += metaLinks.length; } // Handles Twitter/X links. if (twitterLinks.length) { detectedLinks += twitterLinks.length; } // Handles TikTok links. if (tiktokLinks.length) { detectedLinks += tiktokLinks.length; } } if (detectedLinks) { return await urql .mutation(addGroup, { groupID, groupName, groupUsername, mutationKey }) .toPromise() .then(() => urql .mutation(incrementGroup, { groupID, linksDeleted: detectedLinks, mutationKey }) .then( async () => await urql .mutation(increment, { link: detectedLinks, mutationKey }) .toPromise() .then(async () => { if (ctx.msg) { // Replies to the user informing them of the action. await ctx.reply( `@${username} One or more links in your last message were on the banlist\\. Remember TikTok, Meta & Facebook, and Twitter\\/X links along with any reformatting services for them are not allowed here\\. Please consider sharing the media directly or from other social media sources or websites\\.\n\nNo administration action was taken against you other than the message being deleted\\.\n\nIf this was forwarded from a channel consider forwarding without the caption so the media isn't deleted\\.`, { parse_mode: "MarkdownV2" } ); // Deletes the offending message ctx.msg.delete(); } }) ) ); } } }); export { composer as embedCheck };