diff --git a/addons/example.sh b/addons/example.sh index 9ecf2d1..b42cf89 100644 --- a/addons/example.sh +++ b/addons/example.sh @@ -4,7 +4,7 @@ # Addons can register to bashbot events at statup # by providing their name and a callback per event # -#### $$VERSION$$ v0.91-1-gdb03e23 +#### $$VERSION$$ v0.91-6-g9b9125c # # If an event occours each registered event function is called. # @@ -45,7 +45,7 @@ # # export used events -export BASHBOT_EVENT_INLINE BASHBOT_EVENT_CMD BASHBOT_EVENT_REPLY BASHBOT_EVENT_TIMER +export BASHBOT_EVENT_INLINE BASHBOT_EVENT_CMD BASHBOT_EVENT_REPLY BASHBOT_EVENT_TIMER BASHBOT_EVENT_SEND # any global variable defined by addons MUST be prefixed by addon name EXAMPLE_ME="example" @@ -97,4 +97,18 @@ if [[ "$1" = "start"* ]]; then example_every2min(){ send_markdown_message "$(< "${BOTADMIN}")" "This a a every 2 minute event ..." & } + + # register to send + BASHBOT_EVENT_SEND["${EXAMPLE_ME}"]="${EXAMPLE_ME}_log" + EXAMPLE_LOG="${BASHBOT_ETC:-.}/addons/${EXAMPLE_ME}.log" + + # any function defined by addons MUST be prefixed by addon name + # function local variables can have any name, but must be LOCAL + # $1 = send / upload + # $* remaining args are from sendJson and sendUpload + # Note: do not call any send message functions from EVENT_SEND! + example_log(){ + local send="$1"; shift + echo "$(date): Type: ${send} Args: $*" >>"${EXAMPLE_LOG}" + } fi diff --git a/bashbot.sh b/bashbot.sh index 012caa8..790917d 100755 --- a/bashbot.sh +++ b/bashbot.sh @@ -11,7 +11,7 @@ # This file is public domain in the USA and all free countries. # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # -#### $$VERSION$$ v0.91-3-g4594e05 +#### $$VERSION$$ v0.91-6-g9b9125c # # Exit Codes: # - 0 sucess (hopefully) @@ -243,6 +243,7 @@ if [ "${BASHBOT_WGET}" = "" ] && _exists curl ; then -H "Content-Type: application/json" | "${JSONSHFILE}" -s -b -n )" BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "$res")" BOTSENT[ID]="$(JsonGetValue '"result","message_id"' <<< "$res")" + [ "${BASHBOT_EVENT_SEND[*]}" != "" ] && event_send "send" "$@" & } #$1 Chat, $2 what , $3 file, $4 URL, $5 caption sendUpload() { @@ -255,6 +256,7 @@ if [ "${BASHBOT_WGET}" = "" ] && _exists curl ; then res="$(curl -s ${BASHBOT_CURL_ARGS} "$4" -F "chat_id=$1" -F "$2=@$3;${3##*/}" | "${JSONSHFILE}" -s -b -n )" fi BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "$res")" + [ "${BASHBOT_EVENT_SEND[*]}" != "" ] && event_send "upload" "$@" & } else # simple curl or wget call outputs result to stdout @@ -271,10 +273,12 @@ else --header='Content-Type:application/json' "${3}" | "${JSONSHFILE}" -s -b -n )" BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "$res")" BOTSENT[ID]="$(JsonGetValue '"result","message_id"' <<< "$res")" + [ "${BASHBOT_EVENT_SEND[*]}" != "" ] && event_send "send" "$@" & } sendUpload() { sendJson "$1" '"text":"Sorry, wget does not support file upload"' "${MSG_URL}" BOTSENT[OK]="false" + [ "${BASHBOT_EVENT_SEND[*]}" != "" ] && event_send "upload" "$@" & } fi @@ -372,7 +376,7 @@ process_client() { grep -q "$tmpcount" <"${COUNTFILE}" &>/dev/null || cat <<< "$tmpcount" >>"${COUNTFILE}" } -declare -Ax BASBOT_EVENT_INLINE BASBOT_EVENT_MESSAGE BASHBOT_EVENT_CMD BASBOT_EVENT_REPLY BASBOT_EVENT_FORWARD +declare -Ax BASBOT_EVENT_INLINE BASBOT_EVENT_MESSAGE BASHBOT_EVENT_CMD BASBOT_EVENT_REPLY BASBOT_EVENT_FORWARD BASHBOT_EVENT_SENDBASHBOT_EVENT_SEND declare -Ax BASBOT_EVENT_CONTACT BASBOT_EVENT_LOCATION BASBOT_EVENT_FILE BASHBOT_EVENT_TEXT BASHBOT_EVENT_TIMER start_timer(){ @@ -383,6 +387,17 @@ start_timer(){ done; } +EVENT_SEND="0" +event_send() { + # max recursion level 5 to avoid fork bombs + (( EVENT_SEND++ )); [ "$EVENT_SEND" -gt "5" ] && return + # shellcheck disable=SC2153 + for key in "${!BASHBOT_EVENT_SEND[@]}" + do + _exec_if_function "${BASHBOT_EVENT_SEND[${key}]}" "$@" + done +} + EVENT_TIMER="0" event_timer() { local key timer debug="$1" diff --git a/doc/6_reference.md b/doc/6_reference.md index ec3fb55..91a6458 100644 --- a/doc/6_reference.md +++ b/doc/6_reference.md @@ -457,6 +457,8 @@ Usually message is automatically forwarded in 'commands.sh', but you can forwar Since output of JSON.sh is so handy to use in bash, we provide a simple wrapper to read and write JSON.sh style data from and to files. File name is prefixed with BASHBOT_ETC and the suffix '.jssh' is added to file name! File names must not contain '..' +A 'jsshDB' file is a simple 'kay=value' storage. + *Example:* for file name: ```bash # bashbot is installed in /usr/local/telegram-bot-bash, no BASHBOT_ETC set. @@ -468,12 +470,20 @@ File name is prefixed with BASHBOT_ETC and the suffix '.jssh' is added to file n You must include ```source modules/jsshDB.sh``` in 'commands.sh' to have the following functions availible. ##### jssh_newDB -Creats new empty "DB" file if not exist. +Creats new empty jsshDB file if not exist. *usage:* jssh_newDB "filename" +##### jssh_checkDB +Check if DB name respects the rules and returns the real/final path to DB file. +Used internally by all jssh DB functions, but can also used to get the real filename for a jssh DB. + +*usage:* jssh_checkDB "filename" + + + ##### jssh_readDB -Read content of a file in JSON.sh format into given ARRAY. ARRAY name must be delared with "declare -A ARRAY" upfront, +Read content of a .jssh file in JSON.sh format into given ARRAY. ARRAY name must be delared with "declare -A ARRAY" upfront, *usage:* jssh_readDB "ARRAY" "filename" @@ -486,13 +496,16 @@ print "${SOMEVALUES[*]}" ``` ##### jssh_writeDB -wWrite content of given ARRAY into file. ARRAY name must be delared with "declare -A ARRAY" upfront, +Write content of given ARRAY into jsshDB file. ARRAY name must be delared with "declare -A ARRAY" upfront, "DB" file MUST exist or nothing is written. +Note: Every existing content is overwritten. + *usage:* jssh_writeDB "ARRAY" "filename" *example:* ```bash +declare -A MYVALUES MYVALUES["value1"]="value1" MYVALUES["loveit"]="value2" MYVALUES["whynot"]="value3" @@ -504,13 +517,72 @@ jssh_newDB "${DATADIR:-}/myvalues" jssh_writeDB "MYVALUES" "${DATADIR:-}/myvalues" # show whats written -cat ""${DATADIR:-}/myvalues.jssh" +DBfile="$(jssh_checkDB "${DATADIR:-}/myvalues.jssh")" + +cat "DB$file" ["value1"] "value1" ["loveit"] "value2" ["whynot"] "value3" ``` +##### jssh_updateDB +Update/write content of given ARRAY into a jsshDB file. ARRAY name must be delared with "declare -A ARRAY" upfront, +"DB" file MUST exist or nothing is written. + +Note: Existing DB content not in ARRAY is kept. + +*usage:* jssh_updateDB "ARRAY" "filename" + +*example:* +```bash +# continued example from writeDB +MYVALUES=() +MYVALUES["newvalue"]="this is new" + +# update file data-bot-bash/somevalues.jssh from array MYVALUES +jssh_updateDB "MYVALUES" "${DATADIR:-}/myvalues" + +# show whats written +["value1"] "value1" +["loveit"] "value2" +["whynot"] "value3" +["newvalue"] "this is new" + +# now writeDB +cat "$DBfile" +jssh_writeDB "MYVALUES" "${DATADIR:-}/myvalues" + +# show whats written, ups! +cat "$DBfile" +["newvalue"] "this is new" + +``` + +##### jssh_insertDB +Insert, update, append a key=value pair to a jsshDB file, key name is only allowed to contain '-a-zA-Z0-9,._' + +*usage:* jssh_insertDB "key" "value" "filename" + +*example:* +```bash +jssh_insertDB "newkey" "an other value" "${DATADIR:-}/myvalues" +``` + +##### jssh_getDB +Read a key=value pair from a jsshDB file, key name is only allowed to contain '-a-zA-Z0-9,._' + +*usage:* jssh_getDB "key" "filename" + +*example:* +```bash +result="$(jssh_getDB "newvalue" "${DATADIR:-}/myvalues")" + +# lets see whats the value of key newvalue +echo "$result" +this is new +``` + ---- ### Aliases - shortcuts for often used funtions @@ -792,5 +864,5 @@ The name of your bot is availible as bash variable "$ME", there is no need to ca #### [Prev Best Practice](5_practice.md) #### [Next Notes for Developers](7_develop.md) -#### $$VERSION$$ v0.91-0-g31808a9 +#### $$VERSION$$ v0.91-6-g9b9125c diff --git a/doc/7_develop.md b/doc/7_develop.md index 0260ec8..e3230fd 100644 --- a/doc/7_develop.md +++ b/doc/7_develop.md @@ -113,6 +113,18 @@ BAHSBOT_EVENT_TIMER["example_10min","$(( (EVENT_TIMER+10) * -1 ))"]="example_in1 ``` +* BASHBOT_EVENT_SEND is exceuted if sendJson or sendUpload is used to send data to Telegram server + +In contrast to other events, BASHBOT_EVENT_SEND is excecuted as in a subshell, so there no need to spawn +a subshell for longer running commands and changes to shanges to variables are not persistent. + +BASHBOT_EVENT_SEND is mainly for logging purposes and you must not send messages while processing this event. +To avoid fork bombs event processing is suspended if recursion because of sending messages is detected. + +*usage*: BASHBOT_EVENT_SEND[ "uniqe-name" ]="callback" + +"callback" is called with paramter "send" for events from 'sendJson' or "upload" for events from 'sendUpload', followed by the arguments send to the respective function. + ---- #### Create a stripped down Version of your Bot @@ -286,5 +298,5 @@ fi #### [Prev Function Reference](6_reference.md) -#### $$VERSION$$ v0.91-4-gaad0bfe +#### $$VERSION$$ v0.91-6-g9b9125c