diff --git a/src/reflex/scanners.ts b/src/reflex/scanners.ts
new file mode 100644
index 0000000..8ea22f7
--- /dev/null
+++ b/src/reflex/scanners.ts
@@ -0,0 +1,119 @@
+import * as us from 'unscan'
+import fetch from 'node-fetch'
+import { writeFileSync } from 'fs'
+import generateFileName from '../utils/temp/generateFileName.js'
+import Tesseract from 'node-tesseract-ocr';
+
+
+export async function testNSFW(link: string): Promise<JSON> {
+    let p = await saveAttachment(link)
+    let result = await us.nsfw.file(p)
+    return result
+}
+
+export async function testMalware(link: string): Promise<JSON> {
+    let p = await saveAttachment(link)
+    let result = await us.malware.file(p)
+    return result
+}
+
+export async function saveAttachment(link): Promise<string> {
+    const image = (await (await fetch(link)).buffer()).toString('base64')
+    let fileName = generateFileName(link.split('/').pop().split('.').pop())
+    writeFileSync(fileName, image, 'base64')
+    return fileName
+}
+
+export async function testLink(link: string): Promise<JSON> {
+    return await us.link.scan(link)
+}
+
+
+const linkTypes = {
+    "PHISHING": "Links designed to trick users into clicking on them.",
+    "DATING": "Dating sites.",
+    "TRACKERS": "Websites that store or track personal information.",
+    "ADVERTISEMENTS": "Websites only for ads.",
+    "FACEBOOK": "Facebook pages. (Facebook has a number of dangerous trackers. Read more on /privacy)",
+    "AMP": "AMP pages. (AMP is a technology that allows websites to be served by Google. Read more on /privacy)",
+    "FACEBOOK TRACKERS": "Websites that include trackers from Facebook.",
+    "IP GRABBERS": "Websites that store your IP address, which shows your approximate location.",
+    "PORN": "Websites that include pornography.",
+    "GAMBLING": "Gambling sites, often scams.",
+    "MALWARE": "Websites which download files designed to break or slow down your device.",
+    "PIRACY": "Sites which include illegally downloaded material.",
+    "RANSOMWARE": "Websites which download a program that can steal your data and make you pay to get it back.",
+    "REDIRECTS": "Sites like bit.ly which could redirect to a malicious site.",
+    "SCAMS": "Sites which are designed to trick you into doing something.",
+    "TORRENT": "Websites that download torrent files.",
+    "HATE": "Websites that spread hate towards groups or individuals.",
+    "JUNK": "Websites that are designed to make you waste time.",
+}
+export { linkTypes };
+
+
+export async function LinkCheck(message): Promise<string[]> {
+    let links = message.content.match(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi) ?? []
+    let detections = []
+    const promises = links.map(async element => {
+        try {
+            if (element.match(/https?:\/\/[a-zA-Z]+\.?discord(app)?\.(com|net)\/?/)) return // Also matches discord.net, not enough of a bug
+            element = await testLink(element)
+        } catch {}
+        detections.push({tags: element.tags || [], safe: element.safe})
+    });
+    await Promise.all(promises);
+    let detectionsTypes = detections.map(element => {
+        let type = Object.keys(linkTypes).find(type => element.tags.includes(type))
+        if (type) return type
+        // if (!element.safe) return "UNSAFE"
+        return undefined
+    }).filter(element => element !== undefined)
+    return detectionsTypes
+}
+
+export async function NSFWCheck(element): Promise<boolean> {
+    try {
+        let test = (await testNSFW(element))
+        //@ts-ignore
+        return test.nsfw
+    } catch {
+        return false
+    }
+}
+
+export async function SizeCheck(element): Promise<boolean> {
+    if (element.height == undefined || element.width == undefined) return true
+    if (element.height < 20 || element.width < 20) return false
+    return true
+}
+
+export async function MalwareCheck(element): Promise<boolean> {
+    try {
+        //@ts-ignore
+        return (await scan.testMalware(element)).safe
+    } catch {
+        return true
+    }
+}
+
+export function TestString(string, soft, strict): object | null {
+    for(let word of strict || []) {
+        if (string.toLowerCase().includes(word)) {
+            return {word: word, type: "strict"}
+        }
+    }
+    for(let word of soft) {
+        for(let word2 of string.match(/[a-z]+/gi) || []) {
+            if (word2 == word) {
+                return {word: word, type: "strict"}
+            }
+        }
+    }
+    return null
+}
+
+export async function TestImage(url): Promise<string | null> {
+    let text = await Tesseract.recognize(url, {lang: "eng", oem: 1, psm: 3})
+    return text;
+}
