From fe1fb757481f36233f3ad30bb394555c1ca4c488 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 18 Jan 2021 21:09:30 +0100 Subject: [PATCH 01/99] make _round_float more LANG independent (C not installed) --- bashbot.sh | 5 +++-- doc/7_develop.md | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index a3a9958..e6fe4c3 100755 --- a/bashbot.sh +++ b/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.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-0-gad532cc ################################################################## # emmbeded system may claim bash but it is not @@ -89,7 +89,8 @@ _is_function() { # if $2 is not given or is not a positive number zero is assumed _round_float() { local digit="$2"; [[ "$2" =~ ^[${o9o9o9}]+$ ]] || digit="0" - { LC_ALL=C.utf-8 printf "%.${digit}f" "$1"; } 2>/dev/null + : "$(LC_ALL=C printf "%.${digit}f" "$1" 2>/dev/null)" + printf "%s" "${_//,/.}" # make more LANG independent } # date is external, printf is much faster _date(){ diff --git a/doc/7_develop.md b/doc/7_develop.md index ec96dc5..ddfea3e 100644 --- a/doc/7_develop.md +++ b/doc/7_develop.md @@ -284,8 +284,9 @@ bar="${_/__x/_c}" # a_b_c : ${SOMEVAR} # "String in var" $_ -> "var" : $(<"file") # "Content of\n file" $_ -> "file" -# pitfall test command -[ -n "$MYVAR" ] && echo "$_" # outputs "]" +# pitfall [ vs. test command +[ -n "xxx" ] && echo "$_" # $_ -> "]" +test -n "xxx" && echo "$_" # $_ -> "xxx" # pitfall command substitution: globbing and IFS is applied! : "$(echo "a* is born")"# $_ -> a* is globbed even quoted! @@ -386,5 +387,5 @@ fi #### [Prev Function Reference](6_reference.md) -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-0-gad532cc From 62378f7cf643b154ee5e028eaa0527cb8896cffc Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 19 Jan 2021 17:24:53 +0100 Subject: [PATCH 02/99] replace old JsoenGetXxx functions with direct UPD access --- bashbot.sh | 24 ++++++++++++------------ modules/chatMember.sh | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index e6fe4c3..1048e6b 100755 --- a/bashbot.sh +++ b/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.31-dev-0-gad532cc +#### $$VERSION$$ v1.31-dev-0-gfe1fb75 ################################################################## # emmbeded system may claim bash but it is not @@ -420,7 +420,7 @@ delete_message() { get_file() { [ -z "$1" ] && return sendJson "" '"file_id": "'"$1"'"' "${URL}/getFile" - printf '%s\n' "${URL}"/"$(JsonGetString <<< "${res}" '"result","file_path"')" + printf "%s\n" "${URL}/${UPD["result","file_path"]}" } # iconv used to filter out broken utf characters, if not installed fake it @@ -660,15 +660,15 @@ JsonDecode() { printf "%b\n" "${out}${remain}" } -JsonGetString() { - sed -n -e '0,/\['"$1"'\]/ s/\['"$1"'\][ \t]"\(.*\)"$/\1/p' -} -JsonGetLine() { - sed -n -e '0,/\['"$1"'\]/ s/\['"$1"'\][ \t]//p' -} -JsonGetValue() { - sed -n -e '0,/\['"$1"'\]/ s/\['"$1"'\][ \t]\([0-9.,]*\).*/\1/p' -} +#JsonGetString() { +# sed -n -e '0,/\['"$1"'\]/ s/\['"$1"'\][ \t]"\(.*\)"$/\1/p' +#} +#JsonGetLine() { +# sed -n -e '0,/\['"$1"'\]/ s/\['"$1"'\][ \t]//p' +#} +#JsonGetValue() { +# sed -n -e '0,/\['"$1"'\]/ s/\['"$1"'\][ \t]\([0-9.,]*\).*/\1/p' +#} ################ # processing of updates starts here @@ -927,7 +927,7 @@ process_message() { 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]="$(JsonGetString '"result",'"${num}"',"message","contact","vcard"' <<<"${UPDATE}")" + CONTACT[VCARD]="${UPD["result","${num}","message","contact","vcard"]}" fi # venue, must have a position diff --git a/modules/chatMember.sh b/modules/chatMember.sh index 2f9a316..091819e 100644 --- a/modules/chatMember.sh +++ b/modules/chatMember.sh @@ -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.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-0-gfe1fb75 # will be automatically sourced from bashbot @@ -76,7 +76,7 @@ leave_chat() { get_chat_member_status() { sendJson "$1" '"user_id":'"$2"'' "${URL}/getChatMember" # shellcheck disable=SC2154 - JsonGetString '"result","status"' <<< "${res}" + printf "%s\n" "${UPD["result,status"]}" } user_is_creator() { From 427f670a020e8ef7c3e407d680a85ecd698c9cae Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 19 Jan 2021 17:47:15 +0100 Subject: [PATCH 03/99] bashbot.sh: fix UPD array access to use "real" strings --- bashbot.sh | 160 ++++++++++++++++++++++++++--------------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 1048e6b..a01c0d9 100755 --- a/bashbot.sh +++ b/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.31-dev-0-gfe1fb75 +#### $$VERSION$$ v1.31-dev-1-g62378f7 ################################################################## # emmbeded system may claim bash but it is not @@ -420,7 +420,7 @@ delete_message() { get_file() { [ -z "$1" ] && return sendJson "" '"file_id": "'"$1"'"' "${URL}/getFile" - printf "%s\n" "${URL}/${UPD["result","file_path"]}" + printf "%s\n" "${URL}/${UPD["result,file_path"]}" } # iconv used to filter out broken utf characters, if not installed fake it @@ -558,8 +558,8 @@ sendJsonResult(){ [ -n "${BASHBOTDEBUG}" ] && log_message "New Result ==========\n$1" BOTSENT[OK]="${UPD["ok"]}" if [ "${BOTSENT[OK]}" = "true" ]; then - BOTSENT[ID]="${UPD["result","message_id"]}" - BOTSENT[CHAT]="${UPD["result","chat","id"]}" + BOTSENT[ID]="${UPD["result,message_id"]}" + BOTSENT[CHAT]="${UPD["result,chat,id"]}" [ -n "${UPD["result"]}" ] && BOTSENT[RESULT]="${UPD["result"]}" return # hot path everything OK! @@ -568,7 +568,7 @@ sendJsonResult(){ if [ -n "$1" ]; then BOTSENT[ERROR]="${UPD["error_code"]}" BOTSENT[DESCRIPTION]="${UPD["description"]}" - [ -n "${UPD["parameters","retry_after"]}" ] && BOTSENT[RETRY]="${UPD["parameters","retry_after"]}" + [ -n "${UPD["parameters,retry_after"]}" ] && BOTSENT[RETRY]="${UPD["parameters,retry_after"]}" else BOTSENT[OK]="false" BOTSENT[ERROR]="999" @@ -851,146 +851,146 @@ pre_process_message(){ # unset everything to not have old values CMD=( ); iQUERY=( ); MESSAGE=(); CHAT=(); USER=(); CONTACT=(); LOCATION=(); unset CAPTION REPLYTO=( ); FORWARD=( ); URLS=(); VENUE=( ); SERVICE=( ); NEWMEMBER=( ); LEFTMEMBER=( ); PINNED=( ); MIGRATE=( ) - iQUERY[ID]="${UPD["result",${num},"inline_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"]}" + iQUERY[ID]="${UPD["result,${num},inline_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() { 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"]}")" + 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_message() { local num="$1" # Message - MESSAGE[0]+="$(JsonDecode "${UPD["result",${num},"message","text"]}" | sed 's|\\/|/|g')" - MESSAGE[ID]="${UPD["result",${num},"message","message_id"]}" + 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"]}")" + 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"]}" + 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[ID]="${UPD["result",${num},"message","from","id"]}" - 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"]}")" + #USER[ID]="${UPD["result,${num},message,from,id"]}" + 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"]}")" + 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"]}" + 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"]}")" + 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"]}")" + 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"]}" + 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"]}" + 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"]}")" + CAPTION="$(JsonDecode "${UPD["result,${num},message,caption"]}")" # Location - LOCATION[LONGITUDE]="${UPD["result",${num},"message","location","longitude"]}" - LOCATION[LATITUDE]="${UPD["result",${num},"message","location","latitude"]}" + 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"]}" + 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"]}" + 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"]}" + 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"]}" + 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"]}")" + 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"]}")" + 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"]}" + 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"]}")" + 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"]}" + 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"]}" SERVICE[MIGRATE]="${MIGRATE[FROM]} ${MIGRATE[TO]}" [ -z "${MESSAGE[0]}" ] &&\ MESSAGE[0]="/_migrate_group ${SERVICE[MIGRATE]}" From b0f653b705c039311150d414a96dd845836eed27 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 19 Jan 2021 18:09:45 +0100 Subject: [PATCH 04/99] dev: save date of last commit --- dev/dev.inc.sh | 4 +++- dev/git-add.sh | 12 +++++++++--- dev/install-hooks.sh | 4 +--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/dev/dev.inc.sh b/dev/dev.inc.sh index fa0fd75..7a52c72 100644 --- a/dev/dev.inc.sh +++ b/dev/dev.inc.sh @@ -5,7 +5,7 @@ # # Description: common stuff for all dev scripts # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-2-g427f670 ############################################################# # magic to ensure that we're always inside the root of our application, @@ -20,3 +20,5 @@ else printf "Sorry, no git repository %s\n" "$(pwd)" && exit 1 fi +HOOKDIR="dev/hooks" +LASTCOMMIT=".git/.lastcommit" diff --git a/dev/git-add.sh b/dev/git-add.sh index 39c94eb..1e38538 100755 --- a/dev/git-add.sh +++ b/dev/git-add.sh @@ -3,15 +3,21 @@ # # works together with git pre-push.sh and ADD all changed files since last push -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-2-g427f670 #shellcheck disable=SC1090 source "${0%/*}/dev.inc.sh" -[ ! -f .git/.lastcommit ] && printf "No previous commit or hooks not installed, use \"git add\" instead ... Abort\n" && exit +# check for last commit date +if [ ! -f "${LASTCOMMIT}" ]; then + if ! touch -d "$(git log -1 --format=%cD)" "${LASTCOMMIT}"; then + printf "No previous commit found, use \"git add\" instead ... Abort\n" + exit + fi +fi set +f -FILES="$(find ./* -newer .git/.lastcommit| grep -v -e 'DIST\/' -e 'STANDALONE\/' -e 'JSON.sh')" +FILES="$(find ./* -newer "${LASTCOMMIT}" | grep -v -e 'DIST\/' -e 'STANDALONE\/' -e 'JSON.sh')" set -f # FILES="$(find ./* -newer .git/.lastpush)" [ "${FILES}" = "" ] && printf "Nothing changed since last commit ...\n" && exit diff --git a/dev/install-hooks.sh b/dev/install-hooks.sh index e4e41b4..298c0cd 100755 --- a/dev/install-hooks.sh +++ b/dev/install-hooks.sh @@ -1,13 +1,11 @@ #!/usr/bin/env bash # this has to run once atfer git clone # and every time we create new hooks -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-2-g427f670 #shellcheck disable=SC1090 source "${0%/*}/dev.inc.sh" -HOOKDIR="dev/hooks" - printf "Installing hooks..." for hook in pre-commit post-commit pre-push do From 0ee6973143f7bff1ad0962d4de51ec561aff633d Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 19 Jan 2021 21:55:39 +0100 Subject: [PATCH 05/99] modules: send_inline_keyboard fix empty text, improve doc --- doc/6_reference.md | 41 +++++++++++++++++++++-------------------- modules/sendMessage.sh | 4 ++-- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index 463e13d..3f2cd66 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -213,6 +213,12 @@ _keyboard_numpad ---- +##### send_sticker +`send_sticker` sends a sticker using a `file_id` to send a sticker that exists on the Telegram servers. + +*usage:* send_sticker "$CHAT[ID]" "file_id" + + ##### send_button *usage:* send_button "$CHAT[ID]" "message" "text" "URL" @@ -223,32 +229,27 @@ _keyboard_numpad send_button "${CHAT[ID]}" "MAKE MONEY FAST!!!" "Visit my Shop" "https://dealz.rrr.de" ``` -##### send_sticker -`send_sticker` sends a sticker using a `file_id` to send a sticker that exists on the Telegram servers. - -*usage:* send_sticker "$CHAT[ID]" "file_id" - - ##### send_inline_keyboard -Even its called keyboard, this function is different from send_keyboard. The main difference is that it's only possible to -specify URL buttons, no Text Buttons and the Buttons must be an Array of Buttons as specified for -[Telegram InlineMarkup](https://core.telegram.org/bots/api#inlinekeyboardmarkup). +`send_inline_keyboard` send an array of buttons. -The inline buttons must be specified as a JSON string in the following format: - -`[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ]``` - -Each button consists of a pair of text and URL values, sourrounded by '{ }', multiple buttons are separated by '**,**' and everything is wrapped in '[ ]'. - -*usage:* send_inline_keyboard "chat-id" "message" "[ {"text":"text", "url":"url"} ...]" +*usage:* send_inline_keyboard "CHAT[ID]" "message" "[ {"text":"text", "url":"url"} ...]" *alias:* _inline_keyboard "[{"text":"text", "url":"url"} ...]" +The buttons array must be specified as a JSON string in the following format per button row, multiple rowsare concateneated with ',' + +`[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ]` + *example:* ```bash -send_inline_keyboard "${CHAT[ID]}" "MAKE MONEY FAST!!!" '[{"text":"Visit my Shop", url"":"https://dealz.rrr.de"}]' -send_inline_keyboard "${CHAT[ID]}" "" '[{"text":"button 1", url"":"url 1"}, {"text":"button 2", url"":"url 2"} ]' -send_inline_keyboard "${CHAT[ID]}" "" '[{"text":"b 1", url"":"u 1"}, {"text":"b 2", url"":"u 2"}, {"text":"b 2", url"":"u 2"} ]' +# one button, same as send_button +send_inline_keyboard "${CHAT[ID]}" "MAKE MONEY FAST!!!" '[{"text":"Visit my Shop", "url":"https://dealz.rrr.de"}]' + +# one button row +send_inline_keyboard "${CHAT[ID]}" "" '[{"text":"button 1", url"":"http://rrr.de"}, {"text":"button 2", "url":"http://rrr.de"} ]' + +# multiple button rows +send_inline_keyboard "${CHAT[ID]}" "" '[{"text":"b1", "url":"http://rrr.de"}, {"text":"b2", "url":"http://rrr.de"}], [{"text":"b4", "url":"http://rrr.de"}, "text":"b5", "url":"http://rrr.de"}]' ``` *See also [Inline keyboard markup](https://core.telegram.org/bots/api/#inlinekeyboardmarkup)* @@ -1269,5 +1270,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-3-gb0f653b diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 07f5613..842e8c2 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-3-gb0f653b # will be automatically sourced from bashbot @@ -139,7 +139,7 @@ remove_keyboard() { # $1 CHAT $2 message $3 keyboard send_inline_keyboard() { - local text; text='"text":"'$(JsonEscape "$2")'"'; [ -z "$2" ] && text='"text":"'"Keyboard:"'"' + local text; text='"text":"'$(JsonEscape "$2")'"'; [ -z "$2" ] && text='"text":"..."' sendJson "$1" "${text}"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${MSG_URL}" # JSON='"text":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}' } From f66e5702b07dc8e730ef20e197c01a8e83e1b54d Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 19 Jan 2021 21:58:50 +0100 Subject: [PATCH 06/99] bin: send_buttons.sh --- bin/send_buttons.sh | 60 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100755 bin/send_buttons.sh diff --git a/bin/send_buttons.sh b/bin/send_buttons.sh new file mode 100755 index 0000000..5018aef --- /dev/null +++ b/bin/send_buttons.sh @@ -0,0 +1,60 @@ +#!/bin/bash +#=============================================================================== +# +# FILE: bin/send_message.sh +# +USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message ...." "buttons" [debug]' +# +# DESCRIPTION: send a message to the given user/group +# +# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself +# message - message to send +# buttons - buttons to send as button array +# +# -h - display short help +# --help - this help +# +# Set BASHBOT_HOME to your installation directory +# +# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ +# AUTHOR: KayM (gnadelwartz), kay@rrr.de +# CREATED: 18.01.2021 11:34 +# +#### $$VERSION$$ v1.31-dev-4-g0ee6973 +#=============================================================================== + +#### +# parse args +SEND="send_inline_keyboard" +case "$1" in + '') + printf "missing arguments\n" + ;& + "-h"*) + printf 'usage: %s\n' "${USAGE}" + exit 1 + ;; + '--h'*) + sed -n '3,/###/p' <"$0" + exit 1 + ;; +esac + +# set bashbot environment +# shellcheck disable=SC1090 +source "${0%/*}/bashbot_env.inc.sh" "${4:-debug}" # $4 debug + +#### +# ready, do stuff here ----- +if [ "$1" == "BOTADMIN" ]; then + CHAT="${BOT_ADMIN}" +else + CHAT="$1" +fi + +# send message in selected format +"${SEND}" "${CHAT}" "$2" "$3" + +# output send message result +jssh_printDB "BOTSENT" | sort -r + From f2dd64c90007b9600835f36684571041fe4db314 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 19 Jan 2021 22:56:58 +0100 Subject: [PATCH 07/99] modules: send_button remove double JsonEscape --- modules/sendMessage.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 842e8c2..58cd7d8 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.31-dev-3-gb0f653b +#### $$VERSION$$ v1.31-dev-5-gf66e570 # will be automatically sourced from bashbot @@ -143,9 +143,11 @@ send_inline_keyboard() { sendJson "$1" "${text}"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${MSG_URL}" # JSON='"text":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}' } + + # $1 CHAT $2 message $3 button text $4 URL send_button() { - send_inline_keyboard "$1" "$2" '[ {"text":"'"$(JsonEscape "$3")"'", "url":"'"$4"'"}]' + send_inline_keyboard "$1" "$2" '[{"text":"'"$3"'", "url":"'"$4"'"}]' } # $1 chat, $2 file_id on telegram server From e923e2e8fc83442228cfb94ff0ce66ff86829b97 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 19 Jan 2021 23:18:26 +0100 Subject: [PATCH 08/99] modules: helper function _button_row --- modules/sendMessage.sh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 58cd7d8..7eecca2 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.31-dev-5-gf66e570 +#### $$VERSION$$ v1.31-dev-6-gf2dd64c # will be automatically sourced from bashbot @@ -145,11 +145,24 @@ send_inline_keyboard() { } -# $1 CHAT $2 message $3 button text $4 URL +# $1 CHAT $2 message $3 button text send_button() { send_inline_keyboard "$1" "$2" '[{"text":"'"$3"'", "url":"'"$4"'"}]' } +# helper function to create json for a button row +# buttons will specified as "text|url" ... "text|url" +_button_row() { + [ -z "$1" ] && return 1 + local arg json + for arg in "$@" + do + [ -n "${json}" ] && json+="," + json+='{"text":"'"${arg%|*}"'", "url":"'"${arg##*|}"'"}' + done + printf "[%s]" "${json}" +} + # $1 chat, $2 file_id on telegram server send_sticker() { sendJson "$1" '"sticker": "'"$2"'"' "${URL}/sendSticker" From 8854e03ece1451891e4e80133e37f7978bc2edae Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 19 Jan 2021 23:22:38 +0100 Subject: [PATCH 09/99] modules: JsonEscape button text --- modules/sendMessage.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 7eecca2..6f8a83d 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.31-dev-6-gf2dd64c +#### $$VERSION$$ v1.31-dev-7-ge923e2e # will be automatically sourced from bashbot @@ -145,9 +145,9 @@ send_inline_keyboard() { } -# $1 CHAT $2 message $3 button text +# $1 CHAT $2 message $3 button text $4 button url send_button() { - send_inline_keyboard "$1" "$2" '[{"text":"'"$3"'", "url":"'"$4"'"}]' + send_inline_keyboard "$1" "$2" '[{"text":"'"$(JsonEscape "$3")"'", "url":"'"$4"'"}]' } # helper function to create json for a button row @@ -158,7 +158,7 @@ _button_row() { for arg in "$@" do [ -n "${json}" ] && json+="," - json+='{"text":"'"${arg%|*}"'", "url":"'"${arg##*|}"'"}' + json+='{"text":"'"$(JsonEscape "${arg%|*}")"'", "url":"'"${arg##*|}"'"}' done printf "[%s]" "${json}" } From 6c91a327a63681e9093ed186dbdf600c7ca1c0e2 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 19 Jan 2021 23:35:26 +0100 Subject: [PATCH 10/99] bin: send_buttons.sh use _button_row to create buttons --- bin/send_buttons.sh | 15 +++++++++------ modules/sendMessage.sh | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/bin/send_buttons.sh b/bin/send_buttons.sh index 5018aef..fd6a024 100755 --- a/bin/send_buttons.sh +++ b/bin/send_buttons.sh @@ -3,13 +3,14 @@ # # FILE: bin/send_message.sh # -USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message ...." "buttons" [debug]' +USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...' # -# DESCRIPTION: send a message to the given user/group +# DESCRIPTION: send a send buttons in a row to the given user/group # # OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself # message - message to send -# buttons - buttons to send as button array +# text|url - buttons to send in a row, each as "button text|url" +# e.g. "Amazon|https://www.amzon.com" "Mydealz|https://mydealz.de" ... # # -h - display short help # --help - this help @@ -20,7 +21,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message ...." "buttons" [debug]' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.01.2021 11:34 # -#### $$VERSION$$ v1.31-dev-4-g0ee6973 +#### $$VERSION$$ v1.31-dev-8-g8854e03 #=============================================================================== #### @@ -42,7 +43,7 @@ esac # set bashbot environment # shellcheck disable=SC1090 -source "${0%/*}/bashbot_env.inc.sh" "${4:-debug}" # $4 debug +source "${0%/*}/bashbot_env.inc.sh" "debug" #### # ready, do stuff here ----- @@ -51,9 +52,11 @@ if [ "$1" == "BOTADMIN" ]; then else CHAT="$1" fi +TEXT="$2" +shift 2 # send message in selected format -"${SEND}" "${CHAT}" "$2" "$3" +"${SEND}" "${CHAT}" "${TEXT}" "$(_button_row "$@")" # output send message result jssh_printDB "BOTSENT" | sort -r diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 6f8a83d..7f55e75 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.31-dev-7-ge923e2e +#### $$VERSION$$ v1.31-dev-8-g8854e03 # will be automatically sourced from bashbot From f95b6c2e7df82c0f280b9983126a2502639afae3 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 19 Jan 2021 23:53:58 +0100 Subject: [PATCH 11/99] modules: _button_row empty button starts new row --- bin/send_buttons.sh | 2 +- modules/sendMessage.sh | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/bin/send_buttons.sh b/bin/send_buttons.sh index fd6a024..070f84c 100755 --- a/bin/send_buttons.sh +++ b/bin/send_buttons.sh @@ -21,7 +21,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.01.2021 11:34 # -#### $$VERSION$$ v1.31-dev-8-g8854e03 +#### $$VERSION$$ v1.31-dev-9-g6c91a32 #=============================================================================== #### diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 7f55e75..55e997a 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.31-dev-8-g8854e03 +#### $$VERSION$$ v1.31-dev-9-g6c91a32 # will be automatically sourced from bashbot @@ -151,14 +151,15 @@ send_button() { } # helper function to create json for a button row -# buttons will specified as "text|url" ... "text|url" +# buttons will specified as "text|url" ... "text|url" empty arg starts new row _button_row() { [ -z "$1" ] && return 1 - local arg json + local arg json sep for arg in "$@" do - [ -n "${json}" ] && json+="," - json+='{"text":"'"$(JsonEscape "${arg%|*}")"'", "url":"'"${arg##*|}"'"}' + [ -z "${arg}" ] && sep="],[" && continue + json+="${sep}"'{"text":"'"$(JsonEscape "${arg%|*}")"'", "url":"'"${arg##*|}"'"}' + sep="," done printf "[%s]" "${json}" } From f6e319c6eb78fc7cec0ce135e2c4b3b59cf41853 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 20 Jan 2021 16:21:46 +0100 Subject: [PATCH 12/99] doc: advise use of new _button_row helper function --- bin/send_buttons.sh | 9 ++++++--- doc/6_reference.md | 47 ++++++++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/bin/send_buttons.sh b/bin/send_buttons.sh index 070f84c..830fd02 100755 --- a/bin/send_buttons.sh +++ b/bin/send_buttons.sh @@ -9,19 +9,22 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...' # # OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself # message - message to send -# text|url - buttons to send in a row, each as "button text|url" -# e.g. "Amazon|https://www.amzon.com" "Mydealz|https://mydealz.de" ... +# text|url - buttons to send, each button as "text|url" pair or +# "url" only to show url as text also, "" starts new row # # -h - display short help # --help - this help # +# EXAMPLE: 2 buttons on 2 rows, first shows Amazon, second the url as text +# send_buttons.sh "Amazon|https://www.amazon.com" "" "https://mydealz.de" ... +# # Set BASHBOT_HOME to your installation directory # # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.01.2021 11:34 # -#### $$VERSION$$ v1.31-dev-9-g6c91a32 +#### $$VERSION$$ v1.31-dev-10-gf95b6c2 #=============================================================================== #### diff --git a/doc/6_reference.md b/doc/6_reference.md index 3f2cd66..82b2dd5 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -220,36 +220,57 @@ _keyboard_numpad ##### send_button +`send_button` sends a text message followed by a single button. + *usage:* send_button "$CHAT[ID]" "message" "text" "URL" *alias:* _button "text" "URL" *example:* ```bash -send_button "${CHAT[ID]}" "MAKE MONEY FAST!!!" "Visit my Shop" "https://dealz.rrr.de" +send_button "${CHAT[ID]}" "Awesome Deals!" "Visit my Shop" "https://dealz.rrr.de" ``` -##### send_inline_keyboard -`send_inline_keyboard` send an array of buttons. +##### _button_row +`_button_row` is a helper function to create a JSON button array for use with `send_inline_keyboard`. -*usage:* send_inline_keyboard "CHAT[ID]" "message" "[ {"text":"text", "url":"url"} ...]" +*usage:* _button_row "text|url" "text|url" "" "url" "" "text|url" ... -*alias:* _inline_keyboard "[{"text":"text", "url":"url"} ...]" - -The buttons array must be specified as a JSON string in the following format per button row, multiple rowsare concateneated with ',' - -`[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ]` +Each button is specified as a `"tex|url"` pair separated by `|`, text is shown on the button and url is opened on button click. +By default all buttons are displayed on one row, an empty string `""` starts a new button row. +If `"url"` without text is given, the url is shown on the button and opened on button click. *example:* ```bash # one button, same as send_button -send_inline_keyboard "${CHAT[ID]}" "MAKE MONEY FAST!!!" '[{"text":"Visit my Shop", "url":"https://dealz.rrr.de"}]' +send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" "$(_button_row "Visit my Shop|https://dealz.rrr.de")" # one button row -send_inline_keyboard "${CHAT[ID]}" "" '[{"text":"button 1", url"":"http://rrr.de"}, {"text":"button 2", "url":"http://rrr.de"} ]' +send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "button 1|"http://rrr.de" "button 2|http://rrr.de")" # multiple button rows -send_inline_keyboard "${CHAT[ID]}" "" '[{"text":"b1", "url":"http://rrr.de"}, {"text":"b2", "url":"http://rrr.de"}], [{"text":"b4", "url":"http://rrr.de"}, "text":"b5", "url":"http://rrr.de"}]' +send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "b1|http://rrr.de" "b2|http://rrr.de" "" "b3|http://rrr.de" "b4|http://rrr.de")" +``` + +##### send_inline_keyboard +`send_inline_keyboard` send buttons given as an array of buttons in JSON format. + +*usage:* send_inline_keyboard "CHAT[ID]" "message" "[JSON button array]" + +A JSON button array has the following format, but I suggest to use `_button_row` to create them: + +`[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]` + +*example:* +```bash +# one button, same as send_button +send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" '[{"text":"Visit my Shop", "url":"https://dealz.rrr.de"}]' + +# one button row +send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"button 1", url"":"http://rrr.de"}, {"text":"button 2", "url":"http://rrr.de"} ]' + +# multiple button rows +send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"b1", "url":"http://rrr.de"}, {"text":"b2", "url":"http://rrr.de"}], [{"text":"b3", "url":"http://rrr.de"}, "text":"b4", "url":"http://rrr.de"}]' ``` *See also [Inline keyboard markup](https://core.telegram.org/bots/api/#inlinekeyboardmarkup)* @@ -1270,5 +1291,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.31-dev-3-gb0f653b +#### $$VERSION$$ v1.31-dev-10-gf95b6c2 From 85a178d68a971fdfc8446f194cac7df51b39c560 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 20 Jan 2021 16:27:59 +0100 Subject: [PATCH 13/99] doc: small fix for _button_row --- doc/6_reference.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index 82b2dd5..a9aceea 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -236,9 +236,9 @@ send_button "${CHAT[ID]}" "Awesome Deals!" "Visit my Shop" "https://dealz.rrr.de *usage:* _button_row "text|url" "text|url" "" "url" "" "text|url" ... -Each button is specified as a `"tex|url"` pair separated by `|`, text is shown on the button and url is opened on button click. +Each button is specified as a `"text|url"` pair separated by `|`, `text` is shown on the button and `url` is opened on button click. By default all buttons are displayed on one row, an empty string `""` starts a new button row. -If `"url"` without text is given, the url is shown on the button and opened on button click. +If `"url"` without text is given, `url` is shown on the button and opened on button click. *example:* ```bash @@ -1291,5 +1291,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.31-dev-10-gf95b6c2 +#### $$VERSION$$ v1.31-dev-11-gf6e319c From 127cc85a2ab37f706f2ceacb2f0c73d780434112 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 20 Jan 2021 18:20:03 +0100 Subject: [PATCH 14/99] load modules before commands.sh --- bashbot.sh | 15 ++++++++------- doc/6_reference.md | 4 ++-- .../d-send_message-test.result | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index a01c0d9..8d43d72 100755 --- a/bashbot.sh +++ b/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.31-dev-1-g62378f7 +#### $$VERSION$$ v1.31-dev-12-g85a178d ################################################################## # emmbeded system may claim bash but it is not @@ -342,6 +342,13 @@ declare -Ax SERVICE NEWMEMBER LEFTMEMBER PINNED MIGRATE export res CAPTION ME +############### +# load modules +for module in "${MODULEDIR:-.}"/*.sh ; do + # shellcheck source=./modules/aliases.sh + if ! _is_function "$(basename "${module}")" && [ -r "${module}" ]; then source "${module}" "source"; fi +done + ################## # read commands file if we are not sourced COMMANDS="${BASHBOT_ETC:-.}/commands.sh" @@ -353,12 +360,6 @@ else fi debug_checks "start SOURCE=${SOURCE:-no}" "$@" -############### -# load modules -for module in "${MODULEDIR:-.}"/*.sh ; do - # shellcheck source=./modules/aliases.sh - if ! _is_function "$(basename "${module}")" && [ -r "${module}" ]; then source "${module}" "source"; fi -done ##################### # BASHBOT INTERNAL functions diff --git a/doc/6_reference.md b/doc/6_reference.md index a9aceea..7244504 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -246,7 +246,7 @@ If `"url"` without text is given, `url` is shown on the button and opened on but send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" "$(_button_row "Visit my Shop|https://dealz.rrr.de")" # one button row -send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "button 1|"http://rrr.de" "button 2|http://rrr.de")" +send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "button 1|http://rrr.de" "button 2|http://rrr.de")" # multiple button rows send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "b1|http://rrr.de" "b2|http://rrr.de" "" "b3|http://rrr.de" "b4|http://rrr.de")" @@ -1291,5 +1291,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.31-dev-11-gf6e319c +#### $$VERSION$$ v1.31-dev-12-g85a178d diff --git a/test/d-send_message-test/d-send_message-test.result b/test/d-send_message-test/d-send_message-test.result index 3399681..e0f1017 100644 --- a/test/d-send_message-test/d-send_message-test.result +++ b/test/d-send_message-test/d-send_message-test.result @@ -34,10 +34,10 @@ URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?12345 chat:123456 JSON:"text":"\# test for new inline button" URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage -chat:123456 JSON:"text":"Text plus keyboard will appear in chat", "reply_markup": {"inline_keyboard": [ [ {"text":"Button Text", "url":"https://www..."}] ]} +chat:123456 JSON:"text":"Text plus keyboard will appear in chat", "reply_markup": {"inline_keyboard": [ [{"text":"Button Text", "url":"https://www..."}] ]} URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage -chat:123456 JSON:"text":"STABILO 88\/240 Fineliner point 88\n\n[https:\/\/images\-na\.ssl\-images\-amazon\.com\/images\/I\/41oypA3kmHL\.l_SX300\.jpg]\nsecond part of text\nplus newline\.", "reply_markup": {"inline_keyboard": [ [ {"text":"Bei Amazon ansehen \.\.\.", "url":"https://www.amazon.de/dp/B014TN3JYW"}] ]} +chat:123456 JSON:"text":"STABILO 88\/240 Fineliner point 88\n\n[https:\/\/images\-na\.ssl\-images\-amazon\.com\/images\/I\/41oypA3kmHL\.l_SX300\.jpg]\nsecond part of text\nplus newline\.", "reply_markup": {"inline_keyboard": [ [{"text":"Bei Amazon ansehen \.\.\.", "url":"https://www.amazon.de/dp/B014TN3JYW"}] ]} URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage chat:123456 JSON:"text":"\# test for sendfile" From 749eee74a421c243abdfc85e03ffdf3ef3467612 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 20 Jan 2021 19:50:19 +0100 Subject: [PATCH 15/99] dev: adjust make-standalone --- bashbot.sh | 15 +++++++-------- commands.sh | 4 ++-- dev/make-standalone.sh | 21 +++++++++++---------- modules/aliases.sh | 4 ++-- modules/answerInline.sh | 40 ++++++++++++++++++++-------------------- modules/background.sh | 8 ++++---- modules/jsonDB.sh | 12 ++++++------ modules/sendMessage.sh | 16 ++++++++-------- 8 files changed, 60 insertions(+), 60 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 8d43d72..e3781f9 100755 --- a/bashbot.sh +++ b/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.31-dev-12-g85a178d +#### $$VERSION$$ v1.31-dev-13-g127cc85 ################################################################## # emmbeded system may claim bash but it is not @@ -90,7 +90,7 @@ _is_function() { _round_float() { local digit="$2"; [[ "$2" =~ ^[${o9o9o9}]+$ ]] || digit="0" : "$(LC_ALL=C printf "%.${digit}f" "$1" 2>/dev/null)" - printf "%s" "${_//,/.}" # make more LANG independent + printf "%s" "${_//,/.}" # make more LANG independent } # date is external, printf is much faster _date(){ @@ -185,7 +185,7 @@ fi [ -z "${BASHBOT_VAR}" ] && BASHBOT_VAR="${BASHBOT_HOME}" ADDONDIR="${BASHBOT_ETC:-.}/addons" -RUNUSER="${USER}" # USER is overwritten by bashbot array :-(, save original +RUNUSER="${USER}" # USER is overwritten by bashbot array :-(, save original # provide help case "$1" in @@ -325,7 +325,7 @@ fi ################## # here we start with the real stuff -BASHBOT_RETRY="" # retry by default +BASHBOT_RETRY="" # retry by default URL="${BASHBOT_URL:-https://api.telegram.org/bot}${BOTTOKEN}" ME_URL=${URL}'/getMe' @@ -438,7 +438,7 @@ sendJson(){ local json chat="" if [ -n "$1" ]; then chat='"chat_id":'"$1"',' - [[ "$1" == *[!${o9o9o9}-]* ]] && chat='"chat_id":"'"$1"' NAN",' # chat id not a number! + [[ "$1" == *[!${o9o9o9}-]* ]] && chat='"chat_id":"'"$1"' NAN",' # chat id not a number! fi # compose final json json='{'"${chat} $(iconv -f utf-8 -t utf-8 -c <<<"$2")"'}' @@ -887,7 +887,6 @@ process_message() { CHAT[ALL_ADMIN]="${UPD["result,${num},message,chat,all_members_are_administrators"]}" # user ID is now parsed when update is received - #USER[ID]="${UPD["result,${num},message,from,id"]}" 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"]}")" @@ -907,7 +906,7 @@ process_message() { # 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[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"]}")" @@ -1203,7 +1202,7 @@ if [ -z "${SOURCE}" ]; then [ "$1" = "botname" ] && exit ;;& # used to send output of background and interactive to chats - "outproc") # $2 chat_id $3 identifier of job, internal use only! + "outproc") # $2 chat_id $3 identifier of job, internal use only! [ -z "$3" ] && printf "No job identifier\n" && exit 3 [ -z "$2" ] && printf "No chat to send to\n" && exit 3 ME="$(getConfigKey "botname")" diff --git a/commands.sh b/commands.sh index f3f95a4..0b10d04 100644 --- a/commands.sh +++ b/commands.sh @@ -15,7 +15,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.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-13-g127cc85 # # bashbot locale defaults to c.UTF-8, adjust locale in mycommands.sh if needed @@ -127,7 +127,7 @@ if [ -z "$1" ] || [[ "$1" == *"debug"* ]];then '/help'*) send_markdown_message "${CHAT[ID]}" "${bashbot_help}" ;; - '/leavechat'*) # bot leave chat if user is admin in chat + '/leavechat'*) # bot leave chat if user is admin in chat if user_is_admin "${CHAT[ID]}" "${USER[ID]}" || user_is_allowed "${USER[ID]}" "leave" ; then send_markdown_message "${CHAT[ID]}" "*LEAVING CHAT...*" leave_chat "${CHAT[ID]}" diff --git a/dev/make-standalone.sh b/dev/make-standalone.sh index a9f9e69..90e7c0f 100755 --- a/dev/make-standalone.sh +++ b/dev/make-standalone.sh @@ -11,7 +11,7 @@ # If you your bot is finished you can use make-standalone.sh to create the # the old all-in-one bashbot: bashbot.sh and commands.sh only! # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-13-g127cc85 ################################################################### #shellcheck disable=SC1090 @@ -73,13 +73,14 @@ printf "\n... create unified bashbot.sh\n" # first head of bashbot.sh sed -n '0,/for module in/ p' bashbot.sh | head -n -3 - # then mycommands from first non comment line on + # then modules without shebang printf '\n##############################\n# bashbot modules starts here ...\n' - cat modules/*.sh | sed -e 's/^#\!\/bin\/bash.*//' + # shellcheck disable=SC2016 + cat modules/*.sh | sed -e 's/^#\!\/bin\/bash.*//' -e '/^#.*\$\$VERSION\$\$/d' - # last tail of commands.sh - printf '\n##############################\n# bashbot internal functions starts here ...\n\n' - sed -n '/BASHBOT INTERNAL functions/,$ p' bashbot.sh + # last remaining commands.sh + printf '\n##############################\n' + sed -n '/^# read commands file/,$ p' bashbot.sh } >>$$bashbot.sh @@ -90,11 +91,11 @@ rm -rf modules printf "Create minimized Version of bashbot.sh and commands.sh\n" # shellcheck disable=SC2016 -sed -E -e '/(shellcheck)|(^#!\/)|(\$\$VERSION\$\$)/! s/^[[:space:]]*#.*//' -e 's/^[[:space:]]*//' -e '/^$/d' -e 'N;s/\\\n/ /;P;D' bashbot.sh |\ - sed 'N;s/\\\n/ /;P;D' > bashbot.sh.min +sed -E -e '/(shellcheck)|(^#!\/)|(\$\$VERSION\$\$)/! s/^[[:space:]]*#.*//' -e '/shellcheck/! s/\t+#.*//' -e 's/^[[:space:]]*//'\ + -e '/^$/d' bashbot.sh | sed 'N;s/\\\n/ /;P;D' | sed 'N;s/\\\n/ /;P;D' > bashbot.sh.min # shellcheck disable=SC2016 -sed -E -e '/(shellcheck)|(^#!\/)|(\$\$VERSION\$\$)/! s/^[[:space:]]*#.*//' -e 's/^[[:space:]]*//' -e 's/\)[[:space:]]+#.*/)/' -e '/^$/d' commands.sh |\ - sed 'N;s/\\\n/ /;P;D' > commands.sh.min +sed -E -e '/(shellcheck)|(^#!\/)|(\$\$VERSION\$\$)/! s/^[[:space:]]*#.*//' -e '/shellcheck/! s/\t+#.*//' -e 's/^[[:space:]]*//'\ + -e '/^$/d' commands.sh | sed 'N;s/\\\n/ /;P;D' > commands.sh.min chmod +x bashbot.sh.min # make html doc diff --git a/modules/aliases.sh b/modules/aliases.sh index 0e551a7..f8cfc6e 100644 --- a/modules/aliases.sh +++ b/modules/aliases.sh @@ -1,11 +1,11 @@ #!/bin/bash -# file: modules/alaises.sh +# file: modules/aliases.sh # do not edit, this file will be overwritten on update # This file is public domain in the USA and all free countries. # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-13-g127cc85 # # will be automatically sourced from bashbot diff --git a/modules/answerInline.sh b/modules/answerInline.sh index 76ffb64..52f450b 100644 --- a/modules/answerInline.sh +++ b/modules/answerInline.sh @@ -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.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-13-g127cc85 # will be automatically sourced from bashbot @@ -31,70 +31,70 @@ inline_query_compose(){ # title2Json title caption description markup inlinekeyboard case "$2" in # user provided media - "article"|"message") # article ID title message (markup description) + "article"|"message") # article ID title message (markup description) JSON='{"type":"article","id":"'${ID}'","input_message_content": {"message_text":"'$4'"} '$(title2Json "$3" "" "$5" "$6" "$7")'}' ;; - "photo") # photo ID photoURL (thumbURL title description caption) + "photo") # photo ID photoURL (thumbURL title description caption) [ -z "$4" ] && tumb="$3" JSON='{"type":"photo","id":"'${ID}'","photo_url":"'$3'","thumb_url":"'$4${tumb}'"'$(title2Json "$5" "$7" "$6" "$7" "$8")'}' ;; - "gif") # gif ID photoURL (thumbURL title caption) + "gif") # gif ID photoURL (thumbURL title caption) [ -z "$4" ] && tumb="$3" JSON='{"type":"gif","id":"'${ID}'","gif_url":"'$3'", "thumb_url":"'$4${tumb}'"'$(title2Json "$5" "$6" "$7" "$8" "$9")'}' ;; - "mpeg4_gif") # mpeg4_gif ID mpegURL (thumbURL title caption) + "mpeg4_gif") # mpeg4_gif ID mpegURL (thumbURL title caption) [ -n "$4" ] && tumb='","thumb_url":"'$4'"' JSON='{"type":"mpeg4_gif","id":"'${ID}'","mpeg4_url":"'$3'"'${tumb}$(title2Json "$5" "$6" "" "$7" "$8")'}' ;; - "video") # video ID videoURL mime thumbURL title (caption) + "video") # video ID videoURL mime thumbURL title (caption) JSON='{"type":"video","id":"'${ID}'","video_url":"'$3'","mime_type":"'$4'","thumb_url":"'$5'"'$(title2Json "$6" "$7" "$8" "$9" "${10}")'}' ;; - "audio") # audio ID audioURL title (caption) + "audio") # audio ID audioURL title (caption) JSON='{"type":"audio","id":"'${ID}'","audio_url":"'$3'"'$(title2Json "$4" "$5" "" "" "$6")'}' ;; - "voice") # voice ID voiceURL title (caption) + "voice") # voice ID voiceURL title (caption) JSON='{"type":"voice","id":"'${ID}'","voice_url":"'$3'"'$(title2Json "$4" "$5" "" "" "$6")'}' ;; - "document") # document ID title documentURL mimetype (caption description) + "document") # document ID title documentURL mimetype (caption description) JSON='{"type":"document","id":"'${ID}'","document_url":"'$4'","mime_type":"'$5'"'$(title2Json "$3" "$6" "$7" "$8" "$9")'}' ;; - "location") # location ID lat long title + "location") # location ID lat long title JSON='{"type":"location","id":"'${ID}'","latitude":"'$3'","longitude":"'$4'","title":"'$5'"}' ;; - "venue") # venue ID lat long title (address forsquare) + "venue") # venue ID lat long title (address forsquare) [ -z "$6" ] && addr="$5" [ -n "$7" ] && fours=',"foursquare_id":"'$7'"' JSON='{"type":"venue","id":"'${ID}'","latitude":"'$3'","longitude":"'$4'","title":"'$5'","address":"'$6${addr}'"'${fours}'}' ;; - "contact") # contact ID phone first (last thumb) + "contact") # contact ID phone first (last thumb) [ -n "$5" ] && last=',"last_name":"'$5'"' [ -n "$6" ] && tumb='","thumb_url":"'$6'"' JSON='{"type":"contact","id":"'${ID}'","phone_number":"'$3'","first_name":"'$4'"'${last}'"}' ;; # title2Json title caption description markup inlinekeyboard # Cached media stored in Telegram server - "cached_photo") # photo ID file (title description caption) + "cached_photo") # photo ID file (title description caption) JSON='{"type":"photo","id":"'${ID}'","photo_file_id":"'$3'"'$(title2Json "$4" "$6" "$5" "$7" "$8")'}' ;; - "cached_gif") # gif ID file (title caption) + "cached_gif") # gif ID file (title caption) JSON='{"type":"gif","id":"'${ID}'","gif_file_id":"'$3'"'$(title2Json "$4" "$5" "$6" "$7" "$8" )'}' ;; - "cached_mpeg4_gif") # mpeg ID file (title caption) + "cached_mpeg4_gif") # mpeg ID file (title caption) JSON='{"type":"mpeg4_gif","id":"'${ID}'","mpeg4_file_id":"'$3'"'$(title2Json "$4" "$5" "" "$6" "$7")'}' ;; - "cached_sticker") # sticker ID file + "cached_sticker") # sticker ID file JSON='{"type":"sticker","id":"'${ID}'","sticker_file_id":"'$3'"}' ;; - "cached_document") # document ID title file (description caption) + "cached_document") # document ID title file (description caption) JSON='{"type":"document","id":"'${ID}'","document_file_id":"'$4'"'$(title2Json "$3" "$6" "$5" "$6" "$7")'}' ;; - "cached_video") # video ID file title (description caption) + "cached_video") # video ID file title (description caption) JSON='{"type":"video","id":"'${ID}'","video_file_id":"'$3'"'$(title2Json "$4" "$6" "$5" "$7" "$8")'}' ;; - "cached_voice") # voice ID file title (caption) + "cached_voice") # voice ID file title (caption) JSON='{"type":"voice","id":"'${ID}'","voice_file_id":"'$3'"'$(title2Json "$4" "$5" "" "" "$6")'}' ;; - "cached_audio") # audio ID file title (caption) + "cached_audio") # audio ID file title (caption) JSON='{"type":"audio","id":"'${ID}'","audio_file_id":"'$3'"'$(title2Json "$4" "$5" "" "" "$6")'}' ;; esac diff --git a/modules/background.sh b/modules/background.sh index 4409616..b793806 100644 --- a/modules/background.sh +++ b/modules/background.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117,SC2059 -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-13-g127cc85 # will be automatically sourced from bashbot @@ -51,7 +51,7 @@ restart_back() { log_message "Start background job CHAT=$1 JOB=${fifo##*/} CMD=${2##*/} $4 $5" check_back "$1" "$3" && kill_proc "$1" "back-$3-" nohup bash -c "{ $2 \"$4\" \"$5\" \"${fifo}\" | \"${SCRIPT}\" outproc \"$1\" \"${fifo}\"; }" &>>"${fifo}.log" & - sleep 0.5 # give bg job some time to init + sleep 0.5 # give bg job some time to init } @@ -110,7 +110,7 @@ kill_proc() { # $2 message send_interactive() { local fifo; fifo="${DATADIR:-.}/$(procname "$1")" - [ -p "${fifo}" ] && printf '%s\n' "$2" >"${fifo}" & # not blocking! + [ -p "${fifo}" ] && printf '%s\n' "$2" >"${fifo}" & # not blocking! } # old style but may not work because of local checks @@ -154,7 +154,7 @@ job_control() { "killb"*) printf "Kill Job: %s %s\n" "${proc}" " ${fifo##*/}" kill_proc "${CHAT}" "${job}" - rm -f "${FILE}" # remove job + rm -f "${FILE}" # remove job # inform botadmin about stop [ -n "${ADM}" ] && send_normal_message "${ADM}" "Bot ${BOT} kill background jobs ..." & killall="y" diff --git a/modules/jsonDB.sh b/modules/jsonDB.sh index 9c49c3c..9169aa8 100644 --- a/modules/jsonDB.sh +++ b/modules/jsonDB.sh @@ -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.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-13-g127cc85 # # source from commands.sh to use jsonDB functions # @@ -42,7 +42,7 @@ JSSH_KEYOK="[-${azAZo9},._]" # $1 - invalid charcaters are replaced with first character # or deleted if $1 is empty jssh_stripKey() { # tr: we must escape first - in [-a-z...] - if [[ "$1" =~ ^${JSSH_KEYOK} ]]; then # tr needs [\-... + if [[ "$1" =~ ^${JSSH_KEYOK} ]]; then # tr needs [\-... tr -c "${JSSH_KEYOK/\[-/[\\-}\r\n" "${1:0:1}" else tr -dc "${JSSH_KEYOK/\[-/[\\-}\r\n" @@ -86,7 +86,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then jssh_updateDB() { # for atomic update we can't use read/writeDB [ -z "$2" ] && return 1 - local DB="$2.jssh" # check in async + local DB="$2.jssh" # check in async [ ! -f "${DB}" ] && return 2 { flock -e -w 10 200; jssh_updateDB_async "$@"; } 200>"${DB}${JSSH_LOCKNAME}" } @@ -95,7 +95,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then # $1 key name, can only contain -a-zA-Z0-9,._ # $2 key value # $3 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..' - alias jssh_insertDB=jssh_insertKeyDB # backward compatibility + alias jssh_insertDB=jssh_insertKeyDB # backward compatibility # renamed to be more consistent jssh_insertKeyDB() { [[ "$1" =~ ^${JSSH_KEYOK}+$ ]] || return 3 @@ -179,7 +179,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then # medium complex, wrapper async jssh_updateArray() { [ -z "$2" ] && return 1 - local DB="$2.jssh" # name check in async + local DB="$2.jssh" # name check in async [ ! -f "${DB}" ] && return 2 declare -n ARRAY="$1" [[ -z "${ARRAY[*]}" || "${DB}" -nt "${DB}.last$3" ]] && touch "${DB}.last$3" && jssh_readDB "$1" "$2" @@ -216,7 +216,7 @@ jssh_newDB_async() { jssh_newDB "$@"; } jssh_newDB() { local DB; DB="$(jssh_checkDB "$1")" [ -z "${DB}" ] && return 1 - [ -f "${DB}" ] && return 2 # already exist + [ -f "${DB}" ] && return 2 # already exist touch "${DB}" } diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 55e997a..bd54e86 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.31-dev-9-g6c91a32 +#### $$VERSION$$ v1.31-dev-13-g127cc85 # will be automatically sourced from bashbot @@ -176,7 +176,7 @@ if detect_curl ; then # $1 chat $3 ... $n URL or ID send_album(){ [ -z "$1" ] && return 1 - [ -z "$3" ] && return 2 # minimum 2 files + [ -z "$3" ] && return 2 # minimum 2 files local CHAT JSON IMAGE; CHAT="$1"; shift for IMAGE in "$@" do @@ -212,13 +212,13 @@ send_file(){ else # we have a file, check file location ... media="FILE" - [[ "${file}" = *'..'* || "${file}" = '.'* ]] && err=1 # no directory traversal + [[ "${file}" = *'..'* || "${file}" = '.'* ]] && err=1 # no directory traversal if [[ "${file}" = '/'* ]] ; then - [[ ! "${file}" =~ ${FILE_REGEX} ]] && err=2 # absolute must match REGEX + [[ ! "${file}" =~ ${FILE_REGEX} ]] && err=2 # absolute must match REGEX else - file="${UPLOADDIR:-NOUPLOADDIR}/${file}" # others must be in UPLOADDIR + file="${UPLOADDIR:-NOUPLOADDIR}/${file}" # others must be in UPLOADDIR fi - [ ! -r "${file}" ] && err=3 # and file must exits of course + [ ! -r "${file}" ] && err=3 # and file must exits of course # file path error, generate error response if [ -n "${err}" ]; then BOTSENT=(); BOTSENT[OK]="false" @@ -311,7 +311,7 @@ forward_message() { [ -z "$3" ] && return sendJson "$1" '"from_chat_id": '"$2"', "message_id": '"$3"'' "${URL}/forwardMessage" } -forward() { # backward compatibility +forward() { # backward compatibility forward_message "$@" || return } @@ -339,7 +339,7 @@ send_message() { sent=y fi if [ -n "${keyboard}" ]; then - if [[ "${keyboard}" != *"["* ]]; then # pre 0.60 style + if [[ "${keyboard}" != *"["* ]]; then # pre 0.60 style keyboard="[ ${keyboard//\" \"/\" \] , \[ \"} ]" fi send_keyboard "$1" "${text}" "${keyboard}" From 07f026c6a722afdf0dbbc9e1e662095598adca8f Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Thu, 21 Jan 2021 09:22:14 +0100 Subject: [PATCH 16/99] bin: less duplicate code --- bin/bashbot_env.inc.sh | 23 ++++++++++++++++++++++- bin/bashbot_stats.sh | 18 +++--------------- bin/delete_message.sh | 23 ++++------------------- bin/send_broadcast.sh | 17 +++-------------- bin/send_buttons.sh | 21 ++++----------------- bin/send_edit_message.sh | 20 ++++---------------- bin/send_file.sh | 21 ++++----------------- bin/send_message.sh | 19 ++++--------------- 8 files changed, 48 insertions(+), 114 deletions(-) diff --git a/bin/bashbot_env.inc.sh b/bin/bashbot_env.inc.sh index b837412..7feff46 100644 --- a/bin/bashbot_env.inc.sh +++ b/bin/bashbot_env.inc.sh @@ -13,7 +13,7 @@ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.12.2020 12:27 # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-14-g749eee7 #=============================================================================== ############ @@ -63,3 +63,24 @@ BOT_NAME="$(getConfigKey "botname")" [[ -z "${BOT_ADMIN}" || "${BOT_ADMIN}" == "?" ]] && printf "%s\n" "${ORANGE}Warning: Botadmin not set, did you forget to sent command${NC} /start" [[ -z "${BOT_NAME}" ]] && printf "%s\n" "${ORANGE}Warning: Botname not set, did you ever run bashbot?" +# output command result or Telegram response +print_result() { jssh_printDB "BOTSENT" | sort -r; } +print_response() { jssh_printDB "UPD"; } + +# check and output help +print_help() { + case "$1" in + '') + printf "missing arguments\n" + ;& + "-h"*) + printf 'usage: %s\n' "${USAGE}" + exit 1 + ;; + '--h'*) + sed -n '/^#====/,/^#====/p' <"$0" + exit 1 + ;; + esac +} + diff --git a/bin/bashbot_stats.sh b/bin/bashbot_stats.sh index 53a6b25..5c03dae 100755 --- a/bin/bashbot_stats.sh +++ b/bin/bashbot_stats.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090,SC2034 #=============================================================================== # # FILE: bin/bashbot_stats.sh @@ -16,25 +17,12 @@ USAGE='bashbot_stats.sh [-h|--help] [debug]' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 23.12.2020 20:34 # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-14-g749eee7 #=============================================================================== -#### -# parse args -case "$1" in - "-h"*) - printf "usage: %s\n" "${USAGE}" - exit 1 - ;; - '--h'*) - sed -n '3,/###/p' <"$0" - exit 1 - ;; -esac - # set bashbot environment -# shellcheck disable=SC1090 source "${0%/*}/bashbot_env.inc.sh" "$1" +[ -n "$1" ] && print_help #### # ready, do stuff here ----- diff --git a/bin/delete_message.sh b/bin/delete_message.sh index 6d42a40..7bcead1 100755 --- a/bin/delete_message.sh +++ b/bin/delete_message.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090,SC2034 #=============================================================================== # # FILE: bin/delete_message.sh @@ -19,32 +20,17 @@ USAGE='delete_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" [debug]' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 03.01.2021 15:37 # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-14-g749eee7 #=============================================================================== #### # parse args DELETE="delete_message" -case "$1" in - '') - printf "missing arguments\n" - ;& - "-h"*) - printf 'usage: %s\n' "${USAGE}" - exit 1 - ;; - '--h'*) - sed -n '3,/###/p' <"$0" - exit 1 - ;; -esac - # set bashbot environment -# shellcheck disable=SC1090 source "${0%/*}/bashbot_env.inc.sh" "${3:-debug}" # $3 debug +print_help -#### #### # ready, do stuff here ----- if [ "$1" == "BOTADMIN" ]; then @@ -59,5 +45,4 @@ fi [ "${BOTSENT[OK]}" = "true" ] && BOTSENT[ID]="$2" # output send message result -jssh_printDB "BOTSENT" | sort -r - +print_result diff --git a/bin/send_broadcast.sh b/bin/send_broadcast.sh index 9ccc90c..7578052 100755 --- a/bin/send_broadcast.sh +++ b/bin/send_broadcast.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090,SC2034 #=============================================================================== # shellcheck disable=SC2059 # @@ -27,7 +28,7 @@ USAGE='broadcast_message.sh [-h|--help] [--doit] [--groups|--both|--db=file] [fo # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 16.12.2020 16:14 # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-14-g749eee7 #=============================================================================== #### @@ -75,23 +76,11 @@ case "$1" in SEND="send_html_message" shift ;; - '') - printf "missing missing arguments\n" - ;& - "-h"*) - printf 'usage: %s\n' "${USAGE}" - exit 1 - ;; - '--h'*) - sed -n -e '/# shellcheck /d' -e '3,/###/p' <"$0" - exit 1 - ;; esac # set bashbot environment -# shellcheck disable=SC1090 source "${0%/*}/bashbot_env.inc.sh" "$2" # $3 debug - +print_help # read in users from given DB or count.jssh database="${USERDB:-${COUNTFILE}}" diff --git a/bin/send_buttons.sh b/bin/send_buttons.sh index 830fd02..d491531 100755 --- a/bin/send_buttons.sh +++ b/bin/send_buttons.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090,SC2034 #=============================================================================== # # FILE: bin/send_message.sh @@ -24,29 +25,16 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.01.2021 11:34 # -#### $$VERSION$$ v1.31-dev-10-gf95b6c2 +#### $$VERSION$$ v1.31-dev-14-g749eee7 #=============================================================================== #### # parse args SEND="send_inline_keyboard" -case "$1" in - '') - printf "missing arguments\n" - ;& - "-h"*) - printf 'usage: %s\n' "${USAGE}" - exit 1 - ;; - '--h'*) - sed -n '3,/###/p' <"$0" - exit 1 - ;; -esac # set bashbot environment -# shellcheck disable=SC1090 source "${0%/*}/bashbot_env.inc.sh" "debug" +print_help #### # ready, do stuff here ----- @@ -62,5 +50,4 @@ shift 2 "${SEND}" "${CHAT}" "${TEXT}" "$(_button_row "$@")" # output send message result -jssh_printDB "BOTSENT" | sort -r - +print_result diff --git a/bin/send_edit_message.sh b/bin/send_edit_message.sh index ad8bb38..e7fb7f9 100755 --- a/bin/send_edit_message.sh +++ b/bin/send_edit_message.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090,SC2034 #=============================================================================== # # FILE: bin/send_message.sh @@ -22,7 +23,7 @@ USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID] # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 23.12.2020 16:52 # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-14-g749eee7 #=============================================================================== #### @@ -45,24 +46,12 @@ case "$1" in SEND="edit_message_caption" shift ;; - '') - printf "missing arguments\n" - ;& - "-h"*) - printf 'usage: %s\n' "${USAGE}" - exit 1 - ;; - '--h'*) - sed -n '3,/###/p' <"$0" - exit 1 - ;; esac # set bashbot environment -# shellcheck disable=SC1090 source "${0%/*}/bashbot_env.inc.sh" "${4:-debug}" # $4 debug +print_help -#### #### # ready, do stuff here ----- if [ "$1" == "BOTADMIN" ]; then @@ -75,5 +64,4 @@ fi "${SEND}" "${CHAT}" "$2" "$3" # output send message result -jssh_printDB "BOTSENT" | sort -r - +print_result diff --git a/bin/send_file.sh b/bin/send_file.sh index 5a42b2c..d4886db 100755 --- a/bin/send_file.sh +++ b/bin/send_file.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090,SC2034 #=============================================================================== # # FILE: bin/send_file.sh @@ -24,29 +25,16 @@ USAGE='send_file.sh [-h|--help] "CHAT[ID]" "file|URL" "caption ...." [type] [deb # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 25.12.2020 20:24 # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-14-g749eee7 #=============================================================================== #### # parse args SEND="send_file" -case "$1" in - '') - printf "missing arguments\n" - ;& - "-h"*) - printf 'usage: %s\n' "${USAGE}" - exit 1 - ;; - '--h'*) - sed -n '3,/###/p' <"$0" - exit 1 - ;; -esac # set bashbot environment -# shellcheck disable=SC1090 source "${0%/*}/bashbot_env.inc.sh" "${5:-debug}" # $5 debug +print_help #### # ready, do stuff here ----- @@ -64,5 +52,4 @@ FILE="$2" "${SEND}" "${CHAT}" "${FILE}" "$3" "$4" # output send message result -jssh_printDB "BOTSENT" | sort -r - +print_result diff --git a/bin/send_message.sh b/bin/send_message.sh index 21faf2c..2db6cc1 100755 --- a/bin/send_message.sh +++ b/bin/send_message.sh @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC1090,SC2034 #=============================================================================== # # FILE: bin/send_message.sh @@ -21,7 +22,7 @@ USAGE='send_message.sh [-h|--help] [format] "CHAT[ID]" "message ...." [debug]' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 16.12.2020 11:34 # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-14-g749eee7 #=============================================================================== #### @@ -40,22 +41,11 @@ case "$1" in SEND="send_html_message" shift ;; - '') - printf "missing arguments\n" - ;& - "-h"*) - printf 'usage: %s\n' "${USAGE}" - exit 1 - ;; - '--h'*) - sed -n '3,/###/p' <"$0" - exit 1 - ;; esac # set bashbot environment -# shellcheck disable=SC1090 source "${0%/*}/bashbot_env.inc.sh" "${3:-debug}" # $3 debug +print_help "$1" #### # ready, do stuff here ----- @@ -69,5 +59,4 @@ fi "${SEND}" "${CHAT}" "$2" # output send message result -jssh_printDB "BOTSENT" | sort -r - +print_result From e9543991ee7c596d134bbe7dc96a1bfd6dcbc2e6 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Thu, 21 Jan 2021 19:51:04 +0100 Subject: [PATCH 17/99] add shellcheck for bashbot.conf --- dev/shellcheck.files | 3 ++- mycommands.conf | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dev/shellcheck.files b/dev/shellcheck.files index f43ba31..fcd09c6 100644 --- a/dev/shellcheck.files +++ b/dev/shellcheck.files @@ -1,4 +1,5 @@ # list of additional files to check from shellcheck -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-15-g07f026c bashbot.rc +mycommands.conf mycommands.sh.clean diff --git a/mycommands.conf b/mycommands.conf index e06fe09..736928d 100644 --- a/mycommands.conf +++ b/mycommands.conf @@ -1,4 +1,5 @@ #!/bin/bash +# shellcheck disable=SC2034 ####################################################### # # File: mycommands.conf @@ -11,7 +12,7 @@ # Author: KayM (gnadelwartz), kay@rrr.de # Created: 09.01.2021 07:27 # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.31-dev-15-g07f026c ####################################################### ########## From 662c6f48cbbcf38c3faeac9a5b94a578b662cfa5 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Fri, 22 Jan 2021 08:11:57 +0100 Subject: [PATCH 18/99] modules: add edit_inline_keyboard --- modules/sendMessage.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index bd54e86..ca776d0 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.31-dev-13-g127cc85 +#### $$VERSION$$ v1.32-dev-0-ge954399 # will be automatically sourced from bashbot @@ -137,6 +137,13 @@ remove_keyboard() { #JSON='"text":"$2", "reply_markup": {"remove_keyboard":true}' } +# $1 CHAT $2 message-id $3 keyboard +edit_inline_keyboard() { + sendJson "$1" '"message_id":'"$2"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${URL}/editMessageReplyMarkup" + # JSON='"message_id":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}' +} + + # $1 CHAT $2 message $3 keyboard send_inline_keyboard() { local text; text='"text":"'$(JsonEscape "$2")'"'; [ -z "$2" ] && text='"text":"..."' From db8f32b732d7ac146ea8d19c79f7339b020f5bb0 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Fri, 22 Jan 2021 08:14:19 +0100 Subject: [PATCH 19/99] bin: add edit_buttons.sh --- bin/edit_buttons.sh | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100755 bin/edit_buttons.sh diff --git a/bin/edit_buttons.sh b/bin/edit_buttons.sh new file mode 100755 index 0000000..b5c8572 --- /dev/null +++ b/bin/edit_buttons.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# shellcheck disable=SC1090,SC2034 +#=============================================================================== +# +# FILE: bin/edit_buttons.sh +# +USAGE='send_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" "text|url" ...' +# +# DESCRIPTION: send a send buttons in a row to the given user/group +# +# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself +# MESSAGE[ID] - ID of MESSAGE with buttons to edit +# text|url - buttons to send, each button as "text|url" pair or +# "url" only to show url as text also, "" starts new row +# +# -h - display short help +# --help - this help +# +# EXAMPLE: 2 buttons on 2 rows, first shows Amazon, second the url as text +# send_buttons.sh "Amazon|https://www.amazon.com" "" "https://mydealz.de" ... +# +# Set BASHBOT_HOME to your installation directory +# +# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ +# AUTHOR: KayM (gnadelwartz), kay@rrr.de +# CREATED: 21.01.2021 08:10 +# +#### $$VERSION$$ v1.32-dev-1-g662c6f4 +#=============================================================================== + +#### +# parse args +SEND="edit_inline_keyboard" + +# set bashbot environment +source "${0%/*}/bashbot_env.inc.sh" "debug" +print_help + +#### +# ready, do stuff here ----- +if [ "$1" == "BOTADMIN" ]; then + CHAT="${BOT_ADMIN}" +else + CHAT="$1" +fi +MESSAGE_ID="$2" +shift 2 + +# send message in selected format +"${SEND}" "${CHAT}" "${MESSAGE_ID}" "$(_button_row "$@")" + +# output send message result +print_result From 437105020655b3c441cebcf663d508ea83d815ac Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Fri, 22 Jan 2021 08:18:17 +0100 Subject: [PATCH 20/99] bin: rename to edit_message.sh --- bin/edit_message.sh | 67 ++++++++++++++++++++++++++++++++++++++++ bin/send_buttons.sh | 6 ++-- bin/send_edit_message.sh | 2 +- 3 files changed, 71 insertions(+), 4 deletions(-) create mode 100755 bin/edit_message.sh diff --git a/bin/edit_message.sh b/bin/edit_message.sh new file mode 100755 index 0000000..e7fb7f9 --- /dev/null +++ b/bin/edit_message.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# shellcheck disable=SC1090,SC2034 +#=============================================================================== +# +# FILE: bin/send_message.sh +# +USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID]" "message ...." [debug]' +# +# DESCRIPTION: replace a message in the given user/group +# +# OPTIONS: format - normal, markdown, html or caption for file caption (optional) +# CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself +# MESSAGE[ID] - message to replace +# message - message to send in specified format +# if no format is given send_normal_message() format is used +# +# -h - display short help +# --help - this help +# +# Set BASHBOT_HOME to your installation directory +# +# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ +# AUTHOR: KayM (gnadelwartz), kay@rrr.de +# CREATED: 23.12.2020 16:52 +# +#### $$VERSION$$ v1.31-dev-14-g749eee7 +#=============================================================================== + +#### +# parse args +SEND="edit_normal_message" +case "$1" in + "nor"*|"tex"*) + SEND="edit_normal_message" + shift + ;; + "mark"*) + SEND="edit_markdownv2_message" + shift + ;; + "htm"*) + SEND="edit_html_message" + shift + ;; + "cap"*) + SEND="edit_message_caption" + shift + ;; +esac + +# set bashbot environment +source "${0%/*}/bashbot_env.inc.sh" "${4:-debug}" # $4 debug +print_help + +#### +# ready, do stuff here ----- +if [ "$1" == "BOTADMIN" ]; then + CHAT="${BOT_ADMIN}" +else + CHAT="$1" +fi + +# send message in selected format +"${SEND}" "${CHAT}" "$2" "$3" + +# output send message result +print_result diff --git a/bin/send_buttons.sh b/bin/send_buttons.sh index d491531..28fd571 100755 --- a/bin/send_buttons.sh +++ b/bin/send_buttons.sh @@ -25,7 +25,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.01.2021 11:34 # -#### $$VERSION$$ v1.31-dev-14-g749eee7 +#### $$VERSION$$ v1.32-dev-1-g662c6f4 #=============================================================================== #### @@ -43,11 +43,11 @@ if [ "$1" == "BOTADMIN" ]; then else CHAT="$1" fi -TEXT="$2" +MESSAGE="$2" shift 2 # send message in selected format -"${SEND}" "${CHAT}" "${TEXT}" "$(_button_row "$@")" +"${SEND}" "${CHAT}" "${MESSAGE}" "$(_button_row "$@")" # output send message result print_result diff --git a/bin/send_edit_message.sh b/bin/send_edit_message.sh index e7fb7f9..5be25e3 100755 --- a/bin/send_edit_message.sh +++ b/bin/send_edit_message.sh @@ -23,7 +23,7 @@ USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID] # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 23.12.2020 16:52 # -#### $$VERSION$$ v1.31-dev-14-g749eee7 +#### $$VERSION$$ v1.32-dev-1-g662c6f4 #=============================================================================== #### From 407194b23f0ea255843a5d8eb800431513465533 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Fri, 22 Jan 2021 08:34:37 +0100 Subject: [PATCH 21/99] dev: fix symlink bug in version.sh --- dev/version.sh | 3 ++- modules/sendMessage.sh | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dev/version.sh b/dev/version.sh index 5090119..8c58291 100755 --- a/dev/version.sh +++ b/dev/version.sh @@ -43,7 +43,8 @@ unset IFS VERSION="$(git describe --tags --long)" printf "Update to version %s ...\n" "${VERSION}" -FILES="$(find ./*)" +# only regular files, ignore .dot files/dirs, e.g. .git .gitinore in BASEDIR +FILES="$(find ./* -type f)" [ "$1" != "" ] && FILES="$*" # autogenerate REMADME.html REMADE.txt diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index ca776d0..4911085 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.32-dev-0-ge954399 +#### $$VERSION$$ v1.32-dev-1-g662c6f4 # will be automatically sourced from bashbot From 3378c1a5d12b7d02f99c0406a85998e9c92932af Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Fri, 22 Jan 2021 08:51:28 +0100 Subject: [PATCH 22/99] dev: fix symlink counts as file :-( --- bin/send_edit_message.sh | 48 ++++++++++++++-------------------------- dev/version.sh | 5 +++-- 2 files changed, 20 insertions(+), 33 deletions(-) diff --git a/bin/send_edit_message.sh b/bin/send_edit_message.sh index 5be25e3..ca2a4f5 100755 --- a/bin/send_edit_message.sh +++ b/bin/send_edit_message.sh @@ -2,54 +2,38 @@ # shellcheck disable=SC1090,SC2034 #=============================================================================== # -# FILE: bin/send_message.sh +# FILE: bin/edit_buttons.sh # -USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID]" "message ...." [debug]' +USAGE='send_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" "text|url" ...' # -# DESCRIPTION: replace a message in the given user/group +# DESCRIPTION: send a send buttons in a row to the given user/group # -# OPTIONS: format - normal, markdown, html or caption for file caption (optional) -# CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself -# MESSAGE[ID] - message to replace -# message - message to send in specified format -# if no format is given send_normal_message() format is used +# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself +# MESSAGE[ID] - ID of MESSAGE with buttons to edit +# text|url - buttons to send, each button as "text|url" pair or +# "url" only to show url as text also, "" starts new row # # -h - display short help # --help - this help # +# EXAMPLE: 2 buttons on 2 rows, first shows Amazon, second the url as text +# send_buttons.sh "Amazon|https://www.amazon.com" "" "https://mydealz.de" ... +# # Set BASHBOT_HOME to your installation directory # # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de -# CREATED: 23.12.2020 16:52 +# CREATED: 21.01.2021 08:10 # -#### $$VERSION$$ v1.32-dev-1-g662c6f4 +#### $$VERSION$$ v1.32-dev-4-g407194b #=============================================================================== #### # parse args -SEND="edit_normal_message" -case "$1" in - "nor"*|"tex"*) - SEND="edit_normal_message" - shift - ;; - "mark"*) - SEND="edit_markdownv2_message" - shift - ;; - "htm"*) - SEND="edit_html_message" - shift - ;; - "cap"*) - SEND="edit_message_caption" - shift - ;; -esac +SEND="edit_inline_keyboard" # set bashbot environment -source "${0%/*}/bashbot_env.inc.sh" "${4:-debug}" # $4 debug +source "${0%/*}/bashbot_env.inc.sh" "debug" print_help #### @@ -59,9 +43,11 @@ if [ "$1" == "BOTADMIN" ]; then else CHAT="$1" fi +MESSAGE_ID="$2" +shift 2 # send message in selected format -"${SEND}" "${CHAT}" "$2" "$3" +"${SEND}" "${CHAT}" "${MESSAGE_ID}" "$(_button_row "$@")" # output send message result print_result diff --git a/dev/version.sh b/dev/version.sh index 8c58291..4e2d97a 100755 --- a/dev/version.sh +++ b/dev/version.sh @@ -1,6 +1,6 @@ #!/bin/bash # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.32-dev-4-g407194b # shellcheck disable=SC2016 # # Easy Versioning in git: @@ -64,7 +64,8 @@ fi # change version string in given files for file in ${FILES} do - [ ! -f "${file}" ] && continue + # symlink is a file :-( + [[ -L "${file}" || ! -f "${file}" ]] && continue #[ "${file}" == "version" ] && continue printf "%s" " ${file}" >&2 sed -i 's/^#### $$VERSION$$.*/#### \$\$VERSION\$\$ '"${VERSION}"'/' "${file}" From 28328013c770bd6cb418d5856cd725c0e905d035 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Fri, 22 Jan 2021 08:56:25 +0100 Subject: [PATCH 23/99] bin: finally symlink send_edit_message.sh --- bin/edit_message.sh | 4 +-- bin/send_edit_message.sh | 54 +--------------------------------------- 2 files changed, 3 insertions(+), 55 deletions(-) mode change 100755 => 120000 bin/send_edit_message.sh diff --git a/bin/edit_message.sh b/bin/edit_message.sh index e7fb7f9..e446517 100755 --- a/bin/edit_message.sh +++ b/bin/edit_message.sh @@ -2,7 +2,7 @@ # shellcheck disable=SC1090,SC2034 #=============================================================================== # -# FILE: bin/send_message.sh +# FILE: bin/edit_message.sh # USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID]" "message ...." [debug]' # @@ -23,7 +23,7 @@ USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID] # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 23.12.2020 16:52 # -#### $$VERSION$$ v1.31-dev-14-g749eee7 +#### $$VERSION$$ v1.32-dev-5-g3378c1a #=============================================================================== #### diff --git a/bin/send_edit_message.sh b/bin/send_edit_message.sh deleted file mode 100755 index ca2a4f5..0000000 --- a/bin/send_edit_message.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC1090,SC2034 -#=============================================================================== -# -# FILE: bin/edit_buttons.sh -# -USAGE='send_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" "text|url" ...' -# -# DESCRIPTION: send a send buttons in a row to the given user/group -# -# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself -# MESSAGE[ID] - ID of MESSAGE with buttons to edit -# text|url - buttons to send, each button as "text|url" pair or -# "url" only to show url as text also, "" starts new row -# -# -h - display short help -# --help - this help -# -# EXAMPLE: 2 buttons on 2 rows, first shows Amazon, second the url as text -# send_buttons.sh "Amazon|https://www.amazon.com" "" "https://mydealz.de" ... -# -# Set BASHBOT_HOME to your installation directory -# -# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ -# AUTHOR: KayM (gnadelwartz), kay@rrr.de -# CREATED: 21.01.2021 08:10 -# -#### $$VERSION$$ v1.32-dev-4-g407194b -#=============================================================================== - -#### -# parse args -SEND="edit_inline_keyboard" - -# set bashbot environment -source "${0%/*}/bashbot_env.inc.sh" "debug" -print_help - -#### -# ready, do stuff here ----- -if [ "$1" == "BOTADMIN" ]; then - CHAT="${BOT_ADMIN}" -else - CHAT="$1" -fi -MESSAGE_ID="$2" -shift 2 - -# send message in selected format -"${SEND}" "${CHAT}" "${MESSAGE_ID}" "$(_button_row "$@")" - -# output send message result -print_result diff --git a/bin/send_edit_message.sh b/bin/send_edit_message.sh new file mode 120000 index 0000000..e6089f6 --- /dev/null +++ b/bin/send_edit_message.sh @@ -0,0 +1 @@ +edit_message.sh \ No newline at end of file From 8bb4b7e5ac319368e585cb2323d9b2090a251b6f Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Fri, 22 Jan 2021 21:22:16 +0100 Subject: [PATCH 24/99] bin: fix missing print_help arg --- bin/bashbot_env.inc.sh | 2 +- bin/bashbot_stats.sh | 4 ++-- bin/delete_message.sh | 4 ++-- bin/edit_buttons.sh | 4 ++-- bin/edit_message.sh | 4 ++-- bin/send_broadcast.sh | 4 ++-- bin/send_buttons.sh | 4 ++-- bin/send_file.sh | 4 ++-- bin/send_message.sh | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/bin/bashbot_env.inc.sh b/bin/bashbot_env.inc.sh index 7feff46..b4d1568 100644 --- a/bin/bashbot_env.inc.sh +++ b/bin/bashbot_env.inc.sh @@ -13,7 +13,7 @@ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.12.2020 12:27 # -#### $$VERSION$$ v1.31-dev-14-g749eee7 +#### $$VERSION$$ v1.32-dev-6-g2832801 #=============================================================================== ############ diff --git a/bin/bashbot_stats.sh b/bin/bashbot_stats.sh index 5c03dae..4a80b14 100755 --- a/bin/bashbot_stats.sh +++ b/bin/bashbot_stats.sh @@ -17,12 +17,12 @@ USAGE='bashbot_stats.sh [-h|--help] [debug]' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 23.12.2020 20:34 # -#### $$VERSION$$ v1.31-dev-14-g749eee7 +#### $$VERSION$$ v1.32-dev-6-g2832801 #=============================================================================== # set bashbot environment source "${0%/*}/bashbot_env.inc.sh" "$1" -[ -n "$1" ] && print_help +[ -n "$1" ] && print_help "$1" #### # ready, do stuff here ----- diff --git a/bin/delete_message.sh b/bin/delete_message.sh index 7bcead1..39ecbb1 100755 --- a/bin/delete_message.sh +++ b/bin/delete_message.sh @@ -20,7 +20,7 @@ USAGE='delete_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" [debug]' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 03.01.2021 15:37 # -#### $$VERSION$$ v1.31-dev-14-g749eee7 +#### $$VERSION$$ v1.32-dev-6-g2832801 #=============================================================================== #### @@ -29,7 +29,7 @@ DELETE="delete_message" # set bashbot environment source "${0%/*}/bashbot_env.inc.sh" "${3:-debug}" # $3 debug -print_help +print_help "$1" #### # ready, do stuff here ----- diff --git a/bin/edit_buttons.sh b/bin/edit_buttons.sh index b5c8572..116e7e8 100755 --- a/bin/edit_buttons.sh +++ b/bin/edit_buttons.sh @@ -25,7 +25,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" "text|url" ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 21.01.2021 08:10 # -#### $$VERSION$$ v1.32-dev-1-g662c6f4 +#### $$VERSION$$ v1.32-dev-6-g2832801 #=============================================================================== #### @@ -34,7 +34,7 @@ SEND="edit_inline_keyboard" # set bashbot environment source "${0%/*}/bashbot_env.inc.sh" "debug" -print_help +print_help "$1" #### # ready, do stuff here ----- diff --git a/bin/edit_message.sh b/bin/edit_message.sh index e446517..04cb757 100755 --- a/bin/edit_message.sh +++ b/bin/edit_message.sh @@ -23,7 +23,7 @@ USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID] # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 23.12.2020 16:52 # -#### $$VERSION$$ v1.32-dev-5-g3378c1a +#### $$VERSION$$ v1.32-dev-6-g2832801 #=============================================================================== #### @@ -50,7 +50,7 @@ esac # set bashbot environment source "${0%/*}/bashbot_env.inc.sh" "${4:-debug}" # $4 debug -print_help +print_help "$1" #### # ready, do stuff here ----- diff --git a/bin/send_broadcast.sh b/bin/send_broadcast.sh index 7578052..bc08db8 100755 --- a/bin/send_broadcast.sh +++ b/bin/send_broadcast.sh @@ -28,7 +28,7 @@ USAGE='broadcast_message.sh [-h|--help] [--doit] [--groups|--both|--db=file] [fo # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 16.12.2020 16:14 # -#### $$VERSION$$ v1.31-dev-14-g749eee7 +#### $$VERSION$$ v1.32-dev-6-g2832801 #=============================================================================== #### @@ -80,7 +80,7 @@ esac # set bashbot environment source "${0%/*}/bashbot_env.inc.sh" "$2" # $3 debug -print_help +print_help "$1" # read in users from given DB or count.jssh database="${USERDB:-${COUNTFILE}}" diff --git a/bin/send_buttons.sh b/bin/send_buttons.sh index 28fd571..86ac108 100755 --- a/bin/send_buttons.sh +++ b/bin/send_buttons.sh @@ -25,7 +25,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.01.2021 11:34 # -#### $$VERSION$$ v1.32-dev-1-g662c6f4 +#### $$VERSION$$ v1.32-dev-6-g2832801 #=============================================================================== #### @@ -34,7 +34,7 @@ SEND="send_inline_keyboard" # set bashbot environment source "${0%/*}/bashbot_env.inc.sh" "debug" -print_help +print_help "$1" #### # ready, do stuff here ----- diff --git a/bin/send_file.sh b/bin/send_file.sh index d4886db..4c4fc88 100755 --- a/bin/send_file.sh +++ b/bin/send_file.sh @@ -25,7 +25,7 @@ USAGE='send_file.sh [-h|--help] "CHAT[ID]" "file|URL" "caption ...." [type] [deb # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 25.12.2020 20:24 # -#### $$VERSION$$ v1.31-dev-14-g749eee7 +#### $$VERSION$$ v1.32-dev-6-g2832801 #=============================================================================== #### @@ -34,7 +34,7 @@ SEND="send_file" # set bashbot environment source "${0%/*}/bashbot_env.inc.sh" "${5:-debug}" # $5 debug -print_help +print_help "$1" #### # ready, do stuff here ----- diff --git a/bin/send_message.sh b/bin/send_message.sh index 2db6cc1..ca324e9 100755 --- a/bin/send_message.sh +++ b/bin/send_message.sh @@ -22,7 +22,7 @@ USAGE='send_message.sh [-h|--help] [format] "CHAT[ID]" "message ...." [debug]' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 16.12.2020 11:34 # -#### $$VERSION$$ v1.31-dev-14-g749eee7 +#### $$VERSION$$ v1.32-dev-6-g2832801 #=============================================================================== #### From 2960e589413679915d22c01e823e23dacd70e920 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Fri, 22 Jan 2021 23:44:15 +0100 Subject: [PATCH 25/99] doc: add edit_inline_keyboard --- doc/6_reference.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index 7244504..b830895 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -275,6 +275,32 @@ send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"b1", "url":"http://rrr.d *See also [Inline keyboard markup](https://core.telegram.org/bots/api/#inlinekeyboardmarkup)* +##### edit_inline_keyboard +`edit_inline_keyboard` can add inline keyboards to existing messages and replace existing inline keyboards. +In both cases the message itself is not changed, only the attached inline keyboard. + +*usage:* edit_inline_keyboard "CHAT[ID]" "MESSAGE[ID]" "[JSON button array]" + +To create a JSON button array I suggest to use `_button_row`. + +```bash +# message without button +send_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message ..." +echo ${BOTSEND[ID]} +567 + +# add one button row +edit_inline_keyboard "${CHAT[ID]}" "567" "$(_button_row "button 1|http://rrr.de" "button 2|http://rrr.de")" + +# change buttons +edit_inline_keyboard "${CHAT[ID]}" "567" "$(_button_row "Success edit_inline_keyboard|http://rrr.de")" + +# delete button by replace whole message +edit_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message inline *removed*..." + +``` + + ---- ### Edit / Replace Messages @@ -1291,5 +1317,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.31-dev-12-g85a178d +#### $$VERSION$$ v1.32-dev-7-g8bb4b7e From 13052f01dac1abaf0a93d062ef7b2867e9f4fcc2 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 23 Jan 2021 09:12:48 +0100 Subject: [PATCH 26/99] README: mention JSON.awk --- README.html | 4 ++-- README.md | 6 +++--- README.txt | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.html b/README.html index dc43b96..59c69b0 100644 --- a/README.html +++ b/README.html @@ -223,8 +223,8 @@ Written by Drew (@topkecleon) and Kay M (@gnadelwartz).

Released to the public domain wherever applicable. Elsewhere, consider it released under the WTFPLv2.

Linted by #ShellCheck

Prerequisites

-

Uses JSON.sh and the magic of sed.

-

Bashbot is written in bash. It depends on commands typically available in a Linux/Unix Environment. For more concrete information on the common commands provided by recent versions of coreutils, busybox or toybox, see Developer Notes.

+

Uses JSON.sh/JSON.awk and the magic of sed.

+

Bashbot is written in bash. It depends on commands typically available in a Linux/Unix Environment. For more information on commands provided by recent versions of coreutils, busybox or toybox, see Developer Notes.

Note for MacOS and BSD Users: Bashbot will not run without installing additional software as it uses modern bash and (gnu) grep/sed features. See Install Bashbot.

Note for embedded systems: You need to install a "real" bash as the vanilla installation of busybox or toybox is not sufficient. See Install Bashbot.

Bashbot Documentation and Downloads are available on www.github.com.

diff --git a/README.md b/README.md index 87c5d05..19baa8f 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,10 @@ Elsewhere, consider it released under the [WTFPLv2](http://www.wtfpl.net/txt/cop Linted by [#ShellCheck](https://github.com/koalaman/shellcheck) ## Prerequisites -Uses [JSON.sh](http://github.com/dominictarr/JSON.sh) and the magic of sed. +Uses [JSON.sh](http://github.com/dominictarr/JSON.sh)/[JSON.awk](https://github.com/step-/JSON.awk) and the magic of sed. Bashbot is written in bash. It depends on commands typically available in a Linux/Unix Environment. -For more concrete information on the common commands provided by recent versions of [coreutils](https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands), [busybox](https://en.wikipedia.org/wiki/BusyBox#Commands) or [toybox](https://landley.net/toybox/help.html), see [Developer Notes](doc/7_develop.md#common-commands). +For more information on commands provided by recent versions of [coreutils](https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands), [busybox](https://en.wikipedia.org/wiki/BusyBox#Commands) or [toybox](https://landley.net/toybox/help.html), see [Developer Notes](doc/7_develop.md#common-commands). **Note for MacOS and BSD Users:** Bashbot will not run without installing additional software as it uses modern bash and (gnu) grep/sed features. See [Install Bashbot](doc/0_install.md). @@ -238,4 +238,4 @@ See `mycommnds.sh.dist` for an example. If you feel that there's something missing or if you found a bug, feel free to submit a pull request! -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.32-dev-8-g2960e58 diff --git a/README.txt b/README.txt index c558942..571819c 100644 --- a/README.txt +++ b/README.txt @@ -39,11 +39,11 @@ Linted by #ShellCheck Prerequisites -Uses JSON.sh [http://github.com/dominictarr/JSON.sh] and the magic of sed. +Uses JSON.sh [http://github.com/dominictarr/JSON.sh]/JSON.awk and the magic of sed. Bashbot is written in bash. It depends on commands typically available in a Linux/Unix -Environment. For more concrete information on the common commands provided by recent -versions of coreutils [https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands], -busybox or toybox, see Developer_Notes. +Environment. For more information on commands provided by recent versions of coreutils +[https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands], busybox or toybox, +see Developer_Notes. Note for MacOS and BSD Users: Bashbot will not run without installing additional software as it uses modern bash and (gnu) grep/sed features. See Install Bashbot [doc/ 0_install.md]. From 121f131bb4fe3bb6695637f57ee284ae46150c3a Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 23 Jan 2021 09:21:28 +0100 Subject: [PATCH 27/99] dev: fix missing global flag in README.txt creation --- README.html | 2 +- README.md | 2 +- README.txt | 27 ++++++++++++++++----------- dev/version.sh | 4 ++-- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/README.html b/README.html index 59c69b0..7c61d88 100644 --- a/README.html +++ b/README.html @@ -390,6 +390,6 @@ It features background tasks and interactive chats, and can serve as an interfac

@Gnadelwartz

That's it all guys!

If you feel that there's something missing or if you found a bug, feel free to submit a pull request!

-

$$VERSION$$ v1.30-0-g3266427

+

$$VERSION$$ v1.32-dev-9-g13052f0

diff --git a/README.md b/README.md index 19baa8f..0304e4e 100644 --- a/README.md +++ b/README.md @@ -238,4 +238,4 @@ See `mycommnds.sh.dist` for an example. If you feel that there's something missing or if you found a bug, feel free to submit a pull request! -#### $$VERSION$$ v1.32-dev-8-g2960e58 +#### $$VERSION$$ v1.32-dev-9-g13052f0 diff --git a/README.txt b/README.txt index 571819c..68709b3 100644 --- a/README.txt +++ b/README.txt @@ -39,18 +39,21 @@ Linted by #ShellCheck Prerequisites -Uses JSON.sh [http://github.com/dominictarr/JSON.sh]/JSON.awk and the magic of sed. +Uses JSON.sh [http://github.com/dominictarr/JSON.sh]/JSON.awk [https://github.com/step-/ +JSON.awk] and the magic of sed. Bashbot is written in bash. It depends on commands typically available in a Linux/Unix Environment. For more information on commands provided by recent versions of coreutils -[https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands], busybox or toybox, -see Developer_Notes. +[https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands], busybox [https:// +en.wikipedia.org/wiki/BusyBox#Commands] or toybox [https://landley.net/toybox/help.html], +see Developer Notes [doc/7_develop.md#common-commands]. Note for MacOS and BSD Users: Bashbot will not run without installing additional software as it uses modern bash and (gnu) grep/sed features. See Install Bashbot [doc/ 0_install.md]. Note for embedded systems: You need to install a "real" bash as the vanilla installation of busybox or toybox is not sufficient. See Install Bashbot [doc/0_install.md]. -Bashbot Documentation [https://github.com/topkecleon/telegram-bot-bash] and Downloads are -available on www.github.com. +Bashbot Documentation [https://github.com/topkecleon/telegram-bot-bash] and Downloads +[https://github.com/topkecleon/telegram-bot-bash/releases] are available on www.github.com +[https://www.github.com]. Documentation @@ -115,7 +118,8 @@ Documentation Your very first bashbot in a nutshell To install and run bashbot you need access to a Linux/Unix command line with bash, a -Telegram client [https://telegram.org] and a mobile phone with_a_Telegram_account. +Telegram client [https://telegram.org] and a mobile phone with a Telegram account [https:/ +/telegramguide.com/create-a-telegram-account/]. First you need to create a new Telegram Bot token [doc/1_firstbot.md] for your bot and write it down. Now open a Linux/Unix terminal with bash, create a new directory, change to it and install @@ -200,10 +204,11 @@ does). One of the powerful features of Unix shells is variable and command subst using ${} and$() can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped $ is included in untrusted input (e.g. $$ or $(rm -rf /*)). A powerful tool to improve your scripts is shellcheck. You can use it online [https:// -www.shellcheck.net/] or install_shellcheck_locally. Shellcheck is used extensively in -bashbot development to ensure a high code quality (e.g. it's not allowed to push changes -without passing all shellcheck tests). In addition bashbot has a test_suite to check if -important functionality is working as expected. +www.shellcheck.net/] or install shellcheck locally [https://github.com/koalaman/ +shellcheck#installing]. Shellcheck is used extensively in bashbot development to ensure a +high code quality (e.g. it's not allowed to push changes without passing all shellcheck +tests). In addition bashbot has a test suite [doc/7_develop.md] to check if important +functionality is working as expected. Use printf whenever possible @@ -309,5 +314,5 @@ That's it all guys! If you feel that there's something missing or if you found a bug, feel free to submit a pull request! -$$VERSION$$ v1.30-0-g3266427 +$$VERSION$$ v1.32-dev-9-g13052f0 diff --git a/dev/version.sh b/dev/version.sh index 4e2d97a..46639a1 100755 --- a/dev/version.sh +++ b/dev/version.sh @@ -1,6 +1,6 @@ #!/bin/bash # -#### $$VERSION$$ v1.32-dev-4-g407194b +#### $$VERSION$$ v1.32-dev-9-g13052f0 # shellcheck disable=SC2016 # # Easy Versioning in git: @@ -54,7 +54,7 @@ if [[ "${FILES}" == *"README.md"* ]]; then cat "doc/bashbot.ascii" >"README.txt" if [ -r "README.html" ] && type -f html2text >/dev/null; then # convert html links to text [link] - sed -E 's/([^<#]+)<\/a>/\2 [\1]/' ([^<#]+)<\/a>/\2 [\1]/g' >README.txt else type -f fold >/dev/null && fold -s -w 90 README.md >>README.txt From 41e956d517ffe71d8e86b041483392e7895d5ef7 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 23 Jan 2021 09:53:50 +0100 Subject: [PATCH 28/99] remove obsolete JsonGetXxx functions --- bashbot.sh | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index e3781f9..dd647c3 100755 --- a/bashbot.sh +++ b/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.31-dev-13-g127cc85 +#### $$VERSION$$ v1.32-dev-10-g121f131 ################################################################## # emmbeded system may claim bash but it is not @@ -661,15 +661,6 @@ JsonDecode() { printf "%b\n" "${out}${remain}" } -#JsonGetString() { -# sed -n -e '0,/\['"$1"'\]/ s/\['"$1"'\][ \t]"\(.*\)"$/\1/p' -#} -#JsonGetLine() { -# sed -n -e '0,/\['"$1"'\]/ s/\['"$1"'\][ \t]//p' -#} -#JsonGetValue() { -# sed -n -e '0,/\['"$1"'\]/ s/\['"$1"'\][ \t]\([0-9.,]*\).*/\1/p' -#} ################ # processing of updates starts here From 78e45511076369a8b5df99bcebb454c85250a964 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 23 Jan 2021 13:58:45 +0100 Subject: [PATCH 29/99] fix set CHAT[ID] to new id on chat migration --- bashbot.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bashbot.sh b/bashbot.sh index dd647c3..980c0b0 100755 --- a/bashbot.sh +++ b/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.32-dev-10-g121f131 +#### $$VERSION$$ v1.32-dev-11-g41e956d ################################################################## # emmbeded system may claim bash but it is not @@ -982,6 +982,8 @@ process_message() { 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]}" From f995eeea130e441b6fede884f449fe30a94163ec Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 23 Jan 2021 14:06:55 +0100 Subject: [PATCH 30/99] move JsonEscape up before sourcing other files --- bashbot.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 980c0b0..71e9189 100755 --- a/bashbot.sh +++ b/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.32-dev-11-g41e956d +#### $$VERSION$$ v1.32-dev-12-g78e4551 ################################################################## # emmbeded system may claim bash but it is not @@ -105,6 +105,12 @@ getConfigKey() { [[ "$1" =~ ^[-${azAZo9},._]+$ ]] || return 3 [ -r "${BOTCONFIG}.jssh" ] && sed -n 's/\["'"$1"'"\]\t*"\(.*\)"/\1/p' "${BOTCONFIG}.jssh" | tail -n 1 } +# escape / remove text characters for json strings, eg. " -> \" +# $1 string +# output escaped string +JsonEscape(){ + sed 's/\([-"`´,§$%&/(){}#@!?*.\t]\)/\\\1/g' <<< "$1" +} # check if $1 seems a valid token # return true if token seems to be valid check_token(){ @@ -618,13 +624,6 @@ sendJsonResult(){ fi } >>"${ERRORLOG}" -# escape / remove text characters for json strings, eg. " -> \" -# $1 string -# output escaped string -JsonEscape(){ - sed 's/\([-"`´,§$%&/(){}#@!?*.\t]\)/\\\1/g' <<< "$1" -} - # convert common telegram entities to JSON # title caption description markup inlinekeyboard title2Json(){ From d9b3342c3c8ca420cde509a504868b6b2539ce25 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 24 Jan 2021 10:28:04 +0100 Subject: [PATCH 31/99] iBUTTONS: initial code for processing CallbackQuery buttons --- bashbot.sh | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 71e9189..99ef0cb 100755 --- a/bashbot.sh +++ b/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.32-dev-12-g78e4551 +#### $$VERSION$$ v1.32-dev-13-gf995eee ################################################################## # emmbeded system may claim bash but it is not @@ -343,7 +343,7 @@ declare -rx SCRIPT SCRIPTDIR MODULEDIR RUNDIR ADDONDIR BOTACL DATADIR COUNTFILE declare -rx BOTTOKEN URL ME_URL declare -ax CMD -declare -Ax UPD BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO VENUE iQUERY +declare -Ax UPD BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO VENUE iQUERY iBUTTON declare -Ax SERVICE NEWMEMBER LEFTMEMBER PINNED MIGRATE export res CAPTION ME @@ -683,7 +683,15 @@ process_client() { [ -n "${USER[ID]}" ] && [[ -n "${BASHBOTBLOCKED[${USER[ID]}]}" || -n "${BASHBOTBLOCKED[${CHAT[ID]}]}" ]] && return # process per message type - if [ -z "${iQUERY[ID]}" ]; then + 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 iBUTTON=%s\n" -1\ + "${iBUTTON[USERNAME]:0:20} (${iBUTTON[USER_ID]})" "${iBUTTON[0]}" >>"${UPDATELOG}" + else if grep -qs -e '\["result",'"${num}"',"edited_message"' <<<"${UPDATE}"; then # edited message UPDATE="${UPDATE//,${num},\"edited_message\",/,${num},\"message\",}" @@ -694,10 +702,6 @@ process_client() { 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}" - else - process_inline "${num}" "${debug}" - printf "%(%c)T: iQuery received FROM=%s iQUERY=%s\n" -1\ - "${iQUERY[USERNAME]:0:20} (${iQUERY[USER_ID]})" "${iQUERY[0]}" >>"${UPDATELOG}" fi ##### # process inline and message events @@ -840,9 +844,10 @@ event_message() { pre_process_message(){ local num="$1" # unset everything to not have old values - CMD=( ); iQUERY=( ); MESSAGE=(); CHAT=(); USER=(); CONTACT=(); LOCATION=(); unset CAPTION + 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},inline_callback,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"]}" @@ -850,7 +855,7 @@ pre_process_message(){ # always true return 0 } -process_inline() { +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"]}" @@ -860,6 +865,21 @@ process_inline() { # always true return 0 } +process_inline_button() { + local num="$1" + iBUTTON[0]="$(JsonDecode "${UPD["result,${num},inline_callback,query"]}")" + iBUTTON[CHAT_ID]="${UPD["result,${num},inline_callback,chat_instance"]}" + iBUTTON[MESSAGE_ID]="${UPD["result,${num},inline_callback,inline_message_id"]}" + iBUTTON[MESSAGE_TEXT]="${UPD["result,${num},inline_callback,message,text"]}" +# XXX should we give back pressed button or all buttons? + iBUTTON[MESSAGE_BUTTONS]="${UPD["result,${num},inline_callback,message,reply_markup"]}" + iBUTTON[USER_ID]="${UPD["result,${num},inline_callback,from,id"]}" + iBUTTON[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},inline_callback,from,first_name"]}")" + iBUTTON[LAST_NAME]="$(JsonDecode "${UPD["result,${num},inline_callback,from,last_name"]}")" + iBUTTON[USERNAME]="$(JsonDecode "${UPD["result,${num},inline_callback,from,username"]}")" + # always true + return 0 +} process_message() { local num="$1" # Message From 9023b21791127057b2606c72696971b49b383e48 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 24 Jan 2021 12:03:12 +0100 Subject: [PATCH 32/99] test: adjust inline test --- test/d-process_inline-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/d-process_inline-test.sh b/test/d-process_inline-test.sh index c71808e..9e44a52 100755 --- a/test/d-process_inline-test.sh +++ b/test/d-process_inline-test.sh @@ -10,7 +10,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.35-dev-0-gd9b3342 #=============================================================================== # include common functions and definitions @@ -41,7 +41,7 @@ source <( printf 'UPD=( %s )' "$(sed <<<"${UPDATE}" -E -e 's/\t/=/g' -e 's/=(tru printf "Check process_inline ...\n" printf " ... with JsonDecode Bash\n" set -x -{ process_inline "0"; set +x; } >>"${LOGFILE}" 2>&1; +{ process_inline_query "0"; set +x; } >>"${LOGFILE}" 2>&1; # output processed input print_array "iQUERY" >"${OUTPUTFILE}" From 1fe22a03458e1b094c8bf6b1b0a651e1a3d13eb4 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 24 Jan 2021 12:30:56 +0100 Subject: [PATCH 33/99] modules: button url not starting with hhttp is sent as data --- bashbot.sh | 17 ++++++++++------- dev/all-tests.sh | 2 +- modules/sendMessage.sh | 9 ++++++--- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 99ef0cb..eee1333 100755 --- a/bashbot.sh +++ b/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.32-dev-13-gf995eee +#### $$VERSION$$ v1.35-dev-1-g9023b21 ################################################################## # emmbeded system may claim bash but it is not @@ -689,8 +689,8 @@ process_client() { "${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 iBUTTON=%s\n" -1\ - "${iBUTTON[USERNAME]:0:20} (${iBUTTON[USER_ID]})" "${iBUTTON[0]}" >>"${UPDATELOG}" + printf "%(%c)T: Inline Button update received FROM=%s CHAT=%s ID=%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 @@ -866,17 +866,20 @@ process_inline_query() { return 0 } process_inline_button() { +# debugging for impelemetation + log_message "${res}" +set -x local num="$1" - iBUTTON[0]="$(JsonDecode "${UPD["result,${num},inline_callback,query"]}")" + iBUTTON[DATA]="${UPD["result,${num},inline_callback,data"]}" iBUTTON[CHAT_ID]="${UPD["result,${num},inline_callback,chat_instance"]}" iBUTTON[MESSAGE_ID]="${UPD["result,${num},inline_callback,inline_message_id"]}" - iBUTTON[MESSAGE_TEXT]="${UPD["result,${num},inline_callback,message,text"]}" -# XXX should we give back pressed button or all buttons? - iBUTTON[MESSAGE_BUTTONS]="${UPD["result,${num},inline_callback,message,reply_markup"]}" + iBUTTON[MEESSAGE]="$(JsonDecode "${UPD["result,${num},inline_callback,message,text"]}")" +# XXX should we give back pressed button, all buttons or nothing? iBUTTON[USER_ID]="${UPD["result,${num},inline_callback,from,id"]}" iBUTTON[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},inline_callback,from,first_name"]}")" iBUTTON[LAST_NAME]="$(JsonDecode "${UPD["result,${num},inline_callback,from,last_name"]}")" iBUTTON[USERNAME]="$(JsonDecode "${UPD["result,${num},inline_callback,from,username"]}")" +set +x # always true return 0 } diff --git a/dev/all-tests.sh b/dev/all-tests.sh index d0a2051..dd9ebe2 100755 --- a/dev/all-tests.sh +++ b/dev/all-tests.sh @@ -5,7 +5,7 @@ # # Description: run all tests, exit after failed test # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.35-dev-0-gd9b3342 ############################################################# #shellcheck disable=SC1090 diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 4911085..acd0768 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.32-dev-1-g662c6f4 +#### $$VERSION$$ v1.35-dev-1-g9023b21 # will be automatically sourced from bashbot @@ -159,13 +159,16 @@ send_button() { # helper function to create json for a button row # buttons will specified as "text|url" ... "text|url" empty arg starts new row +# url not starting with http:// or https:// will be send as callback_data _button_row() { [ -z "$1" ] && return 1 - local arg json sep + local arg type json sep for arg in "$@" do [ -z "${arg}" ] && sep="],[" && continue - json+="${sep}"'{"text":"'"$(JsonEscape "${arg%|*}")"'", "url":"'"${arg##*|}"'"}' + type="callback_data" + [[ "${arg##*|}" =~ ^https*:// ]] && type="url" + json+="${sep}"'{"text":"'"$(JsonEscape "${arg%|*}")"'", "'"${type}"'":"'"${arg##*|}"'"}' sep="," done printf "[%s]" "${json}" From 461e748c923b75b53252fe0852c21c27d13ecfb9 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 24 Jan 2021 13:04:20 +0100 Subject: [PATCH 34/99] iBUTTON: infrastructe seems to work --- bashbot.sh | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index eee1333..d7ae5ec 100755 --- a/bashbot.sh +++ b/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-1-g9023b21 +#### $$VERSION$$ v1.35-dev-2-g1fe22a0 ################################################################## # emmbeded system may claim bash but it is not @@ -689,8 +689,8 @@ process_client() { "${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 ID=%s DATA:%s \n" -1\ - "${iBUTTON[USERNAME]:0:20} (${iBUTTON[USER_ID]})" "${iBUTTON[CHAT_ID]}" "{iBUTTON[ID]" "{iBUTTON[DATA]" >>"${UPDATELOG}" + 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 @@ -847,7 +847,7 @@ pre_process_message(){ 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},inline_callback,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"]}" @@ -867,19 +867,18 @@ process_inline_query() { } process_inline_button() { # debugging for impelemetation - log_message "${res}" -set -x local num="$1" - iBUTTON[DATA]="${UPD["result,${num},inline_callback,data"]}" - iBUTTON[CHAT_ID]="${UPD["result,${num},inline_callback,chat_instance"]}" - iBUTTON[MESSAGE_ID]="${UPD["result,${num},inline_callback,inline_message_id"]}" - iBUTTON[MEESSAGE]="$(JsonDecode "${UPD["result,${num},inline_callback,message,text"]}")" + iBUTTON[DATA]="${UPD["result,${num},callback_query,data"]}" + #iBUTTON[CHAT_INSTANCE]="${UPD["result,${num},callback_query,chat_instance"]}" + #iBUTTON[INLINE_ID]="${UPD["result,${num},callback_query,inline_message_id"]}" + iBUTTON[CHAT_ID]="${UPD["result,${num},callback_query,message,chat,id"]}" + iBUTTON[MESSAGE_ID]="${UPD["result,${num},callback_query,message,message_id"]}" + iBUTTON[MEESSAGE]="$(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},inline_callback,from,id"]}" - iBUTTON[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},inline_callback,from,first_name"]}")" - iBUTTON[LAST_NAME]="$(JsonDecode "${UPD["result,${num},inline_callback,from,last_name"]}")" - iBUTTON[USERNAME]="$(JsonDecode "${UPD["result,${num},inline_callback,from,username"]}")" -set +x + 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 } From aa2c20b37e8d1630d0d23b4ced197c49ad4ba596 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 24 Jan 2021 13:52:44 +0100 Subject: [PATCH 35/99] doc: add callback buttons --- bin/edit_buttons.sh | 3 ++- bin/send_buttons.sh | 3 ++- doc/6_reference.md | 11 ++++++++--- modules/sendMessage.sh | 4 ++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/bin/edit_buttons.sh b/bin/edit_buttons.sh index 116e7e8..a874d0c 100755 --- a/bin/edit_buttons.sh +++ b/bin/edit_buttons.sh @@ -12,6 +12,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" "text|url" ...' # MESSAGE[ID] - ID of MESSAGE with buttons to edit # text|url - buttons to send, each button as "text|url" pair or # "url" only to show url as text also, "" starts new row +# "url" not http(s):// or tg:// is sent as callback_data # # -h - display short help # --help - this help @@ -25,7 +26,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" "text|url" ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 21.01.2021 08:10 # -#### $$VERSION$$ v1.32-dev-6-g2832801 +#### $$VERSION$$ v1.35-dev-3-g461e748 #=============================================================================== #### diff --git a/bin/send_buttons.sh b/bin/send_buttons.sh index 86ac108..5aba29e 100755 --- a/bin/send_buttons.sh +++ b/bin/send_buttons.sh @@ -11,6 +11,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...' # OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself # message - message to send # text|url - buttons to send, each button as "text|url" pair or +# "url" not http(s):// or tg:// is sent as callback_data # "url" only to show url as text also, "" starts new row # # -h - display short help @@ -25,7 +26,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.01.2021 11:34 # -#### $$VERSION$$ v1.32-dev-6-g2832801 +#### $$VERSION$$ v1.35-dev-3-g461e748 #=============================================================================== #### diff --git a/doc/6_reference.md b/doc/6_reference.md index b830895..ea74960 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -240,6 +240,9 @@ Each button is specified as a `"text|url"` pair separated by `|`, `text` is show By default all buttons are displayed on one row, an empty string `""` starts a new button row. If `"url"` without text is given, `url` is shown on the button and opened on button click. +**Important**: An `url` not startung with http(s):// or tg:// will be converted to a +[Callback Button](https://core.telegram.org/bots/2-0-intro#callback-buttons) + *example:* ```bash # one button, same as send_button @@ -257,9 +260,11 @@ send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "b1|http://rrr.de" " *usage:* send_inline_keyboard "CHAT[ID]" "message" "[JSON button array]" -A JSON button array has the following format, but I suggest to use `_button_row` to create them: +A JSON button array has the following format, but I suggest to use `_button_row` to create them, +see [Inline Keyboard Markup](https://core.telegram.org/bots/api#inlinekeyboardmarkup) -`[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]` +URL buttons: `[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]` +CALLBACK buttons: `[ {"text":"text1", "callback_data":"abc"}, ... {"text":"textN", "callback_data":"defg"} ],[...]` *example:* ```bash @@ -1317,5 +1322,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.32-dev-7-g8bb4b7e +#### $$VERSION$$ v1.35-dev-3-g461e748 diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index acd0768..4b19434 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.35-dev-1-g9023b21 +#### $$VERSION$$ v1.35-dev-3-g461e748 # will be automatically sourced from bashbot @@ -167,7 +167,7 @@ _button_row() { do [ -z "${arg}" ] && sep="],[" && continue type="callback_data" - [[ "${arg##*|}" =~ ^https*:// ]] && type="url" + [[ "${arg##*|}" =~ ^(https*://|tg://) ]] && type="url" json+="${sep}"'{"text":"'"$(JsonEscape "${arg%|*}")"'", "'"${type}"'":"'"${arg##*|}"'"}' sep="," done From cc7afdb149c002963af1a4716a5af7a59b7b4882 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 24 Jan 2021 14:15:01 +0100 Subject: [PATCH 36/99] doc: fix inline_keyboard frormat descritption --- doc/6_reference.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index ea74960..cce4b3a 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -176,15 +176,11 @@ send_album "$(getConfigKey "botadmin")" "http://www.rrr.de/slider/main-image1.jp ---- ##### send_keyboard -Note: Since version 0.6 send_keyboard was changed to use native "JSON Array" notation as used from Telegram. -Detection and emulation for old format will be removed after 1.0 release! +`send_keyboard` sends a custom keyboard, a Telegram client will it show instead of the regular keyboard. +If a user click a button on the custom keyboard, the text shown on the button is send to the chat. Example Keyboard Array definitions: -- yes no in two rows: - - OLD format: 'yes' 'no' (two strings) - - NEW format: '[ "yes" ] , [ "no" ]' (two arrays with a string) -- new layouts made easy with NEW format: - Yes No in one row: '[ "yes" , "no" ]' - Yes No plus Maybe in 2.row: '[ "yes" , "no" ] , [ "maybe" ]' - number pad style keyboard: '[ "1" , "2" , "3" ] , [ "4" , "5" , "6" ] , [ "7" , "8" , "9" ] , [ "0" ]' @@ -205,6 +201,8 @@ _keyboard_numpad ``` ##### remove_keyboard +`remove_keyboard` deletes the last custom keyboard. Depending on used Telegram client this will hide or delete the custom keyboard. + *usage:* remove_keybord "$CHAT[ID]" "message" *alias:* _del_keyboard "message" @@ -260,10 +258,10 @@ send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "b1|http://rrr.de" " *usage:* send_inline_keyboard "CHAT[ID]" "message" "[JSON button array]" -A JSON button array has the following format, but I suggest to use `_button_row` to create them, +I suggest to use `_button_row` to create the JSON button array. In case you want to write by hand the following format must be used, see [Inline Keyboard Markup](https://core.telegram.org/bots/api#inlinekeyboardmarkup) -URL buttons: `[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]` +URL buttons: `[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]`\ CALLBACK buttons: `[ {"text":"text1", "callback_data":"abc"}, ... {"text":"textN", "callback_data":"defg"} ],[...]` *example:* @@ -1322,5 +1320,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-3-g461e748 +#### $$VERSION$$ v1.35-dev-4-gaa2c20b From c90b5658b37a2b17440ff97b8433b5db470791e2 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 24 Jan 2021 14:39:36 +0100 Subject: [PATCH 37/99] doc: better xxx_keyboard description --- doc/6_reference.md | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index cce4b3a..731b7d5 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -173,11 +173,17 @@ send_album "$(getConfigKey "botadmin")" "http://www.rrr.de/slider/main-image1.jp *usage:* send_venue "${CHAT[ID]}" "Latitude" "Longitude" "Title" "Address" "foursquare id (optional)" +##### send_sticker +`send_sticker` sends a sticker using a `file_id` to send a sticker that exists on the Telegram servers. + +*usage:* send_sticker "$CHAT[ID]" "file_id" + + ---- ##### send_keyboard -`send_keyboard` sends a custom keyboard, a Telegram client will it show instead of the regular keyboard. -If a user click a button on the custom keyboard, the text shown on the button is send to the chat. +`send_keyboard` sends a custom keyboard, Telegram clients will show it instead of the regular keyboard. +If the user press a button on the custom keyboard, the text shown on the button is send to the chat. Example Keyboard Array definitions: @@ -209,16 +215,9 @@ _keyboard_numpad *See also: [Keyboard Markup](https://core.telegram.org/bots/api/#replykeyboardmarkup)* ----- - -##### send_sticker -`send_sticker` sends a sticker using a `file_id` to send a sticker that exists on the Telegram servers. - -*usage:* send_sticker "$CHAT[ID]" "file_id" - ##### send_button -`send_button` sends a text message followed by a single button. +`send_button` sends a text message with a single button for opneing and URL. *usage:* send_button "$CHAT[ID]" "message" "text" "URL" @@ -230,7 +229,7 @@ send_button "${CHAT[ID]}" "Awesome Deals!" "Visit my Shop" "https://dealz.rrr.de ``` ##### _button_row -`_button_row` is a helper function to create a JSON button array for use with `send_inline_keyboard`. +`_button_row` is a helper function to make it easier to send messages with with multiple buttons. *usage:* _button_row "text|url" "text|url" "" "url" "" "text|url" ... @@ -254,15 +253,17 @@ send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "b1|http://rrr.de" " ``` ##### send_inline_keyboard -`send_inline_keyboard` send buttons given as an array of buttons in JSON format. +`send_inline_keyboard` send a message with attached buttons, buttons are given as an array of buttons in JSON format. +In contrast to `send_keyboard` the button are attached to a message and do not send text to the chat. *usage:* send_inline_keyboard "CHAT[ID]" "message" "[JSON button array]" -I suggest to use `_button_row` to create the JSON button array. In case you want to write by hand the following format must be used, +I suggest to use `_button_row` to create the JSON button array. For hand crafted JSON the following format must be used, see [Inline Keyboard Markup](https://core.telegram.org/bots/api#inlinekeyboardmarkup) -URL buttons: `[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]`\ -CALLBACK buttons: `[ {"text":"text1", "callback_data":"abc"}, ... {"text":"textN", "callback_data":"defg"} ],[...]` +URL `[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]`\ +CALLBACK `[ {"text":"text1", "callback_data":"abc"}, ... {"text":"textN", "callback_data":"defg"} ],[...]`\ +An URL Button opens the given URL, a CALLBACK button sends an update the bot must react on. *example:* ```bash @@ -1320,5 +1321,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-4-gaa2c20b +#### $$VERSION$$ v1.35-dev-5-gcc7afdb From 9584068ea36052ed43be38ce913c5130d58f9cd2 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 25 Jan 2021 14:52:47 +0100 Subject: [PATCH 38/99] add callback processing to commands and mycommands --- commands.sh | 17 +++++++++++------ doc/6_reference.md | 10 ++++++---- mycommands.conf | 6 +++++- mycommands.sh | 36 +++++++++++++++++++++++++++++++++++- 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/commands.sh b/commands.sh index 0b10d04..d83597b 100644 --- a/commands.sh +++ b/commands.sh @@ -15,7 +15,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.35-dev-6-gc90b565 # # bashbot locale defaults to c.UTF-8, adjust locale in mycommands.sh if needed @@ -66,6 +66,7 @@ fi # copy "mycommands.sh.dist" to "mycommands.sh" and change the values there # defaults to no inline, all commands and nonsense home dir export INLINE="0" +export CALLBACK="0" export MEONLY="0" export FILE_REGEX="${BASHBOT_ETC}/.*" @@ -76,14 +77,18 @@ export FILE_REGEX="${BASHBOT_ETC}/.*" if [ -z "$1" ] || [[ "$1" == *"debug"* ]];then - # detect inline commands.... - # no default commands, all processing is done in myinlines() - if [ "${INLINE}" != "0" ] && [ -n "${iQUERY[ID]}" ]; then + ################# + # detect inline and callback query + if [[ -n "${iQUERY[ID]}" && "${INLINE:-0}" != "0" ]]; then # forward iinline query to optional dispatcher _exec_if_function myinlines - # regular (global) commands ... - # your commands are in mycommands() + elif [[ -n "${iBUTTON[ID]}" && "${CALLBACK:-0}" != "0" ]]; then + # forward iinline query to optional dispatcher + _exec_if_function mycallbacks + + ################# + # regular command else ################### diff --git a/doc/6_reference.md b/doc/6_reference.md index 731b7d5..390bddd 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -216,8 +216,10 @@ _keyboard_numpad *See also: [Keyboard Markup](https://core.telegram.org/bots/api/#replykeyboardmarkup)* +---- + ##### send_button -`send_button` sends a text message with a single button for opneing and URL. +`send_button` sends a text message with a single button to open an URL attached. *usage:* send_button "$CHAT[ID]" "message" "text" "URL" @@ -253,8 +255,8 @@ send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "b1|http://rrr.de" " ``` ##### send_inline_keyboard -`send_inline_keyboard` send a message with attached buttons, buttons are given as an array of buttons in JSON format. -In contrast to `send_keyboard` the button are attached to a message and do not send text to the chat. +`send_inline_keyboard` sends a message with buttons attached, buttons must be given in JSON format. +In contrast to `send_keyboard` buttons are attached to the message and do not send text. *usage:* send_inline_keyboard "CHAT[ID]" "message" "[JSON button array]" @@ -1321,5 +1323,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-5-gcc7afdb +#### $$VERSION$$ v1.35-dev-6-gc90b565 diff --git a/mycommands.conf b/mycommands.conf index 736928d..f2052d0 100644 --- a/mycommands.conf +++ b/mycommands.conf @@ -12,7 +12,7 @@ # Author: KayM (gnadelwartz), kay@rrr.de # Created: 09.01.2021 07:27 # -#### $$VERSION$$ v1.31-dev-15-g07f026c +#### $$VERSION$$ v1.35-dev-6-gc90b565 ####################################################### ########## @@ -47,6 +47,10 @@ Edit commands and messages in mycommands.sh! # To enable this option in your bot, send the /setinline command to @BotFather. export INLINE="0" +# Set CALLBACK to 1 in order to receive callback queries. +# callbacks are sent from inline_keyboards (buttons) attached tp bot messages +export CALLBACK="0" + # if your bot is group admin it get commands sent to other bots # Set MEONLY to 1 to ignore commands sent to other bots export MEONLY="0" diff --git a/mycommands.sh b/mycommands.sh index bc27071..c441061 100644 --- a/mycommands.sh +++ b/mycommands.sh @@ -13,7 +13,7 @@ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # Author: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.35-dev-6-gc90b565 ####################################################### # shellcheck disable=SC1117 @@ -179,6 +179,40 @@ else esac } + mycallbacks() { + ####################### + # callbacks from buttons bot has attached to messages can processed here + # we have no standard use case for processing callbacks, we log them based on user and chat + case "${USER[ID]}+${CHAT[ID]}" in + 'USERID1+'*) # do something for all callbacks from USER + printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBOTTON[USER_ID]}" "${iBOTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\ + >>"${DATADIR}/${iBOTTON[USER_ID]}.log" + answer_callback_query "${iBUTTON[ID]}" "Request has been logged in your user log..." + return + ;; + *'+CHATID1') # do something for all callbacks from CHAT + printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBOTTON[USER_ID]}" "${iBOTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\ + >>"${DATADIR}/${iBOTTON[CHAT_ID]}.log" + answer_callback_query "${iBUTTON[ID]}" "Request has been logged in chat log..." + return + ;; + 'USERID2+CHATID2') # do something only for callbacks form USER in CHAT + printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBOTTON[USER_ID]}" "${iBOTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\ + >>"${DATADIR}/${iBOTTON[USER_ID]}-${iBOTTON[CHAT_ID]}.log" + answer_callback_query "${iBUTTON[ID]}" "Request has been logged in user-chat log..." + return + ;; + *) # all other callbacks are processed here + : # your processing here ... + : + # Telegram needs an ack each callback query, default empty + answer_callback_query "${iBUTTON[ID]}" "" + ;; + esac + + + } + myinlines() { ####################### # Inline query examples, do not use them in production (except image search ;-) From cc4ac1a816eef24e6a5b36ed40c54e1cd54a8a59 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 25 Jan 2021 16:49:15 +0100 Subject: [PATCH 39/99] better callback processing --- commands.sh | 14 +++++++------- mycommands.sh | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/commands.sh b/commands.sh index d83597b..3f940fb 100644 --- a/commands.sh +++ b/commands.sh @@ -15,7 +15,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.35-dev-6-gc90b565 +#### $$VERSION$$ v1.35-dev-7-g9584068 # # bashbot locale defaults to c.UTF-8, adjust locale in mycommands.sh if needed @@ -79,13 +79,13 @@ export FILE_REGEX="${BASHBOT_ETC}/.*" if [ -z "$1" ] || [[ "$1" == *"debug"* ]];then ################# # detect inline and callback query - if [[ -n "${iQUERY[ID]}" && "${INLINE:-0}" != "0" ]]; then - # forward iinline query to optional dispatcher - _exec_if_function myinlines + if [ -n "${iQUERY[ID]}" ]; then + # forward inline query to optional dispatcher + [ "${INLINE:-0}" != "0" ] || _exec_if_function myinlines - elif [[ -n "${iBUTTON[ID]}" && "${CALLBACK:-0}" != "0" ]]; then - # forward iinline query to optional dispatcher - _exec_if_function mycallbacks + elif [ -n "${iBUTTON[ID]}" ]; then + # forward inline query to optional dispatcher + [ "${CALLBACK:-0}" != "0" ] || _exec_if_function mycallbacks ################# # regular command diff --git a/mycommands.sh b/mycommands.sh index c441061..eb2fafd 100644 --- a/mycommands.sh +++ b/mycommands.sh @@ -13,7 +13,7 @@ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # Author: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.35-dev-6-gc90b565 +#### $$VERSION$$ v1.35-dev-7-g9584068 ####################################################### # shellcheck disable=SC1117 @@ -181,8 +181,8 @@ else mycallbacks() { ####################### - # callbacks from buttons bot has attached to messages can processed here - # we have no standard use case for processing callbacks, we log them based on user and chat + # callbacks from buttons attached to messages will be processed here + # no standard use case for processing callbacks, let's log them for some users and chats case "${USER[ID]}+${CHAT[ID]}" in 'USERID1+'*) # do something for all callbacks from USER printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBOTTON[USER_ID]}" "${iBOTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\ From 5ceddde4e8ae9785bf3b7710a990e750f0b24048 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 25 Jan 2021 19:44:45 +0100 Subject: [PATCH 40/99] modules: chatMember: promote_chat_member --- modules/chatMember.sh | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/modules/chatMember.sh b/modules/chatMember.sh index 091819e..faabeaa 100644 --- a/modules/chatMember.sh +++ b/modules/chatMember.sh @@ -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-0-gfe1fb75 +#### $$VERSION$$ v1.35-dev-8-gcc4ac1a # will be automatically sourced from bashbot @@ -68,6 +68,34 @@ leave_chat() { sendJson "$1" "" "${URL}/leaveChat" } +# $1 chat, $2 userid, $3 ... "right[:true]" default false +# right: is_anonymous change_info post_messages edit_messages delete_messages invite_users restrict_members pin_messages promote_member +promote_chat_member() { + local arg bool json chat="$1" user="$2; shift 2" + for arg in "$@" + do + # default false + bool=false; [ "${arg##*:}" = "true" ] && bool="true" + # expand args + case "${arg}" in + *"anon"*) arg="is_anonymous";; + *"change"*) arg="can_change_info";; + *"post"*) arg="can_post_messages";; + *"edit"*) arg="can_edit_messages";; + *"delete"*) arg="can_delete_messages";; + *"pin"*) arg="can_pin_messages";; + *"invite"*) arg="can_invite_users";; + *"restrict"*) arg="can_restrict_members";; + *"promote"*) arg="can_promote_members";; + *) [ -n "${BASHBOT_DEBUG}" ] && debug_log "${FUNCNAME[0]}: unknown promotion ${arg}" + continue;; + esac + # compose json + [ -n "${json}" ] && json+="," + json+='"'"${arg}"'": "'"${bool}"'"' + done + sendJson "${chat}" '"user_id":'"${user}"','"${json}"'' "${URL}/promoteChatMember" +} # bashbot specific functions --------- From 70a3c194a0c000ce69602a9a176985eeaf67823e Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 25 Jan 2021 20:17:38 +0100 Subject: [PATCH 41/99] doc: promote_chat_member --- doc/6_reference.md | 21 ++++++++++++++++++++- modules/chatMember.sh | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index 390bddd..23b472f 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -471,6 +471,25 @@ fi See also [kick Chat Member](https://core.telegram.org/bots/api/#kickchatmember)* + +##### promote_chat_member +`promote_chat_member` promote or denote user right in a chat. Bot must be admin an can only promote own rights. + +Right are specified as "right:bool" pairs, where right is one of `long` or `short` listed below, followed +by `:true` or `:false`. Anything but `:true` (e.g. nothing or :xyz) is `:false`. + +long: `is_anonymous can_change_info can_post_messages can_edit_messages can_delete_messages can_invite_users can_restrict_members can_pin_messages can_promote_member` +short: `anon change post edit delete invite restrict pin promote` + +*usage:* promote_chat_member "CHAT[ID]" "USER[ID]" "right[:true|false]" ... "right[:true|false]" + +See also [promote Chat Member](https://core.telegram.org/bots/api#promotechatmember)* + +*example:* +```bash +# USER can post, can't edit, can't delete, can't pin message, can invite users +promote_chat_member "CHAT[ID}" "USER[ID]" "post:true" "can_edit_message" "delete:false" "pin:xxx" "invite:true" +``` ---- The following functions are bashbot only and not part of the Telegram API. @@ -1323,5 +1342,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-6-gc90b565 +#### $$VERSION$$ v1.35-dev-9-g5ceddde diff --git a/modules/chatMember.sh b/modules/chatMember.sh index faabeaa..c114eaa 100644 --- a/modules/chatMember.sh +++ b/modules/chatMember.sh @@ -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.35-dev-8-gcc4ac1a +#### $$VERSION$$ v1.35-dev-9-g5ceddde # will be automatically sourced from bashbot From 6b102a728a7524fd6358963ad9fcfb854441868a Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 25 Jan 2021 20:34:50 +0100 Subject: [PATCH 42/99] doc: use USER[ID] CHAT[ID] in usage: --- doc/6_reference.md | 94 +++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index 23b472f..6b162e2 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -8,7 +8,7 @@ To insert line brakes in a message or caption you can place `\n` in the text. ##### send_action `send_action` shows users what your bot is currently doing. -*usage:* send_action "${CHAT[ID]}" "action" +*usage:* send_action "CHAT[ID]" "action" *"action":* `typing`, `upload_photo`, `record_video`, `upload_video`, `record_audio`, `upload_audio`, `upload_document`, `find_location`. @@ -23,7 +23,7 @@ send_action "${CHAT[ID]}" "record_audio" ##### send_normal_message `send_normal_message` sends text only messages to the given chat. -*usage:* send_normal_message "${CHAT[ID]}" "message" +*usage:* send_normal_message "CHAT[ID]" "message" *alias:* _normal_message "message" @@ -41,7 +41,7 @@ has more formatting codes and is more robust, but incompatible with old telegram To send characters reserved for markdown v2 formatting, you must prefix them with `\` ( e.g. `\| \= \_ \*`).\ *Hint*: If a message is not sent, have a look in `logs/ERROR.log` -*usage:* send_markdownv2_message "${CHAT[ID]}" "markdown message" +*usage:* send_markdownv2_message "CHAT[ID]" "markdown message" *example:* ```bash @@ -55,7 +55,7 @@ send_markdownv2_message "${CHAT[ID]}" "*bold* __underlined__ [text](link)" This is the old, legacy Telegram markdown style, retained for backward compatibility. It supports a [reduced set of Markdown](https://core.telegram.org/bots/api#markdown-style) only -*usage:* send_markdown_message "${CHAT[ID]}" "markdown message" +*usage:* send_markdown_message "CHAT[ID]" "markdown message" *alias:* _markdown "message" @@ -70,7 +70,7 @@ send_markdown_message "${CHAT[ID]}" "*bold* _italic_ [text](link)" `send_html_message` sends HTML style messages to the given chat. Telegram supports a [reduced set of HTML](https://core.telegram.org/bots/api#html-style) only -*usage:* send_html_message "${CHAT[ID]}" "html message" +*usage:* send_html_message "CHAT[ID]" "html message" *alias:* _html_message "message" @@ -96,7 +96,7 @@ See also [Text formatting options](https://core.telegram.org/bots/api#formatting ##### delete_message A bot can only delete messages if he is admin of a Chat, if not he can delete his own messages only. -*usage:* delete_message "${CHAT[ID]}" "${MESSAGE[ID]}" +*usage:* delete_message "CHAT[ID]" "${MESSAGE[ID]}" See also [deleteMessage limitations](https://core.telegram.org/bots/api#deletemessage) @@ -107,7 +107,7 @@ See also [deleteMessage limitations](https://core.telegram.org/bots/api#deleteme The main use case for send_message is to process the output of interactive chats and background jobs. **For regular Bot commands I recommend using of the dedicated send_xxx_message() functions from above.** -*usage:* send_message "${CHAT[ID]}" "message" +*usage:* send_message "CHAT[ID]" "message" *example:* - see [Usage](2_usage.md#send_message) and [Advanced Usage](3_advanced.md#Interactive-Chats) @@ -118,7 +118,7 @@ The main use case for send_message is to process the output of interactive chats ##### send_file send_file can send local files, URL's or file_id's as different filex types (_e.g. photo video sticker_) -*usage:* send_file "${CHAT[ID]}" "file/URL/file_id" "caption" ["type"] +*usage:* send_file "CHAT[ID]" "file/URL/file_id" "caption" ["type"] URL's must start with `http://` or `https://` and remote server must send an appropriate media type. A file_id must start with `file_id://`, all other file names are threated as local files. @@ -158,7 +158,7 @@ send_file "${CHAT[ID]}" "dog.jpg" "My Dog" ##### send_album -*usage:* send_album "${CHAT[ID]}" "URL1" "URL2" ... "URLn" +*usage:* send_album "CHAT[ID]" "URL1" "URL2" ... "URLn" *example:* ```bash @@ -166,11 +166,11 @@ send_album "$(getConfigKey "botadmin")" "http://www.rrr.de/slider/main-image1.jp ``` ##### send_location -*usage:* send_location "${CHAT[ID]}" "Latitude" "Longitude" +*usage:* send_location "CHAT[ID]" "Latitude" "Longitude" ##### send_venue -*usage:* send_venue "${CHAT[ID]}" "Latitude" "Longitude" "Title" "Address" "foursquare id (optional)" +*usage:* send_venue "CHAT[ID]" "Latitude" "Longitude" "Title" "Address" "foursquare id (optional)" ##### send_sticker @@ -324,7 +324,7 @@ To replace a message you must know the message id of the the original message. T ##### edit_normal_message `edit_normal_message` replace a message with a text message in the given chat. -*usage:* edit_normal_message "${CHAT[ID]}" "MESSAGE-ID" "message" +*usage:* edit_normal_message "CHAT[ID]" "MESSAGE-ID" "message" *example:* ```bash @@ -337,7 +337,7 @@ edit_normal_message "${CHAT[ID]}" "${saved-id}" "this is another text" ##### edit_markdownv2_message `edit_markdownv2_message` replace a message with a markdown v2 message in the given chat. -*usage:* edit_markdownv2_message "${CHAT[ID]}" "MESSAGE-ID" "message" +*usage:* edit_markdownv2_message "CHAT[ID]" "MESSAGE-ID" "message" *example:* ```bash @@ -350,7 +350,7 @@ edit_markdownv2_message "${CHAT[ID]}" "${saved-id}" "this is __markdown__ *V2* t ##### edit_markdown_message `edit_markdown_message` replace a message with a markdown message in the given chat. -*usage:* edit_markdown_message "${CHAT[ID]}" "MESSAGE-ID" "message" +*usage:* edit_markdown_message "CHAT[ID]" "MESSAGE-ID" "message" *example:* ```bash @@ -363,7 +363,7 @@ edit_markdown_message "${CHAT[ID]}" "${saved-id}" "this is *markdown* text" ##### edit_html_message `edit_html_message` replace a message with a html message in the given chat. -*usage:* edit_html_message "${CHAT[ID]}" "MESSAGE-ID" "message" +*usage:* edit_html_message "CHAT[ID]" "MESSAGE-ID" "message" *example:* ```bash @@ -376,7 +376,7 @@ edit_html_message "${CHAT[ID]}" "${saved-id}" "this is html text" ##### edit_message_caption `edit_message_caption` changes the caption of a message (photo, audio, video, document) in the given chat. -*usage:* edit_message_caption "${CHAT[ID]}" "MESSAGE-ID" "caption" +*usage:* edit_message_caption "CHAT[ID]" "MESSAGE-ID" "caption" --- @@ -388,51 +388,51 @@ To use the following functions the bot must have administrator status in the cha `set_chat_title` sets a new chat title. If new title is the same than current title Telegram return error 400 with description "Bad Request: chat title is not modified" -*usage:* set_chat_title "${CHAT[ID]}" "new chat title" +*usage:* set_chat_title "CHAT[ID]" "new chat title" ##### set_chat_description `set_chat_description` sets a new description title. If new description is the same than current description Telegram return error 400 with description "Bad Request: chat description is not modified" -*usage:* set_chat_description "${CHAT[ID]}" "new chat description" +*usage:* set_chat_description "CHAT[ID]" "new chat description" ##### new_chat_invite `new_chat_invite` generate a new invite link for a chat; any previously generated link is revoked. Returns the new invite link as String on success. -*usage:* new_chat_invite "${CHAT[ID]}" +*usage:* new_chat_invite "CHAT[ID]" ##### delete_chat_photo -*usage:* delete_chat_photo "${CHAT[ID]}" +*usage:* delete_chat_photo "CHAT[ID]" ##### pin_chat_message # $1 chat, $2 message_id `pin_chat_message` add a message to the list of pinned messages in a chat. -*usage:* pin_chat_message "${CHAT[ID]}" "message_id" +*usage:* pin_chat_message "CHAT[ID]" "message_id" ##### unpin_chat_message `unpin_chat_message` remove a message from the list of pinned messages in a chat. -*usage:* unpin_chat_message "${CHAT[ID]}" "message_id" +*usage:* unpin_chat_message "CHAT[ID]" "message_id" ##### unpinall_chat_message `unpinall_chat_message` clear the list of pinned messages in a chat. -*usage:* unpinall_chat_message "${CHAT[ID]}" +*usage:* unpinall_chat_message "CHAT[ID]" ##### delete_chat_stickers `delete_chat_stickers` deletes a group sticker set from a supergroup. -*usage:* delete_chat_stickers "${CHAT[ID]}" +*usage:* delete_chat_stickers "CHAT[ID]" ---- @@ -444,21 +444,21 @@ More advanced API functions are currently not implemented in bashbot. ##### kick_chat_member If your Bot is a chat admin he can kick and ban a user. -*usage:* kick_chat_member "${CHAT[ID]}" "${USER[ID]}" +*usage:* kick_chat_member "CHAT[ID]" "USER[ID]" -*alias:* _kick_user "${USER[ID]}" +*alias:* _kick_user "USER[ID]" ##### unban_chat_member If your Bot is a chat admin can unban a kicked user. -*usage:* unban_chat_member "${CHAT[ID]}" "${USER[ID]}" +*usage:* unban_chat_member "CHAT[ID]" "USER[ID]" -*alias:* _unban "${USER[ID]}" +*alias:* _unban "USER[ID]" ##### leave_chat Your Bot will leave the chat. -*usage:* leave_chat "${CHAT[ID]}" +*usage:* leave_chat "CHAT[ID]" *alias:* _leave @@ -473,7 +473,7 @@ See also [kick Chat Member](https://core.telegram.org/bots/api/#kickchatmember)* ##### promote_chat_member -`promote_chat_member` promote or denote user right in a chat. Bot must be admin an can only promote own rights. +`promote_chat_member` promote or denote user rights in a chat. Bot must be admin and can only promote/denote rights he owns. Right are specified as "right:bool" pairs, where right is one of `long` or `short` listed below, followed by `:true` or `:false`. Anything but `:true` (e.g. nothing or :xyz) is `:false`. @@ -497,7 +497,7 @@ The following functions are bashbot only and not part of the Telegram API. ##### bot_is_admin Return true (0) if bot is admin or creator of given chat. -*usage:* bot_is_admin "${CHAT[ID]}" +*usage:* bot_is_admin "CHAT[ID]" *example:* @@ -510,7 +510,7 @@ fi ##### user_is_botadmin Return true (0) if user is admin of bot, user id if botadmin is read from file './botadmin'. -*usage:* user_is_botadmin "${USER[ID]}" +*usage:* user_is_botadmin "USER[ID]" *alias:* _is_botadmin @@ -522,14 +522,14 @@ user_is_botadmin "${CHAT[ID]}" && send_markdown_message "${CHAT[ID]}" "You are * ##### user_is_creator Return true (0) if user is creator of given chat or chat is a private chat. -*usage:* user_is_creator "${CHAT[ID]}" "${USER[ID]}" +*usage:* user_is_creator "CHAT[ID]" "USER[ID]" *alias:* _is_creator ##### user_is_admin Return true (0) if user is admin or creator of given chat. -*usage:* user_is_admin "${CHAT[ID]}" "${USER[ID]}" +*usage:* user_is_admin "CHAT[ID]" "USER[ID]" *alias:* _is_admin @@ -547,7 +547,7 @@ fi `uers_is_allowed` checks if: user id botadmin, user is group admin or user is allowed to execute action.. Allowed actions are configured as User Access Control rules, see [Advanced Usage](3_advanced.md) -*usage:* user_is_allowed "${USER[ID]}" "action" "${CHAT[ID]}" +*usage:* user_is_allowed "USER[ID]" "action" "CHAT[ID]" *example:* ```bash @@ -635,7 +635,7 @@ chats and send messages based on time or other external events. ##### start_proc `startproc` starts a script, the output of the script is sent to the user or chat, user input will be sent back to the script. see [Advanced Usage](3_advanced.md#Interactive-Chats) -*usage:* start_proc "${CHAT[ID]}" "script" +*usage:* start_proc "CHAT[ID]" "script" *alias:* startproc "script" @@ -648,7 +648,7 @@ startproc 'examples/calc.sh' ##### check_proc Return true (0) if an interactive script is running in the chat. -*usage:* check_prog "${CHAT[ID]}" +*usage:* check_prog "CHAT[ID]" *alias:* checkprog @@ -664,7 +664,7 @@ fi ##### kill_proc Kill the interactive script running in the chat -*usage:* kill_proc "${CHAT[ID]}" +*usage:* kill_proc "CHAT[ID]" *alias:* killproc @@ -684,7 +684,7 @@ Starts a script as a background job and attaches a job name to it. All output fr In contrast to interactive chats, background jobs do not receive user input and can run forever. In addition you can suspend and restart running jobs, e.g. after reboot. -*usage:* start_back "${CHAT[ID]}" "script" "jobname" +*usage:* start_back "CHAT[ID]" "script" "jobname" *alias:* background "script" "jobname" @@ -696,7 +696,7 @@ background "examples/notify.sh" "notify" ##### check_back Return true (0) if an background job is active in the given chat. -*usage:* check_back "${CHAT[ID]}" "jobname" +*usage:* check_back "CHAT[ID]" "jobname" *alias:* checkback "jobname" @@ -712,7 +712,7 @@ fi ##### kill_back -*usage:* kill_back "${CHAT[ID]}" "jobname" +*usage:* kill_back "CHAT[ID]" "jobname" *alias:* killback "jobname" @@ -733,7 +733,7 @@ fi `send_interactive` is used to forward messages to interactive jobs. Usually a message is automatically forwarded from within `commands.sh`, but you can send messages yourself. -*usage:* send_interactive "${CHAT[ID]}" "message" +*usage:* send_interactive "CHAT[ID]" "message" ---- @@ -1090,13 +1090,13 @@ Do not use them in other files e.g. `bashbot.sh`, modules, addons etc. ##### _kick_user -*usage:* _kick_user "${USER[ID]}" +*usage:* _kick_user "USER[ID]" *alias for:* kick_chat_member "${CHAT[ID]}" "${USER[ID]}" ##### _unban -*usage:* _unban "${USER[ID]}" +*usage:* _unban "USER[ID]" *alias for:* unban_chat_member "${CHAT[ID]}" "${USER[ID]}" @@ -1272,7 +1272,7 @@ killallproc ---- ##### get_file -*usage:* url="$(get_file "${CHAT[ID]}" "message")" +*usage:* url="$(get_file "CHAT[ID]" "message")" ---- @@ -1306,7 +1306,7 @@ Output ARRAY as JSON.sh style data to STDOUT ---- ##### get_chat_member_status -*usage:* get_chat_member_status "${CHAT[ID]}" "${USER[ID]}" +*usage:* get_chat_member_status "CHAT[ID]" "USER[ID]" ---- @@ -1342,5 +1342,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-9-g5ceddde +#### $$VERSION$$ v1.35-dev-10-g70a3c19 From 47cab8021d040fa41a20fb3e1998bc098c8aeded Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 25 Jan 2021 22:32:14 +0100 Subject: [PATCH 43/99] bin: kickban + promote user --- bin/kickban_user.sh | 47 +++++++++++++++++++++++++++++++++++++++++++++ bin/promote_user.sh | 46 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100755 bin/kickban_user.sh create mode 100755 bin/promote_user.sh diff --git a/bin/kickban_user.sh b/bin/kickban_user.sh new file mode 100755 index 0000000..c6acf8a --- /dev/null +++ b/bin/kickban_user.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# shellcheck disable=SC1090,SC2034 +#=============================================================================== +# +# FILE: bin/kickban_user.sh +# +USAGE='kickban_user.sh [-h|--help] [-u|--unban] "CHAT[ID]" "USER[ID]" [debug]' +# +# DESCRIPTION: kickban or unban a user from the given group +# +# OPTIONS: -u | --unban - unban user +# CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself +# USER[ID] - user to (un)ban +# +# -h - display short help +# --help - this help +# +# +# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ +# AUTHOR: KayM (gnadelwartz), kay@rrr.de +# CREATED: 25.01.2021 20:34 +# +#### $$VERSION$$ v1.35-dev-11-g6b102a7 +#=============================================================================== + +#### +# parse args +BAN="kick_chat_member" +case "$1" in + "-u"|"--unban") + BAN="unban_chat_member" + shift + ;; +esac + +# set bashbot environment +source "${0%/*}/bashbot_env.inc.sh" "${3:-debug}" # $3 debug +print_help "$1" + +#### +# ready, do stuff here ----- + +# send message in selected format +"${BAN}" "$1" "$2" + +# output send message result +print_result diff --git a/bin/promote_user.sh b/bin/promote_user.sh new file mode 100755 index 0000000..3fa3961 --- /dev/null +++ b/bin/promote_user.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# shellcheck disable=SC1090,SC2034 +#=============================================================================== +# +# FILE: bin/promote_user.sh +# +USAGE='promote_user.sh [-h|--help] "CHAT[ID]" "USER[ID]" "right[:true|false]" ..' +# +# DESCRIPTION: promote / denote user rights in given group +# +# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself +# USER[ID] - user to (un)ban +# rights[:true|false] - rights to grant in long or short form, +# followed by :true to grant or :false to renove +# long: is_anonymous can_change_info can_post_messages can_edit_messages +# can_delete_messages can_invite_users can_restrict_members +# can_pin_messages can_promote_member` +# short: anon change post edit delete invite restrict pin promote +# +# -h - display short help +# --help - this help +# +# +# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ +# AUTHOR: KayM (gnadelwartz), kay@rrr.de +# CREATED: 25.01.2021 22:34 +# +#### $$VERSION$$ v1.35-dev-11-g6b102a7 +#=============================================================================== + +#### +# parse args +PROMOTE="promote_chat_member" + +# set bashbot environment +source "${0%/*}/bashbot_env.inc.sh" "debug" # debug +print_help "$1" + +#### +# ready, do stuff here ----- + +# send message in selected format +"${PROMOTE}" "$@" + +# output send message result +print_result From bc414eef5a5452bbb4d96e846aca817205308211 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 26 Jan 2021 12:57:27 +0100 Subject: [PATCH 44/99] init: offer copy mycommands files --- bashbot.sh | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index d7ae5ec..60ff4d5 100755 --- a/bashbot.sh +++ b/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-2-g1fe22a0 +#### $$VERSION$$ v1.35-dev-12-g47cab80 ################################################################## # emmbeded system may claim bash but it is not @@ -1132,6 +1132,17 @@ bot_init() { printf "${ORANGE}You are not root, adjusting permissions may fail. Try \"sudo ./bashbot.sh init\"${NN}Press to stop or to continue..." 1>&2 [ -n "${INTERACTIVE}" ] && read -r runuser fi + # check if mycommands exist + if [ ! -r "${BASHBOT_ETC:-.}/mycommands.sh" ]; then + printf "Mycommands.sh not found, copy ${GREY}mycommands.sh.dist${NC} to mycommands.sh? (y/N) N\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[Yy] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.dist" "${BASHBOT_ETC:-.}/mycommands.sh" + fi + if [ ! -r "${BASHBOT_ETC:-.}/mycommands.conf" ]; then + printf "Mycommands config file not found, copy ${GREY}mycommands.conf.dist${NC} to mycommands.conf? (y/N) N\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[Yy] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.conf.dist" "${BASHBOT_ETC:-.}/mycommands.conf" + fi # adjust permissions printf "Adjusting files and permissions for user \"${touser}\" ...\n" chmod 711 . @@ -1161,8 +1172,8 @@ bot_init() { fi fi # check if botconf seems valid - printf "${GREEN}This is your bot config:${NN}" - sed 's/^/\t/' "${BOTCONFIG}.jssh" | grep -vF '["bot_config_key"]' + printf "${GREEN}This is your bot config:${NN}${GREY}" + sed 's/^/\t/' "${BOTCONFIG}.jssh" | grep -vF '["bot_config_key"]'; printf "${NC}" if check_token "$(getConfigKey "bottoken")" && [[ "$(getConfigKey "botadmin")" =~ ^[${o9o9o9}]+$ ]]; then printf "Bot config seems to be valid. Should I make a backup copy? (Y/n) Y\b" read -r ANSWER @@ -1174,7 +1185,7 @@ bot_init() { printf "${ORANGE}Bot config may incomplete, pls check.${NN}" fi # show result - ls -ld "${DATADIR}" "${LOGDIR}" ./*.jssh* ./*.sh 2>/dev/null + printf "${GREY}"; ls -ldp "${DATADIR}" "${LOGDIR}" ./*.jssh* ./*.sh ./*.conf 2>/dev/null; printf "${NC}" } if ! _is_function send_message ; then From 08a05242f992bf7464e9217df29f73934b027cd3 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 26 Jan 2021 13:02:04 +0100 Subject: [PATCH 45/99] init: offer copy config only for new installations --- bashbot.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 60ff4d5..6842e4a 100755 --- a/bashbot.sh +++ b/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-12-g47cab80 +#### $$VERSION$$ v1.35-dev-13-gbc414ee ################################################################## # emmbeded system may claim bash but it is not @@ -1137,11 +1137,12 @@ bot_init() { printf "Mycommands.sh not found, copy ${GREY}mycommands.sh.dist${NC} to mycommands.sh? (y/N) N\b" read -r ANSWER [[ "${ANSWER}" =~ ^[Yy] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.dist" "${BASHBOT_ETC:-.}/mycommands.sh" - fi - if [ ! -r "${BASHBOT_ETC:-.}/mycommands.conf" ]; then - printf "Mycommands config file not found, copy ${GREY}mycommands.conf.dist${NC} to mycommands.conf? (y/N) N\b" - read -r ANSWER - [[ "${ANSWER}" =~ ^[Yy] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.conf.dist" "${BASHBOT_ETC:-.}/mycommands.conf" + # offer to copy config also + if [ ! -r "${BASHBOT_ETC:-.}/mycommands.conf" ]; then + printf "Mycommands config file not found, copy ${GREY}mycommands.conf.dist${NC} to mycommands.conf? (y/N) N\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[Yy] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.conf.dist" "${BASHBOT_ETC:-.}/mycommands.conf" + fi fi # adjust permissions printf "Adjusting files and permissions for user \"${touser}\" ...\n" From b441384d4a664f5a8a476afeab1aca168e91d783 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 26 Jan 2021 14:34:25 +0100 Subject: [PATCH 46/99] iBUTTON: fix comamnds and mycommands processing --- bashbot.sh | 6 +++--- commands.sh | 6 +++--- mycommands.sh | 18 ++++++++---------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 6842e4a..215980d 100755 --- a/bashbot.sh +++ b/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-13-gbc414ee +#### $$VERSION$$ v1.35-dev-14-g08a0524 ################################################################## # emmbeded system may claim bash but it is not @@ -1134,9 +1134,9 @@ bot_init() { fi # check if mycommands exist if [ ! -r "${BASHBOT_ETC:-.}/mycommands.sh" ]; then - printf "Mycommands.sh not found, copy ${GREY}mycommands.sh.dist${NC} to mycommands.sh? (y/N) N\b" + printf "Mycommands.sh not found, copy ${GREY}mycommands.sh.clean${NC} to mycommands.sh? (y/N) N\b" read -r ANSWER - [[ "${ANSWER}" =~ ^[Yy] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.dist" "${BASHBOT_ETC:-.}/mycommands.sh" + [[ "${ANSWER}" =~ ^[Yy] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.clean" "${BASHBOT_ETC:-.}/mycommands.sh" # offer to copy config also if [ ! -r "${BASHBOT_ETC:-.}/mycommands.conf" ]; then printf "Mycommands config file not found, copy ${GREY}mycommands.conf.dist${NC} to mycommands.conf? (y/N) N\b" diff --git a/commands.sh b/commands.sh index 3f940fb..f2db8a5 100644 --- a/commands.sh +++ b/commands.sh @@ -15,7 +15,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.35-dev-7-g9584068 +#### $$VERSION$$ v1.35-dev-14-g08a0524 # # bashbot locale defaults to c.UTF-8, adjust locale in mycommands.sh if needed @@ -81,11 +81,11 @@ if [ -z "$1" ] || [[ "$1" == *"debug"* ]];then # detect inline and callback query if [ -n "${iQUERY[ID]}" ]; then # forward inline query to optional dispatcher - [ "${INLINE:-0}" != "0" ] || _exec_if_function myinlines + [ "${INLINE:-0}" != "0" ] && _exec_if_function myinlines elif [ -n "${iBUTTON[ID]}" ]; then # forward inline query to optional dispatcher - [ "${CALLBACK:-0}" != "0" ] || _exec_if_function mycallbacks + [ "${CALLBACK:-0}" != "0" ] && _exec_if_function mycallbacks ################# # regular command diff --git a/mycommands.sh b/mycommands.sh index eb2fafd..8538172 100644 --- a/mycommands.sh +++ b/mycommands.sh @@ -13,7 +13,7 @@ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # Author: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.35-dev-7-g9584068 +#### $$VERSION$$ v1.35-dev-14-g08a0524 ####################################################### # shellcheck disable=SC1117 @@ -183,22 +183,22 @@ else ####################### # callbacks from buttons attached to messages will be processed here # no standard use case for processing callbacks, let's log them for some users and chats - case "${USER[ID]}+${CHAT[ID]}" in + case "${iBUTTON[USER_ID]}+${iBUTTON[CHAT_ID]}" in 'USERID1+'*) # do something for all callbacks from USER - printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBOTTON[USER_ID]}" "${iBOTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\ - >>"${DATADIR}/${iBOTTON[USER_ID]}.log" + printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBUTTON[USER_ID]}" "${iBUTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\ + >>"${DATADIR}/${iBUTTON[USER_ID]}.log" answer_callback_query "${iBUTTON[ID]}" "Request has been logged in your user log..." return ;; *'+CHATID1') # do something for all callbacks from CHAT - printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBOTTON[USER_ID]}" "${iBOTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\ - >>"${DATADIR}/${iBOTTON[CHAT_ID]}.log" + printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBUTTON[USER_ID]}" "${iBUTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\ + >>"${DATADIR}/${iBUTTON[CHAT_ID]}.log" answer_callback_query "${iBUTTON[ID]}" "Request has been logged in chat log..." return ;; 'USERID2+CHATID2') # do something only for callbacks form USER in CHAT - printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBOTTON[USER_ID]}" "${iBOTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\ - >>"${DATADIR}/${iBOTTON[USER_ID]}-${iBOTTON[CHAT_ID]}.log" + printf "%s: U=%s C=%s D=%s\n" "$(date)" "${iBUTTON[USER_ID]}" "${iBUTTON[CHAT_ID]}" "${iBUTTON[DATA]}"\ + >>"${DATADIR}/${iBUTTON[USER_ID]}-${iBUTTON[CHAT_ID]}.log" answer_callback_query "${iBUTTON[ID]}" "Request has been logged in user-chat log..." return ;; @@ -209,8 +209,6 @@ else answer_callback_query "${iBUTTON[ID]}" "" ;; esac - - } myinlines() { From 2222875e2b1858bca1509195bdab1c84dd0ad664 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 26 Jan 2021 14:38:31 +0100 Subject: [PATCH 47/99] modules: sendMessage: add answer_callback_query --- modules/sendMessage.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 4b19434..774cdbb 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.35-dev-3-g461e748 +#### $$VERSION$$ v1.35-dev-15-gb441384 # will be automatically sourced from bashbot @@ -174,6 +174,13 @@ _button_row() { printf "[%s]" "${json}" } +# $1 callback id, $2 test to show, alert if not empty +answer_callback_query() { + local alert + [ -n "$3" ] && alert='","show_alert": true' + sendJson "" '"callback_query_id": "'"$1"'","text":"'"$2${alert}"'"' "${URL}/answerCallbackQuery" +} + # $1 chat, $2 file_id on telegram server send_sticker() { sendJson "$1" '"sticker": "'"$2"'"' "${URL}/sendSticker" From b096338c3342bfe76678c27761481ef0c4af86d1 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 26 Jan 2021 14:51:50 +0100 Subject: [PATCH 48/99] doc: add answer_callback_query --- doc/6_reference.md | 15 ++++++++++++++- modules/sendMessage.sh | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index 6b162e2..37392e9 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -289,6 +289,7 @@ In both cases the message itself is not changed, only the attached inline keyboa To create a JSON button array I suggest to use `_button_row`. +*example:* ```bash # message without button send_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message ..." @@ -306,6 +307,18 @@ edit_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message inline ``` +##### answer_callback_query +Each request send from a callback button must be answered by a call to `answer_callback_query`. +If alert is given an alert will be shown by the Telegram client instead of a notification. + +*usage:* answer_callback_query "iBUTTON[ID]" "text notification ..." ["alert"] + +*example:* +```bash +answer_callback_query "${iBUTTON[ID]}" "Button data is: ${iBUTTON[DATA]}" + +answer_callback_query "${iBUTTON[ID]}" "Alert: Button pressed!" "alert" +``` ---- @@ -1342,5 +1355,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-10-g70a3c19 +#### $$VERSION$$ v1.35-dev-16-g2222875 diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 774cdbb..115cbe2 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.35-dev-15-gb441384 +#### $$VERSION$$ v1.35-dev-16-g2222875 # will be automatically sourced from bashbot @@ -174,7 +174,7 @@ _button_row() { printf "[%s]" "${json}" } -# $1 callback id, $2 test to show, alert if not empty +# $1 callback id, $2 text to show, alert if not empty answer_callback_query() { local alert [ -n "$3" ] && alert='","show_alert": true' From e4ee88003e60f30f59c109d1cf4d9a6d5ce6ae14 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 26 Jan 2021 19:44:40 +0100 Subject: [PATCH 49/99] conf: BASHBOT_SLEEP use default, 10s and 2s as example --- mycommands.conf | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mycommands.conf b/mycommands.conf index f2052d0..e5e21ab 100644 --- a/mycommands.conf +++ b/mycommands.conf @@ -12,7 +12,7 @@ # Author: KayM (gnadelwartz), kay@rrr.de # Created: 09.01.2021 07:27 # -#### $$VERSION$$ v1.35-dev-6-gc90b565 +#### $$VERSION$$ v1.35-dev-17-gb096338 ####################################################### ########## @@ -68,7 +68,11 @@ unset BASHBOT_RETRY # set value for adaptive sleeping while waiting for uodates in millisconds # max slepp between polling updates 10s (default 5s) -export BASHBOT_SLEEP="10000" +# export BASHBOT_SLEEP="10000" + +# max slepp between polling updates 2s (default 5s) +# export BASHBOT_SLEEP="2000" + # add 0.2s if no update available, up to BASHBOT_SLEEP (default 0.1s) export BASHBOT_SLEEP_STEP="200" From 75e775606a5a724435928314dc815ddf54d5b314 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 26 Jan 2021 20:49:55 +0100 Subject: [PATCH 50/99] modules: sendMessage: more comforable inline_buttons functions --- modules/sendMessage.sh | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 115cbe2..70753d5 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.35-dev-16-g2222875 +#### $$VERSION$$ v1.35-dev-18-ge4ee880 # will be automatically sourced from bashbot @@ -137,18 +137,18 @@ remove_keyboard() { #JSON='"text":"$2", "reply_markup": {"remove_keyboard":true}' } -# $1 CHAT $2 message-id $3 keyboard -edit_inline_keyboard() { - sendJson "$1" '"message_id":'"$2"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${URL}/editMessageReplyMarkup" - # JSON='"message_id":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}' +# buttons will specified as "texts +#|url" ... "text|url" empty arg starts new row +# url not starting with http:// or https:// will be send as callback_data +send_inline_buttons(){ + send_inline_keyboard "$1" "$2" "$(_button_row "${@:3}")" } - -# $1 CHAT $2 message $3 keyboard -send_inline_keyboard() { - local text; text='"text":"'$(JsonEscape "$2")'"'; [ -z "$2" ] && text='"text":"..."' - sendJson "$1" "${text}"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${MSG_URL}" - # JSON='"text":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}' +# $1 CHAT $2 message-id $3 buttons +# buttons will specified as "text|url" ... "text|url" empty arg starts new row +# url not starting with http:// or https:// will be send as callback_data +edit_inline_buttons(){ + edit_inline_keyboard "$1" "$2" "$(_button_row "${@:3}")" } @@ -174,6 +174,21 @@ _button_row() { printf "[%s]" "${json}" } +# raw inline functions, for special use +# $1 CHAT $2 message-id $3 keyboard +edit_inline_keyboard() { + sendJson "$1" '"message_id":'"$2"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${URL}/editMessageReplyMarkup" + # JSON='"message_id":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}' +} + + +# $1 CHAT $2 message $3 keyboard +send_inline_keyboard() { + local text; text='"text":"'$(JsonEscape "$2")'"'; [ -z "$2" ] && text='"text":"..."' + sendJson "$1" "${text}"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${MSG_URL}" + # JSON='"text":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}' +} + # $1 callback id, $2 text to show, alert if not empty answer_callback_query() { local alert From fa0cb75c603fa79fc78f66339ae0871b05203e50 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 26 Jan 2021 20:53:08 +0100 Subject: [PATCH 51/99] doc: add inline_buttons, move inline_keybord to internal --- doc/6_reference.md | 143 +++++++++++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 50 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index 37392e9..f9ec815 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -230,10 +230,10 @@ _keyboard_numpad send_button "${CHAT[ID]}" "Awesome Deals!" "Visit my Shop" "https://dealz.rrr.de" ``` -##### _button_row -`_button_row` is a helper function to make it easier to send messages with with multiple buttons. +##### send_inline_buttons +`senbd_inline_buttons` sends a message with buttons attached. -*usage:* _button_row "text|url" "text|url" "" "url" "" "text|url" ... +*usage:* send_inline_buttons "CHAT[ID]" "text|url" "text|url" "" "url" "" "text|url" ... Each button is specified as a `"text|url"` pair separated by `|`, `text` is shown on the button and `url` is opened on button click. By default all buttons are displayed on one row, an empty string `""` starts a new button row. @@ -245,47 +245,20 @@ If `"url"` without text is given, `url` is shown on the button and opened on but *example:* ```bash # one button, same as send_button -send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" "$(_button_row "Visit my Shop|https://dealz.rrr.de")" +send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" "Visit my Shop|https://dealz.rrr.de" # one button row -send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "button 1|http://rrr.de" "button 2|http://rrr.de")" +send_inline_keyboard "${CHAT[ID]}" "message" "button 1|http://rrr.de" "button 2|http://rrr.de" # multiple button rows -send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "b1|http://rrr.de" "b2|http://rrr.de" "" "b3|http://rrr.de" "b4|http://rrr.de")" +send_inline_keyboard "${CHAT[ID]}" "message" "b1|http://rrr.de" "b2|http://rrr.de" "" "b3|http://rrr.de" "b4|http://rrr.de" ``` -##### send_inline_keyboard -`send_inline_keyboard` sends a message with buttons attached, buttons must be given in JSON format. -In contrast to `send_keyboard` buttons are attached to the message and do not send text. +##### edit_inline_buttons +`edit_inline_buttons` can add inline buttons to existing messages and replace existing inline buttons. +In both cases the message itself is not changed, only the attached inline buttons. -*usage:* send_inline_keyboard "CHAT[ID]" "message" "[JSON button array]" - -I suggest to use `_button_row` to create the JSON button array. For hand crafted JSON the following format must be used, -see [Inline Keyboard Markup](https://core.telegram.org/bots/api#inlinekeyboardmarkup) - -URL `[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]`\ -CALLBACK `[ {"text":"text1", "callback_data":"abc"}, ... {"text":"textN", "callback_data":"defg"} ],[...]`\ -An URL Button opens the given URL, a CALLBACK button sends an update the bot must react on. - -*example:* -```bash -# one button, same as send_button -send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" '[{"text":"Visit my Shop", "url":"https://dealz.rrr.de"}]' - -# one button row -send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"button 1", url"":"http://rrr.de"}, {"text":"button 2", "url":"http://rrr.de"} ]' - -# multiple button rows -send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"b1", "url":"http://rrr.de"}, {"text":"b2", "url":"http://rrr.de"}], [{"text":"b3", "url":"http://rrr.de"}, "text":"b4", "url":"http://rrr.de"}]' -``` - -*See also [Inline keyboard markup](https://core.telegram.org/bots/api/#inlinekeyboardmarkup)* - -##### edit_inline_keyboard -`edit_inline_keyboard` can add inline keyboards to existing messages and replace existing inline keyboards. -In both cases the message itself is not changed, only the attached inline keyboard. - -*usage:* edit_inline_keyboard "CHAT[ID]" "MESSAGE[ID]" "[JSON button array]" +*usage:* edit_inline_buttons "CHAT[ID]" "MESSAGE[ID]" "text|url" "text|url" ... To create a JSON button array I suggest to use `_button_row`. @@ -297,10 +270,10 @@ echo ${BOTSEND[ID]} 567 # add one button row -edit_inline_keyboard "${CHAT[ID]}" "567" "$(_button_row "button 1|http://rrr.de" "button 2|http://rrr.de")" +edit_inline_keyboard "${CHAT[ID]}" "567" "button 1|http://rrr.de" "button 2|http://rrr.de" # change buttons -edit_inline_keyboard "${CHAT[ID]}" "567" "$(_button_row "Success edit_inline_keyboard|http://rrr.de")" +edit_inline_keyboard "${CHAT[ID]}" "567" "Success edit_inline_keyboard|http://rrr.de" # delete button by replace whole message edit_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message inline *removed*..." @@ -322,6 +295,7 @@ answer_callback_query "${iBUTTON[ID]}" "Alert: Button pressed!" "alert" ---- + ### Edit / Replace Messages Edit a message means replace the content of the message in place. The message stay on the same position in the chat and keep the same @@ -1147,16 +1121,6 @@ Do not use them in other files e.g. `bashbot.sh`, modules, addons etc. ---- -#### _inline_button -*usage:* _inline_button "${1}" "${2}" - -*alias for:* send_inline_button "${CHAT[ID]}" "" "${1}" "${2}" - -#### _inline_keyboard -*usage:* _inline_keyboard "${1}" - -*alias for:* _inline_keyboard "${CHAT[ID]}" "" "${1}" - #### _keyboard_numpad *usage:* _keyboard_numpad @@ -1352,8 +1316,87 @@ The name of your bot is available as bash variable "$ME", there is no need to ca *usage:* ME="$(getBotName)" +---- + +##### send_inline_keyboard +`send_inline_keyboard` sends a message with buttons attached, buttons must be given in JSON format. +In contrast to `send_keyboard` buttons are attached to the message and do not send text. + +*usage:* send_inline_keyboard "CHAT[ID]" "message" "[JSON button array]" + +I suggest to use `_button_row` to create the JSON button array. For hand crafted JSON the following format must be used, +see [Inline Keyboard Markup](https://core.telegram.org/bots/api#inlinekeyboardmarkup) + +URL `[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]`\ +CALLBACK `[ {"text":"text1", "callback_data":"abc"}, ... {"text":"textN", "callback_data":"defg"} ],[...]`\ +An URL Button opens the given URL, a CALLBACK button sends an update the bot must react on. + +*example:* +```bash +# one button, same as send_button +send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" '[{"text":"Visit my Shop", "url":"https://dealz.rrr.de"}]' + +# one button row +send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"button 1", url"":"http://rrr.de"}, {"text":"button 2", "url":"http://rrr.de"} ]' + +# multiple button rows +send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"b1", "url":"http://rrr.de"}, {"text":"b2", "url":"http://rrr.de"}], [{"text":"b3", "url":"http://rrr.de"}, "text":"b4", "url":"http://rrr.de"}]' +``` + +*See also [Inline keyboard markup](https://core.telegram.org/bots/api/#inlinekeyboardmarkup)* + +##### edit_inline_keyboard +`edit_inline_keyboard` can add inline keyboards to existing messages and replace existing inline keyboards. +In both cases the message itself is not changed, only the attached inline keyboard. + +*usage:* edit_inline_keyboard "CHAT[ID]" "MESSAGE[ID]" "[JSON button array]" + +To create a JSON button array I suggest to use `_button_row`. + +*example:* +```bash +# message without button +send_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message ..." +echo ${BOTSEND[ID]} +567 + +# add one button row +edit_inline_keyboard "${CHAT[ID]}" "567" "$(_button_row "button 1|http://rrr.de" "button 2|http://rrr.de")" + +# change buttons +edit_inline_keyboard "${CHAT[ID]}" "567" "$(_button_row "Success edit_inline_keyboard|http://rrr.de")" + +# delete button by replace whole message +edit_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message inline *removed*..." + +``` + +##### _button_row +`_button_row` is a helper function to make it easier to send messages with with multiple buttons. + +*usage:* _button_row "text|url" "text|url" "" "url" "" "text|url" ... + +Each button is specified as a `"text|url"` pair separated by `|`, `text` is shown on the button and `url` is opened on button click. +By default all buttons are displayed on one row, an empty string `""` starts a new button row. +If `"url"` without text is given, `url` is shown on the button and opened on button click. + +**Important**: An `url` not startung with http(s):// or tg:// will be converted to a +[Callback Button](https://core.telegram.org/bots/2-0-intro#callback-buttons) + +*example:* +```bash +# one button, same as send_button +send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" "$(_button_row "Visit my Shop|https://dealz.rrr.de")" + +# one button row +send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "button 1|http://rrr.de" "button 2|http://rrr.de")" + +# multiple button rows +send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "b1|http://rrr.de" "b2|http://rrr.de" "" "b3|http://rrr.de" "b4|http://rrr.de")" +``` + #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-16-g2222875 +#### $$VERSION$$ v1.35-dev-19-g75e7756 From cbf3945e4f8e118a84754e0099faac1f980f545e Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 26 Jan 2021 20:59:10 +0100 Subject: [PATCH 52/99] mycommands: better iBUTTONS example --- mycommands.sh | 9 ++++++--- mycommands.sh.clean | 14 +++++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/mycommands.sh b/mycommands.sh index 8538172..d877028 100644 --- a/mycommands.sh +++ b/mycommands.sh @@ -13,7 +13,7 @@ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # Author: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.35-dev-14-g08a0524 +#### $$VERSION$$ v1.35-dev-20-gfa0cb75 ####################################################### # shellcheck disable=SC1117 @@ -203,8 +203,11 @@ else return ;; *) # all other callbacks are processed here - : # your processing here ... - : + # your processing here ... + if [[ -n "${iBUTTON[CHAT_ID]}" && -n "${iBUTTON[MESSAGE_ID]}" ]]; then + # output random button if message data is available + edit_inline_buttons "${iBUTTON[CHAT_ID]}" "${iBUTTON[MESSAGE_ID]}" "Button ${RANDOM}|${RANDOM}" + fi # Telegram needs an ack each callback query, default empty answer_callback_query "${iBUTTON[ID]}" "" ;; diff --git a/mycommands.sh.clean b/mycommands.sh.clean index 9ae73e2..9f3de30 100644 --- a/mycommands.sh.clean +++ b/mycommands.sh.clean @@ -10,7 +10,7 @@ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # Author: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.35-dev-18-ge4ee880 ####################################################### # shellcheck disable=SC1117 @@ -77,6 +77,18 @@ else esac } + mycallbacks() { + ####################### + # callbacks from buttons attached to messages will be processed here + case "${iBUTTON[USER_ID]}+${iBUTTON[CHAT_ID]}" in + *) # all other callbacks are processed here + : # your processing here ... + : + # Telegram needs an ack each callback query, default empty + answer_callback_query "${iBUTTON[ID]}" "" + ;; + esac + } myinlines() { ####################### # this fuinction is called only if you has set INLINE=1 !! From 8c85c81f946cfbc18398c002f9254881a1220dac Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 26 Jan 2021 21:05:27 +0100 Subject: [PATCH 53/99] commands: fork commands.sh --- bashbot.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 215980d..5b74f96 100755 --- a/bashbot.sh +++ b/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-14-g08a0524 +#### $$VERSION$$ v1.35-dev-21-gcbf3945 ################################################################## # emmbeded system may claim bash but it is not @@ -707,7 +707,7 @@ process_client() { # process inline and message events # first classic command dispatcher # shellcheck source=./commands.sh - source "${COMMANDS}" "${debug}" & + "${COMMANDS}" "${debug}" & # then all registered addons if [ -z "${iQUERY[ID]}" ]; then From 5192212782355dc15215a33c8c9a654077d1cacc Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 07:36:26 +0100 Subject: [PATCH 54/99] doc: more complex buttons, rearrange inline again --- doc/6_reference.md | 209 ++++++++++++++++++++++++++------------------- 1 file changed, 121 insertions(+), 88 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index f9ec815..3670eb0 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -230,17 +230,21 @@ _keyboard_numpad send_button "${CHAT[ID]}" "Awesome Deals!" "Visit my Shop" "https://dealz.rrr.de" ``` +### Inline buttons +Functions to send/edit messages with with some buttons attached. + ##### send_inline_buttons -`senbd_inline_buttons` sends a message with buttons attached. +`senbd_inline_buttons` sends a message with multiple buttons attached. Buttons can be an URL or a CALLBACK button. +By default all buttons are displayed on one row, an empty string `""` starts a new row. *usage:* send_inline_buttons "CHAT[ID]" "text|url" "text|url" "" "url" "" "text|url" ... -Each button is specified as a `"text|url"` pair separated by `|`, `text` is shown on the button and `url` is opened on button click. -By default all buttons are displayed on one row, an empty string `""` starts a new button row. +URL buttons are specified as a `"text|url"` pair separated by `|`, `text` is shown on the button and `url` is opened on button click. If `"url"` without text is given, `url` is shown on the button and opened on button click. -**Important**: An `url` not startung with http(s):// or tg:// will be converted to a -[Callback Button](https://core.telegram.org/bots/2-0-intro#callback-buttons) +*Important* An `url` not startung with http(s):// or tg:// will create a +[CALLBACK Button](https://core.telegram.org/bots/2-0-intro#callback-buttons). + *example:* ```bash @@ -255,12 +259,11 @@ send_inline_keyboard "${CHAT[ID]}" "message" "b1|http://rrr.de" "b2|http://rrr.d ``` ##### edit_inline_buttons -`edit_inline_buttons` can add inline buttons to existing messages and replace existing inline buttons. -In both cases the message itself is not changed, only the attached inline buttons. +`edit_inline_buttons` add inline buttons to existing messages, existing inline buttons will be replaced. +Only the attached buttons will be changed, not the message. *usage:* edit_inline_buttons "CHAT[ID]" "MESSAGE[ID]" "text|url" "text|url" ... -To create a JSON button array I suggest to use `_button_row`. *example:* ```bash @@ -281,7 +284,7 @@ edit_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message inline ``` ##### answer_callback_query -Each request send from a callback button must be answered by a call to `answer_callback_query`. +Each request send from a CALLBACK button must be answered by a call to `answer_callback_query`. If alert is given an alert will be shown by the Telegram client instead of a notification. *usage:* answer_callback_query "iBUTTON[ID]" "text notification ..." ["alert"] @@ -295,6 +298,114 @@ answer_callback_query "${iBUTTON[ID]}" "Alert: Button pressed!" "alert" ---- +#### Inline keyboards +Functions to send/edit more complex button layouts (keyboards), I suggest to start with the simpler inline buttons above. + +##### _button_row +`_button_row` is a helper function to specify a keyboard row in the form "text|url" pairs. +Internally used by inline buttons also. + +*usage:* _button_row "text|url" "text|url" "url" "text|url" ... + +*example:* +```bash +# similar to send_button +send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" "$(_button_row "Visit my Shop|https://dealz.rrr.de")" + +# similar to send_inline_button +send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "button 1|http://rrr.de" "button 2|http://rrr.de")" + +# multiple button rows +send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "b1|http://rrr.de" "b2|http://rrr.de" "" "b3|http://rrr.de" "b4|http://rrr.de")" +``` + +##### send_inline_keyboard +`send_inline_keyboard` sends a message with keyboards attached, keyboards must be specified in JSON format. + +*usage:* send_inline_keyboard "CHAT[ID]" "message" "[JSON button array]" + +I suggest to use `_button_row` to create the used JSON. For hand crafted JSON the following format must be used, +see [Inline Keyboard Markup](https://core.telegram.org/bots/api#inlinekeyboardmarkup) + +URL `[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]`\ +CALLBACK `[ {"text":"text1", "callback_data":"abc"}, ... {"text":"textN", "callback_data":"defg"} ],[...]`\ +An URL Button opens the given URL, a CALLBACK button sends an update the bot must react on. + +*example:* +```bash +# send_button +send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" '[{"text":"Visit my Shop", "url":"https://dealz.rrr.de"}]' + +# send_inline_button +send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"button 1", url"":"http://rrr.de"}, {"text":"button 2", "url":"http://rrr.de"} ]' + +# multiple button rows +send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"b1", "url":"http://rrr.de"}, {"text":"b2", "url":"http://rrr.de"}], [{"text":"b3", "url":"http://rrr.de"}, "text":"b4", "url":"http://rrr.de"}]' + +# more complex keyboard, note the , +keyboard_text="Deal-O-Mat public groups ..." +keyboard_json="$(_button_row "đŸ¤– #Home of Deal-O-Mat Bot đŸ¤–|https://dealz.rrr.de/dealzbot.html") +, $(_button_row "Amazon DE|https://t.me/joinchat/IvvRtlxxxxx" "Home & Family|https://t.me/joinchat/VPh_wexxxxx") +, $(_button_row "Amz International |https://t.me/joinchat/IvvRtkxxxxx" "Amazon WHD|https://t.me/joinchat/IvvRxxxxx") +, $(_button_row "Smartphones|https://t.me/joinchat/IvvRthtqxxxxx" "Gaming|https://t.me/joinchat/IvvRthRyrsmxxxxx") +, $(_button_row "Accessoires|https://t.me/joinchat/IvvRthlJxxxxx" "eBay|https://t.me/joinchat/IvvRthxxxxx") +, $(_button_row "!! Offtopic Discussions !!|https://t.me/joinchat/IvvRthRhxxxxx-pZrWw") +, $(_button_row "Deals >100|https://t.me/joinchat/IvvRtxxxxx" "Leasing|https://t.me/joinchat/IvvRthRbxxxxx") +, $(_button_row "Deals >1000|https://t.me/joinchat/IvvRtlxxxxx" "Deals >500|https://t.me/joinchat/IvvRthvbHxxxxx") + +send_inline_keyboard "CHAT[ID]" "${keyboard_text}" "${keyboard_json}" + +ä result + +---------------------------------+ + | đŸ¤– #Home of Deal-O-Mat Bot đŸ¤– | + |---------------------------------| + | Amazon DE | Home & Family | + |----------------|----------------| + | Amz Internat | Amazon WHD | + |----------------|----------------| + | Smartphones | Gaming | + |----------------|----------------| + | Accessoires | eBay | + |---------------------------------| + | !! Offtopic Discussions !! | + |---------------------------------| + | Deals >100 | Leasing | + |----------------|----------------| + | Deals >1000 | Deals >500 | + +---------------------------------+ + +``` + +*See also [Inline keyboard markup](https://core.telegram.org/bots/api/#inlinekeyboardmarkup)* + +##### edit_inline_keyboard +`edit_inline_keyboard` add inline keyboards to existing messages and replace existing inline keyboards. +Only the attached keyboard will be changed, not the message. + +*usage:* edit_inline_keyboard "CHAT[ID]" "MESSAGE[ID]" "[JSON button array]" + +To create a JSON button array I suggest to use `_button_row`. + +*example:* +```bash +# message without button +send_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message ..." +echo ${BOTSEND[ID]} +567 + +# add one button row with help of _button_row +edit_inline_keyboard "${CHAT[ID]}" "567" "$(_button_row "button 1|http://rrr.de" "button 2|http://rrr.de")" + +# change buttons with help of _button_row +edit_inline_keyboard "${CHAT[ID]}" "567" "$(_button_row "Success edit_inline_keyboard|http://rrr.de")" + +# delete button by replace whole message +edit_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message inline *removed*..." + +``` + +---- + ### Edit / Replace Messages @@ -1316,87 +1427,9 @@ The name of your bot is available as bash variable "$ME", there is no need to ca *usage:* ME="$(getBotName)" ----- - -##### send_inline_keyboard -`send_inline_keyboard` sends a message with buttons attached, buttons must be given in JSON format. -In contrast to `send_keyboard` buttons are attached to the message and do not send text. - -*usage:* send_inline_keyboard "CHAT[ID]" "message" "[JSON button array]" - -I suggest to use `_button_row` to create the JSON button array. For hand crafted JSON the following format must be used, -see [Inline Keyboard Markup](https://core.telegram.org/bots/api#inlinekeyboardmarkup) - -URL `[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ],[...]`\ -CALLBACK `[ {"text":"text1", "callback_data":"abc"}, ... {"text":"textN", "callback_data":"defg"} ],[...]`\ -An URL Button opens the given URL, a CALLBACK button sends an update the bot must react on. - -*example:* -```bash -# one button, same as send_button -send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" '[{"text":"Visit my Shop", "url":"https://dealz.rrr.de"}]' - -# one button row -send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"button 1", url"":"http://rrr.de"}, {"text":"button 2", "url":"http://rrr.de"} ]' - -# multiple button rows -send_inline_keyboard "${CHAT[ID]}" "message" '[{"text":"b1", "url":"http://rrr.de"}, {"text":"b2", "url":"http://rrr.de"}], [{"text":"b3", "url":"http://rrr.de"}, "text":"b4", "url":"http://rrr.de"}]' -``` - -*See also [Inline keyboard markup](https://core.telegram.org/bots/api/#inlinekeyboardmarkup)* - -##### edit_inline_keyboard -`edit_inline_keyboard` can add inline keyboards to existing messages and replace existing inline keyboards. -In both cases the message itself is not changed, only the attached inline keyboard. - -*usage:* edit_inline_keyboard "CHAT[ID]" "MESSAGE[ID]" "[JSON button array]" - -To create a JSON button array I suggest to use `_button_row`. - -*example:* -```bash -# message without button -send_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message ..." -echo ${BOTSEND[ID]} -567 - -# add one button row -edit_inline_keyboard "${CHAT[ID]}" "567" "$(_button_row "button 1|http://rrr.de" "button 2|http://rrr.de")" - -# change buttons -edit_inline_keyboard "${CHAT[ID]}" "567" "$(_button_row "Success edit_inline_keyboard|http://rrr.de")" - -# delete button by replace whole message -edit_markdownv2_message "${CHAT[ID]}" "*HI* this is a _markdown_ message inline *removed*..." - -``` - -##### _button_row -`_button_row` is a helper function to make it easier to send messages with with multiple buttons. - -*usage:* _button_row "text|url" "text|url" "" "url" "" "text|url" ... - -Each button is specified as a `"text|url"` pair separated by `|`, `text` is shown on the button and `url` is opened on button click. -By default all buttons are displayed on one row, an empty string `""` starts a new button row. -If `"url"` without text is given, `url` is shown on the button and opened on button click. - -**Important**: An `url` not startung with http(s):// or tg:// will be converted to a -[Callback Button](https://core.telegram.org/bots/2-0-intro#callback-buttons) - -*example:* -```bash -# one button, same as send_button -send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" "$(_button_row "Visit my Shop|https://dealz.rrr.de")" - -# one button row -send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "button 1|http://rrr.de" "button 2|http://rrr.de")" - -# multiple button rows -send_inline_keyboard "${CHAT[ID]}" "message" "$(_button_row "b1|http://rrr.de" "b2|http://rrr.de" "" "b3|http://rrr.de" "b4|http://rrr.de")" -``` #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-19-g75e7756 +#### $$VERSION$$ v1.35-dev-22-g8c85c81 From 5a0a5712dd17b82cff3bea01615aad29287918ac Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 07:54:28 +0100 Subject: [PATCH 55/99] doc: more button examples --- doc/6_reference.md | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index 3670eb0..509eb4c 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -251,11 +251,31 @@ If `"url"` without text is given, `url` is shown on the button and opened on but # one button, same as send_button send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" "Visit my Shop|https://dealz.rrr.de" +# result + Best Dealz! + +----------------------------+ + | Visit my Shop | + +----------------------------+ + # one button row -send_inline_keyboard "${CHAT[ID]}" "message" "button 1|http://rrr.de" "button 2|http://rrr.de" +send_inline_keyboard "${CHAT[ID]}" "message" "Button 1|http://rrr.de" "Button 2|http://rrr.de" + +# result + message ... + +----------------------------+ + | Button 1 | Button 2 | + +----------------------------+ # multiple button rows -send_inline_keyboard "${CHAT[ID]}" "message" "b1|http://rrr.de" "b2|http://rrr.de" "" "b3|http://rrr.de" "b4|http://rrr.de" +send_inline_keyboard "${CHAT[ID]}" "message" "Button 1|http://rrr.de" "Button 2|http://rrr.de" "" "Button on second row|http://rrr.de" + +# result + message ... + +----------------------------+ + | Button 1 | Button 2 | + |----------------------------| + | Button on second row | + +----------------------------+ ``` ##### edit_inline_buttons @@ -355,7 +375,7 @@ keyboard_json="$(_button_row "đŸ¤– #Home of Deal-O-Mat Bot đŸ¤–|https://dealz.rr send_inline_keyboard "CHAT[ID]" "${keyboard_text}" "${keyboard_json}" -ä result +# result +---------------------------------+ | đŸ¤– #Home of Deal-O-Mat Bot đŸ¤– | |---------------------------------| @@ -1431,5 +1451,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-22-g8c85c81 +#### $$VERSION$$ v1.35-dev-23-g5192212 From 079eb1c289746e8d928cb4f15a18e4476a391412 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 11:54:48 +0100 Subject: [PATCH 56/99] fix running commands.sh in subshell --- bashbot.sh | 4 ++-- doc/6_reference.md | 45 +++++++++++++++++++++++++++++++++++++++++---- mycommands.sh | 17 +++++++++++++---- mycommands.sh.clean | 5 +++-- 4 files changed, 59 insertions(+), 12 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 5b74f96..c799e21 100755 --- a/bashbot.sh +++ b/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-21-gcbf3945 +#### $$VERSION$$ v1.35-dev-24-g5a0a571 ################################################################## # emmbeded system may claim bash but it is not @@ -707,7 +707,7 @@ process_client() { # process inline and message events # first classic command dispatcher # shellcheck source=./commands.sh - "${COMMANDS}" "${debug}" & + { source "${COMMANDS}" "${debug}"; } & # then all registered addons if [ -z "${iQUERY[ID]}" ]; then diff --git a/doc/6_reference.md b/doc/6_reference.md index 509eb4c..8a69d73 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -249,7 +249,7 @@ If `"url"` without text is given, `url` is shown on the button and opened on but *example:* ```bash # one button, same as send_button -send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" "Visit my Shop|https://dealz.rrr.de" +send_inline_buttons "${CHAT[ID]}" "Best Dealz!" "Visit my Shop|https://dealz.rrr.de" # result Best Dealz! @@ -258,7 +258,7 @@ send_inline_keyboard "${CHAT[ID]}" "Best Dealz!" "Visit my Shop|https://dealz.rr +----------------------------+ # one button row -send_inline_keyboard "${CHAT[ID]}" "message" "Button 1|http://rrr.de" "Button 2|http://rrr.de" +send_inline_buttons "${CHAT[ID]}" "message" "Button 1|http://rrr.de" "Button 2|http://rrr.de" # result message ... @@ -267,7 +267,7 @@ send_inline_keyboard "${CHAT[ID]}" "message" "Button 1|http://rrr.de" "Button 2| +----------------------------+ # multiple button rows -send_inline_keyboard "${CHAT[ID]}" "message" "Button 1|http://rrr.de" "Button 2|http://rrr.de" "" "Button on second row|http://rrr.de" +send_inline_buttons "${CHAT[ID]}" "message" "Button 1|http://rrr.de" "Button 2|http://rrr.de" "" "Button on second row|http://rrr.de" # result message ... @@ -276,6 +276,7 @@ send_inline_keyboard "${CHAT[ID]}" "message" "Button 1|http://rrr.de" "Button 2| |----------------------------| | Button on second row | +----------------------------+ + ``` ##### edit_inline_buttons @@ -316,6 +317,42 @@ answer_callback_query "${iBUTTON[ID]}" "Button data is: ${iBUTTON[DATA]}" answer_callback_query "${iBUTTON[ID]}" "Alert: Button pressed!" "alert" ``` + +```bash +# CALLBACK button example +send_inline_buttons "${CHAT[ID]}" "Press Button ..." " Button |RANDOM-BUTTON" + +# result + Press Button ... + +----------------------------+ + | Button | + +----------------------------+ + +# react on button press from mycommands + CALLBACK="1" # enable callbacks +... + mycallbacks() { + local answer + ####################### + # callbacks from buttons attached to messages will be processed here + if [ "${iBUTTON[DATA]}" = "RANDOM-BUTTON" ]; then + answer="Button pressed" + edit_inline_buttons "${iBUTTON[CHAT_ID]}" "${iBUTTON[MESSAGE_ID]}" " Button ${RANDOM}|RANDOM-BUTTON" + fi + + # Telegram needs an ack each callback query, default empty + answer_callback_query "${iBUTTON[ID]}" "${answer}" + ;; + } + +# result, XXXXX: random number changed on each press + Press Button ... + +----------------------------+ + | Button XXXXXX | + +----------------------------+ + +``` + ---- #### Inline keyboards @@ -1451,5 +1488,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-23-g5192212 +#### $$VERSION$$ v1.35-dev-24-g5a0a571 diff --git a/mycommands.sh b/mycommands.sh index d877028..ddb65b6 100644 --- a/mycommands.sh +++ b/mycommands.sh @@ -13,7 +13,7 @@ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # Author: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.35-dev-20-gfa0cb75 +#### $$VERSION$$ v1.35-dev-24-g5a0a571 ####################################################### # shellcheck disable=SC1117 @@ -131,6 +131,9 @@ else '/echo'*) # example echo command send_normal_message "${CHAT[ID]}" "${MESSAGE}" ;; + '/button'*)# inline button, set CALLBACK=1 for processing callbacks + send_inline_buttons "${CHAT[ID]}" "Press Button ..." " Button |RANDOM-BUTTON" + ;; '/question'*) # start interactive questions checkproc if [ "${res}" -gt 0 ] ; then @@ -203,13 +206,19 @@ else return ;; *) # all other callbacks are processed here + local callback_answer # your processing here ... + # message available? if [[ -n "${iBUTTON[CHAT_ID]}" && -n "${iBUTTON[MESSAGE_ID]}" ]]; then - # output random button if message data is available - edit_inline_buttons "${iBUTTON[CHAT_ID]}" "${iBUTTON[MESSAGE_ID]}" "Button ${RANDOM}|${RANDOM}" + if [ "${iBUTTON[DATA]}" = "RANDOM-BUTTON" ]; then + callback_answer="Button pressed" + edit_inline_buttons "${iBUTTON[CHAT_ID]}" "${iBUTTON[MESSAGE_ID]}" "Button ${RANDOM}|RANDOM-BUTTON" + fi + else + callback_answer="Button to old, sorry." fi # Telegram needs an ack each callback query, default empty - answer_callback_query "${iBUTTON[ID]}" "" + answer_callback_query "${iBUTTON[ID]}" "${callback_answer}" ;; esac } diff --git a/mycommands.sh.clean b/mycommands.sh.clean index 9f3de30..fba17a5 100644 --- a/mycommands.sh.clean +++ b/mycommands.sh.clean @@ -10,7 +10,7 @@ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # Author: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.35-dev-18-ge4ee880 +#### $$VERSION$$ v1.35-dev-24-g5a0a571 ####################################################### # shellcheck disable=SC1117 @@ -82,10 +82,11 @@ else # callbacks from buttons attached to messages will be processed here case "${iBUTTON[USER_ID]}+${iBUTTON[CHAT_ID]}" in *) # all other callbacks are processed here + local callback_answer : # your processing here ... : # Telegram needs an ack each callback query, default empty - answer_callback_query "${iBUTTON[ID]}" "" + answer_callback_query "${iBUTTON[ID]}" "${callback_answer}" ;; esac } From b45efa37262d69b7003d5953b76ead0580c5f618 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 12:39:04 +0100 Subject: [PATCH 57/99] init: basic config for new conf file --- bashbot.sh | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index c799e21..22f78a3 100755 --- a/bashbot.sh +++ b/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-24-g5a0a571 +#### $$VERSION$$ v1.35-dev-25-g079eb1c ################################################################## # emmbeded system may claim bash but it is not @@ -1134,14 +1134,28 @@ bot_init() { fi # check if mycommands exist if [ ! -r "${BASHBOT_ETC:-.}/mycommands.sh" ]; then - printf "Mycommands.sh not found, copy ${GREY}mycommands.sh.clean${NC} to mycommands.sh? (y/N) N\b" + printf "Mycommands.sh not found, copy ${GREY}lean file, xamples or one${NC} to mycommands.sh? (c/e/N) N\b" read -r ANSWER - [[ "${ANSWER}" =~ ^[Yy] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.clean" "${BASHBOT_ETC:-.}/mycommands.sh" + [[ "${ANSWER}" =~ ^[cC] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.clean" "${BASHBOT_ETC:-.}/mycommands.sh" + [[ "${ANSWER}" =~ ^[eE] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.dist" "${BASHBOT_ETC:-.}/mycommands.sh" # offer to copy config also if [ ! -r "${BASHBOT_ETC:-.}/mycommands.conf" ]; then - printf "Mycommands config file not found, copy ${GREY}mycommands.conf.dist${NC} to mycommands.conf? (y/N) N\b" + printf "Mycommands config file not found, copy ${GREY}mycommands.conf.dist${NC} to mycommands.conf? (Y/n) Y\b" read -r ANSWER - [[ "${ANSWER}" =~ ^[Yy] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.conf.dist" "${BASHBOT_ETC:-.}/mycommands.conf" + [[ "${ANSWER}" =~ ^[nN] ]] || cp -f "${BASHBOT_ETC:-.}/mycommands.conf.dist" "${BASHBOT_ETC:-.}/mycommands.conf" + fi + # adjust INLINE and CALLBACK + if [ -w "${BASHBOT_ETC:-.}/mycommands.conf" ]; then + printf "Activate processing for ${GREY}nline qeurys, allback buttons, oth or one${NC} in mycommands.sh? (i/c/b/N) N\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[iIbB] ]] && sed -i '/INLINE="/ s/^.*$/export INLINE="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" + [[ "${ANSWER}" =~ ^[cCbB] ]] && sed -i '/CALLBACK="/ s/^.*$/export CALLBACK="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" + printf "Always ignore commands for other Bots in chats ${GREY}(/cmd@other_bot)${NC}? (y/N) N\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[yY] ]] && sed -i '/MEONLY="/ s/^.*$/export MEONLY="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" + printf "Delete administrative messages in chats ${GREY}(pinned, user join/leave, ...)${NC}? (y/N) N\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[yY] ]] && sed -i '/SILENCER="/ s/^.*$/export SILENCER="yes"/' "${BASHBOT_ETC:-.}/mycommands.conf" fi fi # adjust permissions From ca9ea1bf311babc204cbc54d0887d39ef7aa5052 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 13:35:31 +0100 Subject: [PATCH 58/99] init: fix msgs --- bashbot.sh | 9 +++++---- mycommands.sh.clean | 4 +++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 22f78a3..5741766 100755 --- a/bashbot.sh +++ b/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-25-g079eb1c +#### $$VERSION$$ v1.35-dev-26-gb45efa3 ################################################################## # emmbeded system may claim bash but it is not @@ -1144,19 +1144,20 @@ bot_init() { read -r ANSWER [[ "${ANSWER}" =~ ^[nN] ]] || cp -f "${BASHBOT_ETC:-.}/mycommands.conf.dist" "${BASHBOT_ETC:-.}/mycommands.conf" fi - # adjust INLINE and CALLBACK + # adjust INLINE CALLBACK MEONLY SILENCER if [ -w "${BASHBOT_ETC:-.}/mycommands.conf" ]; then - printf "Activate processing for ${GREY}nline qeurys, allback buttons, oth or one${NC} in mycommands.sh? (i/c/b/N) N\b" + printf "Activate processing for ${GREY}nline queries, allback buttons, oth or one${NC} in mycommands.sh? (i/c/b/N) N\b" read -r ANSWER [[ "${ANSWER}" =~ ^[iIbB] ]] && sed -i '/INLINE="/ s/^.*$/export INLINE="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" [[ "${ANSWER}" =~ ^[cCbB] ]] && sed -i '/CALLBACK="/ s/^.*$/export CALLBACK="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" - printf "Always ignore commands for other Bots in chats ${GREY}(/cmd@other_bot)${NC}? (y/N) N\b" + printf "Always ignore commands for other Bots in chat ${GREY}(/cmd@other_bot)${NC}? (y/N) N\b" read -r ANSWER [[ "${ANSWER}" =~ ^[yY] ]] && sed -i '/MEONLY="/ s/^.*$/export MEONLY="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" printf "Delete administrative messages in chats ${GREY}(pinned, user join/leave, ...)${NC}? (y/N) N\b" read -r ANSWER [[ "${ANSWER}" =~ ^[yY] ]] && sed -i '/SILENCER="/ s/^.*$/export SILENCER="yes"/' "${BASHBOT_ETC:-.}/mycommands.conf" fi + printf "Done.\n" fi # adjust permissions printf "Adjusting files and permissions for user \"${touser}\" ...\n" diff --git a/mycommands.sh.clean b/mycommands.sh.clean index fba17a5..eaed7d1 100644 --- a/mycommands.sh.clean +++ b/mycommands.sh.clean @@ -10,7 +10,7 @@ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # Author: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.35-dev-24-g5a0a571 +#### $$VERSION$$ v1.35-dev-26-gb45efa3 ####################################################### # shellcheck disable=SC1117 @@ -55,6 +55,8 @@ else [ -n "${REMOVEKEYBOARD}" ] && remove_keyboard "${CHAT[ID]}" & [[ -n "${REMOVEKEYBOARD_PRIVATE}" && "${CHAT[ID]}" == "${USER[ID]}" ]] && remove_keyboard "${CHAT[ID]}" & + # uncommet to fix first letter upper case because of smartphone auto correction + #[[ "${MESSAGE}" =~ ^/[[:upper:]] ]] && MESSAGE="${MESSAGE:0:1}$(tr '[:upper:]' '[:lower:]' <<<"${MESSAGE:1:1}")${MESSAGE:2}" case "${MESSAGE}" in ################## # example command, replace them by your own From 3f331dc8e8befda1587b03c135f53cac825756fc Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 13:58:55 +0100 Subject: [PATCH 59/99] init: external init extension --- bashbot.sh | 4 +++- bin/bashbot_init.inc.sh | 29 +++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 bin/bashbot_init.inc.sh diff --git a/bashbot.sh b/bashbot.sh index 5741766..29045a2 100755 --- a/bashbot.sh +++ b/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-26-gb45efa3 +#### $$VERSION$$ v1.35-dev-27-gca9ea1b ################################################################## # emmbeded system may claim bash but it is not @@ -1265,6 +1265,8 @@ if [ -z "${SOURCE}" ]; then ;; # run after every update to update files and adjust permissions "init") + # shellcheck source=./bin/bashbot._init.inc.sh" + [ -r "${BASHBOT_HOME:-.}/bin/bashbot_init.inc.sh" ] && source "${BASHBOT_HOME:-.}/bin/bashbot_init.inc.sh" bot_init "$2" debug_checks "end init" "$@" exit diff --git a/bin/bashbot_init.inc.sh b/bin/bashbot_init.inc.sh new file mode 100644 index 0000000..5b86a82 --- /dev/null +++ b/bin/bashbot_init.inc.sh @@ -0,0 +1,29 @@ +#!/bin/bash +#=============================================================================== +# +# FILE: bashbot_init.inc.sh +# +# USAGE: source bashbot_init.inc.sh +# +# DESCRIPTION: extend / overwrite bashbot initialisation +# +# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ +# AUTHOR: KayM (gnadelwartz), kay@rrr.de +# CREATED: 27.01.2021 13:42 +# +#### $$VERSION$$ v1.35-dev-27-gca9ea1b +#=============================================================================== + +########## +# commands to execute before bot_init() is called + + +######### +# uncomment to overwrite default init +# bot_init() { my_init(); } + +######## +# called after default init is finished +my_init() { + : # ypur commands here +} From 0c0dc01f26eea6a461108f6f0f62da4f4d67b2f5 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 16:19:43 +0100 Subject: [PATCH 60/99] init: move to bin/bashbot_init.inc.sh --- bashbot.sh | 88 ++---------------------------- bin/bashbot_init.inc.sh | 117 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 117 insertions(+), 88 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 29045a2..34b8e46 100755 --- a/bashbot.sh +++ b/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-27-gca9ea1b +#### $$VERSION$$ v1.35-dev-28-g3f331dc ################################################################## # emmbeded system may claim bash but it is not @@ -1103,105 +1103,27 @@ start_bot() { done } +# fallback version, full version is in bin/bashbot_init.in.sh # initialize bot environment, user and permissions bot_init() { [ -n "${BASHBOT_HOME}" ] && cd "${BASHBOT_HOME}" || exit 1 - local runuser chown touser botname DEBUG="$1" - # upgrade from old version - # currently no action - printf "Check for Update actions ...\n" - printf "Done.\n" # load addons on startup printf "Initialize modules and addons ...\n" for addons in "${ADDONDIR:-.}"/*.sh ; do # shellcheck source=./modules/aliases.sh - [ -r "${addons}" ] && source "${addons}" "init" "${DEBUG}" + [ -r "${addons}" ] && source "${addons}" "init" "$1" done printf "Done.\n" - # ask for bashbot user - runuser="${RUNUSER}"; [ "${UID}" = "0" ] && runuser="nobody" - printf "Enter User to run bashbot [${runuser}]: " - read -r chown - [ -z "${chown}" ] && chown="${runuser}"; touser="${chown%:*}" - # check user ... - if ! id "${touser}" &>/dev/null; then - printf "${RED}User \"${touser}\" does not exist!${NN}" - exit 3 - elif [[ "${UID}" != "0" && "${touser}" != "${runuser}" ]]; then - # different user but not root ... - printf "${ORANGE}You are not root, adjusting permissions may fail. Try \"sudo ./bashbot.sh init\"${NN}Press to stop or to continue..." 1>&2 - [ -n "${INTERACTIVE}" ] && read -r runuser - fi - # check if mycommands exist - if [ ! -r "${BASHBOT_ETC:-.}/mycommands.sh" ]; then - printf "Mycommands.sh not found, copy ${GREY}lean file, xamples or one${NC} to mycommands.sh? (c/e/N) N\b" - read -r ANSWER - [[ "${ANSWER}" =~ ^[cC] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.clean" "${BASHBOT_ETC:-.}/mycommands.sh" - [[ "${ANSWER}" =~ ^[eE] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.dist" "${BASHBOT_ETC:-.}/mycommands.sh" - # offer to copy config also - if [ ! -r "${BASHBOT_ETC:-.}/mycommands.conf" ]; then - printf "Mycommands config file not found, copy ${GREY}mycommands.conf.dist${NC} to mycommands.conf? (Y/n) Y\b" - read -r ANSWER - [[ "${ANSWER}" =~ ^[nN] ]] || cp -f "${BASHBOT_ETC:-.}/mycommands.conf.dist" "${BASHBOT_ETC:-.}/mycommands.conf" - fi - # adjust INLINE CALLBACK MEONLY SILENCER - if [ -w "${BASHBOT_ETC:-.}/mycommands.conf" ]; then - printf "Activate processing for ${GREY}nline queries, allback buttons, oth or one${NC} in mycommands.sh? (i/c/b/N) N\b" - read -r ANSWER - [[ "${ANSWER}" =~ ^[iIbB] ]] && sed -i '/INLINE="/ s/^.*$/export INLINE="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" - [[ "${ANSWER}" =~ ^[cCbB] ]] && sed -i '/CALLBACK="/ s/^.*$/export CALLBACK="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" - printf "Always ignore commands for other Bots in chat ${GREY}(/cmd@other_bot)${NC}? (y/N) N\b" - read -r ANSWER - [[ "${ANSWER}" =~ ^[yY] ]] && sed -i '/MEONLY="/ s/^.*$/export MEONLY="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" - printf "Delete administrative messages in chats ${GREY}(pinned, user join/leave, ...)${NC}? (y/N) N\b" - read -r ANSWER - [[ "${ANSWER}" =~ ^[yY] ]] && sed -i '/SILENCER="/ s/^.*$/export SILENCER="yes"/' "${BASHBOT_ETC:-.}/mycommands.conf" - fi - printf "Done.\n" - fi # adjust permissions - printf "Adjusting files and permissions for user \"${touser}\" ...\n" + printf "Adjusting files and permissions ...\n" chmod 711 . chmod -R o-w ./* chmod -R u+w "${COUNTFILE}"* "${BLOCKEDFILE}"* "${DATADIR}" logs "${LOGDIR}/"*.log 2>/dev/null chmod -R o-r,o-w "${COUNTFILE}"* "${BLOCKEDFILE}"* "${DATADIR}" "${BOTACL}" 2>/dev/null # jsshDB must writeable by owner find . -name '*.jssh*' -exec chmod u+w \{\} + - chown -Rf "${chown}" . ./* printf "Done.\n" - # adjust values in bashbot.rc - if [ -w "bashbot.rc" ]; then - printf "Adjust user and botname in bashbot.rc ...\n" - sed -i '/^[# ]*runas=/ s|runas=.*$|runas="'"${touser}"'"|' "bashbot.rc" - sed -i '/^[# ]*bashbot=/ s|bashbot=.*$|bashbot="cd '"${PWD}"'; '"${PWD}"'/'"${0##*/}"'"|' "bashbot.rc" - botname="$(getConfigKey "botname")" - [ -n "${botname}" ] && sed -i '/^[# ]*name=/ s|name=.*$|name="'"${botname}"'"|' "bashbot.rc" - printf "Done.\n" - fi - # ask to check bottoken online - if [ -z "$(getConfigKey "botid")" ]; then - printf "Seems to be your first init. Should I verify your bot token online? (y/N) N\b" - read -r ANSWER - if [[ "${ANSWER}" =~ ^[Yy] ]]; then - printf "${GREEN}Contacting telegram to verify your bot token ...${NN}" - $0 botname - fi - fi - # check if botconf seems valid - printf "${GREEN}This is your bot config:${NN}${GREY}" - sed 's/^/\t/' "${BOTCONFIG}.jssh" | grep -vF '["bot_config_key"]'; printf "${NC}" - if check_token "$(getConfigKey "bottoken")" && [[ "$(getConfigKey "botadmin")" =~ ^[${o9o9o9}]+$ ]]; then - printf "Bot config seems to be valid. Should I make a backup copy? (Y/n) Y\b" - read -r ANSWER - if [[ -z "${ANSWER}" || "${ANSWER}" =~ ^[^Nn] ]]; then - printf "Copy bot config to ${BOTCONFIG}.jssh.ok ...\n" - cp "${BOTCONFIG}.jssh" "${BOTCONFIG}.jssh.ok" - fi - else - printf "${ORANGE}Bot config may incomplete, pls check.${NN}" - fi - # show result - printf "${GREY}"; ls -ldp "${DATADIR}" "${LOGDIR}" ./*.jssh* ./*.sh ./*.conf 2>/dev/null; printf "${NC}" + _exec_if_function my_init } if ! _is_function send_message ; then diff --git a/bin/bashbot_init.inc.sh b/bin/bashbot_init.inc.sh index 5b86a82..042e9e0 100644 --- a/bin/bashbot_init.inc.sh +++ b/bin/bashbot_init.inc.sh @@ -11,19 +11,126 @@ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 27.01.2021 13:42 # -#### $$VERSION$$ v1.35-dev-27-gca9ea1b +#### $$VERSION$$ v1.35-dev-28-g3f331dc #=============================================================================== - +# shellcheck disable=SC2059 ########## # commands to execute before bot_init() is called -######### -# uncomment to overwrite default init -# bot_init() { my_init(); } ######## # called after default init is finished my_init() { : # ypur commands here } + + +######### +# extended initialisation for advanced features like: +# +# running bto as rest +# +# +# delete from here to disable extended init +bot_init() { + [ -n "${BASHBOT_HOME}" ] && cd "${BASHBOT_HOME}" || exit 1 + local runuser chown touser botname DEBUG="$1" + # upgrade from old version + # currently no action + printf "Check for Update actions ...\n" + printf "Done.\n" + # load addons on startup + printf "Initialize modules and addons ...\n" + for addons in "${ADDONDIR:-.}"/*.sh ; do + # shellcheck source=./modules/aliases.sh + [ -r "${addons}" ] && source "${addons}" "init" "${DEBUG}" + done + printf "Done.\n" + # ask for bashbot user + # shellcheck disable=SC2153 + runuser="${RUNUSER}"; [ "${UID}" = "0" ] && runuser="nobody" + printf "Enter User to run bashbot [${runuser}]: " + read -r chown + [ -z "${chown}" ] && chown="${runuser}"; touser="${chown%:*}" + # check user ... + if ! id "${touser}" &>/dev/null; then + printf "${RED}User \"${touser}\" does not exist!${NN}" + exit 3 + elif [[ "${UID}" != "0" && "${touser}" != "${runuser}" ]]; then + # different user but not root ... + printf "${ORANGE}You are not root, adjusting permissions may fail. Try \"sudo ./bashbot.sh init\"${NN}Press to stop or to continue..." 1>&2 + [ -n "${INTERACTIVE}" ] && read -r runuser + fi + # check if mycommands exist + if [ ! -r "${BASHBOT_ETC:-.}/mycommands.sh" ]; then + printf "Mycommands.sh not found, copy ${GREY}lean file, xamples or one${NC} to mycommands.sh? (c/e/N) N\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[cC] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.clean" "${BASHBOT_ETC:-.}/mycommands.sh" + [[ "${ANSWER}" =~ ^[eE] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.dist" "${BASHBOT_ETC:-.}/mycommands.sh" + # offer to copy config also + if [ ! -r "${BASHBOT_ETC:-.}/mycommands.conf" ]; then + printf "Mycommands config file not found, copy ${GREY}mycommands.conf.dist${NC} to mycommands.conf? (Y/n) Y\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[nN] ]] || cp -f "${BASHBOT_ETC:-.}/mycommands.conf.dist" "${BASHBOT_ETC:-.}/mycommands.conf" + fi + # adjust INLINE CALLBACK MEONLY SILENCER + if [ -w "${BASHBOT_ETC:-.}/mycommands.conf" ]; then + printf "Activate processing for ${GREY}nline queries, allback buttons, oth or one${NC} in mycommands.sh? (i/c/b/N) N\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[iIbB] ]] && sed -i '/INLINE="/ s/^.*$/export INLINE="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" + [[ "${ANSWER}" =~ ^[cCbB] ]] && sed -i '/CALLBACK="/ s/^.*$/export CALLBACK="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" + printf "Always ignore commands for other Bots in chat ${GREY}(/cmd@other_bot)${NC}? (y/N) N\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[yY] ]] && sed -i '/MEONLY="/ s/^.*$/export MEONLY="1"/' "${BASHBOT_ETC:-.}/mycommands.conf" + printf "Delete administrative messages in chats ${GREY}(pinned, user join/leave, ...)${NC}? (y/N) N\b" + read -r ANSWER + [[ "${ANSWER}" =~ ^[yY] ]] && sed -i '/SILENCER="/ s/^.*$/export SILENCER="yes"/' "${BASHBOT_ETC:-.}/mycommands.conf" + fi + printf "Done.\n" + fi + # adjust permissions + printf "Adjusting files and permissions for user \"${touser}\" ...\n" + chmod 711 . + chmod -R o-w ./* + chmod -R u+w "${COUNTFILE}"* "${BLOCKEDFILE}"* "${DATADIR}" logs "${LOGDIR}/"*.log 2>/dev/null + chmod -R o-r,o-w "${COUNTFILE}"* "${BLOCKEDFILE}"* "${DATADIR}" "${BOTACL}" 2>/dev/null + # jsshDB must writeable by owner + find . -name '*.jssh*' -exec chmod u+w \{\} + + chown -Rf "${chown}" . ./* + printf "Done.\n" + # adjust values in bashbot.rc + if [ -w "bashbot.rc" ]; then + printf "Adjust user and botname in bashbot.rc ...\n" + sed -i '/^[# ]*runas=/ s|runas=.*$|runas="'"${touser}"'"|' "bashbot.rc" + sed -i '/^[# ]*bashbot=/ s|bashbot=.*$|bashbot="cd '"${PWD}"'; '"${PWD}"'/'"${0##*/}"'"|' "bashbot.rc" + botname="$(getConfigKey "botname")" + [ -n "${botname}" ] && sed -i '/^[# ]*name=/ s|name=.*$|name="'"${botname}"'"|' "bashbot.rc" + printf "Done.\n" + fi + # ask to check bottoken online + if [ -z "$(getConfigKey "botid")" ]; then + printf "Seems to be your first init. Should I verify your bot token online? (y/N) N\b" + read -r ANSWER + if [[ "${ANSWER}" =~ ^[Yy] ]]; then + printf "${GREEN}Contacting telegram to verify your bot token ...${NN}" + $0 botname + fi + fi + # check if botconf seems valid + printf "${GREEN}This is your bot config:${NN}${GREY}" + sed 's/^/\t/' "${BOTCONFIG}.jssh" | grep -vF '["bot_config_key"]'; printf "${NC}" + if check_token "$(getConfigKey "bottoken")" && [[ "$(getConfigKey "botadmin")" =~ ^[${o9o9o9}]+$ ]]; then + printf "Bot config seems to be valid. Should I make a backup copy? (Y/n) Y\b" + read -r ANSWER + if [[ -z "${ANSWER}" || "${ANSWER}" =~ ^[^Nn] ]]; then + printf "Copy bot config to ${BOTCONFIG}.jssh.ok ...\n" + cp "${BOTCONFIG}.jssh" "${BOTCONFIG}.jssh.ok" + fi + else + printf "${ORANGE}Bot config may incomplete, pls check.${NN}" + fi + # show result + printf "${GREY}"; ls -ldp "${DATADIR}" "${LOGDIR}" ./*.jssh* ./*.sh ./*.conf 2>/dev/null; printf "${NC}" + _exec_if_function my_init +} From e83f4d443f57e7c41778e13bdbcfe4d6ba6305cf Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 16:29:58 +0100 Subject: [PATCH 61/99] init: finalize external init --- bashbot.sh | 4 ++-- bin/bashbot_init.inc.sh | 16 ++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 34b8e46..aa1c81f 100755 --- a/bashbot.sh +++ b/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-28-g3f331dc +#### $$VERSION$$ v1.35-dev-29-g0c0dc01 ################################################################## # emmbeded system may claim bash but it is not @@ -1108,7 +1108,7 @@ start_bot() { bot_init() { [ -n "${BASHBOT_HOME}" ] && cd "${BASHBOT_HOME}" || exit 1 # load addons on startup - printf "Initialize modules and addons ...\n" + printf "Initialize addons ...\n" for addons in "${ADDONDIR:-.}"/*.sh ; do # shellcheck source=./modules/aliases.sh [ -r "${addons}" ] && source "${addons}" "init" "$1" diff --git a/bin/bashbot_init.inc.sh b/bin/bashbot_init.inc.sh index 042e9e0..c0a3f39 100644 --- a/bin/bashbot_init.inc.sh +++ b/bin/bashbot_init.inc.sh @@ -11,28 +11,32 @@ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 27.01.2021 13:42 # -#### $$VERSION$$ v1.35-dev-28-g3f331dc +#### $$VERSION$$ v1.35-dev-29-g0c0dc01 #=============================================================================== # shellcheck disable=SC2059 + ########## # commands to execute before bot_init() is called - ######## # called after default init is finished my_init() { - : # ypur commands here + : # your init here } ######### -# extended initialisation for advanced features like: # -# running bto as rest +# extended initialisation: # +# - uograde old config +# - backup of botconfig.jssh +# - running bot as service or other user +# - copy clean and dist files if not exist +# - configure bot for INLINE CALLBACK MEONLY SILENCER # -# delete from here to disable extended init +# delete from here to disable extended initialisation bot_init() { [ -n "${BASHBOT_HOME}" ] && cd "${BASHBOT_HOME}" || exit 1 local runuser chown touser botname DEBUG="$1" From a3eec98491e4e27db961d1b8962cde927b120e74 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 18:40:12 +0100 Subject: [PATCH 62/99] disbale obsolete download --- bashbot.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index aa1c81f..d930f2d 100755 --- a/bashbot.sh +++ b/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-29-g0c0dc01 +#### $$VERSION$$ v1.35-dev-30-ge83f4d4 ################################################################## # emmbeded system may claim bash but it is not @@ -381,13 +381,13 @@ fi # $1 URL, $2 filename in DATADIR # outputs final filename -download() { - local empty="no.file" file="${2:-${empty}}" - if [[ "${file}" = *"/"* ]] || [[ "${file}" = "."* ]]; then file="${empty}"; fi - while [ -f "${DATADIR:-.}/${file}" ] ; do file="${RANDOM}-${file}"; done - getJson "$1" >"${DATADIR:-.}/${file}" || return - printf '%s\n' "${DATADIR:-.}/${file}" -} +#download() { +# local empty="no.file" file="${2:-${empty}}" +# if [[ "${file}" = *"/"* ]] || [[ "${file}" = "."* ]]; then file="${empty}"; fi +# while [ -f "${DATADIR:-.}/${file}" ] ; do file="${RANDOM}-${file}"; done +# getJson "$1" >"${DATADIR:-.}/${file}" || return +# printf '%s\n' "${DATADIR:-.}/${file}" +#} # $1 postfix, e.g. chatid # $2 prefix, back- or startbot- @@ -424,6 +424,7 @@ delete_message() { sendJson "$1" '"message_id": '"$2"'' "${DELETE_URL}" } +# get download url for file id, $1 file_id get_file() { [ -z "$1" ] && return sendJson "" '"file_id": "'"$1"'"' "${URL}/getFile" From 279a9e7ca3916f001c43a1c2f0b0e0c74d0e367d Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 19:05:12 +0100 Subject: [PATCH 63/99] doc: add iBUTTON variables --- bashbot.sh | 6 ++---- doc/2_usage.md | 35 ++++++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index d930f2d..e48be1a 100755 --- a/bashbot.sh +++ b/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-30-ge83f4d4 +#### $$VERSION$$ v1.35-dev-31-ga3eec98 ################################################################## # emmbeded system may claim bash but it is not @@ -870,11 +870,9 @@ process_inline_button() { # debugging for impelemetation local num="$1" iBUTTON[DATA]="${UPD["result,${num},callback_query,data"]}" - #iBUTTON[CHAT_INSTANCE]="${UPD["result,${num},callback_query,chat_instance"]}" - #iBUTTON[INLINE_ID]="${UPD["result,${num},callback_query,inline_message_id"]}" iBUTTON[CHAT_ID]="${UPD["result,${num},callback_query,message,chat,id"]}" iBUTTON[MESSAGE_ID]="${UPD["result,${num},callback_query,message,message_id"]}" - iBUTTON[MEESSAGE]="$(JsonDecode "${UPD["result,${num},callback_query,message,text"]}")" + 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"]}")" diff --git a/doc/2_usage.md b/doc/2_usage.md index 6ec08bf..767d6d3 100644 --- a/doc/2_usage.md +++ b/doc/2_usage.md @@ -33,14 +33,19 @@ Have FUN! ├── JSON.sh # bashbots JSON parser, see https://github.com/dominictarr/JSON.sh │ ├── bin # ready to use scripts, use `scriptname --help` for help +│   ├── bashbot_stats.sh # does what it says ... +│   ├── send_broadcast.sh # send message to all known chats │   ├── send_message.sh # send message to given chat │   ├── edit_message.sh # replace given message id in given chat -│   ├── delete_message.sh # delete given message id in given chat -│   ├── send_broadcast.sh # send message to all known chats │   ├── send_file.sh # send file to given chat -│   ├── bashbot_stats.sh # does what it says ... +│   ├── delete_message.sh # delete given message id in given chat +│   ├── send_buttons.sh # send message with attached button +│   ├── edit_buttons.sh # attach/edit message buttons +│   ├── kickban_user.sh # kick/unban user from given chat +│   ├── promote_user.sh # promote/dente user rights in given chat │ │ -│   └── bashbot_env.inc.sh # bashbot location included from scripts, adapt if needed +│   └── bashbot_env.inc.sh # sourced from scripts, adapt locations if needed +│   └── bashbot_init.inc.sh # sourced from bashbot.sh init │ ├── scripts # place your bashbot interactive and background scripts here │   └── interactive.sh.clean # interactive script template for new scripts @@ -91,6 +96,7 @@ Start or Stop your Bot use the following commands: ``` ### Scripts in bin/ +Use `script.sh -h` or `script --help` to get short/long help for script. To count the total number of users and messages run the following command: @@ -244,8 +250,7 @@ e.g. if a new user joins a chat MESSAGE is set to "/_new_chat_user". ### Inline query messages - -Inline query messages are small, non regular messages used for interaction with the user, +Inline query messages are special messages used for interaction with the user, they contain the following variables only: * `${iQUERY}`: Current inline query @@ -256,6 +261,22 @@ they contain the following variables only: * `${iQUERY[LAST_NAME]}`: User's last name +### Callback button messages +Callback button messages special messages swedn from callback buttons, +they contain the following variables only: + +* `$iBUTTON`: This array contains the ID, First name, last name, username and user id of the user clicked on the button + * `${iBUTTON[ID]}`: Callback query ID + * `${iBUTTON[DATA]`: Data attached to button, hopefully unique + * `${iBUTTON[CHAT_ID]`: Chat where button was pressed + * `${iBUTTON[MESSAGE_ID]`: Message to which button is attached + * `${iBUTTON[MESSAGE]`: Text of message + * `${iBUTTON[USER_ID]}`: User's id + * `${iBUTTON[FIRST_NAME]}`: User's first name + * `${iBUTTON[LAST_NAME]}`: User's last name + * `${iBUTTON[USERNAME]}`: User's @username + + ## Send data / get response After every `send_xxx` `get_xxx` call the array BOTSENT contains the most important values from Telegram response. @@ -351,5 +372,5 @@ send_action "${CHAT[ID]}" "action" #### [Prev Create Bot](1_firstbot.md) #### [Next Advanced Usage](3_advanced.md) -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.35-dev-31-ga3eec98 From 41e2d09067fbd8457ea048c6085cb567ad4871e9 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 19:30:03 +0100 Subject: [PATCH 64/99] add chat_member_count --- modules/chatMember.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/chatMember.sh b/modules/chatMember.sh index c114eaa..48ebe75 100644 --- a/modules/chatMember.sh +++ b/modules/chatMember.sh @@ -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.35-dev-9-g5ceddde +#### $$VERSION$$ v1.40-dev-0-g279a9e7 # will be automatically sourced from bashbot @@ -56,6 +56,12 @@ delete_chat_stickers() { } # manage chat member functions ------- +# $1 chat +chat_member_count() { + sendJson "$1" "" "${URL}/getChatMembersCount" + [ "${BOTSENT[OK]}" = "true" ] && printf "%s\n" "${BOTSENT[RESULT]}" +} + kick_chat_member() { sendJson "$1" 'user_id: '"$2"'' "${URL}/kickChatMember" } From cfc4d2eed156605a2d2bbc06186cd7d9bcb40aeb Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 19:34:08 +0100 Subject: [PATCH 65/99] doc: chat_member_count --- doc/6_reference.md | 7 ++++++- modules/chatMember.sh | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index 8a69d73..0c8894e 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -539,6 +539,11 @@ edit_html_message "${CHAT[ID]}" "${saved-id}" "this is html text" ### Manage Group To use the following functions the bot must have administrator status in the chat / group +##### chat_member_count +`chat_member_count` returns (putput) number of chat members. + +*usage:* num_members="$(chat_member_count "CHAT[ID]")" + ##### set_chat_title `set_chat_title` sets a new chat title. If new title is the same than current title Telegram return error 400 with description "Bad Request: chat title is not modified" @@ -1488,5 +1493,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.35-dev-24-g5a0a571 +#### $$VERSION$$ v1.40-dev-1-g41e2d09 diff --git a/modules/chatMember.sh b/modules/chatMember.sh index 48ebe75..7d4c316 100644 --- a/modules/chatMember.sh +++ b/modules/chatMember.sh @@ -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.40-dev-0-g279a9e7 +#### $$VERSION$$ v1.40-dev-1-g41e2d09 # will be automatically sourced from bashbot From 7c748247d885dba73c67e54b39b94450bb709342 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Wed, 27 Jan 2021 21:23:39 +0100 Subject: [PATCH 66/99] dev: make-dist: do not overwrite bashbot.conf --- dev/make-distribution.sh.exclude | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/make-distribution.sh.exclude b/dev/make-distribution.sh.exclude index 2a21666..d005839 100644 --- a/dev/make-distribution.sh.exclude +++ b/dev/make-distribution.sh.exclude @@ -2,6 +2,7 @@ data-bot-bash/* JSON.awk bashbot.rc mycommands.sh +mycommands.conf awk-patch.sh *.jssh* botacl From c693ab5bb9c6a8462765fdde57a6101db7bd239a Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Fri, 29 Jan 2021 20:48:31 +0100 Subject: [PATCH 67/99] modules: factor out processUpdates.sh --- bashbot.sh | 456 ++------------------------------------ modules/jsonDB.sh | 2 +- modules/processUpdates.sh | 446 +++++++++++++++++++++++++++++++++++++ 3 files changed, 464 insertions(+), 440 deletions(-) create mode 100644 modules/processUpdates.sh diff --git a/bashbot.sh b/bashbot.sh index e48be1a..78090fd 100755 --- a/bashbot.sh +++ b/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 diff --git a/modules/jsonDB.sh b/modules/jsonDB.sh index 9169aa8..5a78bb3 100644 --- a/modules/jsonDB.sh +++ b/modules/jsonDB.sh @@ -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 # diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh new file mode 100644 index 0000000..52afda4 --- /dev/null +++ b/modules/processUpdates.sh @@ -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 + +} + From c9daa822bbb44bd7fcb7734cf7837d4a65c3bd9a Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Fri, 29 Jan 2021 20:55:54 +0100 Subject: [PATCH 68/99] fix start --- bashbot.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 78090fd..3c14d13 100755 --- a/bashbot.sh +++ b/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.40-dev-3-g7c74824 +#### $$VERSION$$ v1.40-dev-4-gc693ab5 ################################################################## # emmbeded system may claim bash but it is not @@ -795,10 +795,9 @@ if [ -z "${SOURCE}" ]; then # start bot as background job and check if bot is running "start") + SESSION="${ME:-_bot}-startbot" + BOTPID="$(proclist "${SESSION}")" 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 & From 08b7b85d03e336def22b03a2fc69af82e1507150 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 30 Jan 2021 11:38:30 +0100 Subject: [PATCH 69/99] modules: processUpdates: start experimental webhooks support --- modules/processUpdates.sh | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh index 52afda4..2e64965 100644 --- a/modules/processUpdates.sh +++ b/modules/processUpdates.sh @@ -4,9 +4,38 @@ # File: processUpdates.sh # Note: DO NOT EDIT! this file will be overwritten on update # -#### $$VERSION$$ v1.40-dev-3-g7c74824 +#### $$VERSION$$ v1.40-dev-5-gc9daa82 ################################################################## +############## +# manage webhooks + +# $1 URL to sed updates to: https://host.dom[:port][/path], port and path are optional +# port must be 443, 80, 88 8443, TOKEN will be added to URL for security +# e.g. https://myhost.com -> https://myhost.com/12345678:azndfhbgdfbbbdsfg +# $2 max connections 1-100 default 1 (because of bash ;-) +set_webhook() { + local url='"url": "'"$1/${TOKEN}"'"'max=',"max_connections": 1' + [[ "$2" =~ ^[0-9]+$ ]] && max=',"max_connections": '"$2"'' + # shellcheck disable=SC2153 + sendJson "" "${url}${max}" "${URL}/setWebhook" +} + +get_webhook_info() { + sendJson "" "" "${URL}/getWebhookInfo" + if [ "${BOTSENT[OK]}" = "true" ]; then + BOTSENT[URL]="${UPD[result,url]}" + BOTSENT[COUNT]="${UPD[result,getWebhookInfo]}" + BOTSENT[LASTERR]="${UPD[result,last_error_message]}" + fi +} + +# $1 drop pending updates true/false, default false +delete_webhook() { + local drop; [ "$1" = "true" ] && drop='"drop_pending_updates": true' + sendJson "" "${drop}" "${URL}/deleteWebhook" +} + ################ # processing of updates starts here process_updates() { @@ -292,6 +321,11 @@ start_bot() { send_normal_message "$(getConfigKey "botadmin")" "Bot $(getConfigKey "botname") started ..." & ########## # bot is ready, start processing updates ... + get_updates +} + + +get_updates(){ while true; do # adaptive sleep in ms rounded to next 0.1 s sleep "$(_round_float "${nextsleep}e-3" "1")" From 10d275c5571cf75edba6dbc99f9722dd838102d9 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 30 Jan 2021 14:12:52 +0100 Subject: [PATCH 70/99] bin: any_command.sh for testing bashbot commands --- bin/any_command.sh | 85 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100755 bin/any_command.sh diff --git a/bin/any_command.sh b/bin/any_command.sh new file mode 100755 index 0000000..7403b7c --- /dev/null +++ b/bin/any_command.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# shellcheck disable=SC1090,SC2034,SC2059 +#=============================================================================== +# +# FILE: bin/any_command.sh +# +USAGE='any_command.sh [-h|--help] [--force|--reference] bot_command args ...' +# +# DESCRIPTION: execute (almost) any bashbot command/function +# can be used for testing commands while bot development +# +# OPTIONS: -- force - execute unknown commands/functions +# by default only commands in 6_reference.md are allowed +# +# -h - display short help +# --help - this help +# +# Set BASHBOT_HOME to your installation directory +# +# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ +# AUTHOR: KayM (gnadelwartz), kay@rrr.de +# CREATED: 30.01.2021 10:24 +# +#### $$VERSION$$ v1.40-dev-6-g08b7b85 +#=============================================================================== + +#### +# parse args +COMMAND="" + +# set bashbot environment +source "${0%/*}/bashbot_env.inc.sh" "debug" # debug +print_help "$1" + + +error="" +# check options +if [[ "$1" = "--force" ]]; then + # skip checks + shift +else + # check for --ref + ref="$1"; [[ "$1" == "--ref"* ]] && shift + if [ "${#1}" -lt 11 ];then + printf "${RED}Command must be minimum 11 characters!${NC}\n" + error=3 + fi + if [[ "$1" != *"_"* ]];then + printf "${RED}Command must contain _ (underscore)!${NC}\n" + error=3 + fi + # simple hack to get allowed commands from doc + if grep -q "^##### $1" <<<"$(sed -n -e '/^##### _is_/,$ d' -e '/^##### /p' "../doc/"6_*)"; then + # oiutput reference and exit + if [[ "${ref}" == "--ref"* ]]; then + sed -n -e '/^##### '"$1"'/,/^##/ p' "../doc/"6_* + exit + fi + else + printf "Command ${GREY}%s${NC} not found in 6_reference.md, use ${GREY}--force${NC} to execute!\n" "$1" + error=4 + fi + [ -n "${error}" ] && exit "${error}" +fi + + +#### +# ready, do stuff here ----- +COMMAND="$1" +if [ "$2" == "BOTADMIN" ]; then + ARG1="${BOT_ADMIN}" +else + ARG1="$2" +fi + +# clear result and response +BOTSENT=() +UPD=() + +# send message in selected format +"${COMMAND}" "${ARG1}" "${@:3}" + +# output result an telegram response +print_result +print_response From 9cfeab9cdce41d427ce7c2101579db076d7325e0 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 30 Jan 2021 17:40:23 +0100 Subject: [PATCH 71/99] modules: processUpdate fix webhook handling --- modules/processUpdates.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh index 2e64965..f4452bf 100644 --- a/modules/processUpdates.sh +++ b/modules/processUpdates.sh @@ -4,7 +4,7 @@ # File: processUpdates.sh # Note: DO NOT EDIT! this file will be overwritten on update # -#### $$VERSION$$ v1.40-dev-5-gc9daa82 +#### $$VERSION$$ v1.40-dev-7-g10d275c ################################################################## ############## @@ -15,18 +15,23 @@ # e.g. https://myhost.com -> https://myhost.com/12345678:azndfhbgdfbbbdsfg # $2 max connections 1-100 default 1 (because of bash ;-) set_webhook() { - local url='"url": "'"$1/${TOKEN}"'"'max=',"max_connections": 1' + local url='"url": "'"$1/${BOTTOKEN}"'"' + local max=',"max_connections": 1' [[ "$2" =~ ^[0-9]+$ ]] && max=',"max_connections": '"$2"'' # shellcheck disable=SC2153 sendJson "" "${url}${max}" "${URL}/setWebhook" + unset "BOTSENT[ID]" "BOTSENT[CHAT]" + } get_webhook_info() { sendJson "" "" "${URL}/getWebhookInfo" if [ "${BOTSENT[OK]}" = "true" ]; then - BOTSENT[URL]="${UPD[result,url]}" - BOTSENT[COUNT]="${UPD[result,getWebhookInfo]}" - BOTSENT[LASTERR]="${UPD[result,last_error_message]}" + BOTSENT[URL]="${UPD[result,url]}" + BOTSENT[COUNT]="${UPD[result,pending_update_count]}" + BOTSENT[CERT]="${UPD[result,has_custom_certificate]}" + BOTSENT[LASTERR]="${UPD[result,last_error_message]}" + unset "BOTSENT[ID]" "BOTSENT[CHAT]" fi } @@ -34,6 +39,7 @@ get_webhook_info() { delete_webhook() { local drop; [ "$1" = "true" ] && drop='"drop_pending_updates": true' sendJson "" "${drop}" "${URL}/deleteWebhook" + unset "BOTSENT[ID]" "BOTSENT[CHAT]" } ################ From 1e49f6c2b1ebd11172ff603ea1c0f9350ad307e0 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 30 Jan 2021 20:14:20 +0100 Subject: [PATCH 72/99] modules: processUpdates rename process_client --- modules/processUpdates.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh index f4452bf..662ed87 100644 --- a/modules/processUpdates.sh +++ b/modules/processUpdates.sh @@ -4,7 +4,7 @@ # File: processUpdates.sh # Note: DO NOT EDIT! this file will be overwritten on update # -#### $$VERSION$$ v1.40-dev-7-g10d275c +#### $$VERSION$$ v1.40-dev-8-g9cfeab9 ################################################################## ############## @@ -15,7 +15,7 @@ # e.g. https://myhost.com -> https://myhost.com/12345678:azndfhbgdfbbbdsfg # $2 max connections 1-100 default 1 (because of bash ;-) set_webhook() { - local url='"url": "'"$1/${BOTTOKEN}"'"' + local url='"url": "'"$1/${BOTTOKEN}/"'"' local max=',"max_connections": 1' [[ "$2" =~ ^[0-9]+$ ]] && max=',"max_connections": '"$2"'' # shellcheck disable=SC2153 @@ -44,16 +44,16 @@ delete_webhook() { ################ # processing of updates starts here -process_updates() { +process_multi_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}" + process_update "${num}" "${debug}" done } -process_client() { +process_update() { local num="$1" debug="$2" pre_process_message "${num}" # log message on debug @@ -352,7 +352,7 @@ get_updates(){ if [ "${OFFSET}" != "1" ]; then nextsleep="100" - process_updates "${DEBUGMSG}" + process_multi_updates "${DEBUGMSG}" fi else # oops, something bad happened, wait maxsleep*10 From c0f1af529e089b29f673fea6d1fb28d9b1fdcfa2 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 30 Jan 2021 20:18:54 +0100 Subject: [PATCH 73/99] bin: process_update.sh webhook script --- bin/process_update.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100755 bin/process_update.sh diff --git a/bin/process_update.sh b/bin/process_update.sh new file mode 100755 index 0000000..c9e8bb4 --- /dev/null +++ b/bin/process_update.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# shellcheck disable=SC1090,SC2034,SC2059 +#=============================================================================== +# +# FILE: bin/process_update.sh +# +USAGE='process_update.sh [-h|--help] [debug] [ Date: Sat, 30 Jan 2021 21:36:38 +0100 Subject: [PATCH 74/99] example: apache webhook example --- examples/README.md | 6 ++++- examples/webhook/README.md | 42 +++++++++++++++++++++++++++++++++++ examples/webhook/index.php | 19 ++++++++++++++++ examples/webhook/json.example | 2 ++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 examples/webhook/README.md create mode 100644 examples/webhook/index.php create mode 100644 examples/webhook/json.example diff --git a/examples/README.md b/examples/README.md index 1e89153..55bfa80 100644 --- a/examples/README.md +++ b/examples/README.md @@ -56,6 +56,10 @@ convert existing bots. **jsonDB-keybords** contains a stripped down real world example from my bot showing the usage of jsonDB to store and retrieve values plus use of keyboards in private chats. It's an extended version of mycommands.sh.dist. Messages and help are in german. -#### $$VERSION$$ v1.30-0-g3266427 +### Webhook + +**Webhook** contains instructions on how use webhook API to get updates from telegram instead polling Telegram server. + +#### $$VERSION$$ v1.40-dev-10-gc0f1af5 diff --git a/examples/webhook/README.md b/examples/webhook/README.md new file mode 100644 index 0000000..533db63 --- /dev/null +++ b/examples/webhook/README.md @@ -0,0 +1,42 @@ +#### [Examples](../README.md) + +## Bashtbot webhook examples + +### webhooks + +Bashbot default mode is to poll Telegram server for updates. Telegram offers the more efficiemt webhook method to deliver updates. +Instead of running bashbot with `bashbot.sh start` permanently you can use the webhook method described here (experimental) + +#### Setup webhook + +To get updates with webhooks you must inform Telegram about where to deliver updates, this will be done with `set_webhook`. +For security reasons bashbot adds you bottoken to the path. + +*Example:* + +```bash +bin/any_command.sh set_webhook "https://myserver.com/telegram" +``` + +will instruct Telegram to use the URL `https://myserver.com/telegram//` to deliver updates. +After you setup webhook to deliver updates it'sno more possible to poll updates with `bashbot.sh start`. + +To stop delivering of updates with webhook run `bin/any_command.sh delete_webhook` + + +**Important**: Only https connections with a valid certificate chain are allowed as endpoint for webhook. + +#### Using Apache with php enabled + +If you have an Apache webserver with a valid SLL certificate chain and php running you can use it as webhook endpoint: + +- setup bashbot to run as the same user as your web server (_`bashbot.sh init`_) +- create the directory `telegram/` in webserver root +- copy `index.php` into new directory +- edit `index.php` to point to your bashbot installation +- setup webhook for your server (_e.g. `bin/any_command.sh set_webhook "https://myserver.com/telegram`_) + + +#### $$VERSION$$ v1.40-dev-10-gc0f1af5 + + diff --git a/examples/webhook/index.php b/examples/webhook/index.php new file mode 100644 index 0000000..78377b6 --- /dev/null +++ b/examples/webhook/index.php @@ -0,0 +1,19 @@ + diff --git a/examples/webhook/json.example b/examples/webhook/json.example new file mode 100644 index 0000000..16fdd30 --- /dev/null +++ b/examples/webhook/json.example @@ -0,0 +1,2 @@ +{"update_id":665220889, +"message":{"message_id":760,"from":{"id":586928566,"is_bot":false,"first_name":"Kay","last_name":"M","username":"KayM_Dealz","language_code":"de"},"chat":{"id":586928566,"first_name":"Kay","last_name":"M","username":"KayM_Dealz","type":"private"},"date":1612029749,"text":"/info","entities":[{"offset":0,"length":5,"type":"bot_command"}]}} \ No newline at end of file From a289cb8e5b90194ef3932857989ee8dd2bb196ab Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sat, 30 Jan 2021 21:53:14 +0100 Subject: [PATCH 75/99] examples: fix webhook description --- examples/webhook/README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/examples/webhook/README.md b/examples/webhook/README.md index 533db63..19a864e 100644 --- a/examples/webhook/README.md +++ b/examples/webhook/README.md @@ -4,13 +4,14 @@ ### webhooks -Bashbot default mode is to poll Telegram server for updates. Telegram offers the more efficiemt webhook method to deliver updates. -Instead of running bashbot with `bashbot.sh start` permanently you can use the webhook method described here (experimental) +Bashbot default mode is to poll Telegram server for updates. Telegram offers the more efficient webhook method to deliver updates. +If your server is reachable from the Internet, you can use the webhook method described here (experimental), instead of running bashbot +with `bashbot.sh start` #### Setup webhook -To get updates with webhooks you must inform Telegram about where to deliver updates, this will be done with `set_webhook`. -For security reasons bashbot adds you bottoken to the path. +To get updates with webhooks your server must be reachable from the internet and you must inform Telegram about where to deliver updates, +this will be done by calling `set_webhook URL`. For security reasons bashbot adds you bottoken to the URL. *Example:* @@ -19,7 +20,7 @@ bin/any_command.sh set_webhook "https://myserver.com/telegram" ``` will instruct Telegram to use the URL `https://myserver.com/telegram//` to deliver updates. -After you setup webhook to deliver updates it'sno more possible to poll updates with `bashbot.sh start`. +After you setup webhook to deliver updates it's no more possible to poll updates with `bashbot.sh start`. To stop delivering of updates with webhook run `bin/any_command.sh delete_webhook` @@ -35,8 +36,8 @@ If you have an Apache webserver with a valid SLL certificate chain and php runni - copy `index.php` into new directory - edit `index.php` to point to your bashbot installation - setup webhook for your server (_e.g. `bin/any_command.sh set_webhook "https://myserver.com/telegram`_) - - -#### $$VERSION$$ v1.40-dev-10-gc0f1af5 +- send a command to your bot (_e.g. `/start`_) to check correct setup + +#### $$VERSION$$ v1.40-dev-11-g9316caa From 2a3663a463da917276c9ffac65861092d91e54d4 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 08:58:24 +0100 Subject: [PATCH 76/99] webhook: final index.php --- examples/webhook/README.md | 21 +++++++++++- examples/webhook/index.php | 67 ++++++++++++++++++++++++++++++-------- 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/examples/webhook/README.md b/examples/webhook/README.md index 19a864e..cc558de 100644 --- a/examples/webhook/README.md +++ b/examples/webhook/README.md @@ -38,6 +38,25 @@ If you have an Apache webserver with a valid SLL certificate chain and php runni - setup webhook for your server (_e.g. `bin/any_command.sh set_webhook "https://myserver.com/telegram`_) - send a command to your bot (_e.g. `/start`_) to check correct setup -#### $$VERSION$$ v1.40-dev-11-g9316caa +*Example index.php*, see [index.php](index.php) for a more complete implementation. + +```php + +``` + +#### $$VERSION$$ v1.40-dev-12-ga289cb8 diff --git a/examples/webhook/index.php b/examples/webhook/index.php index 78377b6..f07c97b 100644 --- a/examples/webhook/index.php +++ b/examples/webhook/index.php @@ -1,19 +1,60 @@ From 4833712246757cfec66493014ea159d1b8a5a687 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 10:00:15 +0100 Subject: [PATCH 77/99] doc: webhook functions bin: do not show JSON.sh error --- bin/process_update.sh | 4 +- doc/6_reference.md | 80 +++++++++++++++++++++++++++++++++++++- examples/webhook/index.php | 18 ++++++--- 3 files changed, 94 insertions(+), 8 deletions(-) diff --git a/bin/process_update.sh b/bin/process_update.sh index c9e8bb4..34385fb 100755 --- a/bin/process_update.sh +++ b/bin/process_update.sh @@ -15,7 +15,7 @@ USAGE='process_update.sh [-h|--help] [debug] [/dev/null)" # assign to bashbot ARRAY Json2Array 'UPD' <<<"${UPDATE}" diff --git a/doc/6_reference.md b/doc/6_reference.md index 0c8894e..e540a35 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -1222,6 +1222,84 @@ https://linuxhint.com/associative_array_bash/ https://linuxconfig.org/how-to-use-arrays-in-bash-script +---- + +### Manage Webhooks +Bashbot default mode is to poll Telegram server for updates. Telegram offers the more efficient webhook method to deliver updates. +I recommend to use webhook with `bin/any_command.sh` to test and setup functionality, see also [webhook example](../example/webhook) + +##### get_webhook_info +`get_webhook_info` get current webhook status for your bot, e.g. url, waiting updates, last error. + +*usage:* get_webhook_info + +*example:* +```bash +bin/any_command.sh get_webhook_info + +["URL"] "" +["OK"] "true" +["LASTERR"] "" +["COUNT"] "0" +["CERT"] "false" +["result","pending_update_count"] "0" +["ok"] "true" +["result","has_custom_certificate"] "false" +``` + + +##### delete_webhook +`delete_webhook` deletes current set webhook, deletes outstanding updates if second arg is `true` + +*usage:* delete_webhook [true|false] + +*example:* + +```bash +bin/any_command.sh delete_webhook false + +["RESULT"] "true" +["OK"] "true" +["result"] "true" +["ok"] "true" +["description"] "Webhook was deleted" +``` + + +##### set_webhook +`set_webhook` deletes current set webhook, deletes outstanding updates if second arg is `true` + +*usage:* set_webhook "https://host.dom[:port][/path]" [max_conn] + +First arg is URL to send updates to, port and path are optional. If port is given itmust be on of 443, 80, 88 or 8443. +For security reasons your TOKEN will be added to URL, e.g. https://myhost.com -> https://myhost.com/12345678:azndfhbgdfbbbdsfg +Second arg is max connection rate in the range 1-100, bashbot default is 1. + +*example:* + +```bash +bin/any_command.sh set_webhook https://myhost.com/telegram 2 + +["OK"] "true" +["RESULT"] "true" +["ok"] "true" +["result"] "true" +["description"] "Webhook is set" + +bin/any_command.sh get_webhook_info + +["OK"] "true" +["URL"] "https://myhost.com/telegram/12345678:AABBCCDDEE...aabbccee124567890/" +["COUNT"] "0" +["CERT"] "false" +["ok"] "true" +["result","ip_address"] "1.2.3.4" +["result","url"] "https://myhost.com/telegram/12345678:AABBCCDDEE...aabbccee124567890/" +["result","pending_update_count"] "0" +["result","max_connections"] "2" +["result","has_custom_certificate"] "false" +``` + ---- ### Aliases - shortcuts for often used functions @@ -1493,5 +1571,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.40-dev-1-g41e2d09 +#### $$VERSION$$ v1.40-dev-13-g2a3663a diff --git a/examples/webhook/index.php b/examples/webhook/index.php index f07c97b..51157ef 100644 --- a/examples/webhook/index.php +++ b/examples/webhook/index.php @@ -7,7 +7,7 @@ * @license http://www.wtfpl.net/txt/copying/ WTFPLv2 * @since 30.01.2021 20:24 * -#### $$VERSION$$ v1.40-dev-12-ga289cb8 +#### $$VERSION$$ v1.40-dev-13-g2a3663a ***********************************************************/ // bashbot home dir @@ -15,17 +15,25 @@ // webhook endpoint $cmd=$BASHBOT_HOME.'/bin/process_update.sh'; - // read request data + // prepeare read, e.g. run from CLI $data=''; $input="php://input"; - if (php_sapi_name() == "cli") { $input="php://stdin"; } + $json_file="json.txt"; + if (php_sapi_name() == "cli") { + if(is_readable($json_file)) { + $input=$json_file; + } else { + $input="php://stdin"; + } + } + // read request data if($json = file_get_contents($input)) { $data = $json; } else { $data = implode(" ",$_POST); } // file_put_contents('server.txt', print_r($_SERVER, TRUE)); - // file_put_contents('json.txt', $data); + // file_put_contents($json_file, $data); // process telegram update if ($data == '') { @@ -55,6 +63,6 @@ $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'; header($protocol.' '.$code.' '.$msg); } - exit('Error '.$code.': '.$msg."\n"); + exit('Error '.$code.': '.$msg); } ?> From bc3a3b3defd2b7c1dd3bdc2cc7ca2271827c3af9 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 10:19:33 +0100 Subject: [PATCH 78/99] doc: improve webhook desc --- doc/6_reference.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index e540a35..0c3e255 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -1224,12 +1224,14 @@ https://linuxconfig.org/how-to-use-arrays-in-bash-script ---- -### Manage Webhooks -Bashbot default mode is to poll Telegram server for updates. Telegram offers the more efficient webhook method to deliver updates. -I recommend to use webhook with `bin/any_command.sh` to test and setup functionality, see also [webhook example](../example/webhook) +### Manage webhook +Bashbot default mode is to poll Telegram server for updates, but Telegram offers webhook as a more efficient method to deliver updates also. + +*Important*: Before using webhook your server must be setup to receive and process updates from Telegram! +I recommend to use webhook with a test bot first. [Webhook examples](../examples/webhook) ##### get_webhook_info -`get_webhook_info` get current webhook status for your bot, e.g. url, waiting updates, last error. +`get_webhook_info` get current status of webhook for your bot, e.g. url, waiting updates, last error. *usage:* get_webhook_info @@ -1249,7 +1251,7 @@ bin/any_command.sh get_webhook_info ##### delete_webhook -`delete_webhook` deletes current set webhook, deletes outstanding updates if second arg is `true` +`delete_webhook` deletes iyour bots current webhook, deletes outstanding updates if second arg is `true` *usage:* delete_webhook [true|false] @@ -1267,7 +1269,10 @@ bin/any_command.sh delete_webhook false ##### set_webhook -`set_webhook` deletes current set webhook, deletes outstanding updates if second arg is `true` +`set_webhook` instructs Telgram to use your bots webhook for update delivery. If webhook is set on Telegram +it's no more possible to pull updates from `bashbot start`, you must delete webhook first. + +*Important*: Before using webhook your server must be setup to receive and process updates from Telegram! *usage:* set_webhook "https://host.dom[:port][/path]" [max_conn] @@ -1571,5 +1576,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.40-dev-13-g2a3663a +#### $$VERSION$$ v1.40-dev-14-g4833712 From f377e17e44a16e9f66ff96c38aecccb13bd95d53 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 10:29:38 +0100 Subject: [PATCH 79/99] doc: small webhook desc fixes --- doc/6_reference.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/6_reference.md b/doc/6_reference.md index 0c3e255..629026f 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -1225,9 +1225,9 @@ https://linuxconfig.org/how-to-use-arrays-in-bash-script ---- ### Manage webhook -Bashbot default mode is to poll Telegram server for updates, but Telegram offers webhook as a more efficient method to deliver updates also. +Bashbot default mode is to poll Telegram server for updates but Telegram offers also webhook as a more efficient method to deliver updates. -*Important*: Before using webhook your server must be setup to receive and process updates from Telegram! +*Important*: Before using webhook you must setup your server to receive and process updates from Telegram! I recommend to use webhook with a test bot first. [Webhook examples](../examples/webhook) ##### get_webhook_info @@ -1251,7 +1251,7 @@ bin/any_command.sh get_webhook_info ##### delete_webhook -`delete_webhook` deletes iyour bots current webhook, deletes outstanding updates if second arg is `true` +`delete_webhook` deletes your bots current webhook, deletes outstanding updates also if second arg is `true` *usage:* delete_webhook [true|false] @@ -1269,21 +1269,23 @@ bin/any_command.sh delete_webhook false ##### set_webhook -`set_webhook` instructs Telgram to use your bots webhook for update delivery. If webhook is set on Telegram +`set_webhook` instructs Telegram to use your bots webhook for delivering updates. If a webhook is set it's no more possible to pull updates from `bashbot start`, you must delete webhook first. -*Important*: Before using webhook your server must be setup to receive and process updates from Telegram! +*Important*: Before using webhook you must setup your server to receive and process updates from Telegram! *usage:* set_webhook "https://host.dom[:port][/path]" [max_conn] -First arg is URL to send updates to, port and path are optional. If port is given itmust be on of 443, 80, 88 or 8443. -For security reasons your TOKEN will be added to URL, e.g. https://myhost.com -> https://myhost.com/12345678:azndfhbgdfbbbdsfg +First arg is webhook URL used to send updates to your bot, `:port` and `/path` are optional. +If `:port` is given it must be one of `:443`, `:80`, `:88` or `:8443`, default is`:80`. +For security reasons `BOTTOKEN` will be added to URL (_e.g. `https://myhost.com` -> `https://myhost.com/12345678:azndfhbgdfbbbdsfg`_). + Second arg is max connection rate in the range 1-100, bashbot default is 1. *example:* ```bash -bin/any_command.sh set_webhook https://myhost.com/telegram 2 +bin/any_command.sh set_webhook "https://myhost.com/telegram" "2" ["OK"] "true" ["RESULT"] "true" @@ -1576,5 +1578,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.40-dev-14-g4833712 +#### $$VERSION$$ v1.40-dev-15-gbc3a3b3 From 8034a5f055b1b2c208c8353d1be5252a2abdb476 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 12:38:40 +0100 Subject: [PATCH 80/99] bin: any_command fix reference location --- bin/any_command.sh | 6 +++--- doc/6_reference.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/any_command.sh b/bin/any_command.sh index 7403b7c..6ba68da 100755 --- a/bin/any_command.sh +++ b/bin/any_command.sh @@ -21,7 +21,7 @@ USAGE='any_command.sh [-h|--help] [--force|--reference] bot_command args ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 30.01.2021 10:24 # -#### $$VERSION$$ v1.40-dev-6-g08b7b85 +#### $$VERSION$$ v1.40-dev-16-gf377e17 #=============================================================================== #### @@ -50,10 +50,10 @@ else error=3 fi # simple hack to get allowed commands from doc - if grep -q "^##### $1" <<<"$(sed -n -e '/^##### _is_/,$ d' -e '/^##### /p' "../doc/"6_*)"; then + if grep -q "^##### $1" <<<"$(sed -n -e '/^##### _is_/,$ d' -e '/^##### /p' "${BASHBOT_HOME:-..}doc/"6_*)"; then # oiutput reference and exit if [[ "${ref}" == "--ref"* ]]; then - sed -n -e '/^##### '"$1"'/,/^##/ p' "../doc/"6_* + sed -n -e '/^##### '"$1"'/,/^##/ p' "${BASHBOT_HOME:-..}doc/"6_* exit fi else diff --git a/doc/6_reference.md b/doc/6_reference.md index 629026f..bd35ad5 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -1269,7 +1269,7 @@ bin/any_command.sh delete_webhook false ##### set_webhook -`set_webhook` instructs Telegram to use your bots webhook for delivering updates. If a webhook is set +`set_webhook` instructs Telegram to use your bots webhook for delivering updates. If webhook is set it's no more possible to pull updates from `bashbot start`, you must delete webhook first. *Important*: Before using webhook you must setup your server to receive and process updates from Telegram! @@ -1278,7 +1278,7 @@ it's no more possible to pull updates from `bashbot start`, you must delete webh First arg is webhook URL used to send updates to your bot, `:port` and `/path` are optional. If `:port` is given it must be one of `:443`, `:80`, `:88` or `:8443`, default is`:80`. -For security reasons `BOTTOKEN` will be added to URL (_e.g. `https://myhost.com` -> `https://myhost.com/12345678:azndfhbgdfbbbdsfg`_). +For security reasons `BOTTOKEN` will be added to URL (_e.g. `https://myhost.com` -> `https://myhost.com/12345678:azndfhbgdfbbbdsfg/`_). Second arg is max connection rate in the range 1-100, bashbot default is 1. @@ -1578,5 +1578,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.40-dev-15-gbc3a3b3 +#### $$VERSION$$ v1.40-dev-16-gf377e17 From 342a5da97a9eb28082e5d5503a5ca8347c4823fe Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 12:40:13 +0100 Subject: [PATCH 81/99] fix _exec_if_function --- bashbot.sh | 6 +++--- bin/any_command.sh | 2 +- doc/6_reference.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 3c14d13..e56ed1e 100755 --- a/bashbot.sh +++ b/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.40-dev-4-gc693ab5 +#### $$VERSION$$ v1.40-dev-17-g8034a5f ################################################################## # emmbeded system may claim bash but it is not @@ -754,7 +754,7 @@ if [ -z "${SOURCE}" ]; then ;; # finally starts the read update loop, internal use only "startbot" ) - _exec_if_exist start_bot "$2" + _exec_if_function start_bot "$2" debug_checks "end startbot" "$@" exit ;; @@ -797,7 +797,7 @@ if [ -z "${SOURCE}" ]; then "start") SESSION="${ME:-_bot}-startbot" BOTPID="$(proclist "${SESSION}")" - if _is_function process_updates; then + if _is_function process_update; then # shellcheck disable=SC2086 [ -n "${BOTPID}" ] && kill ${BOTPID} nohup "${SCRIPT}" "startbot" "$2" "${SESSION}" &>/dev/null & diff --git a/bin/any_command.sh b/bin/any_command.sh index 6ba68da..e9aa43c 100755 --- a/bin/any_command.sh +++ b/bin/any_command.sh @@ -21,7 +21,7 @@ USAGE='any_command.sh [-h|--help] [--force|--reference] bot_command args ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 30.01.2021 10:24 # -#### $$VERSION$$ v1.40-dev-16-gf377e17 +#### $$VERSION$$ v1.40-dev-17-g8034a5f #=============================================================================== #### diff --git a/doc/6_reference.md b/doc/6_reference.md index bd35ad5..52edbf0 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -1578,5 +1578,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.40-dev-16-gf377e17 +#### $$VERSION$$ v1.40-dev-17-g8034a5f From 0dd5f83d5a423b96f9d8ab4d907085d67e694173 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 12:42:41 +0100 Subject: [PATCH 82/99] modules: processUpdates: detect conflicting webhook --- modules/processUpdates.sh | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh index 662ed87..5b70c7b 100644 --- a/modules/processUpdates.sh +++ b/modules/processUpdates.sh @@ -4,7 +4,7 @@ # File: processUpdates.sh # Note: DO NOT EDIT! this file will be overwritten on update # -#### $$VERSION$$ v1.40-dev-8-g9cfeab9 +#### $$VERSION$$ v1.40-dev-18-g342a5da ################################################################## ############## @@ -284,11 +284,7 @@ process_message() { # 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}" + local DEBUGMSG # startup message DEBUGMSG="Start BASHBOT updates in Mode \"${1:-normal}\" ==========" log_update "${DEBUGMSG}" @@ -327,11 +323,16 @@ start_bot() { send_normal_message "$(getConfigKey "botadmin")" "Bot $(getConfigKey "botname") started ..." & ########## # bot is ready, start processing updates ... - get_updates + get_updates "${DEBUGMSG}" } get_updates(){ + local errsleep="200" DEBUG="$1" OFFSET=0 + # adaptive sleep defaults + local nextsleep="100" + local stepsleep="${BASHBOT_SLEEP_STEP:-100}" + local maxsleep="${BASHBOT_SLEEP:-5000}" while true; do # adaptive sleep in ms rounded to next 0.1 s sleep "$(_round_float "${nextsleep}e-3" "1")" @@ -341,18 +342,26 @@ get_updates(){ # did we get an response? if [ -n "${UPDATE}" ]; then # we got something, do processing - [ "${OFFSET}" = "-999" ] && [ "${nextsleep}" -gt "$((maxsleep*2))" ] &&\ + [ "${OFFSET}" = "-999" ] && [ "${nextsleep}" -gt "$((maxsleep/2))" ] &&\ log_error "Recovered from timeout/broken/no connection, continue with telegram updates" - # escape bash $ expansion bug + # calculate next sleep interval ((nextsleep+= stepsleep , nextsleep= nextsleep>maxsleep ?maxsleep:nextsleep)) + # escape bash $ expansion bug UPDATE="${UPDATE//$/\\$}" + # warn if webhook is set + if grep -q '^\["error_code"\] 409' <<<"${UPDATE}"; then + OFFSET="-999"; errsleep="$(_round_float "$(( errsleep = 200 * nextsleep ))e-3" "1")" + log_error "Warning conflicting webhook set, can't get updates until delete_webhook! Sleep ${errsleep}s ..." + sleep "${errsleep}" + continue + fi # Offset - OFFSET="$(grep <<< "${UPDATE}" '\["result",[0-9]*,"update_id"\]' | tail -1 | cut -f 2)" + OFFSET="$(grep <<<"${UPDATE}" '\["result",[0-9]*,"update_id"\]' | tail -1 | cut -f 2)" ((OFFSET++)) if [ "${OFFSET}" != "1" ]; then nextsleep="100" - process_multi_updates "${DEBUGMSG}" + process_multi_updates "${DEBUG}" fi else # oops, something bad happened, wait maxsleep*10 From a7c98d750c6b20e1beea4c0f9bbb2ced4d3a0530 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 13:16:27 +0100 Subject: [PATCH 83/99] modules: processUpdates: conflict webhook slow start --- modules/processUpdates.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh index 5b70c7b..e44580e 100644 --- a/modules/processUpdates.sh +++ b/modules/processUpdates.sh @@ -4,7 +4,7 @@ # File: processUpdates.sh # Note: DO NOT EDIT! this file will be overwritten on update # -#### $$VERSION$$ v1.40-dev-18-g342a5da +#### $$VERSION$$ v1.40-dev-19-g0dd5f83 ################################################################## ############## @@ -350,6 +350,7 @@ get_updates(){ UPDATE="${UPDATE//$/\\$}" # warn if webhook is set if grep -q '^\["error_code"\] 409' <<<"${UPDATE}"; then + [ "${OFFSET}" != "-999" ] && nextsleep="${stepsleep}" OFFSET="-999"; errsleep="$(_round_float "$(( errsleep = 200 * nextsleep ))e-3" "1")" log_error "Warning conflicting webhook set, can't get updates until delete_webhook! Sleep ${errsleep}s ..." sleep "${errsleep}" From 5b0b121ba5e0b5e7f58bfd7a187ba4635fe73bd6 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 18:08:18 +0100 Subject: [PATCH 84/99] examples: webhook: make home and file configurable --- examples/webhook/BASHBOT_HOME | 2 + examples/webhook/README.md | 10 ++-- examples/webhook/index.php | 51 ++++++++++++++++----- examples/webhook/{json.example => json.txt} | 0 4 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 examples/webhook/BASHBOT_HOME rename examples/webhook/{json.example => json.txt} (100%) diff --git a/examples/webhook/BASHBOT_HOME b/examples/webhook/BASHBOT_HOME new file mode 100644 index 0000000..bfac0e5 --- /dev/null +++ b/examples/webhook/BASHBOT_HOME @@ -0,0 +1,2 @@ +/usr/local/github/telegram-bot-bash-develop/DIST/telegram-bot-bash +/usr/local/telegram-bot-bash diff --git a/examples/webhook/README.md b/examples/webhook/README.md index cc558de..01b5eb8 100644 --- a/examples/webhook/README.md +++ b/examples/webhook/README.md @@ -32,13 +32,13 @@ To stop delivering of updates with webhook run `bin/any_command.sh delete_webhoo If you have an Apache webserver with a valid SLL certificate chain and php running you can use it as webhook endpoint: - setup bashbot to run as the same user as your web server (_`bashbot.sh init`_) -- create the directory `telegram/` in webserver root -- copy `index.php` into new directory -- edit `index.php` to point to your bashbot installation +- create the directory `telegram/` in apache web root +- copy files all files form here into new directory and change to it +- edit `BASHBOT_HOME` to point to your bashbot installation directory - setup webhook for your server (_e.g. `bin/any_command.sh set_webhook "https://myserver.com/telegram`_) - send a command to your bot (_e.g. `/start`_) to check correct setup -*Example index.php*, see [index.php](index.php) for a more complete implementation. +*Example minimal index.php*, see [index.php](index.php) for complete implementation. ```php ``` -#### $$VERSION$$ v1.40-dev-12-ga289cb8 +#### $$VERSION$$ v1.40-dev-20-ga7c98d7 diff --git a/examples/webhook/index.php b/examples/webhook/index.php index 51157ef..2635e2a 100644 --- a/examples/webhook/index.php +++ b/examples/webhook/index.php @@ -2,18 +2,34 @@ /************************************************************ * @file examples/webhook/index.php * @description example webhook implementation for apache + * write to fifo/file if writeable, else pipe to command + * + * first line of BASHBOT_HOME is used as bot home (optional) + * must start with /, not contain /. and min 20 characters long * * @author KayM (gnadelwartz), kay@rrr.de * @license http://www.wtfpl.net/txt/copying/ WTFPLv2 * @since 30.01.2021 20:24 * -#### $$VERSION$$ v1.40-dev-13-g2a3663a +#### $$VERSION$$ v1.40-dev-20-ga7c98d7 ***********************************************************/ // bashbot home dir + $CONFIG_HOME='BASHBOT_HOME'; $BASHBOT_HOME='/usr/local/telegram-bot-bash'; - // webhook endpoint + // read from config file + if (file_exists($CONFIG_HOME)) { + $tmp = trim(fgets(fopen($CONFIG_HOME, 'r'))); + // start with '/', not '/.', min 20 chars + if (substr($tmp,0,1) == '/' && strlen($tmp) >= 20 && strpos($tmp, '/.') === false) { + $BASHBOT_HOME=$tmp; + } + } + + // script endpoint $cmd=$BASHBOT_HOME.'/bin/process_update.sh'; + // fifo endpoint + $fifo=$BASHBOT_HOME.'/data-bot-bash/webhook-fifo'; // prepeare read, e.g. run from CLI $data=''; @@ -33,27 +49,38 @@ $data = implode(" ",$_POST); } // file_put_contents('server.txt', print_r($_SERVER, TRUE)); - // file_put_contents($json_file, $data); + file_put_contents($json_file, $data); - // process telegram update + // prepare for writing if ($data == '') { error_response(400, "No data received"); } if (! chdir($BASHBOT_HOME)) { error_response(403, "No route to bot home"); } - if (! is_executable($cmd)) { - error_response(502, "Webhook endpoint not found"); - } - if (! $handle = popen( $cmd.' debug', 'w' )) { - error_response(503, "Can't open webhook endpoint"); + // fifo or command? + if (! is_writeable($fifo)) { + // pipe to command + if (! file_exists($cmd)) { + error_response(502, "Webhook endpoint not found"); + } + if (! $handle = popen( $cmd.' debug', 'w' )) { + error_response(503, "Can't open webhook command endpoint"); + } + } else { + // write to fifo + if (! $handle = fopen( $fifo, 'a' )) { + error_response(503, "Can't open webhook file endpoint"); + } + flock($handle, LOCK_EX); } - if (fwrite( $handle, $data.'\n') === false) { + if (fwrite( $handle, str_replace(array("\n", "\r"), '',$data). PHP_EOL) === false) { error_response(504, "Write to webhook failed"); } + flock($handle, LOCK_UN); pclose($handle); - +/**/ function error_response($code, $msg) { $api = substr(php_sapi_name(), 0, 3); @@ -63,6 +90,6 @@ $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'; header($protocol.' '.$code.' '.$msg); } - exit('Error '.$code.': '.$msg); + exit('Error '.$code.': '.$msg. PHP_EOL); } ?> diff --git a/examples/webhook/json.example b/examples/webhook/json.txt similarity index 100% rename from examples/webhook/json.example rename to examples/webhook/json.txt From 6754273c6ee628049947a11c7597112b4d8cca85 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 21:18:40 +0100 Subject: [PATCH 85/99] example: webhook: rewrite setup --- examples/webhook/README.md | 81 +++++++++++++++----------------------- examples/webhook/index.php | 7 ++-- 2 files changed, 36 insertions(+), 52 deletions(-) diff --git a/examples/webhook/README.md b/examples/webhook/README.md index 01b5eb8..1ed8924 100644 --- a/examples/webhook/README.md +++ b/examples/webhook/README.md @@ -1,62 +1,45 @@ #### [Examples](../README.md) -## Bashtbot webhook examples +## Bashtbot webhook example -### webhooks +### Webhooks -Bashbot default mode is to poll Telegram server for updates. Telegram offers the more efficient webhook method to deliver updates. -If your server is reachable from the Internet, you can use the webhook method described here (experimental), instead of running bashbot -with `bashbot.sh start` - -#### Setup webhook - -To get updates with webhooks your server must be reachable from the internet and you must inform Telegram about where to deliver updates, -this will be done by calling `set_webhook URL`. For security reasons bashbot adds you bottoken to the URL. - -*Example:* - -```bash -bin/any_command.sh set_webhook "https://myserver.com/telegram" -``` - -will instruct Telegram to use the URL `https://myserver.com/telegram//` to deliver updates. -After you setup webhook to deliver updates it's no more possible to poll updates with `bashbot.sh start`. - -To stop delivering of updates with webhook run `bin/any_command.sh delete_webhook` +Bashbot default mode is to poll Telegram server for updates but Telegram offers also webhook +as a more efficient method to deliver updates. +If your server is reachable from the Internet you can use the webhook method described here. -**Important**: Only https connections with a valid certificate chain are allowed as endpoint for webhook. +#### Setup Apache webhook -#### Using Apache with php enabled +Prerequisite: An Apache webserver with a valid SLL certificate chain and php enabled. -If you have an Apache webserver with a valid SLL certificate chain and php running you can use it as webhook endpoint: +Prepare Apache to forward webhook to Bashbot: -- setup bashbot to run as the same user as your web server (_`bashbot.sh init`_) -- create the directory `telegram/` in apache web root -- copy files all files form here into new directory and change to it -- edit `BASHBOT_HOME` to point to your bashbot installation directory -- setup webhook for your server (_e.g. `bin/any_command.sh set_webhook "https://myserver.com/telegram`_) -- send a command to your bot (_e.g. `/start`_) to check correct setup +- install bashbot as described in [Bashbot Installation](../../doc/0_install.md) +- create file `data-bot-bash/webhook-fifo` +- run `bashbot.sh init` to setup bashbot to run as same user as Apache (_e.g. www_) +- go to apache web root and create directory `telegram/` +- copy all files from `examples/webhook` to new directory and change to it +- write bashbot installation directory as first line to file `BASHBOT_HOME` +- execute `php index.php` -*Example minimal index.php*, see [index.php](index.php) for complete implementation. +Every call to webhook `https:///telegram//` will execute +`index.php` and write received JSON to file `data-bot-bash/webhook-fifo`. +E.g. the URL `https:///telegram//?json={"test":"me"}` +will append `{"test":"me"}` to the file `data-bot-bash/webhook-fifo`. -```php - -``` - -#### $$VERSION$$ v1.40-dev-20-ga7c98d7 +Now your Apache is ready to forward data to Bashbot. + + +#### Simple update processing + +To configure simple update processing delete file `data-bot-bash/webhook-fifo` after your webhook is working. +Every webhook call now forwards incoming Telegram updates to the named pipe `data-bot-bash/webhook-fifo` +and Bashbot poll them like polling Telegram server. This is much more efficient than polling Telegram server. + +To switch from `Simple processing` to `High traffic processing` start bashbot as `bashbot.sh start-hook`. +Stop bashbot with `bashbot.sh stop` to switch back to `Simple processing` + +#### $$VERSION$$ v1.40-dev-21-g5b0b121 diff --git a/examples/webhook/index.php b/examples/webhook/index.php index 2635e2a..86fc1d9 100644 --- a/examples/webhook/index.php +++ b/examples/webhook/index.php @@ -11,7 +11,7 @@ * @license http://www.wtfpl.net/txt/copying/ WTFPLv2 * @since 30.01.2021 20:24 * -#### $$VERSION$$ v1.40-dev-20-ga7c98d7 +#### $$VERSION$$ v1.40-dev-21-g5b0b121 ***********************************************************/ // bashbot home dir @@ -47,9 +47,10 @@ $data = $json; } else { $data = implode(" ",$_POST); + if ($data == '') { $data = implode(" ",$_GET); } } - // file_put_contents('server.txt', print_r($_SERVER, TRUE)); - file_put_contents($json_file, $data); + // uncomment to save last received JSON + // file_put_contents($json_file, $data); // prepare for writing if ($data == '') { From 4e7b3052de3abcdbd0b7a1411d2124e53a1100c8 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Sun, 31 Jan 2021 21:30:28 +0100 Subject: [PATCH 86/99] example: webhook: fix missing setup part --- examples/webhook/README.md | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/examples/webhook/README.md b/examples/webhook/README.md index 1ed8924..dbb62fe 100644 --- a/examples/webhook/README.md +++ b/examples/webhook/README.md @@ -35,11 +35,42 @@ Now your Apache is ready to forward data to Bashbot. To configure simple update processing delete file `data-bot-bash/webhook-fifo` after your webhook is working. Every webhook call now forwards incoming Telegram updates to the named pipe `data-bot-bash/webhook-fifo` -and Bashbot poll them like polling Telegram server. This is much more efficient than polling Telegram server. + +Now enable webhook on Telegram (_see below_). + +Every incoming Telegram update load Bashbot once for processing one command. Even it seems overkill to load +Bashbot on every update, it's more responsive and create less server load for a low traffic bot. + +*Note:* You must NOT start bashbot when simple update processing is enabled. + + +#### High traffic processing + +High traffic processing writes Telegram updates to the named pipe `data-bot-bash/webhook-fifo` +and Bashbot poll them, this is much more efficient than polling Telegram server. To switch from `Simple processing` to `High traffic processing` start bashbot as `bashbot.sh start-hook`. Stop bashbot with `bashbot.sh stop` to switch back to `Simple processing` -#### $$VERSION$$ v1.40-dev-21-g5b0b121 + +#### Enable webhook on Telegram + +To get updates via webhook your server must be reachable from the internet and you must +instruct Telegram where to deliver updates, this is done by calling bashbot function `set_webhook`. + +*Example:* + +```bash +bin/any_command.sh set_webhook "https://myserver.com/telegram" +``` + +instruct Telegram to use the URL `https://myserver.com/telegram//` to deliver updates. +After you enable webhook to deliver Telegram updates it's no more possible to poll updates with `bashbot.sh start`. + +To stop delivering of Telegram updates via webhook run `bin/any_command.sh delete_webhook`. + +**Important**: Only https connections with a valid certificate chain are allowed as endpoint for webhook. +#### $$VERSION$$ v1.40-dev-22-g6754273 + From e4a983b16fe237a6b93118e477eabfffeff6262d Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 1 Feb 2021 08:59:53 +0100 Subject: [PATCH 87/99] modules: processUpdates: show sleep minutes --- examples/webhook/json.txt | 2 +- modules/processUpdates.sh | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/webhook/json.txt b/examples/webhook/json.txt index 16fdd30..83e85cb 100644 --- a/examples/webhook/json.txt +++ b/examples/webhook/json.txt @@ -1,2 +1,2 @@ {"update_id":665220889, -"message":{"message_id":760,"from":{"id":586928566,"is_bot":false,"first_name":"Kay","last_name":"M","username":"KayM_Dealz","language_code":"de"},"chat":{"id":586928566,"first_name":"Kay","last_name":"M","username":"KayM_Dealz","type":"private"},"date":1612029749,"text":"/info","entities":[{"offset":0,"length":5,"type":"bot_command"}]}} \ No newline at end of file +"message":{"message_id":760,"from":{"id":586928566,"is_bot":false,"first_name":"Kay","last_name":"M","username":"KayM","language_code":"de"},"chat":{"id":589682731,"first_name":"Kay","last_name":"M","username":"KayM","type":"private"},"date":1612029749,"text":"/info","entities":[{"offset":0,"length":5,"type":"bot_command"}]}} diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh index e44580e..71fe881 100644 --- a/modules/processUpdates.sh +++ b/modules/processUpdates.sh @@ -4,7 +4,7 @@ # File: processUpdates.sh # Note: DO NOT EDIT! this file will be overwritten on update # -#### $$VERSION$$ v1.40-dev-19-g0dd5f83 +#### $$VERSION$$ v1.40-dev-23-g4e7b305 ################################################################## ############## @@ -342,7 +342,7 @@ get_updates(){ # did we get an response? if [ -n "${UPDATE}" ]; then # we got something, do processing - [ "${OFFSET}" = "-999" ] && [ "${nextsleep}" -gt "$((maxsleep/2))" ] &&\ + [ "${OFFSET}" = "-999" ] && [ "${nextsleep}" -gt "$((maxsleep*2))" ] &&\ log_error "Recovered from timeout/broken/no connection, continue with telegram updates" # calculate next sleep interval ((nextsleep+= stepsleep , nextsleep= nextsleep>maxsleep ?maxsleep:nextsleep)) @@ -351,8 +351,8 @@ get_updates(){ # warn if webhook is set if grep -q '^\["error_code"\] 409' <<<"${UPDATE}"; then [ "${OFFSET}" != "-999" ] && nextsleep="${stepsleep}" - OFFSET="-999"; errsleep="$(_round_float "$(( errsleep = 200 * nextsleep ))e-3" "1")" - log_error "Warning conflicting webhook set, can't get updates until delete_webhook! Sleep ${errsleep}s ..." + OFFSET="-999"; errsleep="$(_round_float "$(( errsleep= 300*nextsleep ))e-3")" + log_error "Warning conflicting webhook set, can't get updates until delete_webhook! Sleep $((errsleep/60)) min ..." sleep "${errsleep}" continue fi From c1aec9285ed59aaedc80714f0b96542772a274ea Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 1 Feb 2021 09:02:22 +0100 Subject: [PATCH 88/99] start: show already running bot --- bashbot.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index e56ed1e..a50d185 100755 --- a/bashbot.sh +++ b/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.40-dev-17-g8034a5f +#### $$VERSION$$ v1.40-dev-24-ge4a983b ################################################################## # emmbeded system may claim bash but it is not @@ -799,12 +799,13 @@ if [ -z "${SOURCE}" ]; then BOTPID="$(proclist "${SESSION}")" if _is_function process_update; then # shellcheck disable=SC2086 - [ -n "${BOTPID}" ] && kill ${BOTPID} + [ -n "${BOTPID}" ] && kill ${BOTPID} && printf "${GREY}Stop already running bot ...${NN}" 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}" + [ -n "${BOTPID}" ] && printf "${ORANGE}Already running bot found ...${NN}" fi if [ -n "$(proclist "${SESSION}")" ]; then printf "${GREEN}Bot started successfully.${NN}" From e86c8dc11677fda5a7979a04e1addfb37bf99473 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 1 Feb 2021 09:37:22 +0100 Subject: [PATCH 89/99] source: return from source to avoid killing shell --- bashbot.sh | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index a50d185..f1b9e2a 100755 --- a/bashbot.sh +++ b/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.40-dev-24-ge4a983b +#### $$VERSION$$ v1.40-dev-25-gc1aec92 ################################################################## # emmbeded system may claim bash but it is not @@ -51,6 +51,7 @@ if [ -t 1 ] && [ -n "${TERM}" ]; then NC='\e[0m' NN="${NC}\n" fi +declare -r INTERACTIVE RED GREEN ORANGE GREY NC NN # telegram uses utf-8 characters, check if we have an utf-8 charset if [ "${LANG}" = "${LANG%[Uu][Tt][Ff]*}" ]; then @@ -179,8 +180,9 @@ RUNDIR="$(dirname "$0")" MODULEDIR="${SCRIPTDIR}/modules" -# adjust locations based on source and real name -[[ "${SCRIPT}" != "${REALME}" || "$1" == "source" ]] && SOURCE="yes" +# adjust stuff for source +alias exit_source='exit' +[[ "${SCRIPT}" != "${REALME}" || "$1" == "source" ]] && SOURCE="yes" && alias exit_source='printf "Exit from source...\n";return' if [ -n "${BASHBOT_HOME}" ]; then SCRIPTDIR="${BASHBOT_HOME}" @@ -221,9 +223,11 @@ RUNDIR="." # check if JSON.sh is available JSONSHFILE="${BASHBOT_JSONSH:-${SCRIPTDIR}/JSON.sh/JSON.sh}" -[ ! -x "${JSONSHFILE}" ] &&\ - printf "${RED}ERROR:${NC} ${JSONSHFILE} ${RED}does not exist, are we in dev environment?${NN}${GREY}%s${NN}\n"\ - "\$JSONSHFILE is set wrong or bashbot is not installed correctly, see doc/0_install.md" && exit 3 +if [ ! -x "${JSONSHFILE}" ]; then + printf "${RED}ERROR:${NC} ${JSONSHFILE} ${RED}does not exist, are we in dev environment?${NN}${GREY}%s${NN}\n"\ + "\$JSONSHFILE is set wrong or bashbot is not installed correctly, see doc/0_install.md" + exit_source 3 +fi # file locations based on ENVIRONMENT BOTCONFIG="${BASHBOT_ETC:-.}/botconfig" @@ -376,7 +380,7 @@ sed '1ia' /dev/null || printf "${ORANGE}Warning: You may run on a B #jsonDB is now mandatory if ! _is_function jssh_newDB; then printf "${RED}ERROR: Mandatory module jsonDB is missing or not readable!${NN}" - exit 6 + exit_source 6 fi # $1 URL, $2 filename in DATADIR @@ -529,7 +533,7 @@ else else printf "${RED}Error: curl and wget not found, install curl!${NN}" fi - exit 8 + exit_source 8 fi fi @@ -701,7 +705,7 @@ bot_init() { if ! _is_function send_message ; then printf "${RED}ERROR: send_message is not available, did you deactivate ${MODULEDIR}/sendMessage.sh?${NN}" - exit 1 + exit_source 1 fi # check if JSON.awk exist and has x flag From c4d100e0ada45e2932b8832a8f92f22ba4c4a21a Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 1 Feb 2021 10:00:08 +0100 Subject: [PATCH 90/99] source: better exit_source handling --- bashbot.sh | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index f1b9e2a..6b8f43c 100755 --- a/bashbot.sh +++ b/bashbot.sh @@ -30,16 +30,9 @@ BOTCOMMANDS="-h help init start stop status suspendback resumeback killb # 8 - curl/wget missing # 10 - not bash! # -#### $$VERSION$$ v1.40-dev-25-gc1aec92 +#### $$VERSION$$ v1.40-dev-26-ge86c8dc ################################################################## -# emmbeded system may claim bash but it is not -# check for bash like ARRAY handlung -if ! (unset a; set -A a a; eval "a=(a b)"; eval '[ -n "${a[1]}" ]'; ) > /dev/null 2>&1; then - printf "Error: Current shell does not support ARRAY's, may be busybox ash shell. pls install a real bash!\n" - exit 10 -fi - # are we running in a terminal? NN="\n" if [ -t 1 ] && [ -n "${TERM}" ]; then @@ -180,10 +173,21 @@ RUNDIR="$(dirname "$0")" MODULEDIR="${SCRIPTDIR}/modules" -# adjust stuff for source +# adjust stuff for source, use return from source without source alias exit_source='exit' -[[ "${SCRIPT}" != "${REALME}" || "$1" == "source" ]] && SOURCE="yes" && alias exit_source='printf "Exit from source...\n";return' +if [[ "${SCRIPT}" != "${REALME}" || "$1" == "source" ]]; then + SOURCE="yes" + [ -z "$1" ] && alias exit_source='printf "Exit from source ...\n";return' +fi +# emmbeded system may claim bash but it is not +# check for bash like ARRAY handlung +if ! (unset a; set -A a a; eval "a=(a b)"; eval '[ -n "${a[1]}" ]'; ) > /dev/null 2>&1; then + printf "Error: Current shell does not support ARRAY's, may be busybox ash shell. pls install a real bash!\n" + exit_source 10 +fi + +# adjust path variables if [ -n "${BASHBOT_HOME}" ]; then SCRIPTDIR="${BASHBOT_HOME}" else @@ -193,7 +197,7 @@ fi [ -z "${BASHBOT_VAR}" ] && BASHBOT_VAR="${BASHBOT_HOME}" ADDONDIR="${BASHBOT_ETC:-.}/addons" -RUNUSER="${USER}" # USER is overwritten by bashbot array :-(, save original +RUNUSER="${USER}" # save original USER # provide help case "$1" in @@ -216,7 +220,7 @@ esac # OK, ENVIRONMENT is set up, let's do some additional tests if [[ -z "${SOURCE}" && -z "${BASHBOT_HOME}" ]] && ! cd "${RUNDIR}" ; then printf "${RED}ERROR: Can't change to ${RUNDIR} ...${NN}" - exit 1 + exit_source 1 fi RUNDIR="." [ ! -w "." ] && printf "${ORANGE}WARNING: ${RUNDIR} is not writeable!${NN}" @@ -275,7 +279,7 @@ if [ -z "${BOTTOKEN}" ]; then # check data dir file if [ ! -w "${DATADIR}" ]; then printf "${RED}ERROR: ${DATADIR} does not exist or is not writeable!.${NN}" - exit 2 + exit_source 2 fi # setup count file if [ ! -f "${COUNTFILE}.jssh" ]; then @@ -283,7 +287,7 @@ if [ -z "${BOTTOKEN}" ]; then elif [ ! -w "${COUNTFILE}.jssh" ]; then printf "${RED}ERROR: Can't write to ${COUNTFILE}!.${NN}" ls -l "${COUNTFILE}.jssh" - exit 2 + exit_source 2 fi # setup blocked file if [ ! -f "${BLOCKEDFILE}.jssh" ]; then @@ -312,7 +316,7 @@ if [ -z "${BOTTOKEN}" ]; then BOTTOKEN="$(getConfigKey "bottoken")" else printf "\n${RED}Error: Can't recover from missing bot token! Remove ${BOTCONFIG}.jssh and run${NC} bashbot.sh init\n" - exit 7 + exit_source 7 fi fi fi @@ -683,7 +687,7 @@ event_send() { # fallback version, full version is in bin/bashbot_init.in.sh # initialize bot environment, user and permissions bot_init() { - [ -n "${BASHBOT_HOME}" ] && cd "${BASHBOT_HOME}" || exit 1 + cd "${BASHBOT_HOME}" || printf "Can't change to BASHBOT_HOME" && exit_source 1 # load addons on startup printf "Initialize addons ...\n" for addons in "${ADDONDIR:-.}"/*.sh ; do From 91a143ab15a83bac8a7c86d85b8066147580db95 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 1 Feb 2021 10:18:42 +0100 Subject: [PATCH 91/99] bin: basshot_env: improve messages --- bashbot.sh | 2 +- bin/any_command.sh | 2 +- bin/bashbot_env.inc.sh | 13 +++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 6b8f43c..108add2 100755 --- a/bashbot.sh +++ b/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.40-dev-26-ge86c8dc +#### $$VERSION$$ v1.40-dev-27-gc4d100e ################################################################## # are we running in a terminal? diff --git a/bin/any_command.sh b/bin/any_command.sh index e9aa43c..fc75e87 100755 --- a/bin/any_command.sh +++ b/bin/any_command.sh @@ -21,7 +21,7 @@ USAGE='any_command.sh [-h|--help] [--force|--reference] bot_command args ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 30.01.2021 10:24 # -#### $$VERSION$$ v1.40-dev-17-g8034a5f +#### $$VERSION$$ v1.40-dev-27-gc4d100e #=============================================================================== #### diff --git a/bin/bashbot_env.inc.sh b/bin/bashbot_env.inc.sh index b4d1568..6455e17 100644 --- a/bin/bashbot_env.inc.sh +++ b/bin/bashbot_env.inc.sh @@ -13,7 +13,7 @@ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.12.2020 12:27 # -#### $$VERSION$$ v1.32-dev-6-g2832801 +#### $$VERSION$$ v1.40-dev-27-gc4d100e #=============================================================================== ############ @@ -32,20 +32,21 @@ BASHBOT_ETC="${BASHBOT_HOME}" ##### # if files are not readable, eviroment is wrong or bashbot is not initialized -# source bashbot +# check for bashbot if [ ! -r "${BASHBOT_HOME}/bashbot.sh" ]; then printf "%s\n" "Bashbot.sh not found in \"${BASHBOT_HOME}\"" exit 4 fi +dev=" Are we in dev or did you forget to run init?" # check for botconfig.jssh readable if [ ! -r "${BASHBOT_ETC}/botconfig.jssh" ]; then - printf "%s\n" "Bashbot config file in \"${BASHBOT_ETC}\" does not exist or is not readable." + printf "%s\n" "Bashbot config file in \"${BASHBOT_ETC}\" does not exist or is not readable. ${dev}" exit 3 fi # check for count.jssh readable if [ ! -r "${BASHBOT_VAR}/count.jssh" ]; then - printf "%s\n" "Bashbot count file in \"${BASHBOT_VAR}\" does not exist or is not readable. Did you run bashbot init?" + printf "%s\n" "Bashbot count file in \"${BASHBOT_VAR}\" does not exist or is not readable. ${dev}" exit 3 fi @@ -60,8 +61,8 @@ FILE_REGEX="${UPLOADDIR}/.*" # get and check ADMIN and NAME BOT_ADMIN="$(getConfigKey "botadmin")" BOT_NAME="$(getConfigKey "botname")" -[[ -z "${BOT_ADMIN}" || "${BOT_ADMIN}" == "?" ]] && printf "%s\n" "${ORANGE}Warning: Botadmin not set, did you forget to sent command${NC} /start" -[[ -z "${BOT_NAME}" ]] && printf "%s\n" "${ORANGE}Warning: Botname not set, did you ever run bashbot?" +[[ -z "${BOT_ADMIN}" || "${BOT_ADMIN}" == "?" ]] && printf "%s\n" "${ORANGE}Warning: Botadmin not set, send bot command${NC} /start" +[[ -z "${BOT_NAME}" ]] && printf "%s\n" "${ORANGE}Warning: Botname not set, run bashbot.sh botname" # output command result or Telegram response print_result() { jssh_printDB "BOTSENT" | sort -r; } From 737be16b3feb80b6e3a18edc3ff6c99954c5dd1e Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 1 Feb 2021 10:30:47 +0100 Subject: [PATCH 92/99] doc: NOT IMPLEMENTED modules: improve webbhok message --- examples/webhook/README.md | 4 +++- modules/processUpdates.sh | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/webhook/README.md b/examples/webhook/README.md index dbb62fe..6945816 100644 --- a/examples/webhook/README.md +++ b/examples/webhook/README.md @@ -46,6 +46,8 @@ Bashbot on every update, it's more responsive and create less server load for a #### High traffic processing +#### CURRENTLY NOT IMPLEMENTED + High traffic processing writes Telegram updates to the named pipe `data-bot-bash/webhook-fifo` and Bashbot poll them, this is much more efficient than polling Telegram server. @@ -72,5 +74,5 @@ To stop delivering of Telegram updates via webhook run `bin/any_command.sh delet **Important**: Only https connections with a valid certificate chain are allowed as endpoint for webhook. -#### $$VERSION$$ v1.40-dev-22-g6754273 +#### $$VERSION$$ v1.40-dev-28-g91a143a diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh index 71fe881..6890227 100644 --- a/modules/processUpdates.sh +++ b/modules/processUpdates.sh @@ -4,7 +4,7 @@ # File: processUpdates.sh # Note: DO NOT EDIT! this file will be overwritten on update # -#### $$VERSION$$ v1.40-dev-23-g4e7b305 +#### $$VERSION$$ v1.40-dev-28-g91a143a ################################################################## ############## @@ -352,7 +352,7 @@ get_updates(){ if grep -q '^\["error_code"\] 409' <<<"${UPDATE}"; then [ "${OFFSET}" != "-999" ] && nextsleep="${stepsleep}" OFFSET="-999"; errsleep="$(_round_float "$(( errsleep= 300*nextsleep ))e-3")" - log_error "Warning conflicting webhook set, can't get updates until delete_webhook! Sleep $((errsleep/60)) min ..." + log_error "Warning conflicting webhook set, can't get updates until your run delete_webhook! Sleep $((errsleep/60)) min ..." sleep "${errsleep}" continue fi From 3a29a9dc4a44540f831b2d1166209a02944362b0 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 1 Feb 2021 12:58:57 +0100 Subject: [PATCH 93/99] doc: xlink webhook example --- README.html | 3 ++- README.md | 5 +++-- README.txt | 3 ++- bashbot.sh | 4 ++-- doc/6_reference.md | 6 +++--- examples/webhook/README.md | 16 +++++++++------- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/README.html b/README.html index 7c61d88..66faa5c 100644 --- a/README.html +++ b/README.html @@ -284,7 +284,8 @@ Written by Drew (@topkecleon) and Kay M (@gnadelwartz).
  • Setup your environment
  • Bashbot test suite
  • -
    +
  • Examples Directory
  • +
  • Webhook Example
  • Your very first bashbot in a nutshell

    To install and run bashbot you need access to a Linux/Unix command line with bash, a Telegram client and a mobile phone with a Telegram account.

    diff --git a/README.md b/README.md index 0304e4e..c530ef2 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,8 @@ Bashbot [Documentation](https://github.com/topkecleon/telegram-bot-bash) and [Do * Modules, addons, events * Setup your environment * Bashbot test suite -* [Examples Directory](examples/README.md) +* [Examples Directory](examples) +* [Webhook Example](examples/webhook) ### Your very first bashbot in a nutshell @@ -238,4 +239,4 @@ See `mycommnds.sh.dist` for an example. If you feel that there's something missing or if you found a bug, feel free to submit a pull request! -#### $$VERSION$$ v1.32-dev-9-g13052f0 +#### $$VERSION$$ v1.40-dev-29-g737be16 diff --git a/README.txt b/README.txt index 68709b3..0a5498b 100644 --- a/README.txt +++ b/README.txt @@ -112,7 +112,8 @@ Documentation o Setup your environment o Bashbot test suite -* Examples Directory [examples/README.md] +* Examples Directory [examples] +* Webhook Example [examples/webhook] Your very first bashbot in a nutshell diff --git a/bashbot.sh b/bashbot.sh index 108add2..1171b9d 100755 --- a/bashbot.sh +++ b/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.40-dev-27-gc4d100e +#### $$VERSION$$ v1.40-dev-29-g737be16 ################################################################## # are we running in a terminal? @@ -688,7 +688,7 @@ event_send() { # initialize bot environment, user and permissions bot_init() { cd "${BASHBOT_HOME}" || printf "Can't change to BASHBOT_HOME" && exit_source 1 - # load addons on startup + # initialize addons printf "Initialize addons ...\n" for addons in "${ADDONDIR:-.}"/*.sh ; do # shellcheck source=./modules/aliases.sh diff --git a/doc/6_reference.md b/doc/6_reference.md index 52edbf0..ee10b5d 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -1227,8 +1227,8 @@ https://linuxconfig.org/how-to-use-arrays-in-bash-script ### Manage webhook Bashbot default mode is to poll Telegram server for updates but Telegram offers also webhook as a more efficient method to deliver updates. -*Important*: Before using webhook you must setup your server to receive and process updates from Telegram! -I recommend to use webhook with a test bot first. [Webhook examples](../examples/webhook) +*Important*: Before enable webhook you must setup your server to [receive and process webhook updates from Telegram](../examples/webhook) +I recommend to use webhook with a test bot first. ##### get_webhook_info `get_webhook_info` get current status of webhook for your bot, e.g. url, waiting updates, last error. @@ -1578,5 +1578,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v1.40-dev-17-g8034a5f +#### $$VERSION$$ v1.40-dev-29-g737be16 diff --git a/examples/webhook/README.md b/examples/webhook/README.md index 6945816..badbdce 100644 --- a/examples/webhook/README.md +++ b/examples/webhook/README.md @@ -33,15 +33,17 @@ Now your Apache is ready to forward data to Bashbot. #### Simple update processing -To configure simple update processing delete file `data-bot-bash/webhook-fifo` after your webhook is working. -Every webhook call now forwards incoming Telegram updates to the named pipe `data-bot-bash/webhook-fifo` +To configure `Simple update processing` delete the file `data-bot-bash/webhook-fifo` after your webhook is working. +All webhook calls are now forwarded to `bin/process_update.sh` for processing. -Now enable webhook on Telegram (_see below_). +To start `Simple processing ` enable webhook on Telegram (_see below_). Every incoming Telegram update load Bashbot once for processing one command. Even it seems overkill to load -Bashbot on every update, it's more responsive and create less server load for a low traffic bot. +Bashbot on every incoming update, it's more responsive and create less server load for low traffic bots. -*Note:* You must NOT start bashbot when simple update processing is enabled. +If your bot uses `addons` or `BASHBOT_EVENTs` you can't use `Simple processing`. + +*Note:* `Simple processing` works without running `bashbot.sh start`. #### High traffic processing @@ -51,7 +53,7 @@ Bashbot on every update, it's more responsive and create less server load for a High traffic processing writes Telegram updates to the named pipe `data-bot-bash/webhook-fifo` and Bashbot poll them, this is much more efficient than polling Telegram server. -To switch from `Simple processing` to `High traffic processing` start bashbot as `bashbot.sh start-hook`. +To switch from `Simple processing` to `High traffic processing` start bashbot as `bashbot.sh start-webhook`. Stop bashbot with `bashbot.sh stop` to switch back to `Simple processing` @@ -74,5 +76,5 @@ To stop delivering of Telegram updates via webhook run `bin/any_command.sh delet **Important**: Only https connections with a valid certificate chain are allowed as endpoint for webhook. -#### $$VERSION$$ v1.40-dev-28-g91a143a +#### $$VERSION$$ v1.40-dev-29-g737be16 From 9ce139a689e0dec28736ea0459e19a1d4a4fec89 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 1 Feb 2021 16:30:04 +0100 Subject: [PATCH 94/99] bin: bashbot_env: set ME --- README.html | 2 +- README.txt | 2 +- bin/bashbot_env.inc.sh | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.html b/README.html index 66faa5c..dd5d2b8 100644 --- a/README.html +++ b/README.html @@ -391,6 +391,6 @@ It features background tasks and interactive chats, and can serve as an interfac

    @Gnadelwartz

    That's it all guys!

    If you feel that there's something missing or if you found a bug, feel free to submit a pull request!

    -

    $$VERSION$$ v1.32-dev-9-g13052f0

    +

    $$VERSION$$ v1.40-dev-29-g737be16

    diff --git a/README.txt b/README.txt index 0a5498b..ee6d2c2 100644 --- a/README.txt +++ b/README.txt @@ -315,5 +315,5 @@ That's it all guys! If you feel that there's something missing or if you found a bug, feel free to submit a pull request! -$$VERSION$$ v1.32-dev-9-g13052f0 +$$VERSION$$ v1.40-dev-29-g737be16 diff --git a/bin/bashbot_env.inc.sh b/bin/bashbot_env.inc.sh index 6455e17..5abb95b 100644 --- a/bin/bashbot_env.inc.sh +++ b/bin/bashbot_env.inc.sh @@ -13,12 +13,12 @@ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.12.2020 12:27 # -#### $$VERSION$$ v1.40-dev-27-gc4d100e +#### $$VERSION$$ v1.40-dev-30-g3a29a9d #=============================================================================== ############ # set where your bashbot lives -export BASHBOT_HOME BASHBOT_ETC BASHBOT_VAR FILE_REGEX +export BASHBOT_HOME BASHBOT_ETC BASHBOT_VAR FILE_REGEX ME # default: one dir up BASHBOT_HOME="$(cd "${BASH_SOURCE[0]%/*}" >/dev/null 2>&1 && pwd)/../" @@ -61,6 +61,7 @@ FILE_REGEX="${UPLOADDIR}/.*" # get and check ADMIN and NAME BOT_ADMIN="$(getConfigKey "botadmin")" BOT_NAME="$(getConfigKey "botname")" +ME="${BOT_NAME}" [[ -z "${BOT_ADMIN}" || "${BOT_ADMIN}" == "?" ]] && printf "%s\n" "${ORANGE}Warning: Botadmin not set, send bot command${NC} /start" [[ -z "${BOT_NAME}" ]] && printf "%s\n" "${ORANGE}Warning: Botname not set, run bashbot.sh botname" From d876f758ee13b0b9a79c81da7982a272026acfcb Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 1 Feb 2021 18:30:34 +0100 Subject: [PATCH 95/99] no debug_checks on source --- bashbot.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 1171b9d..22dac24 100755 --- a/bashbot.sh +++ b/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.40-dev-29-g737be16 +#### $$VERSION$$ v1.40-dev-31-g9ce139a ################################################################## # are we running in a terminal? @@ -372,7 +372,8 @@ if [ -r "${COMMANDS}" ]; then else [ -z "${SOURCE}" ] && printf "${RED}Warning: ${COMMANDS} does not exist or is not readable!.${NN}" fi -debug_checks "start SOURCE=${SOURCE:-no}" "$@" +# no debug checks on source +[ -z "${SOURCE}" ] && debug_checks "start" "$@" ##################### From 969c7a9fbbd18b07b5852f3a24be5487b4bc7223 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Mon, 1 Feb 2021 19:37:24 +0100 Subject: [PATCH 96/99] webhook: fix some glitches --- bashbot.sh | 7 +++++-- bin/bashbot_init.inc.sh | 7 +++++-- bin/process_update.sh | 4 ++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/bashbot.sh b/bashbot.sh index 22dac24..1a95930 100755 --- a/bashbot.sh +++ b/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.40-dev-31-g9ce139a +#### $$VERSION$$ v1.40-dev-32-gd876f75 ################################################################## # are we running in a terminal? @@ -688,7 +688,10 @@ event_send() { # fallback version, full version is in bin/bashbot_init.in.sh # initialize bot environment, user and permissions bot_init() { - cd "${BASHBOT_HOME}" || printf "Can't change to BASHBOT_HOME" && exit_source 1 + if [ -n "${BASHBOT_HOME}" ] && ! cd "${BASHBOT_HOME}"; then + printf "Can't change to BASHBOT_HOME" + exit 1 + fi # initialize addons printf "Initialize addons ...\n" for addons in "${ADDONDIR:-.}"/*.sh ; do diff --git a/bin/bashbot_init.inc.sh b/bin/bashbot_init.inc.sh index c0a3f39..3a16f39 100644 --- a/bin/bashbot_init.inc.sh +++ b/bin/bashbot_init.inc.sh @@ -11,7 +11,7 @@ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 27.01.2021 13:42 # -#### $$VERSION$$ v1.35-dev-29-g0c0dc01 +#### $$VERSION$$ v1.40-dev-32-gd876f75 #=============================================================================== # shellcheck disable=SC2059 @@ -38,7 +38,10 @@ my_init() { # # delete from here to disable extended initialisation bot_init() { - [ -n "${BASHBOT_HOME}" ] && cd "${BASHBOT_HOME}" || exit 1 + if [ -n "${BASHBOT_HOME}" ] && ! cd "${BASHBOT_HOME}"; then + printf "Can't change to BASHBOT_HOME" + exit 1 + fi local runuser chown touser botname DEBUG="$1" # upgrade from old version # currently no action diff --git a/bin/process_update.sh b/bin/process_update.sh index 34385fb..27bb3a4 100755 --- a/bin/process_update.sh +++ b/bin/process_update.sh @@ -15,7 +15,7 @@ USAGE='process_update.sh [-h|--help] [debug] [/dev/null)" # assign to bashbot ARRAY From 1440d56f482670877c555847f83f84d6f61eba68 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 2 Feb 2021 09:18:25 +0100 Subject: [PATCH 97/99] modules: better shorten URLS[*] --- dev/make-distribution.sh.exclude | 1 + modules/processUpdates.sh | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dev/make-distribution.sh.exclude b/dev/make-distribution.sh.exclude index d005839..c03a2d7 100644 --- a/dev/make-distribution.sh.exclude +++ b/dev/make-distribution.sh.exclude @@ -1,4 +1,5 @@ data-bot-bash/* +webhook-fifo JSON.awk bashbot.rc mycommands.sh diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh index 6890227..5e93952 100644 --- a/modules/processUpdates.sh +++ b/modules/processUpdates.sh @@ -4,7 +4,7 @@ # File: processUpdates.sh # Note: DO NOT EDIT! this file will be overwritten on update # -#### $$VERSION$$ v1.40-dev-28-g91a143a +#### $$VERSION$$ v1.40-dev-33-g969c7a9 ################################################################## ############## @@ -82,7 +82,7 @@ process_update() { 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}" + "${MESSAGE:0:30}${CAPTION:0:30}$(: "${URL[*]/bot*:}"; printf "%s" "${_//[A-Z-]}")" >>"${UPDATELOG}" fi ##### # process inline and message events From f9dab50f84f5b4197757723a4f466cbc21341061 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Tue, 2 Feb 2021 20:33:22 +0100 Subject: [PATCH 98/99] small updates and fixes for 1.40 --- README.html | 13 +++++++------ README.md | 14 ++++++++------ README.txt | 19 +++++++++++-------- bashbot.sh | 16 ++++++++-------- commands.sh | 6 +++--- doc/0_install.md | 2 +- doc/2_usage.md | 14 +++++++------- doc/3_advanced.md | 12 ++++++------ doc/4_expert.md | 2 +- doc/5_practice.md | 4 ++-- modules/processUpdates.sh | 4 ++-- 11 files changed, 56 insertions(+), 50 deletions(-) diff --git a/README.html b/README.html index dd5d2b8..a51e2cb 100644 --- a/README.html +++ b/README.html @@ -341,7 +341,7 @@ It features background tasks and interactive chats, and can serve as an interfac

    Running a Telegram Bot means it is connected to the public and you never know what's send to your Bot.

    Bash scripts in general are not designed to be bulletproof, so consider this Bot as a proof of concept. Bash programmers often struggle with 'quoting hell' and globbing, see Implications of wrong quoting.

    Whenever you are processing input from untrusted sources (messages, files, network) you must be as careful as possible (e.g. set IFS appropriately, disable globbing with set -f and quote everything). In addition remove unused scripts and examples from your Bot (e.g. everything in example/) and disable/remove all unused bot commands.

    -

    It's important to escape or remove $ in input from user, files or network (as bashbot does). One of the powerful features of Unix shells is variable and command substitution using ${} and$() can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped $ is included in untrusted input (e.g. $$ or $(rm -rf /*)).

    +

    It's important to escape or remove $ in input from user, files or network (as bashbot does). One of the powerful features of Unix shells is variable and command substitution using ${} and $() can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped $ is included in untrusted input (e.g. $$ or $(rm -rf /*)).

    A powerful tool to improve your scripts is shellcheck. You can use it online or install shellcheck locally. Shellcheck is used extensively in bashbot development to ensure a high code quality (e.g. it's not allowed to push changes without passing all shellcheck tests). In addition bashbot has a test suite to check if important functionality is working as expected.

    Use printf whenever possible

    If you're writing a script that accepts external input (e.g. from the user as arguments or the file system), you shouldn't use echo to display it. Use printf whenever possible.

    @@ -350,8 +350,9 @@ It features background tasks and interactive chats, and can serve as an interfac

    Never run your Bot as root, this is the most dangerous you can do! Usually the user 'nobody' has almost no rights on Linux/Unix systems. See Expert use on how to run your Bot as an other user.

    Secure your Bot installation

    Your Bot configuration must not be readable by other users. Everyone who can read your Bots token is able to act as your Bot and has access to all chats the Bot is in!

    -

    Everyone with read access to your Bot files can extract your Bots data. Especially your Bot config inconfig.jssh must be protected against other users. No one except you should have write access to the Bot files. The Bot should be restricted to have write access tocount.jssh and data-bot-bash only, all other files must be write protected.

    -

    To set access rights for your bashbot installation to a reasonable default runsudo ./bashbot.sh init after every update or change to your installation directory.

    +

    Everyone with read access to your Bot files can extract your Bots data. Especially your Bot config in config.jssh must be protected against other users. No one except you should have write access to the Bot files. The Bot should be restricted to have write access to count.jssh, data-bot-bash/ and logs/ only, all other files must be write protected.

    +

    To set access rights for your bashbot installation to a reasonable default run sudo ./bashbot.sh init after every update or change to your installation directory.

    +

    Note: Keep old log files in a safe place or even better delete them, they are GDPR relevant and may contain information you don't want to be public.

    FAQ

    Is this Bot insecure?

    Bashbot is not more (in)secure than a Bot written in another language. We have done our best to make it as secure as possible. But YOU are responsible for the bot commands you wrote and you should know about the risks ...

    @@ -365,8 +366,8 @@ It features background tasks and interactive chats, and can serve as an interfac
  • no database, not event driven, not object oriented ...
  • Can I have the single bashbot.sh file back?

    -

    At the beginning bashbot was simply the filebashbot.sh that you could copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more.

    -

    Hey no problem, if you are finished with your cool bot, rundev/make-standalone.sh to create a stripped down version of your bot containing only 'bashbot.sh' and 'commands.sh'! For more information see Create a stripped down version of your Bot.

    +

    At the beginning bashbot was simply the file bashbot.sh that you could copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more.

    +

    Hey no problem, if you are finished with your cool bot, run dev/make-standalone.sh to create a stripped down version of your bot containing only 'bashbot.sh' and 'commands.sh'! For more information see Create a stripped down version of your Bot.

    Can I send messages from CLI and scripts?

    Of course you can send messages from command line and scripts! Simply install bashbot as described here, send the message '/start' to set yourself as botadmin and then stop the bot with ./bashbot.sh stop.

    Bashbot provides some ready to use scripts for sending messages from command line in bin/ dir, e.g. send_message.sh.

    @@ -391,6 +392,6 @@ It features background tasks and interactive chats, and can serve as an interfac

    @Gnadelwartz

    That's it all guys!

    If you feel that there's something missing or if you found a bug, feel free to submit a pull request!

    -

    $$VERSION$$ v1.40-dev-29-g737be16

    +

    $$VERSION$$ v1.40-dev-34-g1440d56

    diff --git a/README.md b/README.md index c530ef2..bc4428a 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,7 @@ Whenever you are processing input from untrusted sources (messages, files, netwo from your Bot (e.g. everything in `example/`) and disable/remove all unused bot commands. It's important to escape or remove `$` in input from user, files or network (_as bashbot does_). -One of the powerful features of Unix shells is variable and command substitution using `${}` and`$()` can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped `$` is included in untrusted input (e.g. `$$` or `$(rm -rf /*)`). +One of the powerful features of Unix shells is variable and command substitution using `${}` and `$()` can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped `$` is included in untrusted input (e.g. `$$` or `$(rm -rf /*)`). A powerful tool to improve your scripts is `shellcheck`. You can [use it online](https://www.shellcheck.net/) or [install shellcheck locally](https://github.com/koalaman/shellcheck#installing). Shellcheck is used extensively in bashbot development @@ -169,9 +169,11 @@ For the same reason every file your Bot can read is in danger of being disclosed ### Secure your Bot installation **Your Bot configuration must not be readable by other users.** Everyone who can read your Bots token is able to act as your Bot and has access to all chats the Bot is in! -Everyone with read access to your Bot files can extract your Bots data. Especially your Bot config in`config.jssh` must be protected against other users. No one except you should have write access to the Bot files. The Bot should be restricted to have write access to`count.jssh` and `data-bot-bash` only, all other files must be write protected. +Everyone with read access to your Bot files can extract your Bots data. Especially your Bot config in `config.jssh` must be protected against other users. No one except you should have write access to the Bot files. The Bot should be restricted to have write access to `count.jssh`, `data-bot-bash/` and `logs/` only, all other files must be write protected. -To set access rights for your bashbot installation to a reasonable default run`sudo ./bashbot.sh init` after every update or change to your installation directory. +To set access rights for your bashbot installation to a reasonable default run `sudo ./bashbot.sh init` after every update or change to your installation directory. + +*Note*: Keep old log files in a safe place or even better delete them, they are GDPR relevant and [may contain information](https://github.com/topkecleon/telegram-bot-bash/issues/174) you don't want to be public. ## FAQ @@ -189,9 +191,9 @@ Well, that's a damn good question... maybe because I'm a Unix admin from the sto - no database, not event driven, not object oriented ... ### Can I have the single bashbot.sh file back? -At the beginning bashbot was simply the file`bashbot.sh` that you could copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more. +At the beginning bashbot was simply the file `bashbot.sh` that you could copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more. -Hey no problem, if you are finished with your cool bot, run`dev/make-standalone.sh` to create a stripped down version of your bot containing only +Hey no problem, if you are finished with your cool bot, run `dev/make-standalone.sh` to create a stripped down version of your bot containing only 'bashbot.sh' and 'commands.sh'! For more information see [Create a stripped down version of your Bot](doc/7_develop.md). ### Can I send messages from CLI and scripts? @@ -239,4 +241,4 @@ See `mycommnds.sh.dist` for an example. If you feel that there's something missing or if you found a bug, feel free to submit a pull request! -#### $$VERSION$$ v1.40-dev-29-g737be16 +#### $$VERSION$$ v1.40-dev-34-g1440d56 diff --git a/README.txt b/README.txt index ee6d2c2..9d6fbcb 100644 --- a/README.txt +++ b/README.txt @@ -202,7 +202,7 @@ f and quote everything). In addition remove unused scripts and examples from you (e.g. everything in example/) and disable/remove all unused bot commands. It's important to escape or remove $ in input from user, files or network (as bashbot does). One of the powerful features of Unix shells is variable and command substitution -using ${} and$() can lead to remote code execution (RCE) or remote information disclosure +using ${} and $() can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped $ is included in untrusted input (e.g. $$ or $(rm -rf /*)). A powerful tool to improve your scripts is shellcheck. You can use it online [https:// www.shellcheck.net/] or install shellcheck locally [https://github.com/koalaman/ @@ -232,11 +232,14 @@ Secure your Bot installation Your Bot configuration must not be readable by other users. Everyone who can read your Bots token is able to act as your Bot and has access to all chats the Bot is in! Everyone with read access to your Bot files can extract your Bots data. Especially your -Bot config inconfig.jssh must be protected against other users. No one except you should -have write access to the Bot files. The Bot should be restricted to have write access -tocount.jssh and data-bot-bash only, all other files must be write protected. -To set access rights for your bashbot installation to a reasonable default runsudo ./ +Bot config in config.jssh must be protected against other users. No one except you should +have write access to the Bot files. The Bot should be restricted to have write access to +count.jssh, data-bot-bash/ and logs/ only, all other files must be write protected. +To set access rights for your bashbot installation to a reasonable default run sudo ./ bashbot.sh init after every update or change to your installation directory. +Note: Keep old log files in a safe place or even better delete them, they are GDPR +relevant and may contain information [https://github.com/topkecleon/telegram-bot-bash/ +issues/174] you don't want to be public. FAQ @@ -264,9 +267,9 @@ Nevertheless there are more reasons from my side: Can I have the single bashbot.sh file back? -At the beginning bashbot was simply the filebashbot.sh that you could copy everywhere and +At the beginning bashbot was simply the file bashbot.sh that you could copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more. -Hey no problem, if you are finished with your cool bot, rundev/make-standalone.sh to +Hey no problem, if you are finished with your cool bot, run dev/make-standalone.sh to create a stripped down version of your bot containing only 'bashbot.sh' and 'commands.sh'! For more information see Create a stripped down version of your Bot [doc/7_develop.md]. @@ -315,5 +318,5 @@ That's it all guys! If you feel that there's something missing or if you found a bug, feel free to submit a pull request! -$$VERSION$$ v1.40-dev-29-g737be16 +$$VERSION$$ v1.40-dev-34-g1440d56 diff --git a/bashbot.sh b/bashbot.sh index 1a95930..4523901 100755 --- a/bashbot.sh +++ b/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.40-dev-32-gd876f75 +#### $$VERSION$$ v1.40-dev-34-g1440d56 ################################################################## # are we running in a terminal? @@ -390,13 +390,13 @@ fi # $1 URL, $2 filename in DATADIR # outputs final filename -#download() { -# local empty="no.file" file="${2:-${empty}}" -# if [[ "${file}" = *"/"* ]] || [[ "${file}" = "."* ]]; then file="${empty}"; fi -# while [ -f "${DATADIR:-.}/${file}" ] ; do file="${RANDOM}-${file}"; done -# getJson "$1" >"${DATADIR:-.}/${file}" || return -# printf '%s\n' "${DATADIR:-.}/${file}" -#} +download() { + local empty="no.file" file="${2:-${empty}}" + if [[ "${file}" = *"/"* ]] || [[ "${file}" = "."* ]]; then file="${empty}"; fi + while [ -f "${DATADIR:-.}/${file}" ] ; do file="${RANDOM}-${file}"; done + getJson "$1" >"${DATADIR:-.}/${file}" || return + printf '%s\n' "${DATADIR:-.}/${file}" +} # $1 postfix, e.g. chatid # $2 prefix, back- or startbot- diff --git a/commands.sh b/commands.sh index f2db8a5..d105123 100644 --- a/commands.sh +++ b/commands.sh @@ -8,14 +8,14 @@ # | |__/ / |_| | | | | | |_| | |__ | |____( (_| | | |__ _ # |_____/ \___/ |_| |_|\___/ \___) |_______)____|_|\___)_| # -# this file *MUST* not be edited! place your config and commands in -# the file "mycommands.sh". a clean version is provided as "mycommands.sh.clean" +# this file *MUST* not edited! place your config in the file "mycommands.conf" +# and commands in "mycommands.sh", a clean version is provided as "mycommands.sh.clean" # # This file is public domain in the USA and all free countries. # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # -#### $$VERSION$$ v1.35-dev-14-g08a0524 +#### $$VERSION$$ v1.40-dev-34-g1440d56 # # bashbot locale defaults to c.UTF-8, adjust locale in mycommands.sh if needed diff --git a/doc/0_install.md b/doc/0_install.md index 199e604..035b37d 100644 --- a/doc/0_install.md +++ b/doc/0_install.md @@ -132,5 +132,5 @@ You must update to [Version 1.20](https://github.com/topkecleon/telegram-bot-bas #### [Next Create Bot](1_firstbot.md) -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-dev-34-g1440d56 diff --git a/doc/2_usage.md b/doc/2_usage.md index 767d6d3..bbef2e7 100644 --- a/doc/2_usage.md +++ b/doc/2_usage.md @@ -295,7 +295,7 @@ In case you need other response values , the array `UPD` contains complete Teleg ## Usage of bashbot functions #### sending messages -To send messages use the `send_xxx_message`functions. +To send messages use the `send_xxx_message` functions. To insert line brakes in a message place `\n` in the text. To send regular text without any markdown use: @@ -311,7 +311,7 @@ To send text with html: send_html_message "${CHAT[ID]}" "lol bold" ``` -To forward messages use the `forward`function: +To forward messages use the `forward` function: ```bash forward "${CHAT[ID]}" "from_chat_id" "message_id" ``` @@ -349,20 +349,20 @@ To send local files or URL's (photo, video, voice, sticker, documents) use the ` send_file "${CHAT[ID]}" "/home/user/dog.jpg" "Lool" "photo" send_file "${CHAT[ID]}" "https://images-na.ssl-images-amazon.com/images/I/81DQ0FpoSNL._AC_SL1500_.jpg" ``` -To send custom keyboards use the `send_keyboard`function: +To send custom keyboards use the `send_keyboard` function: ```bash send_keyboard "${CHAT[ID]}" "Text that will appear in chat?" '[ "Yep" , "No" ]' # note the single quotes! send_keyboard "${CHAT[ID]}" "Text that will appear in chat?" "[ \\"Yep\\" , \\"No\\" ]" # within double quotes you must escape the inside double quots ``` -To send locations use the `send_location`function: +To send locations use the `send_location` function: ```bash send_location "${CHAT[ID]}" "Latitude" "Longitude" ``` -To send venues use the `send_venue`function: +To send venues use the `send_venue` function: ```bash send_venue "${CHAT[ID]}" "Latitude" "Longitude" "Title" "Address" "optional foursquare id" ``` -To send a chat action use the `send_action`function. +To send a chat action use the `send_action` function. Allowed values: typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for locations. ```bash send_action "${CHAT[ID]}" "action" @@ -372,5 +372,5 @@ send_action "${CHAT[ID]}" "action" #### [Prev Create Bot](1_firstbot.md) #### [Next Advanced Usage](3_advanced.md) -#### $$VERSION$$ v1.35-dev-31-ga3eec98 +#### $$VERSION$$ v1.40-dev-34-g1440d56 diff --git a/doc/3_advanced.md b/doc/3_advanced.md index 8ba9cf4..0800be2 100644 --- a/doc/3_advanced.md +++ b/doc/3_advanced.md @@ -144,7 +144,7 @@ echo "Text that will appear in one message \nwith this text on a new line" ``` In case you want extend a message already containing a location, a file, a keyboard etc., -with an additionial text simply add ` mytextstartshere additional text`at the end of the string: +with an additionial text simply add ` mytextstartshere additional text` at the end of the string: ```bash out="Text that will appear mylatstartshere 45 mylongstartshere 45" [[ "$out" != *'in chat'* ]] && out="$out mytextstartshere in chat." @@ -190,7 +190,7 @@ Note: Background jobs run independent from main bot and continue running until y In order to enable **inline mode**, send `/setinline` command to [@BotFather](https://telegram.me/botfather) and provide the placeholder text that the user will see in the input field after typing your bot’s name. -The following commands allows you to send ansers to *inline queries*. To enable bashbot to process inline queries set `INLINE="1"`in 'mycommands.sh'. +The following commands allows you to send ansers to *inline queries*. To enable bashbot to process inline queries set `INLINE="1"` in `mycommands.sh`. To send messages or links through an *inline query*: ```bash @@ -258,7 +258,7 @@ By default you don't have to care about retry, as bashbot resend the message aft Only if the retry fails also an error is returned. The downside is that send_message functions will wait until resend is done. If you want to disable automatic error processing and handle all errors manually (or don't care) -set `BASHBOT_RETRY`to any no zero value. +set `BASHBOT_RETRY` to any no zero value. [Telegram Bot API error codes](https://github.com/TelegramBotAPI/errors) @@ -266,9 +266,9 @@ set `BASHBOT_RETRY`to any no zero value. #### Detect bot blocked If the we can't connect to telegram, e.g. blocked from telegram server but also any other reason, -bashbot set `BOTSENT[ERROR]`to `999`. +bashbot set `BOTSENT[ERROR]` to `999`. -To get a notification on every connection problem create a function named `bashbotBlockRecover`and handle blocks there. +To get a notification on every connection problem create a function named `bashbotBlockRecover` and handle blocks there. If the function returns true (0 or no value) bashbot will retry once and then return to the calling function. In case you return any non 0 value bashbot will return to the calling function without retry. @@ -302,5 +302,5 @@ Note: If you disable automatic retry, se above, you disable also connection prob #### [Prev Getting started](2_usage.md) #### [Next Expert Use](4_expert.md) -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-dev-34-g1440d56 diff --git a/doc/4_expert.md b/doc/4_expert.md index f15d390..e2ef6a1 100644 --- a/doc/4_expert.md +++ b/doc/4_expert.md @@ -434,5 +434,5 @@ for every poll until the maximum of BASHBOT_SLEEP ms. #### [Prev Advanced Use](3_advanced.md) #### [Next Best Practice](5_practice.md) -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-dev-34-g1440d56 diff --git a/doc/5_practice.md b/doc/5_practice.md index 85e9f1c..ca7448d 100644 --- a/doc/5_practice.md +++ b/doc/5_practice.md @@ -12,7 +12,7 @@ If you don't have a github account, it may time to [setup a free account now](ht ### Add commands to mycommands.sh only Do not change `bashbot.sh` and `commands.sh`, instead place your commands in to `mycommands.sh`. To start with a clean/minimal bot copy `mycommands.sh.clean` to `mycommands.sh` and start editing -the message strings and place commands in the`case ... esac` block of the function mycommands(): +the message strings and place commands in the` case ... esac` block of the function mycommands(): ```bash # file: mycommands.sh # your additional bashbot commands @@ -160,5 +160,5 @@ The second warning is about an unused variable, this is true because in our exam #### [Prev Best Practice](5_practice.md) #### [Next Functions Reference](6_reference.md) -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-dev-34-g1440d56 diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh index 5e93952..adb07e1 100644 --- a/modules/processUpdates.sh +++ b/modules/processUpdates.sh @@ -4,7 +4,7 @@ # File: processUpdates.sh # Note: DO NOT EDIT! this file will be overwritten on update # -#### $$VERSION$$ v1.40-dev-33-g969c7a9 +#### $$VERSION$$ v1.40-dev-34-g1440d56 ################################################################## ############## @@ -82,7 +82,7 @@ process_update() { 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}$(: "${URL[*]/bot*:}"; printf "%s" "${_//[A-Z-]}")" >>"${UPDATELOG}" + "${MESSAGE:0:30}${CAPTION:0:30}$(: "${URLS[*]//bot*:}"; printf "%s" "${_//[A-Z-]}")" >>"${UPDATELOG}" fi ##### # process inline and message events From 6fe19556b75d65d217162c929d28f260d5c66171 Mon Sep 17 00:00:00 2001 From: "Kay Marquardt (Gnadelwartz)" Date: Thu, 4 Feb 2021 18:13:32 +0100 Subject: [PATCH 99/99] Bashbot Version 1.40 --- README.md | 2 +- addons/antiFlood.sh | 2 +- addons/example.sh | 2 +- bashbot.rc | 2 +- bashbot.sh | 5 +++-- bin/any_command.sh | 2 +- bin/bashbot_env.inc.sh | 2 +- bin/bashbot_init.inc.sh | 2 +- bin/bashbot_stats.sh | 2 +- bin/delete_message.sh | 2 +- bin/edit_buttons.sh | 2 +- bin/edit_message.sh | 2 +- bin/kickban_user.sh | 2 +- bin/process_update.sh | 2 +- bin/promote_user.sh | 2 +- bin/send_broadcast.sh | 2 +- bin/send_buttons.sh | 2 +- bin/send_file.sh | 2 +- bin/send_message.sh | 2 +- commands.sh | 2 +- dev/all-tests.sh | 2 +- dev/dev.inc.sh | 2 +- dev/git-add.sh | 2 +- dev/hooks/post-commit.sh | 2 +- dev/hooks/pre-commit.sh | 2 +- dev/hooks/pre-push.sh | 2 +- dev/inject-json.sh | 2 +- dev/install-hooks.sh | 2 +- dev/make-distribution.sh | 2 +- dev/make-html.sh | 2 +- dev/make-standalone.sh | 2 +- dev/obfuscate.sh | 2 +- dev/shellcheck.files | 2 +- dev/version.sh | 2 +- doc/0_install.md | 2 +- doc/1_firstbot.md | 2 +- doc/2_usage.md | 2 +- doc/3_advanced.md | 2 +- doc/4_expert.md | 2 +- doc/5_practice.md | 2 +- doc/6_reference.md | 2 +- doc/7_develop.md | 2 +- examples/README.md | 2 +- examples/background-scripts/run_diskusage.sh | 2 +- examples/background-scripts/run_filecontent.sh | 2 +- examples/background-scripts/run_filename.sh | 2 +- examples/background-scripts/run_notify.sh | 2 +- examples/bash2env.sh | 2 +- examples/bashbot-multi.sh | 2 +- examples/bashbot.cron | 2 +- examples/calc.sh | 2 +- examples/jsonDB-keyboard/mycommands.sh | 2 +- examples/notify.sh | 2 +- examples/question.sh | 2 +- examples/send-system-status/botacl | 2 +- examples/send-system-status/mycommands.sh | 2 +- examples/webhook/BASHBOT_HOME | 1 + examples/webhook/README.md | 2 +- examples/webhook/index.php | 2 +- modules/aliases.sh | 2 +- modules/answerInline.sh | 2 +- modules/background.sh | 8 ++++---- modules/chatMember.sh | 4 ++-- modules/jsonDB.sh | 2 +- modules/processUpdates.sh | 2 +- modules/sendMessage.sh | 2 +- mycommands.conf | 2 +- mycommands.sh | 2 +- mycommands.sh.clean | 2 +- scripts/interactive.sh.clean | 2 +- test/ADD-test-new.sh | 2 +- test/ALL-tests.inc.sh | 2 +- test/a-commit-test.sh | 2 +- test/b-example-test.sh | 2 +- test/c-init-test.sh | 2 +- test/d-JSON.sh-test.sh | 2 +- test/d-process_inline-test.sh | 2 +- test/d-process_message-test.sh | 2 +- test/d-send_message-test.sh | 2 +- test/d-user_is-test.sh | 2 +- test/e-env-test.sh | 2 +- 81 files changed, 87 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index bc4428a..f5e0789 100644 --- a/README.md +++ b/README.md @@ -241,4 +241,4 @@ See `mycommnds.sh.dist` for an example. If you feel that there's something missing or if you found a bug, feel free to submit a pull request! -#### $$VERSION$$ v1.40-dev-34-g1440d56 +#### $$VERSION$$ v1.40-0-gf9dab50 diff --git a/addons/antiFlood.sh b/addons/antiFlood.sh index b4012a3..1fd6ef8 100644 --- a/addons/antiFlood.sh +++ b/addons/antiFlood.sh @@ -4,7 +4,7 @@ # this addon counts how many files, e.g. stickers, are sent to # a chat and takes actions if threshold is reached # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 # used events: # diff --git a/addons/example.sh b/addons/example.sh index 87a8caf..15cd539 100644 --- a/addons/example.sh +++ b/addons/example.sh @@ -4,7 +4,7 @@ # Addons can register to bashbot events at startup # by providing their name and a callback per event # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 # # If an event occurs each registered event function is called. # diff --git a/bashbot.rc b/bashbot.rc index 9e51c8c..0ff801d 100755 --- a/bashbot.rc +++ b/bashbot.rc @@ -5,7 +5,7 @@ # # tested on: ubuntu, opensuse, debian # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 # shellcheck disable=SC2009 # shellcheck disable=SC2181 diff --git a/bashbot.sh b/bashbot.sh index 4523901..404fad6 100755 --- a/bashbot.sh +++ b/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.40-dev-34-g1440d56 +#### $$VERSION$$ v1.40-0-gf9dab50 ################################################################## # are we running in a terminal? @@ -460,7 +460,8 @@ sendJson(){ json='{'"${chat} $(iconv -f utf-8 -t utf-8 -c <<<"$2")"'}' if [ -n "${BASHBOTDEBUG}" ] ; then log_update "sendJson (${DETECTED_CURL}) CHAT=${chat#*:} JSON=${2:0:100} URL=${3##*/}" - log_message "DEBUG sendJson ==========\n$("${JSONSHFILE}" -b -n <<<"${json}" 2>&1)" + # mask " and \ , remove newline from json + log_message "DEBUG sendJson ==========\n$("${JSONSHFILE}" -b -n <<<"$(sed -E -e 's/\\"/+/g' -e 's/\\/\\\\/g' -e 's/(\r|\n)//g' <<<"${json}")" 2>&1)" fi # chat id not a number if [[ "${chat}" == *"NAN\"," ]]; then diff --git a/bin/any_command.sh b/bin/any_command.sh index fc75e87..fe8f3e7 100755 --- a/bin/any_command.sh +++ b/bin/any_command.sh @@ -21,7 +21,7 @@ USAGE='any_command.sh [-h|--help] [--force|--reference] bot_command args ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 30.01.2021 10:24 # -#### $$VERSION$$ v1.40-dev-27-gc4d100e +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== #### diff --git a/bin/bashbot_env.inc.sh b/bin/bashbot_env.inc.sh index 5abb95b..d935e64 100644 --- a/bin/bashbot_env.inc.sh +++ b/bin/bashbot_env.inc.sh @@ -13,7 +13,7 @@ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 18.12.2020 12:27 # -#### $$VERSION$$ v1.40-dev-30-g3a29a9d +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== ############ diff --git a/bin/bashbot_init.inc.sh b/bin/bashbot_init.inc.sh index 3a16f39..382b0ec 100644 --- a/bin/bashbot_init.inc.sh +++ b/bin/bashbot_init.inc.sh @@ -11,7 +11,7 @@ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 27.01.2021 13:42 # -#### $$VERSION$$ v1.40-dev-32-gd876f75 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # shellcheck disable=SC2059 diff --git a/bin/bashbot_stats.sh b/bin/bashbot_stats.sh index 4a80b14..df23119 100755 --- a/bin/bashbot_stats.sh +++ b/bin/bashbot_stats.sh @@ -17,7 +17,7 @@ USAGE='bashbot_stats.sh [-h|--help] [debug]' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 23.12.2020 20:34 # -#### $$VERSION$$ v1.32-dev-6-g2832801 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # set bashbot environment diff --git a/bin/delete_message.sh b/bin/delete_message.sh index 39ecbb1..8b26769 100755 --- a/bin/delete_message.sh +++ b/bin/delete_message.sh @@ -20,7 +20,7 @@ USAGE='delete_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" [debug]' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 03.01.2021 15:37 # -#### $$VERSION$$ v1.32-dev-6-g2832801 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== #### diff --git a/bin/edit_buttons.sh b/bin/edit_buttons.sh index a874d0c..0455d1c 100755 --- a/bin/edit_buttons.sh +++ b/bin/edit_buttons.sh @@ -26,7 +26,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" "text|url" ...' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 21.01.2021 08:10 # -#### $$VERSION$$ v1.35-dev-3-g461e748 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== #### diff --git a/bin/edit_message.sh b/bin/edit_message.sh index 04cb757..dd9b766 100755 --- a/bin/edit_message.sh +++ b/bin/edit_message.sh @@ -23,7 +23,7 @@ USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID] # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 23.12.2020 16:52 # -#### $$VERSION$$ v1.32-dev-6-g2832801 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== #### diff --git a/bin/kickban_user.sh b/bin/kickban_user.sh index c6acf8a..cb31df1 100755 --- a/bin/kickban_user.sh +++ b/bin/kickban_user.sh @@ -20,7 +20,7 @@ USAGE='kickban_user.sh [-h|--help] [-u|--unban] "CHAT[ID]" "USER[ID]" [debug]' # AUTHOR: KayM (gnadelwartz), kay@rrr.de # CREATED: 25.01.2021 20:34 # -#### $$VERSION$$ v1.35-dev-11-g6b102a7 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== #### diff --git a/bin/process_update.sh b/bin/process_update.sh index 27bb3a4..22b9898 100755 --- a/bin/process_update.sh +++ b/bin/process_update.sh @@ -15,7 +15,7 @@ USAGE='process_update.sh [-h|--help] [debug] [>"${fifo}.log" & sleep 0.5 # give bg job some time to init @@ -62,7 +62,7 @@ start_proc() { [ -z "$2" ] && return [ -x "${2%% *}" ] || return 1 local fifo; fifo="${DATADIR:-.}/$(procname "$1")" - log_message "Start interactive script CHAT=$1 JOB=${fifo##*/} CMD=$2 $3 $4" + log_update "Start interactive script CHAT=$1 JOB=${fifo##*/} CMD=$2 $3 $4" check_proc "$1" && kill_proc "$1" mkfifo "${fifo}" nohup bash -c "{ $2 \"$4\" \"$5\" \"${fifo}\" | \"${SCRIPT}\" outproc \"$1\" \"${fifo}\" @@ -99,7 +99,7 @@ kill_proc() { fifo="$(procname "$1" "$2")" prid="$(proclist "${fifo}")" fifo="${DATADIR:-.}/${fifo}" - log_message "Stop interactive / background CHAT=$1 JOB=${fifo##*/}" + log_update "Stop interactive / background CHAT=$1 JOB=${fifo##*/}" # shellcheck disable=SC2086 [ -n "${prid}" ] && kill ${prid} [ -s "${fifo}.log" ] || rm -f "${fifo}.log" diff --git a/modules/chatMember.sh b/modules/chatMember.sh index 7d4c316..ddaf992 100644 --- a/modules/chatMember.sh +++ b/modules/chatMember.sh @@ -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.40-dev-1-g41e2d09 +#### $$VERSION$$ v1.40-0-gf9dab50 # will be automatically sourced from bashbot @@ -93,7 +93,7 @@ promote_chat_member() { *"invite"*) arg="can_invite_users";; *"restrict"*) arg="can_restrict_members";; *"promote"*) arg="can_promote_members";; - *) [ -n "${BASHBOT_DEBUG}" ] && debug_log "${FUNCNAME[0]}: unknown promotion ${arg}" + *) [ -n "${BASHBOTDEBUG}" ] && debug_log "${FUNCNAME[0]}: unknown promotion ${arg}" continue;; esac # compose json diff --git a/modules/jsonDB.sh b/modules/jsonDB.sh index 5a78bb3..dfaec7d 100644 --- a/modules/jsonDB.sh +++ b/modules/jsonDB.sh @@ -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.40-dev-3-g7c74824 +#### $$VERSION$$ v1.40-0-gf9dab50 # # source from commands.sh to use jsonDB functions # diff --git a/modules/processUpdates.sh b/modules/processUpdates.sh index adb07e1..cb422e8 100644 --- a/modules/processUpdates.sh +++ b/modules/processUpdates.sh @@ -4,7 +4,7 @@ # File: processUpdates.sh # Note: DO NOT EDIT! this file will be overwritten on update # -#### $$VERSION$$ v1.40-dev-34-g1440d56 +#### $$VERSION$$ v1.40-0-gf9dab50 ################################################################## ############## diff --git a/modules/sendMessage.sh b/modules/sendMessage.sh index 70753d5..4185948 100644 --- a/modules/sendMessage.sh +++ b/modules/sendMessage.sh @@ -6,7 +6,7 @@ # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # # shellcheck disable=SC1117 -#### $$VERSION$$ v1.35-dev-18-ge4ee880 +#### $$VERSION$$ v1.40-0-gf9dab50 # will be automatically sourced from bashbot diff --git a/mycommands.conf b/mycommands.conf index e5e21ab..aace68d 100644 --- a/mycommands.conf +++ b/mycommands.conf @@ -12,7 +12,7 @@ # Author: KayM (gnadelwartz), kay@rrr.de # Created: 09.01.2021 07:27 # -#### $$VERSION$$ v1.35-dev-17-gb096338 +#### $$VERSION$$ v1.40-0-gf9dab50 ####################################################### ########## diff --git a/mycommands.sh b/mycommands.sh index ddb65b6..c8fcd2c 100644 --- a/mycommands.sh +++ b/mycommands.sh @@ -13,7 +13,7 @@ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # Author: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.35-dev-24-g5a0a571 +#### $$VERSION$$ v1.40-0-gf9dab50 ####################################################### # shellcheck disable=SC1117 diff --git a/mycommands.sh.clean b/mycommands.sh.clean index eaed7d1..369d384 100644 --- a/mycommands.sh.clean +++ b/mycommands.sh.clean @@ -10,7 +10,7 @@ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # Author: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.35-dev-26-gb45efa3 +#### $$VERSION$$ v1.40-0-gf9dab50 ####################################################### # shellcheck disable=SC1117 diff --git a/scripts/interactive.sh.clean b/scripts/interactive.sh.clean index bbb7434..15ec448 100755 --- a/scripts/interactive.sh.clean +++ b/scripts/interactive.sh.clean @@ -12,7 +12,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.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 ######################################################################## ###### diff --git a/test/ADD-test-new.sh b/test/ADD-test-new.sh index 59b933b..9df5b48 100755 --- a/test/ADD-test-new.sh +++ b/test/ADD-test-new.sh @@ -10,7 +10,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # magic to ensure that we're always inside the root of our application, diff --git a/test/ALL-tests.inc.sh b/test/ALL-tests.inc.sh index 3f519fe..66ac9a6 100644 --- a/test/ALL-tests.inc.sh +++ b/test/ALL-tests.inc.sh @@ -11,7 +11,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # common variables diff --git a/test/a-commit-test.sh b/test/a-commit-test.sh index dfb9ac9..bc41832 100755 --- a/test/a-commit-test.sh +++ b/test/a-commit-test.sh @@ -10,7 +10,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== ../dev/hooks/pre-commit.sh diff --git a/test/b-example-test.sh b/test/b-example-test.sh index f60d0a6..d26411b 100644 --- a/test/b-example-test.sh +++ b/test/b-example-test.sh @@ -10,7 +10,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # include common functions and definitions diff --git a/test/c-init-test.sh b/test/c-init-test.sh index aca8c1b..8a0564d 100755 --- a/test/c-init-test.sh +++ b/test/c-init-test.sh @@ -10,7 +10,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # include common functions and definitions diff --git a/test/d-JSON.sh-test.sh b/test/d-JSON.sh-test.sh index bb996b7..08a1f42 100755 --- a/test/d-JSON.sh-test.sh +++ b/test/d-JSON.sh-test.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 # include common functions and definitions # shellcheck source=test/ALL-tests.inc.sh diff --git a/test/d-process_inline-test.sh b/test/d-process_inline-test.sh index 9e44a52..601832a 100755 --- a/test/d-process_inline-test.sh +++ b/test/d-process_inline-test.sh @@ -10,7 +10,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.35-dev-0-gd9b3342 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # include common functions and definitions diff --git a/test/d-process_message-test.sh b/test/d-process_message-test.sh index 502d4ad..dd38dd8 100755 --- a/test/d-process_message-test.sh +++ b/test/d-process_message-test.sh @@ -10,7 +10,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # include common functions and definitions diff --git a/test/d-send_message-test.sh b/test/d-send_message-test.sh index aadf8c9..e55b96b 100755 --- a/test/d-send_message-test.sh +++ b/test/d-send_message-test.sh @@ -10,7 +10,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # include common functions and definitions diff --git a/test/d-user_is-test.sh b/test/d-user_is-test.sh index 9d2802e..8daf09b 100755 --- a/test/d-user_is-test.sh +++ b/test/d-user_is-test.sh @@ -10,7 +10,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # include common functions and definitions diff --git a/test/e-env-test.sh b/test/e-env-test.sh index f9e80dc..85dd792 100755 --- a/test/e-env-test.sh +++ b/test/e-env-test.sh @@ -10,7 +10,7 @@ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # AUTHOR: KayM (gnadelwartz), kay@rrr.de # -#### $$VERSION$$ v1.30-0-g3266427 +#### $$VERSION$$ v1.40-0-gf9dab50 #=============================================================================== # include common functions and definitions
  • Examples Directory