2021-06-11 04:20:39 +00:00
const Command = require ( "../lib/command.js" ) ;
const CATEGORY = "misc" ;
const fetch = require ( "node-fetch" ) ;
2022-03-28 21:37:36 +00:00
const { hastebin , safeString , parseHtmlEntities } = require ( "../lib/utils.js" ) ;
2022-03-28 22:12:10 +00:00
const GoogleImages = require ( "google-images" ) ;
const imagesClient = new GoogleImages ( hf . apikeys . gimg , hf . apikeys . google ) ;
2021-06-11 04:20:39 +00:00
const yt = new Command ( "youtube" ) ;
yt . addAlias ( "yt" ) ;
yt . category = CATEGORY ;
yt . helpText = "Search YouTube" ;
yt . usage = "[search term]" ;
yt . callback = async function ( msg , line ) {
if ( ! line ) return "Arguments are required." ;
const req = await fetch (
` https://www.googleapis.com/youtube/v3/search?key= ${
hf . apikeys . google
} & maxResults = 5 & part = snippet & type = video & q = $ { encodeURIComponent ( line ) } `
) . then ( ( x ) => x . json ( ) ) ;
const topVid = req . items [ 0 ] ;
let out = ` ** ${ safeString (
parseHtmlEntities ( topVid . snippet . title )
) } * * | \ ` ${ safeString (
parseHtmlEntities ( topVid . snippet . channelTitle )
) } \ ` \n https://youtu.be/ ${ topVid . id . videoId } \n \n **__See Also:__** \n ` ;
for ( let i = 1 ; i < req . items . length ; i ++ ) {
const vid = req . items [ i ] ;
out += ` - ** ${ safeString (
parseHtmlEntities ( vid . snippet . title )
) } * * | By : \ ` ${ safeString (
parseHtmlEntities ( vid . snippet . channelTitle )
) } \ ` | <https://youtu.be/ ${ vid . id . videoId } > \n ` ;
}
return out ;
} ;
hf . registerCommand ( yt ) ;
const fyt = new Command ( "fyt" ) ;
fyt . category = CATEGORY ;
fyt . helpText = "Search YouTube and take the first result." ;
fyt . usage = "[search term]" ;
fyt . callback = async function ( msg , line ) {
if ( ! line ) return "Arguments are required." ;
const req = await fetch (
` https://www.googleapis.com/youtube/v3/search?key= ${
hf . apikeys . google
} & maxResults = 2 & part = snippet & type = video & q = $ { encodeURIComponent ( line ) } `
) . then ( ( x ) => x . json ( ) ) ;
const vid = req . items [ 0 ] ;
return ` ** ${ safeString (
parseHtmlEntities ( vid . snippet . title )
) } * * | \ ` ${ safeString (
parseHtmlEntities ( vid . snippet . channelTitle )
) } \ ` \n https://youtu.be/ ${ vid . id . videoId } ` ;
} ;
hf . registerCommand ( fyt ) ;
2021-07-24 02:39:57 +00:00
const WA _NO _ANSWER = "<:ms_cross:503341994974773250> No answer." ;
const wolfram = new Command ( "wolfram" ) ;
wolfram . category = CATEGORY ;
2022-03-28 21:16:03 +00:00
wolfram . helpText = "Wolfram Alpha" ;
2021-07-24 02:39:57 +00:00
wolfram . usage = "<-v> [query]" ;
wolfram . addAlias ( "wa" ) ;
2021-07-29 20:16:11 +00:00
wolfram . callback = async function ( msg , line ) {
2021-07-24 02:39:57 +00:00
let verbose = false ;
2021-07-29 20:16:11 +00:00
if ( line . includes ( "-v" ) ) {
line = line . replace ( "-v" , "" ) . trim ( ) ;
2021-07-24 02:39:57 +00:00
verbose = true ;
}
const req = await fetch (
` http://api.wolframalpha.com/v2/query?input= ${ encodeURIComponent (
2021-07-29 20:16:11 +00:00
line
2021-07-24 02:39:57 +00:00
) } & appid = LH2K8H - T3QKETAGT3 & output = json `
) . then ( ( x ) => x . json ( ) ) ;
const data = req . queryresult . pods ;
if ( ! data ) return WA _NO _ANSWER ;
// fake no answer
if ( data [ 0 ] . subpods [ 0 ] . plaintext . includes ( "geoIP" ) ) return WA _NO _ANSWER ;
if ( verbose ) {
const embed = {
2021-07-29 20:16:11 +00:00
title : ` Result for: \` ${ safeString ( line ) } \` ` ,
2021-07-24 02:39:57 +00:00
fields : [ ] ,
footer : {
icon _url : "http://www.wolframalpha.com/share.png" ,
text : "Powered by Wolfram Alpha" ,
} ,
image : {
url : data [ 1 ] . subpods [ 0 ] . img . src ,
} ,
} ;
const extra = data . slice ( 1 , 6 ) ;
for ( const x in extra ) {
embed . fields . push ( {
name : extra [ x ] . title ,
value : ` [ ${
extra [ x ] . subpods [ 0 ] . plaintext . length > 0
? extra [ x ] . subpods [ 0 ] . plaintext
: "<click for image>"
} ] ( $ { extra [ x ] . subpods [ 0 ] . img . src } ) ` ,
inline : true ,
} ) ;
}
return { embed } ;
} else {
2022-03-28 21:37:36 +00:00
let image ;
if ( data [ 1 ] . subpods [ 0 ] . img . src )
image = Buffer . from (
await fetch ( data [ 1 ] . subpods [ 0 ] . img . src ) . then ( ( x ) => x . arrayBuffer ( ) )
) ;
let string = "" ;
if ( data [ 1 ] . subpods [ 0 ] . plaintext . length > 0 )
string = safeString ( data [ 1 ] . subpods [ 0 ] . plaintext ) ;
if ( string . length > 2000 - ( 6 + safeString ( line ) . length ) )
2022-04-02 02:07:15 +00:00
string = "Output too long: " + ( await hastebin ( string ) ) ;
2022-03-28 21:37:36 +00:00
return {
content : ` \` ${ safeString ( line ) } \` -> ${ string . length > 0 ? string : "" } ` ,
file : image && {
file : image ,
name : "wolfram_output.gif" ,
} ,
} ;
2021-07-24 02:39:57 +00:00
}
} ;
hf . registerCommand ( wolfram ) ;
2022-03-28 22:12:10 +00:00
const gimg = new Command ( "gimg" ) ;
gimg . category = CATEGORY ;
gimg . helpText = "Search Google Images" ;
gimg . usage = "[query]" ;
gimg . addAlias ( "img" ) ;
gimg . callback = async function ( msg , line ) {
if ( ! line ) return "No arguments given." ;
const images = await imagesClient . search ( line , {
safe :
msg . channel . nsfw && ! msg . channel ? . topic . includes ( "[no_nsfw]" )
? "off"
: "high" ,
} ) ;
const index = Math . floor ( Math . random ( ) * images . length ) ;
const image = images [ index ] ;
return {
embeds : [
{
title : image . description ,
url : image . parentPage ,
image : {
url : image . url ,
} ,
footer : {
text : ` Image ${ index } / ${ images . length } . Rerun to get a different image. ` ,
} ,
} ,
] ,
} ;
} ;
hf . registerCommand ( gimg ) ;
const fimg = new Command ( "fimg" ) ;
fimg . category = CATEGORY ;
fimg . helpText = "Send first result from Google Images" ;
fimg . usage = "[query]" ;
fimg . callback = async function ( msg , line ) {
if ( ! line ) return "No arguments given." ;
const images = await imagesClient . search ( line , {
safe :
msg . channel . nsfw && ! msg . channel ? . topic . includes ( "[no_nsfw]" )
? "off"
: "high" ,
} ) ;
const image = images [ 0 ] ;
return {
embeds : [
{
title : image . description ,
url : image . parentPage ,
image : {
url : image . url ,
} ,
} ,
] ,
} ;
} ;
hf . registerCommand ( fimg ) ;
2022-04-02 00:13:18 +00:00
const poll = new Command ( "poll" ) ;
poll . category = CATEGORY ;
poll . helpText = "Start a poll" ;
poll . usage = "[topic] [option 1] [option 2] [...option 3-10]" ;
poll . callback = async function ( msg , line , topic , ... options ) {
if ( ! line || ! topic )
return 'Usage: hf!poll "topic" "option 1" "option 2" "...options 3-10"' ;
const arrOptions = [ ... options ] . slice ( 0 , 10 ) ;
if ( arrOptions . length < 2 ) return "A minimum of two options are required." ;
const reactions = [ ] ;
2022-04-02 00:14:11 +00:00
let displayString = ` ** ${ msg . author . username } # ${ msg . author . discriminator } ** has started a poll: \n **__ ${ topic } __** \n ` ;
2022-04-02 00:13:18 +00:00
for ( let i = 0 ; i < arrOptions . length ; i ++ ) {
displayString +=
( i === 9 ? "\ud83d\udd1f" : ` ${ i + 1 } \u 20e3 ` ) +
": " +
arrOptions [ i ] +
"\n" ;
reactions [ i ] = i === 9 ? "\ud83d\udd1f" : ` ${ i + 1 } \u 20e3 ` ;
}
return {
content : displayString ,
addReactions : reactions ,
} ;
} ;
hf . registerCommand ( poll ) ;
const vote = new Command ( "vote" ) ;
vote . category = CATEGORY ;
vote . helpText = "Start a yes/no vote" ;
vote . usage = "[topic]" ;
vote . callback = async function ( msg , line ) {
if ( ! line ) return "No topic given." ;
return {
content : ` ** ${ msg . author . username } # ${ msg . author . discriminator } ** has started a vote: \n **__ ${ line } __** \n <:ms_tick:503341995348066313>: Yes \n <:ms_cross:503341994974773250>: No ` ,
addReactions : [
2022-04-02 00:15:40 +00:00
":ms_tick:503341995348066313" ,
2022-04-02 00:13:18 +00:00
":ms_cross:503341994974773250" ,
] ,
} ;
} ;
2022-04-02 00:14:57 +00:00
hf . registerCommand ( vote ) ;
2022-04-05 04:31:20 +00:00
const DAYS = [ "Sun" , "Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" ] ;
const arsched = new Command ( "arsched" ) ;
arsched . category = CATEGORY ;
arsched . helpText = "aNONradio.net schedule" ;
2022-04-09 01:54:51 +00:00
arsched . addAlias ( "anonradio" ) ;
2022-04-05 04:31:20 +00:00
arsched . callback = async function ( msg , line ) {
const now = new Date ( ) ;
const schedule = await fetch ( "https://anonradio.net/schedule/" ) . then ( ( res ) =>
res . text ( )
) ;
let lines = schedule . split ( "\n" ) ;
lines = lines . slice ( 4 , lines . length - 2 ) ;
const parsedLines = [ ] ;
for ( const line of lines ) {
const [ _ , time , id , name ] = line . match ( /^(.{3,4} .{4})\s+(.+?) {2}(.+?)$/ ) ;
const tmp = time . split ( " " ) ;
const day = tmp [ 0 ] ;
let hour = tmp [ 1 ] ;
const currentDay = now . getUTCDay ( ) ;
const targetDay = DAYS . indexOf ( day ) ;
const delta = ( targetDay + 7 - currentDay ) % 7 ;
let currentYear = now . getUTCFullYear ( ) ;
2022-04-05 04:32:19 +00:00
const currentMonth = now . getUTCMonth ( ) + 1 ;
2022-04-05 04:31:20 +00:00
const currentDateDay = now . getUTCDate ( ) ;
let targetMonth = currentMonth ;
const lastDay = new Date ( currentYear , currentMonth , 0 ) . getDate ( ) ;
let targetDateDay = currentDateDay + delta ;
if ( targetDateDay > lastDay ) {
targetMonth = currentMonth === 12 ? 1 : currentMonth + 1 ;
targetDateDay = 1 ;
if ( currentMonth === 12 ) currentYear ++ ;
}
hour = hour . slice ( 0 , 2 ) + ":" + hour . slice ( - 2 ) ;
const timestamp =
Date . parse (
` ${ DAYS [ targetDay ] } , ${ currentYear } - ${ targetMonth } - ${ targetDateDay } ${ hour } UTC `
) / 1000 ;
parsedLines . push ( { timestamp , id , name } ) ;
}
const liveNow = parsedLines . splice ( 0 , 1 ) [ 0 ] ;
liveNow . name = liveNow . name . replace ( " <- Live NOW" , "" ) ;
return {
embeds : [
{
title : "Click to listen" ,
url : "http://anonradio.net:8000/anonradio" ,
author : {
name : ` LIVE NOW: ${ liveNow . name } ( \` ${ liveNow . id } \` ) ` ,
} ,
fields : parsedLines . map ( ( line ) => ( {
inline : true ,
name : ` ${ line . name } ( \` ${ line . id } \` ) ` ,
value : ` <t: ${ line . timestamp } :R> ` ,
} ) ) ,
} ,
] ,
} ;
} ;
hf . registerCommand ( arsched ) ;
2022-04-20 19:45:32 +00:00
const REGEX _IPV4 = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/ ;
const shodan = new Command ( "shodan" ) ;
shodan . category = CATEGORY ;
shodan . helpText = "Look up an IP on Shodan InternetDB" ;
shodan . callback = async function ( msg , line ) {
if ( ! line || line == "" ) return "Arguments required." ;
if ( ! REGEX _IPV4 . test ( line ) ) return "Invalid IP address." ;
const data = await fetch ( "https://internetdb.shodan.io/" + line ) . then ( ( res ) =>
res . json ( )
) ;
return {
embed : {
title : ` Results for \` ${ data . ip } \` ` ,
fields : [
{
title : "Hostnames" ,
value :
data . hostnames . length > 0
? data . hostnames . map ( ( str ) => ` \` ${ str } \` ` ) . join ( "\n" )
: "None" ,
inline : true ,
} ,
{
title : "Open ports" ,
value : data . ports . length > 0 ? data . ports . join ( ", " ) : "None" ,
inline : true ,
} ,
{
title : "Tags" ,
value :
data . tags . length > 0
? data . tags . map ( ( str ) => ` \` ${ str } \` ` ) . join ( ", " )
: "None" ,
inline : true ,
} ,
{
title : "CPEs" ,
value :
data . cpes . length > 0
? data . cpes . map ( ( str ) => ` \` ${ str } \` ` ) . join ( "\n" )
: "None" ,
inline : true ,
} ,
{
title : "Vulnerabilities" ,
value :
data . vulns . length > 0
? data . vulns . map ( ( str ) => ` \` ${ str } \` ` ) . join ( "\n" )
: "None" ,
inline : true ,
} ,
] ,
} ,
} ;
} ;
hf . registerCommand ( shodan ) ;