Docs/Plugins/Image Scan
Image Scan
Catch scams that arrive as pictures - fingerprint matching plus optional OCR through your censor lists.
Requires the IMAGE_SCAN feature; the OCR layer additionally requires
IMAGE_SCAN_OCR.
Scammers long since learned to put the pitch in a screenshot instead of the message body. Image Scan gives you two layers against that:
- Layer 1 - fingerprints. Every posted image is fingerprinted (perceptually - crops, recompression and small edits still match) and compared against the scam images your moderators have taught. Cheap enough to run on everything. This covers uploads AND posted links: a pasted image URL or a link preview is scanned just like an attached file. GIFs are fully supported: the frames are rebuilt the way a viewer plays them and a sampled set is fingerprinted, so a match on ANY frame catches the file - a scam hidden three frames in does not slip past.
- Layer 2 - OCR. Optionally, text is read out of images and run through the censor lists you already maintain (blocked words, tokens, domains, invites). Costs more per image, hence the separate grant.
plugins:
imagescan:
enabled: true
mode: enforce # 'shadow' is the default: log detections, delete nothing
match_fingerprints: true
fingerprint_distance: 8 # match tolerance
ocr_enabled: true
learn_from_ocr_hits: true
log_channel: 674638168474915242
Teaching it
- In Discord: reply to a scam image with
!scamimage add, and it joins your server's corpus. A GIF teaches one fingerprint per distinct frame in a single command. - In the dashboard: the Image Scan page accepts drag-and-drop uploads - images are fingerprinted in your browser; only the fingerprint and a small preview thumbnail are stored (the preview is what operators see when you submit an entry for the fleet-wide list). GIFs (and anything you only have a link to) go through Teach from a link: paste the image URL and the fingerprinting happens on the bot's side, every frame included.
- Every server inherits a fleet-wide corpus of known scam images, so a scam already caught elsewhere is blocked in your server from day one.
- You can offer your own catches too: Submit to global on any of your fingerprints sends it to the HepBoat operators for review. If approved, every HepBoat server starts blocking it, your entry gets a badge saying it is global now - thank you! - and the global registry keeps it even if you later remove your own copy.
- Duplicate protection works both ways: an image the fleet-wide list already covers cannot be submitted, and teaching it locally is refused with a note that every server is already protected - no wasted entries.
learn_from_ocr_hits closes the loop: when OCR catches an image, its
fingerprint is learned automatically, so the next copy is caught by the cheap
layer instantly.
Scoping and safety
mode: shadowruns everything but deletes nothing - detections go tolog_channelso you can tune before enforcing.channel_whitelist/channel_blacklistscope where scanning happens;exempt_rolesskips your staff; moderators are never scanned.- Size and rate guards (
max_bytes,max_pixels,rate_limit_per_minute) keep the scanner from being weaponised against your own server.
The dashboard page shows an effectiveness strip - how many fingerprints you have, how many came from the fleet, and what they have caught.
Other settings
scan_bots(on by default) - scan images posted by bots and webhooks too. Scam art is often posted through a compromised bot, so this is deliberately the opposite default to the honeypot's.ocr_languages(default['eng']) - the languages the OCR layer reads. Set this if your server's scams arrive in another language.ocr_min_chars(default 8) - ignore OCR results shorter than this, which keeps stray letters out of your filters.ocr_timeout_ms- how long to spend on one image before giving up.
Commands
| Command | What it does |
|---|---|
/scamimage add |
Teach the bot that an image is a scam (reply to it, or pass a URL). |
/scamimage remove |
Forget a scam-image fingerprint by its 16-character hash. |
/scamimage list |
Show this server's scam-image fingerprints. |
/scamimage test |
Check an image against the fingerprint list without changing anything. |