#!/bin/bash # Initialize basic variables . /etc/konata.conf printf "Content-Type: text/plain\n\n" # 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) uid=$(jq -r '.message.from.id' <<< $input) # Debugging commands debug(){ local date=$(date '+%Y-%m-%d %H:%M:%S') local log="/var/log/lighttpd/konata.log" local fun=$1; shift local args=$* if [ ! -z $debug ] then case $fun in acl) printf "[ACL] $date $uid $args\n" >> $log ;; rpl) printf "[RPL] $date $uid REPLY\n" >> $log ;; esac fi } # ACL on users if [ -f /etc/konata/acl.json ] then readarray -t admins <<< $(jq -r '.admins[]' < /etc/konata/acl.json) readarray -t banned <<< $(jq -r '.banned[]' < /etc/konata/acl.json) contains(){ local n=$# local value=${!n} for ((i=1; i<$#; i++ )) { if [ "${!i}" == "${value}" ] then echo "y" return 0 fi } echo "n" return 1 } if [ $(contains "${banned[@]}" "$uid") == "y" ] then debug acl "REJECT: $msg" exit 1 else debug acl "ACCEPT: $msg" fi fi # 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(){ fmt=$(sed 's/\t//g' <<< $1) curl -sX POST "https://api.telegram.org/bot$token/sendMessage" \ -d "chat_id=$chat" -d "parse_mode=html" \ -d "disable_web_page_preview=true" \ --data-urlencode "text=$fmt" debug rpl } sendlog(){ chat=$logchat sendmsg "$1" } sendfile(){ curl -sF document=@"$1" "https://api.telegram.org/bot$token/sendDocument?chat_id=$chat" debug rpl } sendpic(){ curl -sX POST "https://api.telegram.org/bot$token/sendPhoto" \ -d "chat_id=$chat" -d "parse_mode=html" \ -d "photo=$1" -d "caption=$2" debug rpl } # 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(){ if [ $(contains "${admins[@]}" "$uid") == "y" ] then debug acl "ADMIN: $msg" else fail fi } fail(){ debug acl "REJECT (ADMIN): $msg" sendmsg "Sorry, you are not allowed to use this command!" exit 1 } # Public commands help(){ if [ $(jq -r '.message.chat.type' <<< $input) == "private" ] then sendmsg "Hiya! I'm vimicito'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. - /wttr [city] - Get the weather for a city. - /repo - Get my source code. And a lot more to come!" else sendmsg "Please ask me in private!" fi } alive(){ sendmsg "Alive and well!" } id(){ uid=$(jq -r '.message.from.id' <<< $input) sendmsg "User ID: $uid 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[*]}: $def Example: $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" elif [ $sfw == "q" ] || [ $sfw == "x" ] then sendmsg "This picture appears to be NSFW! Here's the sauce." else sendmsg "No data!" fi } 4c(){ args tmp="/tmp/4chan" threads="$tmp/${args[0]}.json" [ ! -d $tmp ] && mkdir $tmp [ $(find $threads -mmin +60) ] && rm $threads [ ! -f $threads ] && wget -O $threads https://a.4cdn.org/${args[0]}/threads.json thread=$(jq -r '.[].threads[].no' < $threads | shuf | head -n1) posts=$(curl -s https://a.4cdn.org/${args[0]}/thread/$thread.json) imgs=$(jq -r ".posts[] | select(.ext==\".jpg\"), select(.ext==\".png\")" <<< $posts) no=$(jq -r ".no" <<< $imgs | shuf | head -n1) img=$(jq -r "select(.no==$no) | .tim" <<< $imgs) ext=$(jq -r "select(.no==$no) | .ext" <<< $imgs) url="https://i.4cdn.org/${args[0]}/${img}${ext}" sendpic "$url" "sauce" } lfy(){ args query=$(sed "s/\ /+/g" <<< ${args[*]}) sendmsg "Let me look that up for you... ${args[*]}" } 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')" } wttr(){ args res=$(curl wttr.in/${args[0]}?format=3) sendmsg "$res" } repo(){ sendmsg "You can find my source code here." } # 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)@$(cat /etc/hostname) [${PWD}] $ ${args[*]} $(echo ${args[*]} | bash - 2>&1)" } dump(){ admin out=/tmp/$RANDOM.json jq <<< "$input" > $out sendmsg "Event saved to $out. Retrieve using /sh_cat_$out. Remove using /sh_rm_-v_$out." } # Notes and such anyone(){ sendmsg "Quite possibly. Why do you ask?" } # Miscellaneous tag(){ if [ $(jq -r '.message.chat.type' <<< $input) != "private" ] then chid=$(jq -r '.message.chat.id' <<< $input | sed 's/-100//') msgid=$(jq -r '.message.message_id' <<< $input) name=$(jq -r '.message.from.first_name' <<< $input) uid=$(jq -r '.message.from.id' <<< $input) text=$(jq -r '.message.text' <<< $input) sendlog "You've been tagged. User: $name Link: here Message contents: $text" fi } say(){ args res=$(echo ${args[*]} | cut -d' ' -f2-) sendmsg "$res" } hack(){ # Congrats retards, you've finally done it case "$msg" in *Facebook* | *facebook* | *fb* | \ *Instagram* | *instagram* | *insta* | \ *WhatsApp* | *whatsapp* | *whatapp* | \ *Telegram* | *telegram* | *tele* | \ *Gmail* | *gmail* | \ *girlfriend* | *gf* ) sendmsg "Stop asking stupid questions!" ;; esac } # Match incoming messages case "$cmd" in # Public commands /help@$bot) help ;; /start@$bot) help ;; /alive@$bot) alive ;; /id@$bot) id ;; /ud@$bot*) ud ;; /konata@$bot) konata ;; /konachan@$bot*) konachan ;; /4c@$bot*) 4c ;; /lfy@$bot*) lfy ;; /ip@$bot*) ip ;; /wttr@$bot*) wttr ;; /repo@$bot) repo ;; # Administrative /mp3@$bot*) mp3 ;; /sys@$bot) sys ;; /neo@$bot) neo ;; /sh@$bot*) sh ;; /dump@$bot*) dump ;; # Notes and such !anyone*) anyone ;; esac case "$msg" in # Miscellaneous *@vimicito*) tag ;; Konata\ say*) say ;; *hack*) hack ;; esac