327 lines
7.7 KiB
Bash
Executable File
327 lines
7.7 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# Hard requirement for lighttpd
|
||
printf "Content-Type: text/plain\n\n"
|
||
|
||
# Initialize basic variables
|
||
. /etc/konata.conf
|
||
|
||
# Parse incoming messages
|
||
input=$(cat /dev/stdin)
|
||
msg=$(jq -r '.message.text' <<< $input | sed "s/_/\ /g")
|
||
cmd=$(cut -d" " -f1 <<< $msg)
|
||
args=($(cut -sd" " -f2- <<< $msg))
|
||
chat=$(jq -r '.message.chat.id' <<< $input)
|
||
user=$(jq -r '.message.from.username' <<< $input)
|
||
|
||
# Append bot's tag to any command without one
|
||
if ! grep -q "/.*@" <<< $cmd
|
||
then
|
||
cmd=${cmd}@$bot
|
||
fi
|
||
# Convert k.command to /command
|
||
if grep -q "k\." <<< $cmd
|
||
then
|
||
cmd=$(sed "s/k\./\//g" <<< $cmd)
|
||
fi
|
||
|
||
# Functions for outgoing messages
|
||
sendmsg(){
|
||
# Escape any special characters first, see https://0x0.st/NO7J.
|
||
fmt=$(sed 's/[>#+-=|{}.!]/\\&/g' <<< $1 | sed 's/\t//g')
|
||
sendraw "$fmt"
|
||
}
|
||
|
||
escape(){
|
||
sed "s/[$1]/\\\&/g" <<< $2
|
||
}
|
||
|
||
sendraw(){
|
||
curl -sX POST "https://api.telegram.org/bot$token/sendMessage" \
|
||
-d "chat_id=$chat" -d "parse_mode=markdownv2" \
|
||
-d "disable_web_page_preview=true" \
|
||
--data-urlencode "text=$1"
|
||
}
|
||
|
||
sendlog(){
|
||
chat=$logchat
|
||
sendmsg "$1"
|
||
}
|
||
|
||
sendfile(){
|
||
curl -sF document=@"$1" "https://api.telegram.org/bot$token/sendDocument?chat_id=$chat"
|
||
}
|
||
|
||
sendpic(){
|
||
curl -sX POST "https://api.telegram.org/bot$token/sendPhoto" \
|
||
-d "chat_id=$chat" -d "parse_mode=markdownv2" \
|
||
-d "photo=$1" -d "caption=$2"
|
||
}
|
||
|
||
# Internal checks
|
||
args(){
|
||
if [ -z ${args[*]} ]
|
||
then
|
||
sendmsg "Don't just click me like that. See /help@$bot for more info on how to use this bot."
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
admin(){
|
||
case $user in
|
||
ghnou) true ;;
|
||
*) fail ;;
|
||
esac
|
||
debug "Admin @$user tried to execute $cmd and was approved."
|
||
}
|
||
|
||
fail(){
|
||
debug "User @$user tried to execute $cmd and was rejected."
|
||
sendmsg "Sorry, you are not allowed to use this command!"
|
||
exit 1
|
||
}
|
||
|
||
# Debugging commands
|
||
debug(){
|
||
[ ! -z $debug ] && echo "[DEBUG] $1" >&2
|
||
}
|
||
|
||
# Public commands
|
||
help(){
|
||
sendmsg "Hiya! I'm [ghnou](https://t.me/ghnou)'s personal bot, Konata.
|
||
|
||
*Currently I have the following features:*
|
||
- \`/help\` - Show this help message.
|
||
- \`/alive\` - Check whether I'm running.
|
||
- \`/cv \[country\]\` - Check COVID-19 stats.
|
||
- \`/id\` - Get the current chat's ID.
|
||
- \`/ud \[term\]\` - Get a definition from Urban Dictionary.
|
||
- \`/konata\` - Get one of my selfies :3
|
||
- \`/konachan \[query\]\` - Get a picture from Konachan.
|
||
- \`/4c \[board\]\` - Get a random image from 4chan.
|
||
- \`/lfy \[query\]\` - Let me look that up for you...
|
||
- \`/ip \[address\]\` - Get information for an IP address.
|
||
- \`/repo\` - Get my source code.
|
||
|
||
And a lot more to come!"
|
||
}
|
||
|
||
alive(){
|
||
sendmsg "Alive and well!"
|
||
}
|
||
|
||
cv(){
|
||
args
|
||
stats=$(curl -s "https://corona.lmao.ninja/v2/countries/${args[*]}")
|
||
mapfile -t cv <<< $(jq -cr '.[]' <<< $stats)
|
||
if [ "${cv[4]}" == "0" ]
|
||
then
|
||
updated="Perhaps the stats are not updated yet?"
|
||
fi
|
||
if [ ! -z ${cv[1]} ]
|
||
then
|
||
pct(){ bc <<< "scale = 2; $1 * $2 / $3"; }
|
||
mil(){ bc <<< "scale = 3; $1 / 1000000"; }
|
||
kil(){ bc <<< "scale = 2; $1 / 1000"; }
|
||
sendmsg "*Today's COVID-19 stats for ${cv[1]}:*
|
||
*Cases:* ${cv[4]}
|
||
*Active:* $(kil ${cv[9]})k
|
||
*Deaths:* ${cv[6]}
|
||
\($(kil ${cv[5]})k t, $(pct 100 ${cv[5]} ${cv[3]})% c, $(pct 100 ${cv[5]} ${cv[15]})% p\)
|
||
*Total:* $(kil ${cv[3]})k \($(pct 1 ${cv[11]} 10000)%\)
|
||
*Tests:* $(mil ${cv[13]})M \($(pct 1 ${cv[14]} 10000)%\)
|
||
*Population:* $(mil ${cv[15]})M
|
||
|
||
Queried at $(date +'%Y-%m-%d %H:%M %Z').
|
||
Stay safe and get yourself vaccinated!
|
||
$updated"
|
||
else
|
||
sendmsg "This country doesn't have any stats!"
|
||
fi
|
||
}
|
||
|
||
id(){
|
||
sendmsg "Chat ID: $chat"
|
||
}
|
||
|
||
ud(){
|
||
args
|
||
enc=$(echo "${args[*]}" | sed "s/\ /%20/g")
|
||
res=$(curl -s "https://api.urbandictionary.com/v0/define?term=$enc")
|
||
if jq -re '.list[0].definition' <<< $res
|
||
then
|
||
def=$(jq -r '.list[0].definition' <<< $res | sed "s/[][]//g")
|
||
sam=$(jq -r '.list[0].example' <<< $res | sed "s/[][]//g")
|
||
sendmsg "*Definition for __${args[*]}__:*
|
||
$(escape "()" "$def")
|
||
|
||
*Example:*
|
||
$(escape "()" "$sam")"
|
||
else
|
||
sendmsg "No definition found for ${args[*]}."
|
||
fi
|
||
}
|
||
|
||
konata(){
|
||
args="izumi_konata"
|
||
konachan
|
||
}
|
||
|
||
konachan(){
|
||
args
|
||
query=$(sed "s/\ /_/g" <<< ${args[*]})
|
||
data=$(curl -s "https://konachan.net/post.json?limit=1&page=1&tags=order:random%20$query")
|
||
jpeg=$(jq -r '.[0].jpeg_url' <<< $data)
|
||
file=$(jq -r '.[0].file_url' <<< $data)
|
||
sfw=$(jq -r '.[0].rating' <<< $data)
|
||
if [ $sfw == "s" ]
|
||
then
|
||
sendpic "$jpeg" "[sauce]($file)"
|
||
elif [ $sfw == "q" ] || [ $sfw == "x" ]
|
||
then
|
||
sendmsg "This picture appears to be NSFW! Here's the [sauce]($file)."
|
||
else
|
||
sendmsg "No data!"
|
||
fi
|
||
}
|
||
|
||
4c(){
|
||
args
|
||
tmp="/tmp/4chan"
|
||
json="$tmp/${args[0]}.json"
|
||
[ ! -d $tmp ] && mkdir $tmp
|
||
[ $(find $json -mmin +60) ] && rm $json
|
||
[ ! -f $json ] && wget -O $json https://a.4cdn.org/${args[0]}/threads.json
|
||
thread=$(jq -r '.[].threads[].no' < $json | shuf | head -n1)
|
||
img=$(curl -s https://a.4cdn.org/${args[0]}/thread/$thread.json | jq -r '.posts[].tim' | shuf | head -n1)
|
||
url="https://i.4cdn.org/${args[0]}/$img"
|
||
# TODO: Try to determine from JSON output whether image is PNG or JPG.
|
||
sendpic "$url.jpg"
|
||
sendpic "$url.png"
|
||
}
|
||
|
||
lfy(){
|
||
args
|
||
query=$(sed "s/\ /+/g" <<< ${args[*]})
|
||
sendmsg "[Let me look that up for you](https://lmgtfy.app/?s=d&iee=1&q=$query)"
|
||
}
|
||
|
||
ip(){
|
||
args
|
||
ip=${args[0]}
|
||
res=$(curl -s http://ip-api.com/json/$ip)
|
||
# See https://0x0.st/Nlc0 for reference.
|
||
mapfile -t data <<< $(jq -cr '.[]' <<< $res)
|
||
sendmsg "*IP information for $ip:*
|
||
*Country:* ${data[1]}
|
||
*Region:* ${data[4]}
|
||
*City:* ${data[6]} ${data[5]}
|
||
*ISP:* ${data[10]}
|
||
*ASN:* ${data[12]}
|
||
*Time:* $(TZ=${data[9]} date +'%H:%M %Z')"
|
||
}
|
||
|
||
repo(){
|
||
sendmsg "You can find my source code [here](https://git.ghnou.su/ghnou/konata)."
|
||
}
|
||
|
||
# Administrative
|
||
mp3(){
|
||
admin
|
||
args
|
||
tmp="/tmp/mp3"
|
||
[ ! -d $tmp ] && mkdir $tmp
|
||
sendmsg "Downloading, this might take a while..."
|
||
youtube-dl -f 140 --max-filesize 50M -o "$tmp/%(title)s.%(ext)s" "${args[*]}"
|
||
rm $tmp/*.part
|
||
if [ -f $tmp/* ]
|
||
then
|
||
sendfile "$tmp/$(ls $tmp)"
|
||
rm $tmp/*
|
||
else
|
||
sendmsg "I couldn't download this file. Perhaps it's too large?"
|
||
fi
|
||
}
|
||
|
||
sys(){
|
||
admin
|
||
mtot=$(grep MemTotal /proc/meminfo | awk '{print $2}')
|
||
mavl=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
|
||
mem=$(bc <<< "scale=1; ($mtot-$mavl) / 1024")
|
||
ups=$(cut -d. -f1 < /proc/uptime)
|
||
upd=$(bc <<< "$ups / 60 / 60 / 24")
|
||
disk=$(df -h / | tail -n1 | awk '{print $3}')
|
||
kernel=$(uname -r)
|
||
load=$(cut -d' ' -f1,2,3 < /proc/loadavg)
|
||
sendmsg "*System usage stats:*
|
||
*Memory:* ${mem}M
|
||
*Disk:* ${disk}
|
||
*Kernel:* ${kernel}
|
||
*Uptime:* ${upd}d
|
||
*Load:* ${load}"
|
||
}
|
||
|
||
neo(){
|
||
admin
|
||
sendmsg "\`$(neofetch --stdout)\`"
|
||
}
|
||
|
||
sh(){
|
||
admin
|
||
sendmsg "\`$(whoami)@${HOSTNAME}:${PWD}$\` \`${args[*]}\`
|
||
\`$(echo ${args[*]} | bash - 2>&1)\`"
|
||
}
|
||
|
||
# Notes and such
|
||
anyone(){
|
||
sendmsg "Quite possibly. [Why do you ask?](https://dontasktoask.com)"
|
||
}
|
||
|
||
# Miscellaneous
|
||
tag(){
|
||
sendmsg "Please stand by, he'll get to your message soon™️..."
|
||
chid=$(jq -r '.message.chat.id' <<< $input | sed 's/-100//')
|
||
msgid=$(jq -r '.message.message_id' <<< $input)
|
||
uname=$(jq -r '.message.from.username' <<< $input)
|
||
uid=$(jq -r '.message.from.id' <<< $input)
|
||
text=$(jq -r '.message.text' <<< $input)
|
||
sendlog "*You've been tagged.*
|
||
*User:* [$uname](tg://user?id=$uid)
|
||
*Link:* [here](https://t.me/c/$chid/$msgid)
|
||
*Message contents:*
|
||
$(escape "()" "$text")"
|
||
}
|
||
hiya(){
|
||
sendmsg "Hiya! :3"
|
||
}
|
||
|
||
# Match incoming messages
|
||
case "$cmd" in
|
||
# Public commands
|
||
/help@$bot) help ;;
|
||
/start@$bot) help ;;
|
||
/alive@$bot) alive ;;
|
||
/cv@$bot*) cv ;;
|
||
/id@$bot) id ;;
|
||
/ud@$bot*) ud ;;
|
||
/konata@$bot) konata ;;
|
||
/konachan@$bot*) konachan ;;
|
||
/4c@$bot*) 4c ;;
|
||
/lfy@$bot*) lfy ;;
|
||
/ip@$bot*) ip ;;
|
||
/repo@$bot) repo ;;
|
||
# Administrative
|
||
/mp3@$bot*) mp3 ;;
|
||
/sys@$bot) sys ;;
|
||
/neo@$bot) neo ;;
|
||
/sh@$bot*) sh ;;
|
||
# Notes and such
|
||
!anyone*) anyone ;;
|
||
esac
|
||
|
||
case "$msg" in
|
||
# Miscellaneous
|
||
*@ghnou*) tag ;;
|
||
*Konata*) hiya ;;
|
||
esac
|