#!/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) msg=$(sed "s/_/\ /g" <<< $msg) cmd=$(cut -d" " -f1 <<< $msg) args=($(cut -d" " -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" -d "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" } # 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 - /4c \[board\] - Get a random image from 4chan. - /repo - Get my source code. Admin only commands: - /mp3 \[link\] - Download an mp3 file from YouTube. - /stat - Uptime, memory, storage stats. - /term - Execute a command on the system. And a lot more to come!" } alive(){ sendmsg "Alive and well!" } cv(){ stats=$(curl -s "https://corona.lmao.ninja/v2/countries/${args[*]}") country=$(jq -r '.country' <<< $stats) cases=$(jq -r '.todayCases' <<< $stats) pm=$(jq -r '.testsPerOneMillion' <<< $stats) pct=$(echo "scale = 2; $pm / 10000" | bc) if jq -re '.country' <<< $stats then sendmsg "Today's COVID-19 cases for $country: $cases \($pct% of the population tested\). Stay safe!" else sendmsg "This country doesn't have any stats!" fi } id(){ sendmsg "Chat ID: $chat" } ud(){ 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(){ data=$(curl -s "https://konachan.net/post.json?limit=1&page=1&tags=order:random%20izumi_konata") 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)" else sendmsg "This picture appears to be NSFW! Here's the [sauce]($file)." fi } 4c(){ 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 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" } repo(){ sendmsg "You can find my source code [here](https://git.ghnou.su/ghnou/konata)." } # Administrative mp3(){ admin 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 } stat(){ admin total=$(grep MemTotal /proc/meminfo | awk '{print $2}') avail=$(grep MemAvailable /proc/meminfo | awk '{print $2}') used=$(bc <<< "$total-$avail") sendmsg "$(uptime | cut -c2-) I am using ${used}K of memory and \ $(df -h / | tail -n1 | awk '{print $3}') of storage." } term(){ admin sendmsg "\`$(whoami)@${HOSTNAME}:${PWD}$\` \`${args[*]}\` \`$(echo ${args[*]} | bash - 2>&1)\`" } fail(){ debug "User @$user tried to execute $cmd and was rejected." sendmsg "Sorry, you are not allowed to use this command!" exit 1 } admin(){ case $user in ghnou) true ;; *) fail ;; esac debug "Admin @$user tried to execute $cmd and was approved." } # 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™️..." sendlog "You've been tagged: $msg" } # 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 ;; /4c@$bot*) 4c ;; /repo@$bot) repo ;; # Administrative /mp3@$bot*) mp3 ;; /stat@$bot) stat ;; /term@$bot*) term ;; # Notes and such !anyone*) anyone ;; esac case "$msg" in # Miscellaneous *@ghnou*) tag ;; esac