@ file : Opt In ( Experimental Time :: class ) Ċ @ file : Suppress (" StringLiteral Dup lication ") Ċ Ċ package Ġcom . kot l ind is cord . k ord . extensions . modules . extra . ph ishing Ċ Ċ import Ġcom . kot l ind is cord . k ord . extensions . DIS C ORD _ RED Ċ import Ġcom . kot l ind is cord . k ord . extensions . Discord Relay ed Exception Ċ import Ġcom . kot l ind is cord . k ord . extensions . checks . has Permission Ċ import Ġcom . kot l ind is cord . k ord . extensions . checks . isNot Bot Ċ import Ġcom . kot l ind is cord . k ord . extensions . commands . Arguments Ċ import Ġcom . kot l ind is cord . k ord . extensions . commands . converters . impl . string Ċ import Ġcom . kot l ind is cord . k ord . extensions . extensions . Extension Ċ import Ġcom . kot l ind is cord . k ord . extensions . extensions . ep hemeral Message Command Ċ import Ġcom . kot l ind is cord . k ord . extensions . extensions . ep hemeral Slash Command Ċ import Ġcom . kot l ind is cord . k ord . extensions . extensions . event Ċ import Ġcom . kot l ind is cord . k ord . extensions . types . respond Ċ import Ġcom . kot l ind is cord . k ord . extensions . utils . dm Ċ import Ġcom . kot l ind is cord . k ord . extensions . utils . get Jump Url Ċ import Ġcom . kot l ind is cord . k ord . extensions . utils . scheduling . Scheduler Ċ import Ġcom . kot l ind is cord . k ord . extensions . utils . scheduling . Task Ċ import Ġdev . k ord . core . behavior . ban Ċ import Ġdev . k ord . core . behavior . channel . create Message Ċ import Ġdev . k ord . core . entity . Message Ċ import Ġdev . k ord . core . entity . channel . Guild Message Channel Ċ import Ġdev . k ord . core . event . message . Message Create Event Ċ import Ġdev . k ord . core . event . message . Message Update Event Ċ import Ġdev . k ord . rest . builder . message . create . embed Ċ import Ġkotlinx . coroutines . flow . filter Ċ import Ġkotlinx . coroutines . flow . last OrNull Ċ import Ġkotlinx . coroutines . launch Ċ import Ġmu . Kotlin Logging Ċ import Ġkotlin . time . Experimental Time Ċ Ċ /** ĠPh ishing Ġextension , Ġresponsible Ġfor Ġchecking Ġfor Ġph ishing Ġdomains Ġin Ġmessages . Ġ**/ Ċ class ĠPh ishing Extension ( private Ġval Ġsettings : ĠExt Ph ishing Builder ) Ġ: ĠExtension () Ġ{ ĊĠĠĠ Ġoverride Ġval Ġname Ġ= Ġ" ph ishing " ĊĊĠĠĠ Ġprivate Ġval Ġapi Ġ= ĠPh ishing Api ( settings . appName ) ĊĠĠĠ Ġprivate Ġval Ġdomain Cache : ĠMutable Set < String > Ġ= Ġmutable Set Of () ĊĠĠĠ Ġprivate Ġval Ġlogger Ġ= ĠKotlin Logging . logger Ġ{ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġscheduler Ġ= ĠScheduler () ĊĠĠĠ Ġprivate Ġvar Ġcheck Task : ĠTask ? Ġ= Ġnull ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġsetup () Ġ{ ĊĠĠĠĠĠĠĠ Ġdomain Cache . addAll ( api . getAll Domains ()) ĊĊĠĠĠĠĠĠĠ Ġcheck Task Ġ= Ġscheduler . schedule ( settings . update Delay , Ġpolling Seconds Ġ= Ġ 3 0 , Ġcallback Ġ= Ġ:: update Domains ) ĊĊĠĠĠĠĠĠĠ Ġevent < Message Create Event > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ġ{ Ġis Not Bot () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ġ{ Ġevent . message . author Ġ!= Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ġ{ Ġevent . guild Id Ġ!= Ġnull Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsettings . checks . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( passed ) Ġit () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġaction Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Message ( event . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġevent < Message Update Event > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ġ{ Ġis Not Bot () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ġ{ Ġevent . new . author . value Ġ!= Ġnull Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ġ{ Ġevent . new . guild Id . value Ġ!= Ġnull Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsettings . checks . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( passed ) Ġit () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġaction Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Message ( event . message . as Message ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġep hemeral Message Command Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ" Ph ishing ĠCheck " ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( this @ Ph ishing Extension . settings . required Command Permission Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ġ{ Ġhas Permission ( this @ Ph ishing Extension . settings . required Command Permission !! ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġaction Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( message Ġin Ġtarget Messages ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdomains Ġ= Ġparse Domains ( message . content . lowercase ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmatches Ġ= Ġdomains Ġintersect Ġdomain Cache ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrespond Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġ= Ġif Ġ( matches . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" â ļłï¸ı Ġ[ Message Ġ${ message . id . value } ]( ${ message . get Jump Url () }) Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"** contains Ġ${ matches . size } Ġph ishing Ġlink / s ** ." ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" âľ ħ Ġ[ Message Ġ${ message . id . value } ]( ${ message . get Jump Url () }) Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"** does Ġnot Ġcontain Ġany Ġph ishing Ġlinks ** ." ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġep hemeral Slash Command (:: Domain Args ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ" ph ishing - check " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdescription Ġ= Ġ" Check Ġwhether Ġa Ġgiven Ġdomain Ġis Ġa Ġknown Ġph ishing Ġdomain ." ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( this @ Ph ishing Extension . settings . required Command Permission Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Ġ{ Ġhas Permission ( this @ Ph ishing Extension . settings . required Command Permission !! ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġaction Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrespond Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġ= Ġif Ġ( domain Cache . contains ( arguments . domain . lowercase ())) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" â ļłï¸ı Ġ`${ arguments . domain }` Ġis Ġa Ġknown Ġph ishing Ġdomain ." ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" âľ ħ Ġ`${ arguments . domain }` Ġis Ġnot Ġa Ġknown Ġph ishing Ġdomain ." ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġhandle Message ( message : ĠMessage ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdomains Ġ= Ġparse Domains ( message . content . lowercase ()) ĊĠĠĠĠĠĠĠ Ġval Ġmatches Ġ= Ġdomains Ġintersect Ġdomain Cache ĊĊĠĠĠĠĠĠĠ Ġif Ġ( matches . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Found Ġa Ġmessage Ġwith Ġ${ matches . size } Ġph ishing Ġdomains ." Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( settings . notify User ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . k ord . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . author !!. dm Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent Ġ= Ġ" We 've Ġdetected Ġthat Ġthe Ġfollowing Ġmessage Ġcontains Ġa Ġph ishing Ġdomain . ĠFor Ġthis Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" reason , Ġ** ${ settings . detection Action . message }** ." ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġembed Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtitle Ġ= Ġ" Ph ishing Ġdomain Ġdetected " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescription Ġ= Ġmessage . content ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcolor Ġ= ĠDIS C ORD _ RED ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinline Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ" Channel " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġmessage . channel . mention ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinline Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ" Message ĠID " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġ"` ${ message . id . value }` " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinline Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ" Server " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġmessage . get Guild (). name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( settings . detection Action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDetection Action . Ban Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . get Author As Member () !!. ban Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreason Ġ= Ġ" Message Ġcontained Ġa Ġph ishing Ġdomain " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . delete (" Message Ġcontained Ġa Ġph ishing Ġdomain ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDetection Action . Delete Ġ-> Ġmessage . delete (" Message Ġcontained Ġa Ġph ishing Ġdomain ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDetection Action . Kick Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . get Author As Member () !!. kick (" Message Ġcontained Ġa Ġph ishing Ġdomain ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage . delete (" Message Ġcontained Ġa Ġph ishing Ġdomain ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDetection Action . Log Only Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠDo Ġnothing , Ġwe Ġalways Ġlog ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog Deletion ( message , Ġmatches ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġlog Deletion ( message : ĠMessage , Ġmatches : ĠSet < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġguild Ġ= Ġmessage . get Guild () ĊĊĠĠĠĠĠĠĠ Ġval Ġchannel Ġ= Ġmessage ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. get Guild () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. channels ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . name Ġ== Ġsettings . log Channel Name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. last OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . as Channel OrNull () Ġas ? ĠGuild Message Channel ĊĊĠĠĠĠĠĠĠ Ġif Ġ( channel Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . warn Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Unable Ġto Ġfind Ġa Ġchannel Ġnamed Ġ${ settings . log Channel Name } Ġon Ġ${ guild . name } Ġ(${ guild . id . value })" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġmatch List Ġ= Ġ"# ĠPh ishing ĠDomain ĠMat ches \ n \ n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"** Total :** Ġ${ matches . size }\ n \ n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmatches . join ToString ("\ n ") Ġ{ Ġ"* Ġ`$ it `" Ġ} ĊĊĠĠĠĠĠĠĠ Ġchannel . create Message Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd File (" matches . md ", Ġmatch List . byte InputStream ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġembed Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtitle Ġ= Ġ" Ph ishing Ġdomain Ġdetected " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescription Ġ= Ġmessage . content ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcolor Ġ= ĠDIS C ORD _ RED ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinline Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ" Author " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġ"${ message . author !!. mention } Ġ(" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"` ${ message . author !!. tag }` Ġ/ Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"` ${ message . author !!. id . value }` " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ")" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinline Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ" Channel " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġ"${ message . channel . mention } Ġ(` ${ message . channelId . value }`) " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinline Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ" Message " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġ"[ `${ message . id . value }` ]( ${ message . get Jump Url () })" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfield Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinline Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġ" Total ĠMat ches " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Ġ= Ġmatches . size . toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġparse Domains ( content : ĠString ): ĠMutable Set < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdomains : ĠMutable Set < String > Ġ= Ġmutable Set Of () ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( match Ġin Ġsettings . url Regex . findAll ( content )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġfound Ġ= Ġmatch . groups [ 1 ] !!. value . trim ('/') ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(" /" Ġin Ġfound ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfound Ġ= Ġfound . split ("/", Ġlimit Ġ= Ġ 2 ). first () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdomains . add ( found ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġlogger . debug Ġ{ Ġ" Found Ġ${ domains . size } Ġdomains : Ġ${ domains . join ToString () }" Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġdomains ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġun load () Ġ{ ĊĠĠĠĠĠĠĠ Ġcheck Task ?. cancel () ĊĠĠĠĠĠĠĠ Ġcheck Task Ġ= Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Suppress (" Magic Number ") ĊĠĠĠ Ġinternal Ġsuspend Ġfun Ġupdate Domains () Ġ{ ĊĠĠĠĠĠĠĠ Ġlogger . trace Ġ{ Ġ" Updating Ġdomains ..." Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠAn Ġextra Ġ 3 0 Ġseconds Ġfor Ġsafety ĊĠĠĠĠĠĠĠ Ġapi . get Recent Domains ( settings . update Delay . in Whole Seconds Ġ+ Ġ 3 0 ). forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( it . type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDomain Change Type . Add Ġ-> Ġdomain Cache . addAll ( it . domains ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠDomain Change Type . Delete Ġ-> Ġdomain Cache . removeAll ( it . domains ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcheck Task ?. restart () Ġ Ġ// ĠOff Ġwe Ġgo Ġagain ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠArguments Ġclass Ġfor Ġdomain - relevant Ġcommands . Ġ**/ ĊĠĠĠ Ġinner Ġclass ĠDomain Args Ġ: ĠArguments () Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĠTarget ed Ġdomain Ġstring . Ġ**/ ĊĠĠĠĠĠĠĠ Ġval Ġdomain Ġby Ġstring (" domain ", Ġ" Domain Ġto Ġcheck ") Ġ{ Ġ_, Ġvalue Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(" /" Ġin Ġvalue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠDiscord Relay ed Exception (" Please Ġprovide Ġthe Ġdomain Ġname Ġonly , Ġwithout Ġthe Ġprotocol Ġor Ġa Ġpath .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ