mirror of
https://github.com/octoleo/telegram-bot-bash.git
synced 2024-12-27 04:32:49 +00:00
modules: factor out processUpdates.sh
This commit is contained in:
parent
7c748247d8
commit
c693ab5bb9
456
bashbot.sh
456
bashbot.sh
@ -30,7 +30,7 @@ BOTCOMMANDS="-h help init start stop status suspendback resumeback killb
|
||||
# 8 - curl/wget missing
|
||||
# 10 - not bash!
|
||||
#
|
||||
#### $$VERSION$$ v1.35-dev-31-ga3eec98
|
||||
#### $$VERSION$$ v1.40-dev-3-g7c74824
|
||||
##################################################################
|
||||
|
||||
# emmbeded system may claim bash but it is not
|
||||
@ -467,6 +467,7 @@ sendJson(){
|
||||
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "${@}" &
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# curl / wget specific functions
|
||||
#
|
||||
@ -662,77 +663,8 @@ JsonDecode() {
|
||||
}
|
||||
|
||||
|
||||
################
|
||||
# processing of updates starts here
|
||||
process_updates() {
|
||||
local max num debug="$1"
|
||||
max="$(grep -F ',"update_id"]' <<< "${UPDATE}" | tail -1 | cut -d , -f 2 )"
|
||||
Json2Array 'UPD' <<<"${UPDATE}"
|
||||
for ((num=0; num<=max; num++)); do
|
||||
process_client "${num}" "${debug}"
|
||||
done
|
||||
}
|
||||
|
||||
process_client() {
|
||||
local num="$1" debug="$2"
|
||||
pre_process_message "${num}"
|
||||
# log message on debug
|
||||
[[ -n "${debug}" ]] && log_message "New Message ==========\n$(grep -F '["result",'"${num}" <<<"${UPDATE}")"
|
||||
|
||||
# check for users / groups to ignore
|
||||
jssh_updateArray_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
|
||||
[ -n "${USER[ID]}" ] && [[ -n "${BASHBOTBLOCKED[${USER[ID]}]}" || -n "${BASHBOTBLOCKED[${CHAT[ID]}]}" ]] && return
|
||||
|
||||
# process per message type
|
||||
if [ -n "${iQUERY[ID]}" ]; then
|
||||
process_inline_query "${num}" "${debug}"
|
||||
printf "%(%c)T: Inline Query update received FROM=%s iQUERY=%s\n" -1\
|
||||
"${iQUERY[USERNAME]:0:20} (${iQUERY[USER_ID]})" "${iQUERY[0]}" >>"${UPDATELOG}"
|
||||
elif [ -n "${iBUTTON[ID]}" ]; then
|
||||
process_inline_button "${num}" "${debug}"
|
||||
printf "%(%c)T: Inline Button update received FROM=%s CHAT=%s CALLBACK=%s DATA:%s \n" -1\
|
||||
"${iBUTTON[USERNAME]:0:20} (${iBUTTON[USER_ID]})" "${iBUTTON[CHAT_ID]}" "${iBUTTON[ID]}" "${iBUTTON[DATA]}" >>"${UPDATELOG}"
|
||||
else
|
||||
if grep -qs -e '\["result",'"${num}"',"edited_message"' <<<"${UPDATE}"; then
|
||||
# edited message
|
||||
UPDATE="${UPDATE//,${num},\"edited_message\",/,${num},\"message\",}"
|
||||
Json2Array 'UPD' <<<"${UPDATE}"
|
||||
MESSAGE[0]="/_edited_message "
|
||||
fi
|
||||
process_message "${num}" "${debug}"
|
||||
printf "%(%c)T: update received FROM=%s CHAT=%s CMD=%s\n" -1 "${USER[USERNAME]:0:20} (${USER[ID]})"\
|
||||
"${CHAT[USERNAME]:0:20}${CHAT[TITLE]:0:30} (${CHAT[ID]})"\
|
||||
"${MESSAGE:0:30}${CAPTION:0:30}${URLS[*]:0:30}" >>"${UPDATELOG}"
|
||||
fi
|
||||
#####
|
||||
# process inline and message events
|
||||
# first classic command dispatcher
|
||||
# shellcheck source=./commands.sh
|
||||
{ source "${COMMANDS}" "${debug}"; } &
|
||||
|
||||
# then all registered addons
|
||||
if [ -z "${iQUERY[ID]}" ]; then
|
||||
event_message "${debug}"
|
||||
else
|
||||
event_inline "${debug}"
|
||||
fi
|
||||
|
||||
# last count users
|
||||
jssh_countKeyDB_async "${CHAT[ID]}" "${COUNTFILE}"
|
||||
}
|
||||
|
||||
declare -Ax BASHBOT_EVENT_INLINE BASHBOT_EVENT_MESSAGE BASHBOT_EVENT_CMD BASHBOT_EVENT_REPLYTO BASHBOT_EVENT_FORWARD BASHBOT_EVENT_SEND
|
||||
declare -Ax BASHBOT_EVENT_CONTACT BASHBOT_EVENT_LOCATION BASHBOT_EVENT_FILE BASHBOT_EVENT_TEXT BASHBOT_EVENT_TIMER BASHBOT_BLOCKED
|
||||
|
||||
start_timer(){
|
||||
# send alarm every ~60 s
|
||||
while :; do
|
||||
sleep 59.5
|
||||
kill -ALRM $$
|
||||
done;
|
||||
}
|
||||
|
||||
EVENT_SEND="0"
|
||||
declare -Ax BASHBOT_EVENT_SEND
|
||||
event_send() {
|
||||
# max recursion level 5 to avoid fork bombs
|
||||
(( EVENT_SEND++ )); [ "${EVENT_SEND}" -gt "5" ] && return
|
||||
@ -743,364 +675,6 @@ event_send() {
|
||||
done
|
||||
}
|
||||
|
||||
EVENT_TIMER="0"
|
||||
event_timer() {
|
||||
local key timer debug="$1"
|
||||
(( EVENT_TIMER++ ))
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_TIMER[@]}"
|
||||
do
|
||||
timer="${key##*,}"
|
||||
[[ ! "${timer}" =~ ^-*[1-9][0-9]*$ ]] && continue
|
||||
if [ "$(( EVENT_TIMER % timer ))" = "0" ]; then
|
||||
_exec_if_function "${BASHBOT_EVENT_TIMER[${key}]}" "timer" "${key}" "${debug}"
|
||||
[ "$(( EVENT_TIMER % timer ))" -lt "0" ] && \
|
||||
unset BASHBOT_EVENT_TIMER["${key}"]
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
event_inline() {
|
||||
local key debug="$1"
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_INLINE[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_INLINE[${key}]}" "inline" "${key}" "${debug}"
|
||||
done
|
||||
}
|
||||
event_message() {
|
||||
local key debug="$1"
|
||||
# ${MESSAEG[*]} event_message
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_MESSAGE[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_MESSAGE[${key}]}" "message" "${key}" "${debug}"
|
||||
done
|
||||
|
||||
# ${TEXT[*]} event_text
|
||||
if [ -n "${MESSAGE[0]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_TEXT[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_TEXT[${key}]}" "text" "${key}" "${debug}"
|
||||
done
|
||||
|
||||
# ${CMD[*]} event_cmd
|
||||
if [ -n "${CMD[0]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_CMD[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_CMD[${key}]}" "command" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
# ${REPLYTO[*]} event_replyto
|
||||
if [ -n "${REPLYTO[UID]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_REPLYTO[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_REPLYTO[${key}]}" "replyto" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${FORWARD[*]} event_forward
|
||||
if [ -n "${FORWARD[UID]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_FORWARD[@]}"
|
||||
do
|
||||
_exec_if_function && "${BASHBOT_EVENT_FORWARD[${key}]}" "forward" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${CONTACT[*]} event_contact
|
||||
if [ -n "${CONTACT[FIRST_NAME]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_CONTACT[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_CONTACT[${key}]}" "contact" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${VENUE[*]} event_location
|
||||
# ${LOCATION[*]} event_location
|
||||
if [ -n "${LOCATION[LONGITUDE]}" ] || [ -n "${VENUE[TITLE]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_LOCATION[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_LOCATION[${key}]}" "location" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${URLS[*]} event_file
|
||||
# NOTE: compare again #URLS -1 blanks!
|
||||
if [[ "${URLS[*]}" != " " ]]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_FILE[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_FILE[${key}]}" "file" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
}
|
||||
pre_process_message(){
|
||||
local num="$1"
|
||||
# unset everything to not have old values
|
||||
CMD=( ); iQUERY=( ); iBUTTON=(); MESSAGE=(); CHAT=(); USER=(); CONTACT=(); LOCATION=(); unset CAPTION
|
||||
REPLYTO=( ); FORWARD=( ); URLS=(); VENUE=( ); SERVICE=( ); NEWMEMBER=( ); LEFTMEMBER=( ); PINNED=( ); MIGRATE=( )
|
||||
iQUERY[ID]="${UPD["result,${num},inline_query,id"]}"
|
||||
iBUTTON[ID]="${UPD["result,${num},callback_query,id"]}"
|
||||
CHAT[ID]="${UPD["result,${num},message,chat,id"]}"
|
||||
USER[ID]="${UPD["result,${num},message,from,id"]}"
|
||||
[ -z "${CHAT[ID]}" ] && CHAT[ID]="${UPD["result,${num},edited_message,chat,id"]}"
|
||||
[ -z "${USER[ID]}" ] && USER[ID]="${UPD["result,${num},edited_message,from,id"]}"
|
||||
# always true
|
||||
return 0
|
||||
}
|
||||
process_inline_query() {
|
||||
local num="$1"
|
||||
iQUERY[0]="$(JsonDecode "${UPD["result,${num},inline_query,query"]}")"
|
||||
iQUERY[USER_ID]="${UPD["result,${num},inline_query,from,id"]}"
|
||||
iQUERY[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},inline_query,from,first_name"]}")"
|
||||
iQUERY[LAST_NAME]="$(JsonDecode "${UPD["result,${num},inline_query,from,last_name"]}")"
|
||||
iQUERY[USERNAME]="$(JsonDecode "${UPD["result,${num},inline_query,from,username"]}")"
|
||||
# always true
|
||||
return 0
|
||||
}
|
||||
process_inline_button() {
|
||||
# debugging for impelemetation
|
||||
local num="$1"
|
||||
iBUTTON[DATA]="${UPD["result,${num},callback_query,data"]}"
|
||||
iBUTTON[CHAT_ID]="${UPD["result,${num},callback_query,message,chat,id"]}"
|
||||
iBUTTON[MESSAGE_ID]="${UPD["result,${num},callback_query,message,message_id"]}"
|
||||
iBUTTON[MESSAGE]="$(JsonDecode "${UPD["result,${num},callback_query,message,text"]}")"
|
||||
# XXX should we give back pressed button, all buttons or nothing?
|
||||
iBUTTON[USER_ID]="${UPD["result,${num},callback_query,from,id"]}"
|
||||
iBUTTON[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},callback_query,from,first_name"]}")"
|
||||
iBUTTON[LAST_NAME]="$(JsonDecode "${UPD["result,${num},callback_query,from,last_name"]}")"
|
||||
iBUTTON[USERNAME]="$(JsonDecode "${UPD["result,${num},callback_query,from,username"]}")"
|
||||
# always true
|
||||
return 0
|
||||
}
|
||||
process_message() {
|
||||
local num="$1"
|
||||
# Message
|
||||
MESSAGE[0]+="$(JsonDecode "${UPD["result,${num},message,text"]}" | sed 's|\\/|/|g')"
|
||||
MESSAGE[ID]="${UPD["result,${num},message,message_id"]}"
|
||||
|
||||
# Chat ID is now parsed when update is received
|
||||
CHAT[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,last_name"]}")"
|
||||
CHAT[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,first_name"]}")"
|
||||
CHAT[USERNAME]="$(JsonDecode "${UPD["result,${num},message,chat,username"]}")"
|
||||
# set real name as username if empty
|
||||
[ -z "${CHAT[USERNAME]}" ] && CHAT[USERNAME]="${CHAT[FIRST_NAME]} ${CHAT[LAST_NAME]}"
|
||||
CHAT[TITLE]="$(JsonDecode "${UPD["result,${num},message,chat,title"]}")"
|
||||
CHAT[TYPE]="$(JsonDecode "${UPD["result,${num},message,chat,type"]}")"
|
||||
CHAT[ALL_ADMIN]="${UPD["result,${num},message,chat,all_members_are_administrators"]}"
|
||||
|
||||
# user ID is now parsed when update is received
|
||||
USER[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,from,first_name"]}")"
|
||||
USER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,from,last_name"]}")"
|
||||
USER[USERNAME]="$(JsonDecode "${UPD["result,${num},message,from,username"]}")"
|
||||
# set real name as username if empty
|
||||
[ -z "${USER[USERNAME]}" ] && USER[USERNAME]="${USER[FIRST_NAME]} ${USER[LAST_NAME]}"
|
||||
|
||||
# in reply to message from
|
||||
if [ -n "${UPD["result,${num},message,reply_to_message,from,id"]}" ]; then
|
||||
REPLYTO[UID]="${UPD["result,${num},message,reply_to_message,from,id"]}"
|
||||
REPLYTO[0]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,text"]}")"
|
||||
REPLYTO[ID]="${UPD["result,${num},message,reply_to_message,message_id"]}"
|
||||
REPLYTO[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,from,first_name"]}")"
|
||||
REPLYTO[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,from,last_name"]}")"
|
||||
REPLYTO[USERNAME]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,from,username"]}")"
|
||||
fi
|
||||
|
||||
# forwarded message from
|
||||
if [ -n "${UPD["result,${num},message,forward_from,id"]}" ]; then
|
||||
FORWARD[UID]="${UPD["result,${num},message,forward_from,id"]}"
|
||||
FORWARD[ID]="${MESSAGE[ID]}" # same as message ID
|
||||
FORWARD[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,forward_from,first_name"]}")"
|
||||
FORWARD[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,forward_from,last_name"]}")"
|
||||
FORWARD[USERNAME]="$(JsonDecode "${UPD["result,${num},message,forward_from,username"]}")"
|
||||
fi
|
||||
|
||||
# get file URL from telegram, check for any of them!
|
||||
if grep -qs -e '\["result",'"${num}"',"message","[avpsd].*,"file_id"\]' <<<"${UPDATE}"; then
|
||||
URLS[AUDIO]="$(get_file "${UPD["result,${num},message,audio,file_id"]}")"
|
||||
URLS[DOCUMENT]="$(get_file "${UPD["result,${num},message,document,file_id"]}")"
|
||||
URLS[PHOTO]="$(get_file "${UPD["result,${num},message,photo,0,file_id"]}")"
|
||||
URLS[STICKER]="$(get_file "${UPD["result,${num},message,sticker,file_id"]}")"
|
||||
URLS[VIDEO]="$(get_file "${UPD["result,${num},message,video,file_id"]}")"
|
||||
URLS[VOICE]="$(get_file "${UPD["result,${num},message,voice,file_id"]}")"
|
||||
fi
|
||||
# Contact, must have phone_number
|
||||
if [ -n "${UPD["result,${num},message,contact,phone_number"]}" ]; then
|
||||
CONTACT[USER_ID]="$(JsonDecode "${UPD["result,${num},message,contact,user_id"]}")"
|
||||
CONTACT[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,contact,first_name"]}")"
|
||||
CONTACT[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,contact,last_name"]}")"
|
||||
CONTACT[NUMBER]="${UPD["result,${num},message,contact,phone_number"]}"
|
||||
CONTACT[VCARD]="${UPD["result,${num},message,contact,vcard"]}"
|
||||
fi
|
||||
|
||||
# venue, must have a position
|
||||
if [ -n "${UPD["result,${num},message,venue,location,longitude"]}" ]; then
|
||||
VENUE[TITLE]="$(JsonDecode "${UPD["result,${num},message,venue,title"]}")"
|
||||
VENUE[ADDRESS]="$(JsonDecode "${UPD["result,${num},message,venue,address"]}")"
|
||||
VENUE[LONGITUDE]="${UPD["result,${num},message,venue,location,longitude"]}"
|
||||
VENUE[LATITUDE]="${UPD["result,${num},message,venue,location,latitude"]}"
|
||||
VENUE[FOURSQUARE]="${UPD["result,${num},message,venue,foursquare_id"]}"
|
||||
fi
|
||||
|
||||
# Caption
|
||||
CAPTION="$(JsonDecode "${UPD["result,${num},message,caption"]}")"
|
||||
|
||||
# Location
|
||||
LOCATION[LONGITUDE]="${UPD["result,${num},message,location,longitude"]}"
|
||||
LOCATION[LATITUDE]="${UPD["result,${num},message,location,latitude"]}"
|
||||
|
||||
# service messages, group or channel only!
|
||||
if [[ "${CHAT[ID]}" == "-"* ]] ; then
|
||||
# new chat member
|
||||
if [ -n "${UPD["result,${num},message,new_chat_member,id"]}" ]; then
|
||||
SERVICE[NEWMEMBER]="${UPD["result,${num},message,new_chat_member,id"]}"
|
||||
NEWMEMBER[ID]="${SERVICE[NEWMEMBER]}"
|
||||
NEWMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,first_name"]}")"
|
||||
NEWMEMBER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,last_name"]}")"
|
||||
NEWMEMBER[USERNAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,username"]}")"
|
||||
NEWMEMBER[ISBOT]="${UPD["result,${num},message,new_chat_member,is_bot"]}"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_member ${NEWMEMBER[ID]} ${NEWMEMBER[USERNAME]:=${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]}}"
|
||||
fi
|
||||
# left chat member
|
||||
if [ -n "${UPD["result,${num},message,left_chat_member,id"]}" ]; then
|
||||
SERVICE[LEFTMEMBER]="${UPD["result,${num},message,left_chat_member,id"]}"
|
||||
LEFTMEMBER[ID]="${SERVICE[LEFTMEBER]}"
|
||||
LEFTMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,first_name"]}")"
|
||||
LEFTMEMBER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,last_name"]}")"
|
||||
LEFTMEBER[USERNAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,username"]}")"
|
||||
LEFTMEMBER[ISBOT]="${UPD["result,${num},message,left_chat_member,is_bot"]}"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_left_chat_member ${LEFTMEMBER[ID]} ${LEFTMEMBER[USERNAME]:=${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]}}"
|
||||
fi
|
||||
# chat title / photo, check for any of them!
|
||||
if grep -qs -e '\["result",'"${num}"',"message","new_chat_[tp]' <<<"${UPDATE}"; then
|
||||
SERVICE[NEWTITLE]="$(JsonDecode "${UPD["result,${num},message,new_chat_title"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWTITLE]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_title ${USER[ID]} ${SERVICE[NEWTITLE]}"
|
||||
SERVICE[NEWPHOTO]="$(get_file "${UPD["result,${num},message,new_chat_photo,0,file_id"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWPHOTO]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_photo ${USER[ID]} ${SERVICE[NEWPHOTO]}"
|
||||
fi
|
||||
# pinned message
|
||||
if [ -n "${UPD["result,${num},message,pinned_message,message_id"]}" ]; then
|
||||
SERVICE[PINNED]="${UPD["result,${num},message,pinned_message,message_id"]}"
|
||||
PINNED[ID]="${SERVICE[PINNED]}"
|
||||
PINNED[MESSAGE]="$(JsonDecode "${UPD["result,${num},message,pinned_message,text"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_new_pinned_message ${USER[ID]} ${PINNED[ID]} ${PINNED[MESSAGE]}"
|
||||
fi
|
||||
# migrate to super group
|
||||
if [ -n "${UPD["result,${num},message,migrate_to_chat_id"]}" ]; then
|
||||
MIGRATE[TO]="${UPD["result,${num},message,migrate_to_chat_id"]}"
|
||||
MIGRATE[FROM]="${UPD["result,${num},message,migrate_from_chat_id"]}"
|
||||
# CHAT is already migrated, so set new chat id
|
||||
[ "${CHAT[ID]}" = "${MIGRATE[FROM]}" ] && CHAT[ID]="${MIGRATE[FROM]}"
|
||||
SERVICE[MIGRATE]="${MIGRATE[FROM]} ${MIGRATE[TO]}"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_migrate_group ${SERVICE[MIGRATE]}"
|
||||
fi
|
||||
# set SERVICE to yes if a service message was received
|
||||
[[ "${SERVICE[*]}" =~ ^[[:blank:]]*$ ]] || SERVICE[0]="yes"
|
||||
fi
|
||||
|
||||
# split message in command and args
|
||||
[[ "${MESSAGE[0]}" == "/"* ]] && read -r CMD <<<"${MESSAGE[0]}" && CMD[0]="${CMD[0]%%@*}"
|
||||
# everything went well
|
||||
return 0
|
||||
}
|
||||
|
||||
#########################
|
||||
# main get updates loop, should never terminate
|
||||
declare -A BASHBOTBLOCKED
|
||||
start_bot() {
|
||||
local DEBUGMSG OFFSET=0
|
||||
# adaptive sleep defaults
|
||||
local nextsleep="100"
|
||||
local stepsleep="${BASHBOT_SLEEP_STEP:-100}"
|
||||
local maxsleep="${BASHBOT_SLEEP:-5000}"
|
||||
# startup message
|
||||
DEBUGMSG="Start BASHBOT updates in Mode \"${1:-normal}\" =========="
|
||||
log_update "${DEBUGMSG}"
|
||||
# redirect to Debug.log
|
||||
[[ "$1" == *"debug" ]] && exec &>>"${DEBUGLOG}"
|
||||
log_debug "${DEBUGMSG}"; DEBUGMSG="$1"
|
||||
[[ "${DEBUGMSG}" == "xdebug"* ]] && set -x
|
||||
# cleaup old pipes and empty logfiles
|
||||
find "${DATADIR}" -type p -delete
|
||||
find "${DATADIR}" -size 0 -name "*.log" -delete
|
||||
# load addons on startup
|
||||
for addons in "${ADDONDIR:-.}"/*.sh ; do
|
||||
# shellcheck source=./modules/aliases.sh
|
||||
[ -r "${addons}" ] && source "${addons}" "startbot" "${DEBUGMSG}"
|
||||
done
|
||||
# shellcheck source=./commands.sh
|
||||
source "${COMMANDS}" "startbot"
|
||||
# start timer events
|
||||
if [ -n "${BASHBOT_START_TIMER}" ] ; then
|
||||
# shellcheck disable=SC2064
|
||||
trap "event_timer ${DEBUGMSG}" ALRM
|
||||
start_timer &
|
||||
# shellcheck disable=SC2064
|
||||
trap "kill -9 $!; exit" EXIT INT HUP TERM QUIT
|
||||
fi
|
||||
# cleanup countfile on startup
|
||||
jssh_deleteKeyDB "CLEAN_COUNTER_DATABASE_ON_STARTUP" "${COUNTFILE}"
|
||||
[ -f "${COUNTFILE}.jssh.flock" ] && rm -f "${COUNTFILE}.jssh.flock"
|
||||
# store start time and cleanup botconfig on startup
|
||||
jssh_updateKeyDB "startup" "$(_date)" "${BOTCONFIG}"
|
||||
[ -f "${BOTCONFIG}.jssh.flock" ] && rm -f "${BOTCONFIG}.jssh.flock"
|
||||
# read blocked users
|
||||
jssh_readDB_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
|
||||
# inform botadmin about start
|
||||
send_normal_message "$(getConfigKey "botadmin")" "Bot $(getConfigKey "botname") started ..." &
|
||||
##########
|
||||
# bot is ready, start processing updates ...
|
||||
while true; do
|
||||
# adaptive sleep in ms rounded to next 0.1 s
|
||||
sleep "$(_round_float "${nextsleep}e-3" "1")"
|
||||
# get next update
|
||||
UPDATE="$(getJson "${URL}/getUpdates?offset=${OFFSET}" 2>/dev/null | "${JSONSHFILE}" -b -n 2>/dev/null | iconv -f utf-8 -t utf-8 -c)"
|
||||
# did we get an response?
|
||||
if [ -n "${UPDATE}" ]; then
|
||||
# we got something, do processing
|
||||
[ "${OFFSET}" = "-999" ] && [ "${nextsleep}" -gt "$((maxsleep*2))" ] &&\
|
||||
log_error "Recovered from timeout/broken/no connection, continue with telegram updates"
|
||||
# escape bash $ expansion bug
|
||||
((nextsleep+= stepsleep , nextsleep= nextsleep>maxsleep ?maxsleep:nextsleep))
|
||||
UPDATE="${UPDATE//$/\\$}"
|
||||
# Offset
|
||||
OFFSET="$(grep <<< "${UPDATE}" '\["result",[0-9]*,"update_id"\]' | tail -1 | cut -f 2)"
|
||||
((OFFSET++))
|
||||
|
||||
if [ "${OFFSET}" != "1" ]; then
|
||||
nextsleep="100"
|
||||
process_updates "${DEBUGMSG}"
|
||||
fi
|
||||
else
|
||||
# oops, something bad happened, wait maxsleep*10
|
||||
(( nextsleep=nextsleep*2 , nextsleep= nextsleep>maxsleep*10 ?maxsleep*10:nextsleep ))
|
||||
# second time, report problem
|
||||
if [ "${OFFSET}" = "-999" ]; then
|
||||
log_error "Repeated timeout/broken/no connection on telegram update, sleep $(_round_float "${nextsleep}e-3")s"
|
||||
# try to recover
|
||||
if _is_function bashbotBlockRecover && [ -z "$(getJson "${ME_URL}")" ]; then
|
||||
log_error "Try to recover, calling bashbotBlockRecover ..."
|
||||
bashbotBlockRecover >>"${ERRORLOG}"
|
||||
fi
|
||||
fi
|
||||
OFFSET="-999"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# fallback version, full version is in bin/bashbot_init.in.sh
|
||||
# initialize bot environment, user and permissions
|
||||
@ -1178,9 +752,9 @@ if [ -z "${SOURCE}" ]; then
|
||||
debug_checks "end outproc" "$@"
|
||||
exit
|
||||
;;
|
||||
# finally starts the read update loop, internal use only1
|
||||
# finally starts the read update loop, internal use only
|
||||
"startbot" )
|
||||
start_bot "$2"
|
||||
_exec_if_exist start_bot "$2"
|
||||
debug_checks "end startbot" "$@"
|
||||
exit
|
||||
;;
|
||||
@ -1221,14 +795,18 @@ if [ -z "${SOURCE}" ]; then
|
||||
|
||||
# start bot as background job and check if bot is running
|
||||
"start")
|
||||
# shellcheck disable=SC2086
|
||||
SESSION="${ME:-_bot}-startbot"
|
||||
BOTPID="$(proclist "${SESSION}")"
|
||||
# shellcheck disable=SC2086
|
||||
[ -n "${BOTPID}" ] && kill ${BOTPID}
|
||||
nohup "${SCRIPT}" "startbot" "$2" "${SESSION}" &>/dev/null &
|
||||
printf "Session Name: %s\n" "${SESSION}"
|
||||
sleep 1
|
||||
if _is_function process_updates; then
|
||||
# shellcheck disable=SC2086
|
||||
SESSION="${ME:-_bot}-startbot"
|
||||
BOTPID="$(proclist "${SESSION}")"
|
||||
# shellcheck disable=SC2086
|
||||
[ -n "${BOTPID}" ] && kill ${BOTPID}
|
||||
nohup "${SCRIPT}" "startbot" "$2" "${SESSION}" &>/dev/null &
|
||||
printf "Session Name: %s\n" "${SESSION}"
|
||||
sleep 1
|
||||
else
|
||||
printf "${ORANGE}Update processing disabled, bot can only send messages.${NN}"
|
||||
fi
|
||||
if [ -n "$(proclist "${SESSION}")" ]; then
|
||||
printf "${GREEN}Bot started successfully.${NN}"
|
||||
else
|
||||
|
@ -5,7 +5,7 @@
|
||||
# This file is public domain in the USA and all free countries.
|
||||
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
|
||||
#
|
||||
#### $$VERSION$$ v1.31-dev-13-g127cc85
|
||||
#### $$VERSION$$ v1.40-dev-3-g7c74824
|
||||
#
|
||||
# source from commands.sh to use jsonDB functions
|
||||
#
|
||||
|
446
modules/processUpdates.sh
Normal file
446
modules/processUpdates.sh
Normal file
@ -0,0 +1,446 @@
|
||||
#!/bin/bash
|
||||
##################################################################
|
||||
#
|
||||
# File: processUpdates.sh
|
||||
# Note: DO NOT EDIT! this file will be overwritten on update
|
||||
#
|
||||
#### $$VERSION$$ v1.40-dev-3-g7c74824
|
||||
##################################################################
|
||||
|
||||
################
|
||||
# processing of updates starts here
|
||||
process_updates() {
|
||||
local max num debug="$1"
|
||||
max="$(grep -F ',"update_id"]' <<< "${UPDATE}" | tail -1 | cut -d , -f 2 )"
|
||||
Json2Array 'UPD' <<<"${UPDATE}"
|
||||
for ((num=0; num<=max; num++)); do
|
||||
process_client "${num}" "${debug}"
|
||||
done
|
||||
}
|
||||
|
||||
process_client() {
|
||||
local num="$1" debug="$2"
|
||||
pre_process_message "${num}"
|
||||
# log message on debug
|
||||
[[ -n "${debug}" ]] && log_message "New Message ==========\n$(grep -F '["result",'"${num}" <<<"${UPDATE}")"
|
||||
|
||||
# check for users / groups to ignore
|
||||
jssh_updateArray_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
|
||||
[ -n "${USER[ID]}" ] && [[ -n "${BASHBOTBLOCKED[${USER[ID]}]}" || -n "${BASHBOTBLOCKED[${CHAT[ID]}]}" ]] && return
|
||||
|
||||
# process per message type
|
||||
if [ -n "${iQUERY[ID]}" ]; then
|
||||
process_inline_query "${num}" "${debug}"
|
||||
printf "%(%c)T: Inline Query update received FROM=%s iQUERY=%s\n" -1\
|
||||
"${iQUERY[USERNAME]:0:20} (${iQUERY[USER_ID]})" "${iQUERY[0]}" >>"${UPDATELOG}"
|
||||
elif [ -n "${iBUTTON[ID]}" ]; then
|
||||
process_inline_button "${num}" "${debug}"
|
||||
printf "%(%c)T: Inline Button update received FROM=%s CHAT=%s CALLBACK=%s DATA:%s \n" -1\
|
||||
"${iBUTTON[USERNAME]:0:20} (${iBUTTON[USER_ID]})" "${iBUTTON[CHAT_ID]}" "${iBUTTON[ID]}" "${iBUTTON[DATA]}" >>"${UPDATELOG}"
|
||||
else
|
||||
if grep -qs -e '\["result",'"${num}"',"edited_message"' <<<"${UPDATE}"; then
|
||||
# edited message
|
||||
UPDATE="${UPDATE//,${num},\"edited_message\",/,${num},\"message\",}"
|
||||
Json2Array 'UPD' <<<"${UPDATE}"
|
||||
MESSAGE[0]="/_edited_message "
|
||||
fi
|
||||
process_message "${num}" "${debug}"
|
||||
printf "%(%c)T: update received FROM=%s CHAT=%s CMD=%s\n" -1 "${USER[USERNAME]:0:20} (${USER[ID]})"\
|
||||
"${CHAT[USERNAME]:0:20}${CHAT[TITLE]:0:30} (${CHAT[ID]})"\
|
||||
"${MESSAGE:0:30}${CAPTION:0:30}${URLS[*]:0:30}" >>"${UPDATELOG}"
|
||||
fi
|
||||
#####
|
||||
# process inline and message events
|
||||
# first classic command dispatcher
|
||||
# shellcheck disable=SC2153,SC1090
|
||||
{ source "${COMMANDS}" "${debug}"; } &
|
||||
|
||||
# then all registered addons
|
||||
if [ -z "${iQUERY[ID]}" ]; then
|
||||
event_message "${debug}"
|
||||
else
|
||||
event_inline "${debug}"
|
||||
fi
|
||||
|
||||
# last count users
|
||||
jssh_countKeyDB_async "${CHAT[ID]}" "${COUNTFILE}"
|
||||
}
|
||||
|
||||
pre_process_message(){
|
||||
local num="$1"
|
||||
# unset everything to not have old values
|
||||
CMD=( ); iQUERY=( ); iBUTTON=(); MESSAGE=(); CHAT=(); USER=(); CONTACT=(); LOCATION=(); unset CAPTION
|
||||
REPLYTO=( ); FORWARD=( ); URLS=(); VENUE=( ); SERVICE=( ); NEWMEMBER=( ); LEFTMEMBER=( ); PINNED=( ); MIGRATE=( )
|
||||
iQUERY[ID]="${UPD["result,${num},inline_query,id"]}"
|
||||
iBUTTON[ID]="${UPD["result,${num},callback_query,id"]}"
|
||||
CHAT[ID]="${UPD["result,${num},message,chat,id"]}"
|
||||
USER[ID]="${UPD["result,${num},message,from,id"]}"
|
||||
[ -z "${CHAT[ID]}" ] && CHAT[ID]="${UPD["result,${num},edited_message,chat,id"]}"
|
||||
[ -z "${USER[ID]}" ] && USER[ID]="${UPD["result,${num},edited_message,from,id"]}"
|
||||
# always true
|
||||
return 0
|
||||
}
|
||||
|
||||
process_inline_query() {
|
||||
local num="$1"
|
||||
iQUERY[0]="$(JsonDecode "${UPD["result,${num},inline_query,query"]}")"
|
||||
iQUERY[USER_ID]="${UPD["result,${num},inline_query,from,id"]}"
|
||||
iQUERY[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},inline_query,from,first_name"]}")"
|
||||
iQUERY[LAST_NAME]="$(JsonDecode "${UPD["result,${num},inline_query,from,last_name"]}")"
|
||||
iQUERY[USERNAME]="$(JsonDecode "${UPD["result,${num},inline_query,from,username"]}")"
|
||||
# always true
|
||||
return 0
|
||||
}
|
||||
|
||||
process_inline_button() {
|
||||
# debugging for impelemetation
|
||||
local num="$1"
|
||||
iBUTTON[DATA]="${UPD["result,${num},callback_query,data"]}"
|
||||
iBUTTON[CHAT_ID]="${UPD["result,${num},callback_query,message,chat,id"]}"
|
||||
iBUTTON[MESSAGE_ID]="${UPD["result,${num},callback_query,message,message_id"]}"
|
||||
iBUTTON[MESSAGE]="$(JsonDecode "${UPD["result,${num},callback_query,message,text"]}")"
|
||||
# XXX should we give back pressed button, all buttons or nothing?
|
||||
iBUTTON[USER_ID]="${UPD["result,${num},callback_query,from,id"]}"
|
||||
iBUTTON[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},callback_query,from,first_name"]}")"
|
||||
iBUTTON[LAST_NAME]="$(JsonDecode "${UPD["result,${num},callback_query,from,last_name"]}")"
|
||||
iBUTTON[USERNAME]="$(JsonDecode "${UPD["result,${num},callback_query,from,username"]}")"
|
||||
# always true
|
||||
return 0
|
||||
}
|
||||
|
||||
process_message() {
|
||||
local num="$1"
|
||||
# Message
|
||||
MESSAGE[0]+="$(JsonDecode "${UPD["result,${num},message,text"]}" | sed 's|\\/|/|g')"
|
||||
MESSAGE[ID]="${UPD["result,${num},message,message_id"]}"
|
||||
|
||||
# Chat ID is now parsed when update is received
|
||||
CHAT[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,last_name"]}")"
|
||||
CHAT[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,first_name"]}")"
|
||||
CHAT[USERNAME]="$(JsonDecode "${UPD["result,${num},message,chat,username"]}")"
|
||||
# set real name as username if empty
|
||||
[ -z "${CHAT[USERNAME]}" ] && CHAT[USERNAME]="${CHAT[FIRST_NAME]} ${CHAT[LAST_NAME]}"
|
||||
CHAT[TITLE]="$(JsonDecode "${UPD["result,${num},message,chat,title"]}")"
|
||||
CHAT[TYPE]="$(JsonDecode "${UPD["result,${num},message,chat,type"]}")"
|
||||
CHAT[ALL_ADMIN]="${UPD["result,${num},message,chat,all_members_are_administrators"]}"
|
||||
|
||||
# user ID is now parsed when update is received
|
||||
USER[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,from,first_name"]}")"
|
||||
USER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,from,last_name"]}")"
|
||||
USER[USERNAME]="$(JsonDecode "${UPD["result,${num},message,from,username"]}")"
|
||||
# set real name as username if empty
|
||||
[ -z "${USER[USERNAME]}" ] && USER[USERNAME]="${USER[FIRST_NAME]} ${USER[LAST_NAME]}"
|
||||
|
||||
# in reply to message from
|
||||
if [ -n "${UPD["result,${num},message,reply_to_message,from,id"]}" ]; then
|
||||
REPLYTO[UID]="${UPD["result,${num},message,reply_to_message,from,id"]}"
|
||||
REPLYTO[0]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,text"]}")"
|
||||
REPLYTO[ID]="${UPD["result,${num},message,reply_to_message,message_id"]}"
|
||||
REPLYTO[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,from,first_name"]}")"
|
||||
REPLYTO[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,from,last_name"]}")"
|
||||
REPLYTO[USERNAME]="$(JsonDecode "${UPD["result,${num},message,reply_to_message,from,username"]}")"
|
||||
fi
|
||||
|
||||
# forwarded message from
|
||||
if [ -n "${UPD["result,${num},message,forward_from,id"]}" ]; then
|
||||
FORWARD[UID]="${UPD["result,${num},message,forward_from,id"]}"
|
||||
FORWARD[ID]="${MESSAGE[ID]}" # same as message ID
|
||||
FORWARD[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,forward_from,first_name"]}")"
|
||||
FORWARD[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,forward_from,last_name"]}")"
|
||||
FORWARD[USERNAME]="$(JsonDecode "${UPD["result,${num},message,forward_from,username"]}")"
|
||||
fi
|
||||
|
||||
# get file URL from telegram, check for any of them!
|
||||
if grep -qs -e '\["result",'"${num}"',"message","[avpsd].*,"file_id"\]' <<<"${UPDATE}"; then
|
||||
URLS[AUDIO]="$(get_file "${UPD["result,${num},message,audio,file_id"]}")"
|
||||
URLS[DOCUMENT]="$(get_file "${UPD["result,${num},message,document,file_id"]}")"
|
||||
URLS[PHOTO]="$(get_file "${UPD["result,${num},message,photo,0,file_id"]}")"
|
||||
URLS[STICKER]="$(get_file "${UPD["result,${num},message,sticker,file_id"]}")"
|
||||
URLS[VIDEO]="$(get_file "${UPD["result,${num},message,video,file_id"]}")"
|
||||
URLS[VOICE]="$(get_file "${UPD["result,${num},message,voice,file_id"]}")"
|
||||
fi
|
||||
# Contact, must have phone_number
|
||||
if [ -n "${UPD["result,${num},message,contact,phone_number"]}" ]; then
|
||||
CONTACT[USER_ID]="$(JsonDecode "${UPD["result,${num},message,contact,user_id"]}")"
|
||||
CONTACT[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,contact,first_name"]}")"
|
||||
CONTACT[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,contact,last_name"]}")"
|
||||
CONTACT[NUMBER]="${UPD["result,${num},message,contact,phone_number"]}"
|
||||
CONTACT[VCARD]="${UPD["result,${num},message,contact,vcard"]}"
|
||||
fi
|
||||
|
||||
# venue, must have a position
|
||||
if [ -n "${UPD["result,${num},message,venue,location,longitude"]}" ]; then
|
||||
VENUE[TITLE]="$(JsonDecode "${UPD["result,${num},message,venue,title"]}")"
|
||||
VENUE[ADDRESS]="$(JsonDecode "${UPD["result,${num},message,venue,address"]}")"
|
||||
VENUE[LONGITUDE]="${UPD["result,${num},message,venue,location,longitude"]}"
|
||||
VENUE[LATITUDE]="${UPD["result,${num},message,venue,location,latitude"]}"
|
||||
VENUE[FOURSQUARE]="${UPD["result,${num},message,venue,foursquare_id"]}"
|
||||
fi
|
||||
|
||||
# Caption
|
||||
CAPTION="$(JsonDecode "${UPD["result,${num},message,caption"]}")"
|
||||
|
||||
# Location
|
||||
LOCATION[LONGITUDE]="${UPD["result,${num},message,location,longitude"]}"
|
||||
LOCATION[LATITUDE]="${UPD["result,${num},message,location,latitude"]}"
|
||||
|
||||
# service messages, group or channel only!
|
||||
if [[ "${CHAT[ID]}" == "-"* ]] ; then
|
||||
# new chat member
|
||||
if [ -n "${UPD["result,${num},message,new_chat_member,id"]}" ]; then
|
||||
SERVICE[NEWMEMBER]="${UPD["result,${num},message,new_chat_member,id"]}"
|
||||
NEWMEMBER[ID]="${SERVICE[NEWMEMBER]}"
|
||||
NEWMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,first_name"]}")"
|
||||
NEWMEMBER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,last_name"]}")"
|
||||
NEWMEMBER[USERNAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,username"]}")"
|
||||
NEWMEMBER[ISBOT]="${UPD["result,${num},message,new_chat_member,is_bot"]}"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_member ${NEWMEMBER[ID]} ${NEWMEMBER[USERNAME]:=${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]}}"
|
||||
fi
|
||||
# left chat member
|
||||
if [ -n "${UPD["result,${num},message,left_chat_member,id"]}" ]; then
|
||||
SERVICE[LEFTMEMBER]="${UPD["result,${num},message,left_chat_member,id"]}"
|
||||
LEFTMEMBER[ID]="${SERVICE[LEFTMEBER]}"
|
||||
LEFTMEMBER[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,first_name"]}")"
|
||||
LEFTMEMBER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,last_name"]}")"
|
||||
LEFTMEBER[USERNAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,username"]}")"
|
||||
LEFTMEMBER[ISBOT]="${UPD["result,${num},message,left_chat_member,is_bot"]}"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_left_chat_member ${LEFTMEMBER[ID]} ${LEFTMEMBER[USERNAME]:=${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]}}"
|
||||
fi
|
||||
# chat title / photo, check for any of them!
|
||||
if grep -qs -e '\["result",'"${num}"',"message","new_chat_[tp]' <<<"${UPDATE}"; then
|
||||
SERVICE[NEWTITLE]="$(JsonDecode "${UPD["result,${num},message,new_chat_title"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWTITLE]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_title ${USER[ID]} ${SERVICE[NEWTITLE]}"
|
||||
SERVICE[NEWPHOTO]="$(get_file "${UPD["result,${num},message,new_chat_photo,0,file_id"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWPHOTO]}" ] &&\
|
||||
MESSAGE[0]="/_new_chat_photo ${USER[ID]} ${SERVICE[NEWPHOTO]}"
|
||||
fi
|
||||
# pinned message
|
||||
if [ -n "${UPD["result,${num},message,pinned_message,message_id"]}" ]; then
|
||||
SERVICE[PINNED]="${UPD["result,${num},message,pinned_message,message_id"]}"
|
||||
PINNED[ID]="${SERVICE[PINNED]}"
|
||||
PINNED[MESSAGE]="$(JsonDecode "${UPD["result,${num},message,pinned_message,text"]}")"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_new_pinned_message ${USER[ID]} ${PINNED[ID]} ${PINNED[MESSAGE]}"
|
||||
fi
|
||||
# migrate to super group
|
||||
if [ -n "${UPD["result,${num},message,migrate_to_chat_id"]}" ]; then
|
||||
MIGRATE[TO]="${UPD["result,${num},message,migrate_to_chat_id"]}"
|
||||
MIGRATE[FROM]="${UPD["result,${num},message,migrate_from_chat_id"]}"
|
||||
# CHAT is already migrated, so set new chat id
|
||||
[ "${CHAT[ID]}" = "${MIGRATE[FROM]}" ] && CHAT[ID]="${MIGRATE[FROM]}"
|
||||
SERVICE[MIGRATE]="${MIGRATE[FROM]} ${MIGRATE[TO]}"
|
||||
[ -z "${MESSAGE[0]}" ] &&\
|
||||
MESSAGE[0]="/_migrate_group ${SERVICE[MIGRATE]}"
|
||||
fi
|
||||
# set SERVICE to yes if a service message was received
|
||||
[[ "${SERVICE[*]}" =~ ^[[:blank:]]*$ ]] || SERVICE[0]="yes"
|
||||
fi
|
||||
|
||||
# split message in command and args
|
||||
[[ "${MESSAGE[0]}" == "/"* ]] && read -r CMD <<<"${MESSAGE[0]}" && CMD[0]="${CMD[0]%%@*}"
|
||||
# everything went well
|
||||
return 0
|
||||
}
|
||||
|
||||
#########################
|
||||
# main get updates loop, should never terminate
|
||||
declare -A BASHBOTBLOCKED
|
||||
start_bot() {
|
||||
local DEBUGMSG OFFSET=0
|
||||
# adaptive sleep defaults
|
||||
local nextsleep="100"
|
||||
local stepsleep="${BASHBOT_SLEEP_STEP:-100}"
|
||||
local maxsleep="${BASHBOT_SLEEP:-5000}"
|
||||
# startup message
|
||||
DEBUGMSG="Start BASHBOT updates in Mode \"${1:-normal}\" =========="
|
||||
log_update "${DEBUGMSG}"
|
||||
# redirect to Debug.log
|
||||
# shellcheck disable=SC2153
|
||||
[[ "$1" == *"debug" ]] && exec &>>"${DEBUGLOG}"
|
||||
log_debug "${DEBUGMSG}"; DEBUGMSG="$1"
|
||||
[[ "${DEBUGMSG}" == "xdebug"* ]] && set -x
|
||||
# cleaup old pipes and empty logfiles
|
||||
find "${DATADIR}" -type p -delete
|
||||
find "${DATADIR}" -size 0 -name "*.log" -delete
|
||||
# load addons on startup
|
||||
for addons in "${ADDONDIR:-.}"/*.sh ; do
|
||||
# shellcheck disable=SC1090
|
||||
[ -r "${addons}" ] && source "${addons}" "startbot" "${DEBUGMSG}"
|
||||
done
|
||||
# shellcheck disable=SC1090
|
||||
source "${COMMANDS}" "startbot"
|
||||
# start timer events
|
||||
if [ -n "${BASHBOT_START_TIMER}" ] ; then
|
||||
# shellcheck disable=SC2064
|
||||
trap "event_timer ${DEBUGMSG}" ALRM
|
||||
start_timer &
|
||||
# shellcheck disable=SC2064
|
||||
trap "kill -9 $!; exit" EXIT INT HUP TERM QUIT
|
||||
fi
|
||||
# cleanup countfile on startup
|
||||
jssh_deleteKeyDB "CLEAN_COUNTER_DATABASE_ON_STARTUP" "${COUNTFILE}"
|
||||
[ -f "${COUNTFILE}.jssh.flock" ] && rm -f "${COUNTFILE}.jssh.flock"
|
||||
# store start time and cleanup botconfig on startup
|
||||
jssh_updateKeyDB "startup" "$(_date)" "${BOTCONFIG}"
|
||||
[ -f "${BOTCONFIG}.jssh.flock" ] && rm -f "${BOTCONFIG}.jssh.flock"
|
||||
# read blocked users
|
||||
jssh_readDB_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
|
||||
# inform botadmin about start
|
||||
send_normal_message "$(getConfigKey "botadmin")" "Bot $(getConfigKey "botname") started ..." &
|
||||
##########
|
||||
# bot is ready, start processing updates ...
|
||||
while true; do
|
||||
# adaptive sleep in ms rounded to next 0.1 s
|
||||
sleep "$(_round_float "${nextsleep}e-3" "1")"
|
||||
# get next update
|
||||
# shellcheck disable=SC2153
|
||||
UPDATE="$(getJson "${URL}/getUpdates?offset=${OFFSET}" 2>/dev/null | "${JSONSHFILE}" -b -n 2>/dev/null | iconv -f utf-8 -t utf-8 -c)"
|
||||
# did we get an response?
|
||||
if [ -n "${UPDATE}" ]; then
|
||||
# we got something, do processing
|
||||
[ "${OFFSET}" = "-999" ] && [ "${nextsleep}" -gt "$((maxsleep*2))" ] &&\
|
||||
log_error "Recovered from timeout/broken/no connection, continue with telegram updates"
|
||||
# escape bash $ expansion bug
|
||||
((nextsleep+= stepsleep , nextsleep= nextsleep>maxsleep ?maxsleep:nextsleep))
|
||||
UPDATE="${UPDATE//$/\\$}"
|
||||
# Offset
|
||||
OFFSET="$(grep <<< "${UPDATE}" '\["result",[0-9]*,"update_id"\]' | tail -1 | cut -f 2)"
|
||||
((OFFSET++))
|
||||
|
||||
if [ "${OFFSET}" != "1" ]; then
|
||||
nextsleep="100"
|
||||
process_updates "${DEBUGMSG}"
|
||||
fi
|
||||
else
|
||||
# oops, something bad happened, wait maxsleep*10
|
||||
(( nextsleep=nextsleep*2 , nextsleep= nextsleep>maxsleep*10 ?maxsleep*10:nextsleep ))
|
||||
# second time, report problem
|
||||
if [ "${OFFSET}" = "-999" ]; then
|
||||
log_error "Repeated timeout/broken/no connection on telegram update, sleep $(_round_float "${nextsleep}e-3")s"
|
||||
# try to recover
|
||||
if _is_function bashbotBlockRecover && [ -z "$(getJson "${ME_URL}")" ]; then
|
||||
log_error "Try to recover, calling bashbotBlockRecover ..."
|
||||
bashbotBlockRecover >>"${ERRORLOG}"
|
||||
fi
|
||||
fi
|
||||
OFFSET="-999"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
|
||||
declare -Ax BASHBOT_EVENT_INLINE BASHBOT_EVENT_MESSAGE BASHBOT_EVENT_CMD BASHBOT_EVENT_REPLYTO BASHBOT_EVENT_FORWARD BASHBOT_EVENT_SEND
|
||||
declare -Ax BASHBOT_EVENT_CONTACT BASHBOT_EVENT_LOCATION BASHBOT_EVENT_FILE BASHBOT_EVENT_TEXT BASHBOT_EVENT_TIMER BASHBOT_BLOCKED
|
||||
|
||||
start_timer(){
|
||||
# send alarm every ~60 s
|
||||
while :; do
|
||||
sleep 59.5
|
||||
kill -ALRM $$
|
||||
done;
|
||||
}
|
||||
|
||||
EVENT_TIMER="0"
|
||||
event_timer() {
|
||||
local key timer debug="$1"
|
||||
(( EVENT_TIMER++ ))
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_TIMER[@]}"
|
||||
do
|
||||
timer="${key##*,}"
|
||||
[[ ! "${timer}" =~ ^-*[1-9][0-9]*$ ]] && continue
|
||||
if [ "$(( EVENT_TIMER % timer ))" = "0" ]; then
|
||||
_exec_if_function "${BASHBOT_EVENT_TIMER[${key}]}" "timer" "${key}" "${debug}"
|
||||
[ "$(( EVENT_TIMER % timer ))" -lt "0" ] && \
|
||||
unset BASHBOT_EVENT_TIMER["${key}"]
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
event_inline() {
|
||||
local key debug="$1"
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_INLINE[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_INLINE[${key}]}" "inline" "${key}" "${debug}"
|
||||
done
|
||||
}
|
||||
event_message() {
|
||||
local key debug="$1"
|
||||
# ${MESSAEG[*]} event_message
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_MESSAGE[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_MESSAGE[${key}]}" "message" "${key}" "${debug}"
|
||||
done
|
||||
|
||||
# ${TEXT[*]} event_text
|
||||
if [ -n "${MESSAGE[0]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_TEXT[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_TEXT[${key}]}" "text" "${key}" "${debug}"
|
||||
done
|
||||
|
||||
# ${CMD[*]} event_cmd
|
||||
if [ -n "${CMD[0]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_CMD[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_CMD[${key}]}" "command" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
# ${REPLYTO[*]} event_replyto
|
||||
if [ -n "${REPLYTO[UID]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_REPLYTO[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_REPLYTO[${key}]}" "replyto" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${FORWARD[*]} event_forward
|
||||
if [ -n "${FORWARD[UID]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_FORWARD[@]}"
|
||||
do
|
||||
_exec_if_function && "${BASHBOT_EVENT_FORWARD[${key}]}" "forward" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${CONTACT[*]} event_contact
|
||||
if [ -n "${CONTACT[FIRST_NAME]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_CONTACT[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_CONTACT[${key}]}" "contact" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${VENUE[*]} event_location
|
||||
# ${LOCATION[*]} event_location
|
||||
if [ -n "${LOCATION[LONGITUDE]}" ] || [ -n "${VENUE[TITLE]}" ]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_LOCATION[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_LOCATION[${key}]}" "location" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
# ${URLS[*]} event_file
|
||||
# NOTE: compare again #URLS -1 blanks!
|
||||
if [[ "${URLS[*]}" != " " ]]; then
|
||||
# shellcheck disable=SC2153
|
||||
for key in "${!BASHBOT_EVENT_FILE[@]}"
|
||||
do
|
||||
_exec_if_function "${BASHBOT_EVENT_FILE[${key}]}" "file" "${key}" "${debug}"
|
||||
done
|
||||
fi
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user