bashbot-lib/bashbot-lib.sh

149 lines
5.2 KiB
Bash
Executable File

#!/bin/bash
# this is just a library
# you will need to provide the following in the implementation:
# 1. the api url with it's corresponding token as
# api_url="api.telegram.org/bot[insert your api token]/"
# pay attention to the trailing forward slash
# 2. the bot id as
# bot_id="[insert your bot_id]"
# 3. the following files to read and write from
# updates.txt
# sentmessages.txt
# callbacks.txt
# pay attention to the trailing forward slash
# 4. (optional) a directory for the bot's files as
# bot_tmpdir="/some/path/"
# pay attention to the trailing forward slash
# IMPORTANT: this library is not asynchronous, only one message
# is read at a time and is done so in order
# IMPORTANT: this library uses the getUpdates method with
# tcp_keepalive,NOT webhooks
calc_offset() {
local current="$(bc -l <<< "$(tail -n 1 "${bot_tmpdir}updates.txt" | \
grep -om1 "\"update_id\":[0-9]\+" | \
grep -om1 "[0-9]\+") + 1" 2>/dev/null)"
[ ! -z "${current}" ] && printf "%d" "${current}"
}
getupd() {
local offset="$(calc_offset)"
local update="$(curl -sX GET --keepalive-time 300 "${api_url}getUpdates" -d "offset=${offset}" \
-d "limit=1" -d "timeout=300"\
| sed 's/{"ok":true,"result":\[\]}\|^{"ok":false.*\|^{"ok":true,"result":\[{\?//g;:a;N;$!ba;s/\n//g;s/}\]}$//g;')"
printf "%s" ${update}
[ ! -z "${update}" ] && printf "%s\n" "${update}" >> "${bot_tmpdir}updates.txt"
}
getmsg_id() {
tail -n1 "${bot_tmpdir}${1}" | grep -om1\
"\"message\":{\"message_id\":[0-9]\+\|^\"message_id\":[0-9]\+" | grep -om1 "[0-9]\+"
}
getusr_id() {
tail -n1 "${bot_tmpdir}${1}" | grep -om1\
"\"from\":{\"id\":[0-9]\+" | grep -om1 "[0-9]\+"
}
getchat_id() {
tail -n1 "${bot_tmpdir}${1}" | grep -om1\
"\"chat\":{\"id\":-\?[0-9]\+" | grep -om1 "\-\?[0-9]\+"
}
utf-16-surrogate-pair-decode() {
# shamelessly stolen from stackoverflow
local out="$1"
local remain=""
local regexp='(.*)\\u[dD]([0-9a-fA-F]{3})\\u[dD]([0-9a-fA-F]{3})(.*)'
while [[ "${out}" =~ $regexp ]] ; do
# match 2 \udxxx hex values, calculate new U, then split and replace
local W1="$(( ( 0xd${BASH_REMATCH[2]} & 0x3ff) <<10 ))"
local W2="$(( 0xd${BASH_REMATCH[3]} & 0x3ff ))"
U="$(( ( W1 | W2 ) + 0x10000 ))"
remain="$(printf '\\U%8.8x' "${U}")${BASH_REMATCH[4]}${remain}"
out="${BASH_REMATCH[1]}"
done
echo -e "${out}${remain}"
}
gettext() {
local text="$(tail -n 1 "${bot_tmpdir}${1}" | grep -om1\
'{\?\("text"\|"caption"\):"\(\\"\|[^"]*\)*"\(,\|}\)' | grep -v "^{" | tail -n1)"
grep "^\"text\"" <<< "${text}" >/dev/null && utf-16-surrogate-pair-decode "${text:8:-2}"\
|| {
grep "^\"caption\"" <<< "${text}" >/dev/null && utf-16-surrogate-pair-decode "${text:11:-2}"
}
}
getusr_name(){
local user_name="$(tail -n 1 "${bot_tmpdir}${1}" | grep -om1\
'"first_name":"\(\\"\|[^"]*\)*",\("username"\|"language_code"\)' | head -n1)"
grep "\"username\"$" <<< "${user_name}" >/dev/null && utf-16-surrogate-pair-decode "${user_name:14:-12}"\
|| {
grep "\"language_code\"$" <<< "${user_name}" >/dev/null && utf-16-surrogate-pair-decode "${user_name:14:-17}"
}
}
getusrname(){
local username="$(tail -n 1 "${bot_tmpdir}${1}" | grep -om1\
'"username":"\(\\"\|[^"]*\)*"\(,"language_code"\|},"chat"\)' | head -n1)"
grep "\"language_code\"$" <<< "${username}" >/dev/null && utf-16-surrogate-pair-decode "${username:12:-17}"\
|| {
grep "},\"chat\"$" <<< "${username}" >/dev/null && utf-16-surrogate-pair-decode "${username:12:-9}"
}
}
getchat_title(){
local chat_title="$(tail -n 1 "${bot_tmpdir}${1}" | grep -om1\
'"title":"\(\\"\|[^"]*\)*","type":"group"' | head -n1)"
[ ! -z "${chat_title}" ] && utf-16-surrogate-pair-decode "${chat_title:9:-16}"\
|| getusr_name "${1}"
}
getcbk_data() {
local callbacks="$(tail -n 1 "${bot_tmpdir}${1}"\
| grep "\"callback_query\"" | grep -om1 '"data":"\(\\"\|[^"]*\)*"}')"
[ ! -z "${callbacks}" ] && utf-16-surrogate-pair-decode "${callbacks:8:-2}"
}
sendmsg() {
sentmsg="$(curl -sX GET "${api_url}sendMessage" -d "chat_id=${1}" \
-d "text=${2}" \
-d 'reply_markup={"inline_keyboard":[[{"text":"check again","callback_data":"recheck"}]]}')" \
&& [ ! -z "${sentmsg}" ] && printf "%s\n" "${sentmsg}"\
| sed 's/^{"ok":false.*\|^{"ok":true,"result":{\|}$//g'\
>> "${bot_tmpdir}sentmsgs.txt"
}
replymsg() {
sentmsg="$(curl -sX GET "${api_url}sendMessage" -d "chat_id=${curmsg[chat_id]}" -d "reply_to_message_id=${curmsg[message_id]}" \
-d "text=${curmsg[text]}" \
&& [ ! -z "${sentmsg}" ] && printf "%s\n" "${sentmsg}"\
| sed 's/^{"ok":false.*\|^{"ok":true,"result":{\|}$//g'\
>> "${bot_tmpdir}sentmsgs.txt"
}
# TODO
#editmsg() {
# curl -sX GET "${api_url}editMessageText" -d "chat_id=${1}" -d "message_id=${2}" \
# -d "text=${3}"
#}
#
#delmsg() {
# curl -sX GET "${api_url}deleteMessage" -d "chat_id=${1}"\
# -d "message_id=${2}"
#}
getmsg_content(){
local -n _REF="${1}"
_REF[user_id]="$(getusr_id "${2}")"
_REF[user_name]="$(getusr_name "${2}")"
_REF[username]="$(getusrname "${2}")"
_REF[chat_id]="$(getchat_id "${2}")"
_REF[chat_title]="$(getchat_title "${2}")"
_REF[msg_id]="$(getmsg_id "${2}")"
_REF[text]="$(gettext "${2}")"
_REF[callback]="$(getcbk_data "${2}")"
}