t push origin masterMerge branch 'develop'

This commit is contained in:
Kay Marquardt (Gnadelwartz) 2020-06-09 09:21:27 +02:00
commit 30b5b1a79a
70 changed files with 904 additions and 418 deletions

8
.gitignore vendored
View File

@ -1,9 +1,13 @@
*~
/.github/
/count
/token
/count*
/token*
/bocked*
*.save
*.log
*.swp
*.swo
/log/*
/JSON.sh/
/data-bot-bash/
/DIST/

View File

@ -139,6 +139,7 @@ Written by Drew (@topkecleon), Daniil Gentili (@danogentili), and Kay M (@gnadel
<li>Sending Messages, Files, Keyboards</li>
<li>User Access Control</li>
<li>Inline Queries</li>
<li>jsshDB Bashbot key-value storage</li>
<li>Background and Interactive Jobs</li>
</ul></li>
<li><a href="doc/7_develop.md">Deveoper Notes</a>
@ -178,6 +179,7 @@ It features background tasks and interactive chats, and can serve as an interfac
<p>Running a Telegram Bot means it is connected to the public and you never know whats send to your Bot.</p>
<p>Bash scripts in general are not designed to be bullet proof, so consider this Bot as a proof of concept. Bash programmers often struggle with 'quoting hell' and globbing, see <a href="https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells">Implications of wrong quoting</a></p>
<p>Whenever you are processing input from from untrusted sources (messages, files, network) you must be as carefull as possible, e.g. set IFS appropriate, disable globbing (set -f) and quote everthing. In addition delete unused scripts and examples from your Bot, e.g. scripts 'notify', 'calc', 'question', and disable all not used commands.</p>
<p><strong>Note:</strong> Until v0.941 (mai/22/2020) telegram-bot-bash has a remote code execution bug, pls update if you use an older version! One of the most powerful features of unix shells like bash is variable and command substitution, this can lead to RCE and information disclosing bugs if you do not escape '$' porperly, see <a href="https://github.com/topkecleon/telegram-bot-bash/issues/125">Issue #125</a></p>
<p>A powerful tool to improve your scripts is <code>shellcheck</code>. You can <a href="https://www.shellcheck.net/">use it online</a> or <a href="https://github.com/koalaman/shellcheck#installing">install shellcheck locally</a>. Shellcheck is used extensive in bashbot development to enshure a high code quality, e.g. it's not allowed to push changes without passing all shellcheck tests. In addition bashbot has a <a href="doc/7_develop.md">test suite</a> to check if important functionality is working as expected.</p>
<h3>Do not use #!/usr/bin/env bash</h3>
<p><strong>We stay with /bin/bash shebang, because it's more save from security perspective.</strong></p>
@ -193,6 +195,7 @@ It features background tasks and interactive chats, and can serve as an interfac
<h2>FAQ</h2>
<h3>Is this Bot insecure?</h3>
<p>Bashbot is not more (in)secure as any other Bot written in any other 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 ...</p>
<p><strong>Note:</strong> Until v0.941 (mai/22/2020) telegram-bot-bash has a remote code execution bug, pls update if you use an older version!</p>
<h3>Why Bash and not the much better xyz?</h3>
<p>Well, thats a damn good question ... may be because I'm an Unix/Linux admin from stone age. Nevertheless there are more reasons from my side:</p>
<ul>
@ -224,10 +227,10 @@ It features background tasks and interactive chats, and can serve as an interfac
<a class="sourceLine" id="cb4-3" title="3"></a>
<a class="sourceLine" id="cb4-4" title="4"><span class="fu">wget</span> -t 1 -T 10 https://api.telegram.org/bot</a>
<a class="sourceLine" id="cb4-5" title="5"><span class="co">#Connecting to api.telegram.org (api.telegram.org)|46.38.243.234|:443... failed: Connection timed out.</span></a></code></pre></div>
<p>This may happen if to many wrong requests are sent to api.telegram.org, e.g. using a wrong token or not existing API calls. If you have a fixed IP you can ask telegram service to unblock your ip or change your IP. If you are running a tor proxy on your server you may uncomment the <code>BASHBOT_CURL_ARGS</code> line in 'mycommands.sh'</p>
<p>This may happen if to many wrong requests are sent to api.telegram.org, e.g. using a wrong token or not existing API calls. If you have a fixed IP you can ask telegram service to unblock your ip or change your IP. If you are running a socks or tor proxy on your server look for the <code>BASHBOT_CURL_ARGS</code> lines in 'mycommands.sh' as example.</p>
<p>@Gnadelwartz</p>
<h2>That's it!</h2>
<p>If you feel that there's something missing or if you found a bug, feel free to submit a pull request!</p>
<h4>$$VERSION$$ V0.94-9-g46af634</h4>
<h4>$$VERSION$$ v0.96-dev3-0-gdddd1ce</h4>
</body>
</html>

View File

@ -52,6 +52,7 @@ Bashbot [Documentation](https://github.com/topkecleon/telegram-bot-bash) and [Do
* Sending Messages, Files, Keyboards
* User Access Control
* Inline Queries
* jsshDB Bashbot key-value storage
* Background and Interactive Jobs
* [Deveoper Notes](doc/7_develop.md)
* Debug bashbot
@ -109,6 +110,9 @@ Bash scripts in general are not designed to be bullet proof, so consider this Bo
Whenever you are processing input from from untrusted sources (messages, files, network) you must be as carefull as possible, e.g. set IFS appropriate, disable globbing (set -f) and quote everthing. In addition delete unused scripts and examples from your Bot, e.g. scripts 'notify', 'calc', 'question', and disable all not used commands.
**Note:** Until v0.941 (mai/22/2020) telegram-bot-bash has a remote code execution bug, pls update if you use an older version!
One of the most powerful features of unix shells like bash is variable and command substitution, this can lead to RCE and information disclosing bugs if you do not escape '$' porperly, see [Issue #125](https://github.com/topkecleon/telegram-bot-bash/issues/125)
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 extensive in bashbot development to enshure 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.
@ -140,6 +144,8 @@ To set access rights for your bashbot installation to a reasonable default run `
### Is this Bot insecure?
Bashbot is not more (in)secure as any other Bot written in any other 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 ...
**Note:** Until v0.941 (mai/22/2020) telegram-bot-bash has a remote code execution bug, pls update if you use an older version!
### Why Bash and not the much better xyz?
Well, thats a damn good question ... may be because I'm an Unix/Linux admin from stone age. Nevertheless there are more reasons from my side:
@ -183,7 +189,7 @@ curl -m 10 https://api.telegram.org/bot
wget -t 1 -T 10 https://api.telegram.org/bot
#Connecting to api.telegram.org (api.telegram.org)|46.38.243.234|:443... failed: Connection timed out.
```
This may happen if to many wrong requests are sent to api.telegram.org, e.g. using a wrong token or not existing API calls. If you have a fixed IP you can ask telegram service to unblock your ip or change your IP. If you are running a tor proxy on your server you may uncomment the ```BASHBOT_CURL_ARGS``` line in 'mycommands.sh'
This may happen if to many wrong requests are sent to api.telegram.org, e.g. using a wrong token or not existing API calls. If you have a fixed IP you can ask telegram service to unblock your ip or change your IP. If you are running a socks or tor proxy on your server look for the ```BASHBOT_CURL_ARGS``` lines in 'mycommands.sh' as example.
@Gnadelwartz
@ -192,4 +198,4 @@ This may happen if to many wrong requests are sent to api.telegram.org, e.g. usi
If you feel that there's something missing or if you found a bug, feel free to submit a pull request!
#### $$VERSION$$ V0.94-9-g46af634
#### $$VERSION$$ v0.96-dev3-0-gdddd1ce

View File

@ -65,6 +65,7 @@ availible on www.github.com
* Sending Messages, Files, Keyboards
* User Access Control
* Inline Queries
* jsshDB Bashbot key-value storage
* Background and Interactive Jobs
* [Deveoper Notes](doc/7_develop.md)
* Debug bashbot
@ -147,6 +148,13 @@ globbing (set -f) and quote everthing. In addition delete unused scripts and
examples from your Bot, e.g. scripts 'notify', 'calc', 'question', and disable
all not used commands.
**Note:** Until v0.941 (mai/22/2020) telegram-bot-bash has a remote code
execution bug, pls update if you use an older version!
One of the most powerful features of unix shells like bash is variable and
command substitution, this can lead to RCE and information disclosing bugs if
you do not escape '$' porperly, see [Issue
#125](https://github.com/topkecleon/telegram-bot-bash/issues/125)
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
@ -200,6 +208,9 @@ Bashbot is not more (in)secure as any other Bot written in any other 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 ...
**Note:** Until v0.941 (mai/22/2020) telegram-bot-bash has a remote code
execution bug, pls update if you use an older version!
### Why Bash and not the much better xyz?
Well, thats a damn good question ... may be because I'm an Unix/Linux admin
from stone age. Nevertheless there are more reasons from my side:
@ -259,8 +270,8 @@ failed: Connection timed out.
This may happen if to many wrong requests are sent to api.telegram.org, e.g.
using a wrong token or not existing API calls. If you have a fixed IP you can
ask telegram service to unblock your ip or change your IP. If you are running a
tor proxy on your server you may uncomment the ```BASHBOT_CURL_ARGS``` line in
'mycommands.sh'
socks or tor proxy on your server look for the ```BASHBOT_CURL_ARGS``` lines
in 'mycommands.sh' as example.
@Gnadelwartz
@ -270,4 +281,4 @@ tor proxy on your server you may uncomment the ```BASHBOT_CURL_ARGS``` line in
If you feel that there's something missing or if you found a bug, feel free to
submit a pull request!
#### $$VERSION$$ V0.94-9-g46af634
#### $$VERSION$$ v0.96-dev3-0-gdddd1ce

View File

@ -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$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# used events:
#

View File

@ -4,7 +4,7 @@
# Addons can register to bashbot events at statup
# by providing their name and a callback per event
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
#
# If an event occours each registered event function is called.
#

View File

@ -1,7 +1,7 @@
#!/bin/sh
# description: Start or stop telegram-bash-bot
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-12-g3f85134
# shellcheck disable=SC2009
# shellcheck disable=SC2181
@ -31,29 +31,22 @@ runcmd="echo Dry run:" # not actived until you edit lines below
# runcmd="runuser $runas -s /bin/bash -c " # runasuser with *runuser*
# edit the values of the following lines to fit your config:
start="/usr/local/telegram-bot-bash/bashbot.sh" # location of your bashbot.sh script
start="cd /usr/local/telegram-bot-bash; /usr/local/telegram-bot-bash/bashbot.sh" # location of your bashbot.sh script
name='' # your bot name as given to botfather, e.g. mysomething_bot
# END Configuration
#######################
lockfile="$(dirname $start)/lockfile"
[ "$name" = "" ] && name="$runas"
case "$1" in
'start')
$runcmd "$start start" # >/dev/null 2>&1 </dev/null
RETVAL=$?
if [ "$RETVAL" = "0" ]; then
touch "$lockfile" >/dev/null 2>&1
fi
;;
'stop')
$runcmd "$start kill"
RETVAL=$?
if [ "$RETVAL" = "0" ]; then
rm -f "$lockfile"
fi
;;
'status')
ps -f -u "$runas" | grep "$name" | grep -qF "bashbot.sh startbot"
@ -76,10 +69,10 @@ case "$1" in
'suspendback'|'resumeback'|'killback')
$runcmd "$start $1"
RETVAL=$?
# kill inotifywait from runuser if long running bg scripts use it
KILLINOTIFY=""
if [ "$1" != "resumeback" ] && [ -n "${KILLINOTIFY}" ]; then
kill -9 "$(ps -u "$runas" | grep inotifywait | sed 's/ .*//')" >/dev/null 2>&1
# kill inotifywait from runuser
if [ "$1" != "resumeback" ]; then
# shellcheck disable=SC2046
kill -9 $(ps -u "$runas" | grep inotifywait | sed 's/ .*//') >/dev/null 2>&1
fi
;;
*)

View File

@ -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.94-7-g3d92bf3
#### $$VERSION$$ v0.96-pre-0-geb49241
#
# Exit Codes:
# - 0 sucess (hopefully)
@ -20,7 +20,8 @@
# - 3 user / command / file not found
# - 4 unkown command
# - 5 cannot connect to telegram bot
# shellcheck disable=SC2140
# - 6 mandatory module not found
# shellcheck disable=SC2140,SC2031,SC2120,SC1091
# are we runnig in a terminal?
if [ -t 1 ] && [ -n "$TERM" ]; then
@ -48,6 +49,22 @@ _is_function()
{
[ "$(LC_ALL=C type -t "$1")" = "function" ]
}
# read JSON.sh style data and asssign to an ARRAY
# $1 ARRAY name, must be declared with "declare -A ARRAY" before calling
Json2Array() {
# shellcheck source=./commands.sh
[ -z "$1" ] || source <( printf "$1"'=( %s )' "$(sed -E -n -e '/\["[-0-9a-zA-Z_,."]+"\]\+*\t/ s/\t/=/gp' -e 's/=(true|false)/="\1"/')" )
}
# output ARRAY as JSON.sh style data
# $1 ARRAY name, must be declared with "declare -A ARRAY" before calling
Array2Json() {
local key
declare -n ARRAY="$1"
for key in "${!ARRAY[@]}"
do
printf '["%s"]\t"%s"\n' "${key//,/\",\"}" "${ARRAY[${key}]//\"/\\\"}"
done
}
# get location and name of bashbot.sh
SCRIPT="$0"
@ -67,14 +84,16 @@ fi
if [ -n "$BASHBOT_HOME" ]; then
SCRIPTDIR="$BASHBOT_HOME"
[ -z "${BASHBOT_ETC}" ] && BASHBOT_ETC="$BASHBOT_HOME"
[ -z "${BASHBOT_VAR}" ] && BASHBOT_VAR="$BASHBOT_HOME"
else
BASHBOT_HOME="${SCRIPTDIR}"
fi
[ -z "${BASHBOT_ETC}" ] && BASHBOT_ETC="$BASHBOT_HOME"
[ -z "${BASHBOT_VAR}" ] && BASHBOT_VAR="$BASHBOT_HOME"
ADDONDIR="${BASHBOT_ETC:-./addons}"
ADDONDIR="${BASHBOT_ETC:-.}/addons"
RUNUSER="${USER}" # USER is overwritten by bashbot array
# OK everthing setup, lest start
if [ "${SOURCE}" != "yes" ] && [ -z "$BASHBOT_HOME" ] && ! cd "${RUNDIR}" ; then
echo -e "${RED}ERROR: Can't change to ${RUNDIR} ...${NC}"
exit 1
@ -87,15 +106,42 @@ if [ ! -w "." ]; then
ls -ld .
fi
###############
# load modules
for modules in "${MODULEDIR:-.}"/*.sh ; do
# shellcheck source=./modules/aliases.sh
if ! _is_function "$(basename "${modules}")" && [ -r "${modules}" ]; then source "${modules}" "source"; fi
done
# shellcheck source=./modules/jsonDB.sh
source "${MODULEDIR:-.}"/jsonDB.sh
#####################
# BASHBOT INTERNAL functions
#
#jsonDB is now mandatory
if ! _is_function jssh_newDB ; then
echo -e "${RED}ERROR: Mandatory module jsonDB is missing or not readable!"
exit 6
fi
# Setup and check environment if BOTTOKEN is NOT set
TOKENFILE="${BASHBOT_ETC:-.}/token"
BOTADMIN="${BASHBOT_ETC:-.}/botadmin"
BOTACL="${BASHBOT_ETC:-.}/botacl"
DATADIR="${BASHBOT_VAR:-.}/data-bot-bash"
# !!!!! DEPRECATED !!!!!
BLOCKEDFILE="${BASHBOT_VAR:-.}/blocked"
COUNTFILE="${BASHBOT_VAR:-.}/count"
LOGDIR="${RUNDIR:-.}/logs"
if [ ! -d "${LOGDIR}" ] || [ ! -w "${LOGDIR}" ]; then
LOGDIR="${RUNDIR:-.}"
fi
ERRORLOG="${LOGDIR}/ERROR.log"
# we assume everthing is already set up correctly if we have TOKEN
if [ -z "${BOTTOKEN}" ]; then
# BOTTOKEN empty read from file
@ -143,15 +189,28 @@ if [ -z "${BOTTOKEN}" ]; then
ls -ld "${DATADIR}"
exit 2
fi
# setup count file !!!!! DEPRECATED !!!!!
if [ ! -f "${COUNTFILE}" ]; then
printf '\n' >"${COUNTFILE}"
elif [ ! -w "${COUNTFILE}" ]; then
# setup count file
if [ ! -f "${COUNTFILE}.jssh" ]; then
jssh_newDB_async "${COUNTFILE}"
jssh_insertKeyDB_async 'counted_user_chat_id' "num_messages_seen" "${COUNTFILE}"
# convert old file on creation
if [ -r "${COUNTFILE}" ];then
sed 's/COUNT/\[\"/;s/$/\"\]\t\"1\"/' < "${COUNTFILE}" >> "${COUNTFILE}.jssh"
fi
elif [ ! -w "${COUNTFILE}.jssh" ]; then
echo -e "${RED}ERROR: Can't write to ${COUNTFILE}!.${NC}"
ls -l "${COUNTFILE}"
ls -l "${COUNTFILE}.jssh"
exit 2
fi
# setup blocked file
if [ ! -f "${BLOCKEDFILE}.jssh" ]; then
jssh_newDB_async "${BLOCKEDFILE}"
jssh_insertKeyDB_async 'blocked_user_or_chat_id' "name and reason" "${BLOCKEDFILE}"
fi
fi
# cleanup (remove double entries) countfile on startup
[ "${SOURCE}" != "yes" ] && jssh_deleteKeyDB_async "CLEAN_COUNTER_DATABASE_ON_STARTUP" "${COUNTFILE}"
# do we have BSD sed
if ! sed '1ia' </dev/null 2>/dev/null; then
echo -e "${ORANGE}Warning: You may run on a BSD style system without gnu utils ...${NC}"
@ -172,6 +231,7 @@ fi
##################
# here we start with the real stuff
URL="${BASHBOT_URL:-https://api.telegram.org/bot}${BOTTOKEN}"
BOTSEND_RETRY="no" # do not retry by default
ME_URL=$URL'/getMe'
@ -186,7 +246,7 @@ declare -Ax UPD BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO
export res CAPTION
#################EW#
##################
# read commamds file if we are not sourced
COMMANDS="${BASHBOT_ETC:-.}/commands.sh"
if [ "${SOURCE}" != "yes" ]; then
@ -199,15 +259,9 @@ if [ "${SOURCE}" != "yes" ]; then
source "${COMMANDS}" "source"
fi
###############
# load modules
for modules in "${MODULEDIR:-.}"/*.sh ; do
# shellcheck source=./modules/aliases.sh
if ! _is_function "$(basename "${modules}")" && [ -r "${modules}" ]; then source "${modules}" "source"; fi
done
#################
# BASHBOT INTERNAL functions
# BASHBOT COMMON functions
# $1 URL, $2 filename in DATADIR
# outputs final filename
download() {
@ -261,34 +315,35 @@ TIMEOUT="${BASHBOT_TIMEOUT}"
[[ "$TIMEOUT" =~ ^[0-9]+$ ]] || TIMEOUT="20"
if [ -z "${BASHBOT_WGET}" ] && _exists curl ; then
[ -z "${BASHBOT_CURL}" ] && BASHBOT_CURL="curl"
# simple curl or wget call, output to stdout
getJson(){
# shellcheck disable=SC2086
curl -sL -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}" "$1"
"${BASHBOT_CURL}" -sL -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}" "$1"
}
# usage: sendJson "chat" "JSON" "URL"
sendJson(){
local chat="";
[ -n "${1}" ] && chat='"chat_id":'"${1}"','
# shellcheck disable=SC2086
res="$(curl -s -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}" -d '{'"${chat} $(iconv -f utf-8 -t utf-8 -c <<<$2)"'}' -X POST "${3}" \
res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} -m "${TIMEOUT}"\
-d '{'"${chat} $(iconv -f utf-8 -t utf-8 -c <<<$2)"'}' -X POST "${3}" \
-H "Content-Type: application/json" | "${JSONSHFILE}" -s -b -n )"
BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "$res")"
BOTSENT[ID]="$(JsonGetValue '"result","message_id"' <<< "$res")"
[ "${SOURCE}" != "yes" ] && [ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "$@" &
sendJsonResult "${res}" "sendJson (curl)" "$@"
}
#$1 Chat, $2 what , $3 file, $4 URL, $5 caption
sendUpload() {
[ "$#" -lt 4 ] && return
if [ -n "$5" ]; then
# shellcheck disable=SC2086
res="$(curl -s -k ${BASHBOT_CURL_ARGS} "$4" -F "chat_id=$1" -F "$2=@$3;${3##*/}" -F "caption=$5" | "${JSONSHFILE}" -s -b -n )"
res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} "$4" -F "chat_id=$1"\
-F "$2=@$3;${3##*/}" -F "caption=$5" | "${JSONSHFILE}" -s -b -n )"
else
# shellcheck disable=SC2086
res="$(curl -s -k ${BASHBOT_CURL_ARGS} "$4" -F "chat_id=$1" -F "$2=@$3;${3##*/}" | "${JSONSHFILE}" -s -b -n )"
res="$("${BASHBOT_CURL}" -s -k ${BASHBOT_CURL_ARGS} "$4" -F "chat_id=$1"\
-F "$2=@$3;${3##*/}" | "${JSONSHFILE}" -s -b -n )"
fi
BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "$res")"
[ "${SOURCE}" != "yes" ] && [ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "upload" "$@" &
sendJsonResult "${res}" "sendUpload (curl)" "$@"
}
else
# simple curl or wget call outputs result to stdout
@ -303,22 +358,102 @@ else
# shellcheck disable=SC2086
res="$(wget --no-check-certificate -t 2 -T "${TIMEOUT}" ${BASHBOT_WGET_ARGS} -qO - --post-data='{'"${chat} $(iconv -f utf-8 -t utf-8 -c <<<$2)"'}' \
--header='Content-Type:application/json' "${3}" | "${JSONSHFILE}" -s -b -n )"
BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "$res")"
BOTSENT[ID]="$(JsonGetValue '"result","message_id"' <<< "$res")"
[ "${SOURCE}" != "yes" ] && [ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "$@" &
sendJsonResult "${res}" "sendJson (wget)" "$@"
}
sendUpload() {
sendJson "$1" '"text":"Sorry, wget does not support file upload"' "${MSG_URL}"
printf "%s: %s\n" "$(date)" "Sorry, wget does not support file upload\n" >>"${ERRORLOG}"
BOTSENT[OK]="false"
[ "${SOURCE}" != "yes" ] && [ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "upload" "$@" &
}
fi
# retry sendJson
# $1 function $2 sleep $3 ... $n arguments
sendJsonRetry(){
local retry="${1}"; shift
[[ "${1}" =~ ^[0-9.]+$ ]] && sleep "${1}"; shift
case "${retry}" in
'sendJson'*)
sendJson "$@"
;;
'sendUpload'*)
sendUpload "$@"
;;
*)
printf "%s: SendJsonRetry: unknown, cannot retry %s\n" "$(date)" "${retry}" >>"${ERRORLOG}"
;;
esac
}
# process sendJson result
# stdout is written to ERROR.log
# $1 result $2 function $3 .. $n original arguments, $3 is Chat_id
sendJsonResult(){
BOTSENT=( )
BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "${1}")"
if [ "${BOTSENT[OK]}" = "true" ]; then
BOTSENT[ID]="$(JsonGetValue '"result","message_id"' <<< "${1}")"
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "${@:2}"
return
# hot path everthing OK!
else
# oops something went wrong!
if [ "${res}" != "" ]; then
BOTSENT[ERROR]="$(JsonGeOtValue '"error_code"' <<< "${1}")"
BOTSENT[DESCRIPTION]="$(JsonGetString '"description"' <<< "${1}")"
BOTSENT[RETRY]="$(JsonGetValue '"parameters","retry_after"' <<< "${1}")"
else
BOTSENT[ERROR]="999"
BOTSENT[DESCRIPTION]="Timeout or broken/no connection"
fi
# log error
printf "%s: RESULT=%s ACTION=%s CHAT[ID]=%s ERROR=%s DESC=%s\n" "$(date)"\
"${BOTSENT[OK]}" "${2}" "${3}" "${BOTSENT[ERROR]}" "${BOTSENT[DESCRIPTION]}"
# warm path, do not retry on error
[ -n "${BOTSEND_RETRY}" ] && return
# OK, we can retry sendJson, let's see what's failed
# throttled, telegram say we send to much messages
if [ -n "${BOTSENT[RETRY]}" ]; then
BOTSEND_RETRY="(( ${BOTSENT[RETRY]} * 15/10 ))"
printf "Retry %s in %s seconds ...\n" "${2}" "${BOTSEND_RETRY}"
sendJsonRetry "${2}" "${BOTSEND_RETRY}" "${@:2}"
unset BOTSEND_RETRY
return
fi
# timeout, failed connection or blocked
if [ "${BOTSENT[ERROR]}" == "999" ];then
# check if default curl and args are OK
if ! curl -sL -k -m 2 "${URL}" >/dev/null 2>&1 ; then
printf "BASHBOT IP Adress is blocked!\n"
# user provided function to recover or notify block
if _exec_if_function bashbotBlockRecover; then
BOTSEND_RETRY="2"
printf "Function bashbotBlockRecover returned true, retry %s.\n" "${2}"
sendJsonRetry "${2}" "${BOTSEND_RETRY}" "${@:2}"
unset BOTSEND_RETRY
fi
return
fi
# we are not blocked, default curl and args are working
if [ -n "${BASHBOT_CURL_ARGS}" ] || [ -n "${BASHBOT_CURL}" ]; then
BOTSEND_RETRY="2"
printf "Possible Problem with \"%s %s\", retry %s with default curl config ...\n"\
"${BASHBOT_CURL}" "${BASHBOT_CURL_ARGS}" "${2}"
unset BASHBOT_CURL BASHBOT_CURL_ARGS
sendJsonRetry "${2}" "${BOTSEND_RETRY}" "${@:2}"
unset BOTSEND_RETRY
fi
fi
fi
} >>"${ERRORLOG}"
# escape / remove text charaters for json strings, eg. " -> \"
# $1 string
# output escaped string
JsonEscape() {
sed 's/\([-"`´,§$%&ß/(){}#@?*]\)/\\\1/g' <<< "$1"
JsonEscape(){
sed 's/\([-"`´,§$%&/(){}#@!?*.]\)/\\\1/g' <<< "$1"
}
# convert common telegram entities to JSON
@ -330,7 +465,7 @@ title2Json(){
[ -n "$3" ] && desc=',"description":"'$(JsonEscape "$3")'"'
[ -n "$4" ] && markup=',"parse_mode":"'$(JsonEscape "$4")'"'
[ -n "$5" ] && keyboard=',"reply_markup":"'$(JsonEscape "$5")'"'
echo "${title}${caption}${desc}${markup}${keyboard}"
printf '%s\n' "${title}${caption}${desc}${markup}${keyboard}"
}
# get bot name
@ -348,6 +483,7 @@ JsonDecode() {
remain="$(printf '\\U%8.8x' "${U}")${BASH_REMATCH[4]}${remain}"
out="${BASH_REMATCH[1]}"
done
# this echo must stay for correct decoding!
echo -e "${out}${remain}"
}
@ -360,22 +496,6 @@ JsonGetLine() {
JsonGetValue() {
sed -n -e '0,/\['"$1"'\]/ s/\['"$1"'\][ \t]\([0-9.,]*\).*/\1/p'
}
# read JSON.sh style data and asssign to an ARRAY
# $1 ARRAY name, must be declared with "declare -A ARRAY" before calling
Json2Array() {
# shellcheck source=./commands.sh
[ -z "$1" ] || source <( printf "$1"'=( %s )' "$(sed -E -n -e '/\["[-0-9a-zA-Z_,."]+"\]\+*\t/ s/\t/=/gp' -e 's/=(true|false)/="\1"/')" )
}
# output ARRAY as JSON.sh style data
# $1 ARRAY name, must be declared with "declare -A ARRAY" before calling
Array2Json() {
local key
declare -n ARRAY="$1"
for key in "${!ARRAY[@]}"
do
printf '["%s"]\t"%s"\n' "${key//,/\",\"}" "${ARRAY[${key}]//\"/\\\"}"
done
}
################
# processing of updates starts here
@ -390,8 +510,16 @@ process_updates() {
process_client() {
local num="$1" debug="$2"
CMD=( ); iQUERY=( )
[[ "${debug}" = *"debug"* ]] && cat <<< "$UPDATE" >>"${LOGDIR}/MESSAGE.log"
iQUERY[ID]="${UPD["result",${num},"inline_query","id"]}"
[[ "${debug}" = *"debug"* ]] && cat <<< "$UPDATE" >>"MESSAGE.log"
CHAT[ID]="${UPD["result",${num},"message","chat","id"]}"
USER[ID]="${UPD["result",${num},"message","from","id"]}"
# check for uers / groups to ignore
if [ -n "${USER[ID]}" ]; then
[[ " ${!BASHBOT_BLOCKED[*]} " == *" ${USER[ID]} "* ]] && return
jssh_readDB_async "BASHBOT_BLOCKED" "${BLOCKEDFILE}"
fi
if [ -z "${iQUERY[ID]}" ]; then
process_message "${num}" "${debug}"
else
@ -411,13 +539,11 @@ process_client() {
fi
# last count users
# !!!!! DEPRECATED !!!!!
tmpcount="COUNT${CHAT[ID]}"
grep -q "$tmpcount" <"${COUNTFILE}" &>/dev/null || cat <<< "$tmpcount" >>"${COUNTFILE}"
jssh_countKeyDB_async "${CHAT[ID]}" "${COUNTFILE}"
}
declare -Ax BASBOT_EVENT_INLINE BASBOT_EVENT_MESSAGE BASHBOT_EVENT_CMD BASBOT_EVENT_REPLY BASBOT_EVENT_FORWARD BASHBOT_EVENT_SEND
declare -Ax BASBOT_EVENT_CONTACT BASBOT_EVENT_LOCATION BASBOT_EVENT_FILE BASHBOT_EVENT_TEXT BASHBOT_EVENT_TIMER
declare -Ax BASBOT_EVENT_CONTACT BASBOT_EVENT_LOCATION BASBOT_EVENT_FILE BASHBOT_EVENT_TEXT BASHBOT_EVENT_TIMER BASHBOT_BLOCKED
start_timer(){
# send alarm every ~60 s
@ -551,8 +677,8 @@ process_message() {
MESSAGE[0]="$(JsonDecode "${UPD["result",${num},"message","text"]}" | sed 's#\\/#/#g')"
MESSAGE[ID]="${UPD["result",${num},"message","message_id"]}"
# Chat
CHAT[ID]="${UPD["result",${num},"message","chat","id"]}"
# Chat ID is now parsed when update isrecieved
#CHAT[ID]="${UPD["result",${num},"message","chat","id"]}"
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"]}")"
@ -561,8 +687,8 @@ process_message() {
CHAT[ALL_ADMIN]="${UPD["result",${num},"message","chat","all_members_are_administrators"]}"
CHAT[ALL_MEMBERS_ARE_ADMINISTRATORS]="${CHAT[ALL_ADMIN]}" # backward compatibility
# User
USER[ID]="${UPD["result",${num},"message","from","id"]}"
# user ID is now parsed when update isrecieved
#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"]}")"
@ -665,9 +791,9 @@ start_bot() {
local mysleep="100" # ms
local addsleep="100"
local maxsleep="$(( ${BASHBOT_SLEEP:-5000} + 100 ))"
[[ "${DEBUG}" = *"debug" ]] && exec &>>"DEBUG.log"
[[ "${DEBUG}" == *"debug" ]] && exec &>>"${LOGDIR}/DEBUG.log"
[ -n "${DEBUG}" ] && date && echo "Start BASHBOT in Mode \"${DEBUG}\""
[[ "${DEBUG}" = "xdebug"* ]] && set -x
[[ "${DEBUG}" == "xdebug"* ]] && set -x
#cleaup old pipes and empty logfiles
find "${DATADIR}" -type p -delete
find "${DATADIR}" -size 0 -name "*.log" -delete
@ -687,8 +813,9 @@ start_bot() {
trap "kill -9 $!; exit" EXIT INT HUP TERM QUIT
fi
while true; do
UPDATE="$(getJson "$UPD_URL$OFFSET" | "${JSONSHFILE}" -s -b -n | iconv -f utf-8 -t utf-8 -c)"
# ignore timeout error message on waiting for updates
UPDATE="$(getJson "$UPD_URL$OFFSET" 2>/dev/null | "${JSONSHFILE}" -s -b -n | iconv -f utf-8 -t utf-8 -c)"
UPDATE="${UPDATE//$/\\$}"
# Offset
OFFSET="$(grep <<< "${UPDATE}" '\["result",[0-9]*,"update_id"\]' | tail -1 | cut -f 2)"
((OFFSET++))
@ -706,6 +833,7 @@ start_bot() {
# initialize bot environment, user and permissions
bot_init() {
[ -n "${BASHBOT_HOME}" ] && cd "${BASHBOT_HOME}" || exit 1
local DEBUG="$1"
# upgrade from old version
local OLDTMP="${BASHBOT_VAR:-.}/tmp-bot-bash"
@ -734,12 +862,12 @@ bot_init() {
[ -w "bashbot.rc" ] && sed -i '/^[# ]*runas=/ s/runas=.*$/runas="'$TOUSER'"/' "bashbot.rc"
chown -R "$TOUSER" . ./*
chmod 711 .
chmod -R a-w ./*
chmod -R u+w "${COUNTFILE}" "${DATADIR}" "${BOTADMIN}" ./*.log 2>/dev/null
chmod -R o-r,o-w "${COUNTFILE}" "${DATADIR}" "${TOKENFILE}" "${BOTADMIN}" "${BOTACL}" 2>/dev/null
chmod -R o-w ./*
chmod -R u+w "${COUNTFILE}"* "${BLOCKEDFILE}"* "${DATADIR}" "${BOTADMIN}" "${LOGDIR}/"*.log 2>/dev/null
chmod -R o-r,o-w "${COUNTFILE}"* "${BLOCKEDFILE}"* "${DATADIR}" "${TOKENFILE}" "${BOTADMIN}" "${BOTACL}" 2>/dev/null
# jsshDB must writeable by owner
find . -name '*.jssh' -exec chmod u+w \{\} +
ls -la
#ls -la
fi
}
@ -748,12 +876,12 @@ if ! _is_function send_message ; then
exit 1
fi
JSONSHFILE="${BASHBOT_JSONSH:-${RUNDIR}/JSON.sh/JSON.sh}"
JSONSHFILE="${BASHBOT_JSONSH:-${SCRIPTDIR}/JSON.sh/JSON.sh}"
[[ "${JSONSHFILE}" != *"/JSON.sh" ]] && echo -e "${RED}ERROR: \"${JSONSHFILE}\" ends not with \"JSONS.sh\".${NC}" && exit 3
if [ ! -f "${JSONSHFILE}" ]; then
echo "Seems to be first run, Downloading ${JSONSHFILE}..."
[[ "${JSONSHFILE}" = "${RUNDIR}/JSON.sh/JSON.sh" ]] && mkdir "JSON.sh" 2>/dev/null && chmod +w "JSON.sh"
mkdir "${SCRIPTDIR}/JSON.sh" 2>/dev/null && chmod +w "${SCRIPTDIR}/JSON.sh"
getJson "https://cdn.jsdelivr.net/gh/dominictarr/JSON.sh/JSON.sh" >"${JSONSHFILE}"
chmod +x "${JSONSHFILE}"
fi
@ -805,16 +933,38 @@ if [ "${SOURCE}" != "yes" ]; then
BOTPID="$(proclist "${SESSION}")"
case "$1" in
"count") # !!!!! DEPRECATED !!!!!
echo "A total of $(wc -l <"${COUNTFILE}") users used me."
"stats"|'count')
declare -A STATS
jssh_readDB_async "STATS" "${COUNTFILE}"
for MSG in ${!STATS[*]}
do
[[ ! "${MSG}" =~ ^[0-9-]*$ ]] && continue
(( USERS++ ))
done
for MSG in ${STATS[*]}
do
(( MESSAGES+=MSG ))
done
echo "A total of ${MESSAGES} messages from ${USERS} users are processed."
exit
;;
"broadcast") # !!!!! DEPRECATED !!!!!
NUMCOUNT="$(wc -l <"${COUNTFILE}")"
echo "Sending the broadcast $* to $NUMCOUNT users."
[ "$NUMCOUNT" -gt "300" ] && sleep="sleep 0.5"
'broadcast')
declare -A SENDALL
shift
while read -r f; do send_markdown_message "${f//COUNT}" "$*"; $sleep; done <"${COUNTFILE}"
jssh_readDB_async "SENDALL" "${COUNTFILE}"
echo -e "Sending broadcast message to all users \c"
for MSG in ${!SENDALL[*]}
do
[[ ! "${MSG}" =~ ^[0-9-]*$ ]] && continue
(( USERS++ ))
if [ -n "$*" ]; then
send_markdown_message "${MSG}" "$*"
echo -e ".\c"
sleep 0.1
fi
done
echo -e "\nMessage \"$*\" sent to ${USERS} users."
exit
;;
"status")
if [ -n "${BOTPID}" ]; then
@ -860,7 +1010,7 @@ if [ "${SOURCE}" != "yes" ]; then
;;
*)
echo -e "${RED}${REALME}: BAD REQUEST${NC}"
echo -e "${RED}Available arguments: ${GREY}start, stop, kill, status, count, broadcast, help, suspendback, resumeback, killback${NC}"
echo -e "${RED}Available arguments: ${GREY}start, stop, kill, status, status, broadcast, help, suspendback, resumeback, killback${NC}"
exit 4
;;
esac

View File

@ -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$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-12-g3f85134
#
# adjust your language setting here, e.g.when run from other user or cron.
@ -126,7 +126,9 @@ if [ -z "${1}" ] || [[ "${1}" == *"debug"* ]];then
unban_chat_member "${CHAT[ID]}" "${USER[ID]}"
;;
*) # forward messages to optional dispatcher
'/'*) # discard all unkown commands
: ;;
*) # forward message to interactive chats
_exec_if_function send_interactive "${CHAT[ID]}" "${MESSAGE}"
;;
esac

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# this has to run once atfer git clone
# and every time we create new hooks
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-1-g2a66ee9
# magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script

View File

@ -3,7 +3,7 @@
#
# works together with git pre-push.sh and ADD all changed files since last push
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-20-gbd22e2a
############
# NOTE: you MUST run install-hooks.sh again when updating this file!
@ -30,7 +30,7 @@ fi
# run shellcheck before commit
set +f
FILES="$(find ./* -name '*.sh' | grep -v 'DIST\/' )"
FILES="$(find ./* -name '*.sh' | grep -v 'DIST\/' | grep -v 'STANDALONE\/')"
set -f
FILES="${FILES} $(sed '/^#/d' <"dev/shellcheck.files")"
if [ "$FILES" != "" ]; then

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
############
# NOTE: you MUST run install-hooks.sh again when updating this file!

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# this has to run once atfer git clone
# and every time we create new hooks
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script

View File

@ -2,7 +2,7 @@
# file: make-distribution.sh
# creates files and arcchives to dirtribute bashbot
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ 0.96-dev2-6-gda98b09
# magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script
@ -21,9 +21,9 @@ DISTFILES="bashbot.rc bashbot.sh commands.sh mycommands.sh mycommands.sh.clean d
# run tests first!
for test in "dev/all-tests.sh"
for test in dev/all-test*.sh
do
[ ! -x ""${test} ] && continue
[ ! -x "${test}" ] && continue
if ! "${test}" ; then
echo "Test ${test} failed, can't create dist!"
exit 1

View File

@ -5,7 +5,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$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-22-g19c45c4
# magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script
@ -18,18 +18,10 @@ fi
#DISTNAME="telegram-bot-bash"
DISTDIR="./STANDALONE/${DISTNAME}"
DISTFILES="bashbot.sh commands.sh mycommands.sh modules LICENSE README.txt token count botacl botadmin"
DISTFILES="bashbot.sh bashbot.rc commands.sh mycommands.sh dev/obfuscate.sh modules LICENSE README.txt token count botacl botadmin"
# run tests first!
for test in "dev/all-tests.sh"
do
[ ! -x "${test}" ] && continue
if ! "${test}" ; then
echo "Test ${test} failed, can't create standalone!"
exit 1
fi
done
# run pre_commit on files
dev/hooks/pre-commit.sh
# create dir for distribution and copy files
mkdir -p "${DISTDIR}" 2>/dev/null
@ -41,7 +33,7 @@ cd "${DISTDIR}" || exit 1
# here the magic starts
# create all in one bashbot.sh file
echo "OK, noe lets do the magic ..."
echo "OK, now lets do the magic ..."
echo " ... create unified commands.sh"
{
@ -73,7 +65,7 @@ echo " ... create unified bashbot.sh"
# last tail of commands.sh
printf '\n##############################\n# bashbot internal functions starts here ...\n\n'
sed -n '/BASHBOT INTERNAL functions/,$ p' bashbot.sh | head -n -4
sed -n '/BASHBOT INTERNAL functions/,$ p' bashbot.sh
} >>$$bashbot.sh
@ -82,6 +74,11 @@ chmod +x bashbot.sh
rm -rf modules
echo "Create minimized Version of bashbot.sh and commands.sh"
sed -E -e '/(shellcheck)|(#!\/bin\/bash)/! s/^[[:space:]]*#.*//' -e 's/^[[:space:]]*//' -e '/^$/d' bashbot.sh > bashbot.sh.min
sed -E -e '/(shellcheck)|(#!\/bin\/bash)/! s/^[[:space:]]*#.*//' -e 's/^[[:space:]]*//' -e '/^$/d' commands.sh > commands.sh.min
chmod +x bashbot.sh.min
echo "Done!"
cd .. || exit 1

18
dev/obfuscate.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
# shellcheck disable=SC2028,2016
# joke hack to obfuscate bashbot.min.sh
infile="bashbot.sh"
outfile="./bashbot.obf.sh"
[ ! -f "${infile}" ] && echo "Hey, this is a joke hack to obfuscate ${infile}, copy me to STANDANLONE first" && exit
{
echo '#!/bin/bash'
echo 'b="./bashbot";h="$PWD";cd "$(mktemp -d)"||exit'
echo 'printf '"'%s\n'"' '"'$(gzip -9 <bashbot.sh | base64)'"'|base64 -d|gunzip >"$b";export BASHBOT_HOME="$h";chmod +x "$b";"$b" "$@";b="$(pwd)";cd ..;rm -rf "$b"'
} >"${outfile}"
chmod +x "${outfile}"
ls -l "${outfile}"
echo "Try to run ${outfile} init ;-)"

View File

@ -1,4 +1,4 @@
# list of additional files to check from shellcheck
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
bashbot.rc
mycommands.sh.clean

View File

@ -1,6 +1,6 @@
#!/bin/bash
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# shellcheck disable=SC2016
#
# Easy Versioning in git:

View File

@ -101,5 +101,5 @@ The old format is supported for backward compatibility, but may fail for corner
#### [Next Create Bot](1_firstbot.md)
#### $$VERSION$$ V0.94-8-g876361f
#### $$VERSION$$ v0.96-dev-7-g0153928

View File

@ -65,5 +65,5 @@ group. This step is up to you actually.
#### [Prev Installation](0_install.md)
#### [Next Getting started](2_usage.md)
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928

View File

@ -17,36 +17,44 @@ Have FUN!
### Files
```
.
├── mycommands.sh # THIS is your bot, place logic and commands here!
├── mycommands.sh # THIS is your bot, place logic and commands here!
├── mycommands.sh.clean # copy to "mycommands.sh" if you start devloping your bot
├── mycommands.sh.dist # example bot, also used for testing bashbot internally
├── mycommands.sh.clean # copy to "mycommands.sh" if you start devloping your bot
├── mycommands.sh.dist # example bot, also used for testing bashbot internally
├── bashbot.sh # main bashbot script - DO NOT EDIT!
├── commands.sh # command dispatcher - DO NOT EDIT!
├── JSON.sh # bashbots JSON parser, see https://github.com/dominictarr/JSON.sh
├── count.jssh # count bashbot usage in jssh key-value store
├── blocked.jssh # list of blocked USER[ID] in jssh key-value store
├── modules # optional functions, sourced by commands.sh
│   ├── aliases.sh # to disable modules rename them xxx.sh.off
├── bashbot.sh # main bashbot script - DO NOT EDIT!
├── commands.sh # command dispatcher - DO NOT EDIT!
├── JSON.sh # bashbots JSON parser, see https://github.com/dominictarr/JSON.sh
├── scripts # place your bashbot interactive and background scripts here
│   └── interactive.sh.clean # interactive script template for new scripts
├── logs # here you'll find ERROR, DEBUG and MESSAGE.log
├── modules # optional functions, sourced by commands.sh
│   ├── aliases.sh # to disable modules rename them xxx.sh.off
│   ├── answerInline.sh
│   ├── jsshDB.sh # read and store JSON.sh stlye JSON
│   ├── background.sh # interactive and background functions
│   ├── jsshDB.sh # read and store JSON.sh stlye JSON, mandatory
│   ├── background.sh # interactive and background functions
│   ├── chatMember.sh
│   └── sendMessage.sh # main send message functions, do not disable
│   └── sendMessage.sh # main send message functions, mandatory
├── addons # optional addons, disbaled by default
│   ├── example.sh # to enable addons change their XXX_ENABLE to true
│   ├── antiFlood.sh # simple addon taking actions based on # files and text sent to chat
├── addons # optional addons, disbaled by default
│   ├── example.sh # to enable addons change their XXX_ENABLE to true
│   ├── antiFlood.sh # simple addon taking actions based on # files and text sent to chat
│   └── xxxxxage.sh
├── bashbot.rc # start/stop script if you run basbot as service
├── bashbot.rc # start/stop script if you run basbot as service
├── examples # example scripts and configs for bashbot
│   ├── README.md # description of files and examples
│   ├── bash2env.shh # script to convert /bin/bash shebang to /usr/bin/env, see [Security Considerations](../README.md#Security-Considerations)
│   └── bashbot.cron # example crontab
├── examples # example scripts and configs for bashbot
│   ├── README.md # description of files and examples
│   ├── bash2env.sh # script to convert shebang to /usr/bin/env, see [Security Considerations](../README.md#Security-Considerations)
│   └── bashbot.cron # example crontab
├── doc # Documentation and License
├── doc # Documentation and License
├── html
├── LICENSE
├── README.html
@ -69,14 +77,21 @@ Start or Stop your Bot use the following commands:
./bashbot.sh kill
```
### User count
### User stats
deprecated, will be removed!
To count the total number of users and messages run the following command:
```
./bashbot.sh stats
```
### Sending broadcasts to all users
To send a broadcast to all of users that ever used the bot run the following command:
```
./bashbot.sh broadcast "Hey! I just wanted to let you know that the bot's been updated!"
```
deprecated, will be removed!
----
@ -241,5 +256,5 @@ send_action "${CHAT[ID]}" "action"
#### [Prev Create Bot](1_firstbot.md)
#### [Next Advanced Usage](3_advanced.md)
#### $$VERSION$$ V0.94-2-gced78d3
#### $$VERSION$$ v0.96-dev3-14-g5fc4d01a

View File

@ -21,7 +21,9 @@ user_is_botadmin "${USER[ID]}" && send_markdown_message "${CHAT[ID]}" "You are *
user_is_admin "${CHAT[ID]}" "${USER[ID]}" && send_markdown_message "${CHAT[ID]}" "You are *CHATADMIN*."
```
In addition you can check individual capabilities of users as you must define in the file ```./botacl```:
```bash
# file: botacl
# a user not listed here, will return false from 'user_is_allowed'
@ -45,6 +47,7 @@ In addition you can check individual capabilities of users as you must define in
*:*:98979695
```
You must use the function ```user_is_allowed``` to check if a user has the capability to do something. Example: Check if user has capability to start bot.
```bash
case "$MESSAGE" in
################################################
@ -61,13 +64,37 @@ You must use the function ```user_is_allowed``` to check if a user has the capab
**See also [Bashbot User Access Control functions](6_reference.md#User-Access-Control)**
### Interactive Chats
To create interactive chats, write *(or edit the 'exmaples/question.sh' script)* a bash *(or C or python)* script, make it executable
and then use the 'startproc' function to start the script.
The output of the script will be sent to the user and user input will be sent to the script.
To stop the script use the function 'killprog'
Interactive chats are scripts, reading user input and echo data to the user.
The output of the script will be processed by 'send_messages' to enable you to not only send text, but also keyboards, files, locations and more.
Each newline in the output will start an new message to the user, to have line breaks in your message you can use 'mynewlinestartshere'.
To create a new interactive chat script copy 'scripts/interactive.sh.clean' to e.g. 'scripts/mynewinteractive.sh', make it executeable
and then use 'start_proc' function from your bot, it's possible to pass two arguments. You find more examples for interactive scripts in 'examples'
*usage*: start_proc chat_id script arg1 arg2
**Note:** From Version 0.96 on scripts must read user input from '$3' instead of stdin!
```bash
#!/bin/bash
######
# parameters
# $1 $2 args as given to start_proc chat srcipt arg1 arg2
# $3 path to named pipe
#######################
# place your commands here
#
INPUT="${3:-/dev/stdin}" # read from stdin if run in terminal
echo "Enter a message:"
read -r test <"${INPUT}"
echo -e "Your Message: ${test}\nbye!"
```
#### message formatting and keyboards
The output of the script will be processed by 'send_messages', so you can not only send text, but also keyboards, files, locations and more.
Each newline in the output will start an new message to the user, to insert line breaks in your message you must insert ' mynewlinestartshere ' instead of a newline..
To open up a keyboard in an interactive script, print out the keyboard layout in the following way:
```bash
@ -107,7 +134,6 @@ out="Text that will appear mylatstartshere 45 mylongstartshere 45"
[[ "$out" != *'in chat'* ]] && out="$out mytextstartshere in chat."
echo "$out"
```
Note: Interactive Chats run independent from main bot and continue running until your script exits or you /cancel if from your Bot.
### Background Jobs
@ -180,5 +206,5 @@ See also [answer_inline_multi, answer_inline_compose](6_reference.md#answer_inli
#### [Prev Getting started](2_usage.md)
#### [Next Expert Use](4_expert.md)
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-13-g601fe0e

View File

@ -277,6 +277,26 @@ Uses given URL instead of offical telegram API URL, useful if you have your own
```
##### BASHBOT_TOKEN
If BASHBOT_TOKEN is set, bashbot assumes you know what you are doing and skips environment validation and
uses the value of BASHBOT_TOKEN as bot token.
I recommend to run 'bashbot.sh init' at least one time without BASHBOT_TOKEN set to validate and setup
the environment. Afterwards you can delete the token file and provide the bot token in BASHBOT_TOKEN.
##### BASHBOT_CURL_ARGS
The value of BASHBOT_CURL_ARGS is passed to every curl execution.
```bash
# use socks gateway on localhost
export BASHBOT_CURL_ARGS="--socks5-hostname localhost"
```
##### BASHBOT_CURL
If BASHBOT_CURL is not set your systems default curl is used. If you want to use an alternative curl executable
set BASHBOT_CURL to point to it.
```bash
# use curl from /usr/local/bin
export BASHBOT_CURL="/usr/local/bin/mycurl"
```
##### BASHBOT_WGET
Bashbot uses ```curl``` to communicate with telegram server. if ```curl``` is not availible ```wget``` is used.
@ -290,6 +310,20 @@ If 'BASHBOT_WGET' is set to any value (not undefined or not empty) wget is used
```
##### BASHBOT_TIMEOUT
Bashbot uses a default timeout of 20 seconds for curl and wget. If you want a different timeout, set
BASHBOT_TIMEOUT to a numeric value between 1 and 999. Any non numeric or negative value is ignored.
```bash
# set timeout to 100 seconds
export BASHBOT_TIMEOUT="100"
# 100s is not a numbers
export BASHBOT_TIMEOUT="100s" # wrong, default timeout is used
# -100 is not between 1 and 999s
export BASHBOT_TIMEOUT="-100" # wrong, default timeout is used
```
##### BASHBOT_SLEEP
Instead of polling permanently or with a fixed delay, bashbot offers a simple adaptive polling.
If messages are recieved bashbot polls with no dealy. If no messages are availible bashbot add 100ms delay
@ -348,5 +382,5 @@ for every poll until the maximum of BASHBOT_SLEEP ms.
#### [Prev Advanced Use](3_advanced.md)
#### [Next Best Practice](5_practice.md)
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-17-g720dc59

View File

@ -152,5 +152,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$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928

View File

@ -462,19 +462,50 @@ Usually message is automatically forwarded in 'commands.sh', but you can forwar
----
### jsshDB
Since output generated by JSON.sh is so handy to use in bash, we use the format for a simple keys/value storage and providing
fucntions to read and write JSON.sh style data from and to files.
Since output generated by JSON.sh is so handy to use in bash, we use the format for a simple keys/value file store.
The file extions is '.jssh' and for security reasons location of jssh files is restricted to BASHBOT_ETC and BASHBOT_DATA..
Note: File names containg '..' and absolute file names pointing outside BASHBOT_ETC or BASHBOT_DATA are refused by jsshDB functions.
#### fast and slow operations
Note2: Since version 0.94 jsshDB functions support file locking with flock. Write / Update operations use flock to wait until
previous operations are finished. see "man flock" for more information. Bashbot uses a maximum timeout of 10 seconds for flock.
jsshDB files are simple text files and if you append a new Key/value pairs to the end of the file it overwrites
an existing key/value pair. We use this behaivor for "fast" file operations.
If you don't want atomic write / update operations use the *_async variant of jsshDB functions. If flock is not availible
the *_async variant is automatically used.
"fast funtions" add a new key/value pair to the end of the file without deleting an existing one, this is fast but over (long)
time the file grows infinitly.
*Example:* for file name:
"slow funtions" in contrast modify the key/value pairs in place and write the whole file back,
this is slower but clean up the file. All previously added key/value pairs are replaced
and only the last one is written back to the file.
fast functions:
```
jssh_insertKeyDB , jssh_addKeyDB , jssh_countKeyDB
```
slow functions:
```
jssh_writeDB, jssh_updateDB , jssh_deleteKeyDB, jssh_clearDB
```
#### File naming and locking
A jssh fileDB consists of two files which must reside inside BASHBOT_ETC or BASHBOT_DATA.
- `filename.jssh` is a text file containing the key/value data in json.sh format.
- `filename.jssh.flock` is used for read/write locking with flock
Path names containing `..` or not located in BASHBOT_ETC or BASHBOT_DATA are refused by jsshDB functions with an error.
Since version 0.94 jsshDB functions support file locking with flock. write/update operations are serialised with flock to wait until
previous operations are finished, see "man flock" for information. To avoid deadlocks we use a timeout of 10s for write and 5s for read operations.
Every jssh_*DB function exist as jssj_*DB_async also.
In case flock is not availibe or you don't want locking, jssh_*DB_async functions without file locking will be used.
*Example:* for allowed file names:
```bash
# bashbot is installed in /usr/local/telegram-bot-bash, BASHBOT_ETC is not set.
"myfile" -> /usr/local/telegram-bot-bash/myfile.jssh
@ -488,12 +519,25 @@ Creats new empty jsshDB file if not exist.
*usage:* jssh_newDB "filename"
*usage:* jssh_newDB_async "filename"
##### jssh_clearDB
Delete all contents of jsshDB file.
*usage:* jssh_clearDB "filename"
*usage:* jssh_clearDB_async "filename"
##### jssh_checkDB
Check if DB name respects the rules mentioned above and returns the real/final path to DB file.
Check if DB name respects the rules mentioned above and print to STDOUT 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.
An error is returned and nothing is printed if the given filename is not valid
*usage:* jssh_checkDB "filename"
*usage:* jssh_checkDB_async "filename"
```bash
if file=$(jssh_checkDB somename); then
echo "Final filename is ${file}"
@ -659,18 +703,20 @@ jssh_printDB READVALUES
["whynot","subindex1"] "whynot A"
```
##### jssh_insertDB
##### jssh_insertKeyDB
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"
*usage:* jssh_insertKeyDB "key" "value" "filename"
*usage:* jssh_insertDB_asnyc "key" "value" "filename"
*usage:* jssh_insertKeyDB_asnyc "key" "value" "filename"
Note: insertDB uses also excusiv write locking, but with a maximum timeout of 2s. insertDB is a "fast" operation, simply adding the value to the end of the file.
*deprecated:* jssh_insertDB *was renamed in verion 0.96 to* jssh_insertKeyDB
Note: inserKeytDB uses also excusive write locking, but with a maximum timeout of 2s. insertKeyDB is a "fast" operation, simply adding the value to the end of the file.
*example:*
```bash
jssh_insertDB "newkey" "an other value" "${DATADIR:-.}/myvalues"
jssh_insertKeyDB "newkey" "an other value" "${DATADIR:-.}/myvalues"
```
##### jssh_deleteKeyDB
@ -685,6 +731,22 @@ Deleted a key=value pair froma jsshDB file, key name is only allowed to contain
jssh_deleteKeyDB "delkey"" "${DATADIR:-.}/myvalues"
```
##### jssh_countKeyDB
Increase a key=value pair from a jsshDB file by 1, key name is only allowed to contain '-a-zA-Z0-9,._'
If value is given key is increased by value.
Side effect: if value is given key is updated "in place" (slower) and file is cleand up, if no value is given fast path is used
and new count is added to the end of file.
*usage:* jssh_countKeyDB "key" "filename" ["value"]
*usage:* jssh_countKeyDB_async "key" "filename" ["value"]
*example:*
```bash
jssh_countKeyDB "usercount"" "${DATADIR:-.}/myvalues"
```
https://linuxhint.com/associative_array_bash/
https://linuxconfig.org/how-to-use-arrays-in-bash-script
@ -973,5 +1035,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.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-5-g407e147

View File

@ -328,5 +328,5 @@ fi
#### [Prev Function Reference](6_reference.md)
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928

View File

@ -55,6 +55,6 @@ convert existing bots.
**external-use** will contain some examples on how to send messages from external scripts to Telegram chats or users.
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928

View File

@ -1,10 +1,16 @@
#!/bin/bash
# file: run_diskcusage.sh
# example for an background job display a system value
#
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-12-g3f85134
######
# parameters
# $1 $2 args as given to starct_proc chat srcipt arg1 arg2
# $3 path to named pipe/log
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment

View File

@ -2,7 +2,13 @@
# file: run_filename
# background job to display content of all new files in WATCHDIR
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-12-g3f85134
######
# parameters
# $1 $2 args as given to starct_proc chat srcipt arg1 arg2
# $3 path to named pipe/log
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment
@ -33,3 +39,4 @@ loop_callback() {
}
watch_dir_loop "$WATCHDIR"

View File

@ -2,7 +2,13 @@
# file: run_filename
# background job to display all new files in WATCHDIR
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-12-g3f85134
######
# parameters
# $1 $2 args as given to starct_proc chat srcipt arg1 arg2
# $3 path to named pipe/log
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment
@ -31,3 +37,4 @@ loop_callback() {
}
watch_dir_loop "$WATCHDIR"

View File

@ -1,10 +1,16 @@
#!/bin/bash
# file: notify.sh
# example for an background job, run with startback notify.sh
#
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-12-g3f85134
######
# parameters
# $1 $2 args as given to starct_proc chat srcipt arg1 arg2
# $3 path to named pipe/log
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment

View File

@ -6,7 +6,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.94-7-g3d92bf3
#### $$VERSION$$ v0.96-dev-7-g0153928
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment

View File

@ -2,7 +2,7 @@
# file. multibot.sh
# description: run multiple telegram bots from one installation
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
if [ "${2}" = "" ] || [ "${2}" = "-h" ]; then
echo "Usage: $0 botname command"

View File

@ -7,7 +7,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.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
SHELL=/bin/sh

View File

@ -1,11 +1,18 @@
#!/bin/bash
# file: calc.sh
# example for an interactive chat, run with startproc calc.sh
#
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
#### $$VERSION$$ v0.96-dev3-12-g3f85134
#### $$VERSION$$ V0.94-0-gbdb50c8
######
# parameters
# $1 $2 args as given to starct_proc chat srcipt arg1 arg2
# $3 path to named pipe/log
INPUT="${3:-/dev/stdin}"
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment
@ -18,11 +25,11 @@ unset IFS
echo 'Starting Calculator ...'
echo 'Enter first number.'
read -r A
read -r A <"${INPUT}"
echo 'Enter second number.'
read -r B
read -r B <"${INPUT}"
echo 'Select Operation: mykeyboardstartshere [ "Addition" , "Subtraction" , "Multiplication" , "Division" , "Cancel" ]'
read -r opt
read -r opt <"${INPUT}"
echo -n 'Result: '
case $opt in
'add'* | 'Add'* ) res="$(( A + B ))" ;;
@ -34,3 +41,4 @@ case $opt in
esac
echo "$res"
echo "Bye .."

View File

@ -1,10 +1,16 @@
#!/bin/bash
# file: notify.sh
# example for an background job, run with startback notify.sh
#
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-12-g3f85134
######
# parameters
# $1 $2 args as given to starct_proc chat srcipt arg1 arg2
# $3 path to named pipe/log
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment

View File

@ -1,11 +1,19 @@
#!/bin/bash
# file: question.sh
# example for an interactive chat, run with startproc question.sh
#
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
#### $$VERSION$$ v0.96-dev3-14-g5fc4d01a
######
# parameters
# $1 $2 args as given to starct_proc chat srcipt arg1 arg2
# $3 path to named pipe
INPUT="${3:-/dev/stdin}"
#### $$VERSION$$ V0.94-0-gbdb50c8
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment
@ -18,16 +26,16 @@ unset IFS
echo "Why hello there.
Would you like some tea (y/n)?"
read -r answer
read -r answer <"${INPUT}"
[[ $answer =~ ^([yY][eE][sS]|[yY])$ ]] && echo "OK then, here you go: http://www.rivertea.com/blog/wp-content/uploads/2013/12/Green-Tea.jpg" || echo "OK then."
until [ "$SUCCESS" = "y" ] ;do
echo 'Do you like Music? mykeyboardstartshere "Yass!" , "No"'
read -r answer
read -r answer <"${INPUT}"
case $answer in
'Yass!') echo "Goody! mykeyboardendshere";SUCCESS=y;;
'No') echo "Well that's weird. mykeyboardendshere";SUCCESS=y;;
'') echo "empty answer!" && exit;;
'') echo "empty answer!" && exit ;;
*) SUCCESS=n;;
esac
done
exit

View File

@ -1,7 +1,7 @@
# file: botacl
# a user not listed here, will return false from 'user_is_allowed'
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# Format:
# user:ressource:chat

View File

@ -5,7 +5,7 @@
# to show how you can customize bashbot by only editing mycommands.sh
# NOTE: this is not tested, simply copied from original source and reworked!
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
#
# shellcheck disable=SC2154
# shellcheck disable=SC2034

View File

@ -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$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
#
# source from commands.sh to use the aliases

View File

@ -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$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# source from commands.sh to use the inline functions

View File

@ -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$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-pre-0-geb49241
# source from commands.sh if you want ro use interactive or background jobs
@ -39,23 +39,29 @@ killproc() {
# $1 chatid
# $2 program
# $3 jobname
# $4 $5 parameters
start_back() {
local fifo; fifo="${DATADIR:-.}/$(procname "$1")"
printf '%s\n' "$1:$3:$2" >"${fifo}$3-back.cmd"
start_proc "$1" "$2" "back-$3-"
#local fifo; fifo="${DATADIR:-.}/$(procname "$1")"
printf '%s\n' "$1:$3:$2" >"${DATADIR:-.}/$(procname "$1")$3-back.cmd"
restart_back "$@"
}
restart_back() {
local fifo; fifo="${DATADIR:-.}/$(procname "$1" "back-$3-")"
kill_proc "$1" "back-$3-"
nohup bash -c "{ $2 \"$4\" \"$5\" \"${fifo}\" | \"${SCRIPT}\" outproc \"${1}\" \"${fifo}\"; }" &>>"${fifo}.log" &
}
# $1 chatid
# $2 program
# $3 prefix
# $3 $4 parameters
start_proc() {
[ -z "$2" ] && return
[ -x "${2%% *}" ] || return 1
local fifo; fifo="${DATADIR:-.}/$(procname "$1" "$3")"
kill_proc "$1" "$3"
local fifo; fifo="${DATADIR:-.}/$(procname "$1")"
kill_proc "$1"
mkfifo "${fifo}"
nohup bash -c "{ tail -f < \"${fifo}\" | $2 \"\" \"\" \"$fifo\" | \"${SCRIPT}\" outproc \"${1}\" \"${fifo}\"
nohup bash -c "{ $2 \"$4\" \"$5\" \"$fifo\" | \"${SCRIPT}\" outproc \"${1}\" \"${fifo}\"
rm \"${fifo}\"; [ -s \"${fifo}.log\" ] || rm -f \"${fifo}.log\"; }" &>>"${fifo}.log" &
}
@ -95,7 +101,7 @@ kill_proc() {
[ -p "${fifo}" ] && rm -f "${fifo}";
}
# $1 chat
# $1 chatid
# $2 message
send_interactive() {
local fifo; fifo="${DATADIR:-.}/$(procname "$1")"
@ -120,20 +126,20 @@ job_control() {
CHAT="${content%%:*}"
job="${content#*:}"
proc="${job#*:}"
job="back-${job%:*}-"
job="${job%:*}"
fifo="$(procname "${CHAT}" "${job}")"
case "$1" in
"resumeb"*|"backgr"*)
echo "Restart Job: ${proc} ${fifo}"
start_proc "${CHAT}" "${proc}" "${job}"
printf "Restart Job: %s %s\n" "${proc}" " ${fifo}"
restart_back "${CHAT}" "${proc}" "${job}"
;;
"suspendb"*)
echo "Suspend Job: ${proc} ${fifo}"
printf "Suspend Job: %s %s\n" "${proc}" " ${fifo}"
kill_proc "${CHAT}" "${job}"
killall="y"
;;
"killb"*)
echo "Kill Job: ${proc} ${fifo}"
printf "Kill Job: %s %s\n" "${proc}" " ${fifo}"
kill_proc "${CHAT}" "${job}"
rm -f "${FILE}" # remove job
killall="y"

View File

@ -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$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# source once magic, function named like file
eval "$(basename "${BASH_SOURCE[0]}")(){ :; }"

View File

@ -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$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-pre-0-geb49241
#
# source from commands.sh to use jsonDB functions
#
@ -36,7 +36,7 @@ if _exists flock; then
local DB; DB="$(jssh_checkDB "$2")"
[ -z "${DB}" ] && return 1
[ ! -f "${DB}" ] && return 2
# shared lock, many processes can read, maximum wait 1s
# shared lock, many processes can read, max wait 1s
{ flock -s -w 1 200; Json2Array "$1" <"${DB}"; } 200>"${DB}${BASHBOT_LOCKNAME}"
}
@ -63,7 +63,7 @@ if _exists flock; then
declare -n ARRAY="$1"
[ -z "${ARRAY[*]}" ] && return 1
declare -A oldARR newARR
declare -A oldARR
# start atomic update here, exclusive max wait 10s
{ flock -e -w 10 200
@ -73,14 +73,12 @@ if _exists flock; then
Array2Json "$1" >"${DB}"
else
# merge arrays
local o1 o2 n1 n2
o1="$(declare -p oldARR)"; o2="${o1#*\(}"
n1="$(declare -p ARRAY)"; n2="${n1#*\(}"
unset IFS; set -f
#shellcheck disable=SC2034,SC2190,SC2206
newARR=( ${o2:0:${#o2}-1} ${n2:0:${#n2}-1} )
set +f
Array2Json "newARR" >"${DB}"
local key
for key in "${!ARRAY[@]}"
do
oldARR["${key}"]="${ARRAY["${key}"]}"
done
Array2Json "oldARR" >"${DB}"
fi
} 200>"${DB}${BASHBOT_LOCKNAME}"
}
@ -89,13 +87,15 @@ if _exists flock; then
# $1 key name, can onyl contain -a-zA-Z0-9,._
# $2 key value
# $3 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'
jssh_insertDB() {
alias jssh_insertDB=jssh_insertKeyDB # backward compatibility
# renamed to be more consistent
jssh_insertKeyDB() {
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
local key="$1" value="$2"
local DB; DB="$(jssh_checkDB "$3")"
[ -z "${DB}" ] && return 1
[ ! -f "${DB}" ] && return 2
# start atomic update here, exclusive max wait 2si, it's append, not overwrite
# start atomic update here, exclusive max wait 2, it's append, not overwrite
{ flock -e -w 2 200
# it's append, but last one counts, its a simple DB ...
printf '["%s"]\t"%s"\n' "${key//,/\",\"}" "${value//\"/\\\"}" >>"${DB}"
@ -118,30 +118,79 @@ if _exists flock; then
} 200>"${DB}${BASHBOT_LOCKNAME}"
}
# get key/value from jsshDB
# $1 key name, can onyl contain -a-zA-Z0-9,._
# $2 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'
alias jssh_getDB=jssh_getKeyDB
jssh_getKeyDB() {
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
local DB; DB="$(jssh_checkDB "$2")"
declare -A oldARR
# start atomic delete here, exclusive max wait 1s
{ flock -s -w 1 200
Json2Array "oldARR" <"${DB}"
} 200>"${DB}${BASHBOT_LOCKNAME}"
printf '%f' "${oldARR["$1"]}"
}
# add a value to key, used for conters
# $1 key name, can onyl contain -a-zA-Z0-9,._
# $2 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'
# $3 optional count, value added to counter, add 1 if empty
# side effect: if $3 is not given, we add to end of file to be as fast as possible
jssh_countKeyDB() {
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
local DB; DB="$(jssh_checkDB "$2")"
declare -A oldARR
# start atomic delete here, exclusive max wait 5
{ flock -e -w 5 200
Json2Array "oldARR" <"${DB}"
if [ "$3" != "" ]; then
(( oldARR["$1"]+="$3" ));
Array2Json "oldARR" >"${DB}"
else
# it's append, but last one counts, its a simple DB ...
(( oldARR["$1"]++ ));
printf '["%s"]\t"%s"\n' "${1//,/\",\"}" "${oldARR["$1"]//\"/\\\"}" >>"${DB}"
fi
} 200>"${DB}${BASHBOT_LOCKNAME}"
}
# update key/value in place to jsshDB
# $1 key name, can onyl contain -a-zA-Z0-9,._
# $2 key value
# $3 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'
#no own locking, so async is the same as updatekeyDB
jssh_updateKeyDB() {
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
declare -A oldARR
oldARR["$1"]="$2"
jssh_updateDB "oldARR" "${3}" || return 3
}
# $1 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'
jssh_clearDB() {
local DB; DB="$(jssh_checkDB "$1")"
[ -z "${DB}" ] && return 1
{ flock -e -w 10 200
printf '' >"${DB}"
} 200>"${DB}${BASHBOT_LOCKNAME}"
}
else
#########
# we have no flock, use "old" not atomic functions
jssh_readDB() {
jssh_readDB_async "$@"
}
jssh_writeDB() {
jssh_writeDB_async "$@"
}
jssh_updateDB() {
jssh_updateDB_async "$@"
}
jssh_insertDB() {
jssh_insertDB_async "$@"
}
jssh_deleteKeyDB() {
jssh_deleteKeyDB_async "$@"
}
alias jssh_readDB=ssh_readDB_async
alias jssh_writeDB=jssh_writeDB_async
alias jssh_updateDB=jssh_updateDB_async
alias jssh_insertDB=jssh_insertDB_async
alias ssh_deleteKeyDB=jssh_deleteKeyDB_async
alias jssh_getDB=jssh_getKeyDB_async
alias jssh_getKeyDB=jssh_getKeyDB_async
alias jssh_countKeyDB=jssh_countKeyDB_async
alias jssh_updateKeyDB=jssh_updateKeyDB_async
alias jssh_clearDB=jssh_clearDB_async
fi
##############
@ -149,45 +198,38 @@ fi
# print ARRAY content to stdout instead of file
# $1 ARRAY name, must be delared with "declare -A ARRAY" upfront
jssh_printDB_async() { jssh_printDB "$@"; }
jssh_printDB() {
Array2Json "$1"
}
# get key/value from jsshDB
# $1 key name, can onyl contain -a-zA-Z0-9,._
# $2 key value
# $3 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'
# returns value
jssh_getDB() {
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
declare -A getARR
jssh_readDB "getARR" "$3" || return "$?"
printf '%s\n' "${getARR[${key}]}"
}
# $1 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'
jssh_newDB_async() { jssh_newDB "$@"; }
jssh_newDB() {
local DB; DB="$(jssh_checkDB "$1")"
[ -z "${DB}" ] && return 1
[ -f "${DB}" ] && return 2 # already exist, do not zero out
printf '\n' >"${DB}"
[ -f "${DB}" ] && return 2 # already exist
touch "${DB}"
}
# $1 filename, check filename, it must be relative to BASHBOT_ETC, and not contain '..'
# $1 filename, check filename, it must be relative to BASHBOT_VAR, and not contain '..'
# returns real path to DB file if everything is ok
jssh_checkDB_sync() { jssh_checkDB "$@"; }
jssh_checkDB(){
local DB
[ -z "$1" ] && return 1
local DB="${BASHBOT_ETC:-.}/$1.jssh"
if [[ "$1" = "${BASHBOT_ETC:-.}"* ]] || [[ "$1" = "${BASHBOT_DATA:-.}"* ]]; then
DB="$1.jssh"
fi
[[ "$1" = *'..'* ]] && return 2
printf '%s\n' "${DB}"
if [[ "$1" == "${BASHBOT_VAR:-.}"* ]] || [[ "$1" == "${BASHBOT_DATA:-.}"* ]]; then
DB="$1.jssh"
else
DB="${BASHBOT_VAR:-.}/$1.jssh"
fi
printf '%s' "${DB}"
}
######################
# "old" implementations as non atomic functions
# implementations as non atomic functions
# can be used explictitly or as fallback if flock is not availible
jssh_readDB_async() {
local DB; DB="$(jssh_checkDB "$2")"
@ -206,25 +248,24 @@ jssh_writeDB_async() {
jssh_updateDB_async() {
declare -n ARRAY="$1"
[ -z "${ARRAY[*]}" ] && return 1
declare -A oldARR newARR
declare -A oldARR
jssh_readDB_async "oldARR" "$2" || return "$?"
if [ -z "${oldARR[*]}" ]; then
# no old content
jssh_writeDB_async "$1" "$2"
else
# merge arrays
local o1 o2 n1 n2
o1="$(declare -p oldARR)"; o2="${o1#*\(}"
n1="$(declare -p ARRAY)"; n2="${n1#*\(}"
unset IFS; set -f
#shellcheck disable=SC2034,SC2190,SC2206
newARR=( ${o2:0:${#o2}-1} ${n2:0:${#n2}-1} )
set +f
jssh_writeDB_async "newARR" "$2"
local key
for key in "${!ARRAY[@]}"
do
oldARR["${key}"]="${ARRAY["${key}"]}"
done
Array2Json "oldARR" >"${DB}"
fi
}
jssh_insertDB_async() {
jssh_insertDB_async() { jssh_insertKeyDB "$@"; }
jssh_insertKeyDB_async() {
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
local key="$1" value="$2"
local DB; DB="$(jssh_checkDB "$3")"
@ -244,3 +285,41 @@ jssh_deleteKeyDB_async() {
jssh_writeDB_async "oldARR" "$2"
}
jssh_getKeyDB_async() {
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
local DB; DB="$(jssh_checkDB "$2")"
declare -A oldARR
Json2Array "oldARR" <"${DB}"
printf '%s' "${oldARR["$1"]}"
}
jssh_countKeyDB_async() {
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
local DB COUNT="1"; DB="$(jssh_checkDB "$2")"
[ "$3" != "" ] && COUNT="$3"
declare -A oldARR
# start atomic delete here, exclusive max wait 10s
Json2Array "oldARR" <"${DB}"
(( oldARR["$1"]+=COUNT ));
Array2Json "oldARR" >"${DB}"
}
# updatie key/value in place to jsshDB
# $1 key name, can onyl contain -a-zA-Z0-9,._
# $2 key value
# $3 filename (must exist!), must be relative to BASHBOT_ETC, and not contain '..'
#no own locking, so async is the same as updatekeyDB
jssh_updateKeyDB_async() {
[[ "$1" =~ ^[-a-zA-Z0-9,._]+$ ]] || return 3
declare -A oldARR
oldARR["$1"]="$2"
jssh_updateDB_async "oldARR" "${3}" || return 3
}
jssh_clearDB_async() {
local DB; DB="$(jssh_checkDB "$1")"
[ -z "${DB}" ] && return 1
printf '' >"${DB}"
}

View File

@ -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$$ v0.941-0-ga055b77
#### $$VERSION$$ 0.96-dev2-7-g6d1e7cc
# source once magic, function named like file
eval "$(basename "${BASH_SOURCE[0]}")(){ :; }"
@ -40,6 +40,16 @@ send_markdown_message() {
done
}
send_markdownv2_message() {
local text; text="$(JsonEscape "${2}")"
# markdown v2 needs additional double escaping!
text="$(sed -E -e 's|([#{}()!.-])|\\\1|g' <<< "$text")"
until [ -z "${text}" ]; do
sendJson "${1}" '"text":"'"${text:0:4096}"'","parse_mode":"markdownv2"' "${MSG_URL}"
text="${text:4096}"
done
}
send_html_message() {
local text; text="$(JsonEscape "${2}")"
until [ -z "${text}" ]; do
@ -179,6 +189,7 @@ send_message() {
[ -z "$2" ] && return
local text keyboard btext burl no_keyboard file lat long title address sent
text="$(sed <<< "${2}" 's/ mykeyboardend.*//;s/ *my[kfltab][a-z]\{2,13\}startshere.*//')$(sed <<< "${2}" -n '/mytextstartshere/ s/.*mytextstartshere//p')"
# shellcheck disable=SC2001
text="$(sed <<< "${text}" 's/ *mynewlinestartshere */\r\n/g')"
[ "$3" != "safe" ] && {
no_keyboard="$(sed <<< "${2}" '/mykeyboardendshere/!d;s/.*mykeyboardendshere.*/mykeyboardendshere/')"

View File

@ -8,7 +8,7 @@
# #### if you start to develop your own bot, use the clean version of this file:
# #### mycommands.clean
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
#
# uncomment the following lines to overwrite info and help messages

View File

@ -4,7 +4,7 @@
# files: mycommands.sh.clean
# copy to mycommands.sh and add all your commands and functions here ...
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
#
##########

44
scripts/interactive.sh.clean Executable file
View File

@ -0,0 +1,44 @@
#!/bin/bash
# file: interactive.sh
# template for an interactive chat
# test it with: start_proc "${CHAT[ID]}" "./scripts/interactive.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$$ v0.96-dev3-12-g3f85134
######
# parameters
# $1 $2 args as given to starct_proc chat srcipt arg1 arg2
# $3 path to named pipe
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment
export 'LC_ALL=C.UTF-8'
export 'LANG=C.UTF-8'
export 'LANGUAGE=C.UTF-8'
unset IFS
# set -f # if you are paranoid use set -f to disable globbing
#######################
# place your commands here
#
# IMPORTTANT: to read user input from $INPUT
INPUT="${3:-/dev/stdin}"
#
# read -r variable <"${INPUT}"
# example wait form user input and echo it
echo "Enter a message:"
read -r test <"${INPUT}"
echo -e "Your Message: ${test}\nbye!"
# your commands ends here
######################

View File

@ -2,7 +2,7 @@
#
# ADD a new test skeleton to test dir, but does not activate test
#
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-0-gdddd1ce
# common variables
export TESTME DIRME TESTDIR LOGFILE REFDIR TESTNAME
@ -11,10 +11,11 @@ export TESTME DIRME TESTDIR LOGFILE REFDIR TESTNAME
TESTNAME="${REFDIR//-/ }"
# common filenames
export TOKENFILE ACLFILE COUNTFILE ADMINFILE DATADIR JSONSHFILE
export TOKENFILE ACLFILE COUNTFILE BLOCKEDFILE ADMINFILE DATADIR JSONSHFILE
TOKENFILE="token"
ACLFILE="botacl"
COUNTFILE="count"
COUNTFILE="count.jssh"
BLOCKEDFILE="blocked.jssh"
ADMINFILE="botadmin"
DATADIR="data-bot-bash"
JSONSHFILE="JSON.sh/JSON.sh"
@ -31,8 +32,9 @@ export INPUTFILE REFFILE OUTPUTFILE
OUTPUTFILE="${TESTDIR}/${REFDIR}.out"
# do not query telegram when testing
export BASHBOT_URL
export BASHBOT_URL TESTTOKEN
BASHBOT_URL="https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?"
TESTTOKEN="123456789:BASHBOTTESTSCRIPTbashbottestscript_"
# print arrays in reproducible order
print_array() {

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
../dev/hooks/pre-commit.sh

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
# file: b-example-test.sh
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,12 +1,11 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-1-g2a66ee9
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh
source "./ALL-tests.inc.sh"
TESTTOKEN="bashbottestscript"
TESTFILES="${TOKENFILE} ${ACLFILE} ${COUNTFILE} ${ADMINFILE}"
TESTFILES="${TOKENFILE} ${ACLFILE} ${COUNTFILE} ${BLOCKEDFILE} ${ADMINFILE}"
set -e
@ -33,7 +32,7 @@ trap exit 1 EXIT
cd "${TESTDIR}" || exit
echo "Test if $JSONSHFILE exists ..."
[ ! -x "$JSONSHFILE" ] && { echo "${NOSUCCESS} Fail diff ${file}!"; exit 1; }
[ ! -x "$JSONSHFILE" ] && { echo "${NOSUCCESS} json.sh not found"; exit 1; }
echo "Test Sourcing of bashbot.sh ..."
# shellcheck source=./bashbot.sh
@ -45,6 +44,7 @@ trap '' EXIT
cd "${DIRME}" || exit 1
echo "${SUCCESS}"
echo "Test bashbot.sh count"
cp "${REFDIR}/count.test" "${TESTDIR}/count"
#"${TESTDIR}/bashbot.sh" count
echo "Test bashbot.sh stat"
cp "${REFDIR}/count.test" "${TESTDIR}/count.jssh"
"${TESTDIR}/bashbot.sh" stats >"${TESTDIR}/stats.out"
diff -q "${TESTDIR}/stats.out" "${REFDIR}/stats.out" >>"${LOGFILE}" || { echo "${NOSUCCESS} Fail diff stats output!"; FAIL="1"; }

View File

@ -0,0 +1 @@
["blocked_user_or_chat_id"] "name and reason"

View File

@ -1 +0,0 @@

View File

@ -0,0 +1 @@
["counted_user_chat_id"] "num_messages_seen"

View File

@ -1,80 +1,27 @@
COUNT-3474588
COUNT2224533
COUNT-10011894466
COUNT7053247
COUNT6391479
COUNT6341244
COUNT4919830
COUNT2640175
COUNT7349731
COUNT7244826
COUNT2741728
COUNT6376258
COUNT-10012414459
COUNT5869285
COUNT-10011297801
COUNT190323
COUNT7784183
COUNT-2766119
COUNT-3859393
COUNT-10013599717
COUNT-10012886611
COUNT2442778
COUNT5759451
COUNT5254245
COUNT3781067
COUNT7916264
COUNT7235018
COUNT3349831
COUNT2933766
COUNT5924516
COUNT6374645
COUNT6407149
COUNT2383316
COUNT5447722
COUNT231261
COUNT7853337
COUNT7768269
COUNT7546987
COUNT7882954
COUNT6081264
COUNT4473899
COUNT6000622
COUNT7489339
COUNT7925467
COUNT146383
COUNT1850458
COUNT5232050
COUNT7827320
COUNT3230155
COUNT5110579
COUNT2968981
COUNT6709735
COUNT3042403
COUNT6973351
COUNT3739552
COUNT6073516
COUNT7773218
COUNT7570810
COUNT7165830
COUNT7836756
COUNT2603688
COUNT2792256
COUNT1199924
COUNT7044680
COUNT5011616
COUNT5944645
COUNT6040303
COUNT7787713
COUNT7670967
COUNT4902763
COUNT8168450
COUNT5233276
COUNT-10012311537
COUNT7648681
COUNT4170584
COUNT3045040
COUNT5919227
COUNT3364980
COUNT-3450384
COUNT7287381
["counted_user_id"] "num_messages_seen"
["712677"] "2"
["-1001189446"] "29"
["-1001288661"] "6"
["-1001433755"] "4"
["-408138"] "2"
["1246831"] "7"
["-1001186489"] "4"
["-1001259400"] "8"
["791626"] "18"
["-1001293952"] "4"
["-1001435141"] "7"
["733039"] "2"
["-1001319011"] "6"
["-1001220313"] "15"
["26122"] "3"
["988411"] "8"
["908527"] "6"
["-1001450413"] "58"
["748933"] "2"
["-1001425571"] "5"
["788295"] "3"
["586928"] "45"
["-1001359971"] "7"
["1069707"] "19"
["-1001189446"] "30"
["-1001189446"] "31"

View File

@ -0,0 +1 @@
A total of 272 messages from 24 users are processed.

View File

@ -1 +1 @@
bashbottestscript
123456789:BASHBOTTESTSCRIPTbashbottestscript_

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-0-gdddd1ce
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh
@ -30,8 +30,11 @@ echo "Check process_message ..."
set -x
{ process_message "0"; set +x; } >>"${LOGFILE}" 2>&1;
USER[ID]="123456789"
CHAT[ID]="123456789"
# output processed input
print_array "USER" "CHAT" "REPLYTO" "FORWARD" "URLS" "CONTACT" "CAPTION" "LOCATION" "MESSAGE" "VENUE" >"${OUTPUTFILE}"
print_array "USER" "CHAT" "REPLYTO" "FORWARD" "URLS" "CONTACT" "CAPTION" "LOCATION" "MESSAGE" "VENUE" "SERVICE">"${OUTPUTFILE}"
diff -c "${REFFILE}" "${OUTPUTFILE}" || exit 1
echo "${SUCCESS}"

View File

@ -89,3 +89,16 @@
["result",0,"message","voice","duration"] 2
["result",0,"message","voice","mime_type"] "audio/ogg"
["result",0,"message","voice","file_size"] 4262
["result",0,"message","new_chat_participant","id"] 123456789
["result",0,"message","new_chat_participant","is_bot"] false
["result",0,"message","new_chat_participant","first_name"] "Kay"
["result",0,"message","new_chat_participant","last_name"] "M"
["result",0,"message","new_chat_member","id"] 123456789
["result",0,"message","new_chat_member","is_bot"] false
["result",0,"message","new_chat_member","first_name"] "Kay"
["result",0,"message","new_chat_member","last_name"] "M"
["result",0,"message","new_chat_members",0,"id"] 123456789
["result",0,"message","new_chat_members",0,"is_bot"] false
["result",0,"message","new_chat_members",0,"first_name"] "Kay"
["result",0,"message","new_chat_members",0,"last_name"] "M"
["result",0,"message","left_chat_member","id"] 123456789

View File

@ -42,3 +42,9 @@ VENUE: FOURSQUARE 4c4321afce54e21eee980d1a
VENUE: LATITUDE 49.631824
VENUE: LONGITUDE 8.377072
VENUE: TITLE Kolb's Biergarten
SERVICE: 0 yes
SERVICE: LEFTMEMBER 123456789
SERVICE: NEWMEMBER 123456789
SERVICE: NEWPHOTO
SERVICE: NEWTILE
SERVICE: PINNED

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-1-g2a66ee9
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh
@ -54,7 +54,12 @@ done < "${INPUTFILE}" 2>>"${LOGFILE}"
echo " done."
{ diff -c "${REFFILE}" "${OUTPUTFILE}" || exit 1; } | cat -v
sort -d -o "${OUTPUTFILE}.sort" "${OUTPUTFILE}"
sort -d -o "${REFFILE}.sort" "${REFFILE}"
{ diff -c "${REFFILE}.sort" "${OUTPUTFILE}.sort" || exit 1; } | cat -v
rm -f "${REFFILE}.sort"
echo " ... all \"send_message\" functions seems to work as expected."
echo "${SUCCESS}"

View File

@ -1,64 +1,64 @@
chat:123456 JSON:"text":"\# test for text only output"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage
chat:123456 JSON:"text":"This is a normal text"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage
chat:123456 JSON:"text":"This is a normal text
with a line break"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage
chat:123456 JSON:"text":" This is a <b>HTML<\/b> text","parse_mode":"html"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage
chat:123456 JSON:"text":" This is a <b>HTML<\/b> text
with a line break","parse_mode":"html"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage
chat:123456 JSON:"text":" This is a \*MARKDOWN\* text","parse_mode":"markdown"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage
chat:123456 JSON:"text":" This is a \*MARKDOWN\* text
with a line break","parse_mode":"markdown"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage
chat:123456 JSON:"text":"\# test for keyboard\, file\, venue output"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
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": {"keyboard": [ [ "Yep, sure" , "No, highly unlikely" ] ] , "one_time_keyboard":true}
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage
chat:123456 JSON:"latitude": la10, "longitude": lo20
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendLocation
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendLocation
chat:123456 JSON:"latitude": la10, "longitude": lo20, "address": "Diagon Alley N. 37", "title": "my home"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendVenue
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendVenue
chat:123456 JSON:"text":"\# test for new inline button"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
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..."}] ]}
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
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
[https:\/\/images\-na.ssl\-images\-amazon.com\/images\/I\/41oypA3kmHL.l_SX300.jpg]
[https:\/\/images\-na\.ssl\-images\-amazon\.com\/images\/I\/41oypA3kmHL\.l_SX300\.jpg]
second part of text
plus 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?bashbottestscript/sendMessage
plus 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"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendMessage
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendMessage
chat:123456 JSON:"photo":"/tmp/allowed/this_is_my.gif","caption":"Text plus absolute file will appear in chat"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendPhoto
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendPhoto
chat:123456 JSON:"action": "upload_photo"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendChatAction
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendChatAction
chat:123456 JSON:"document":"/tmp/allowed/this_is_my.doc","caption":"Text plus absolute file will appear in chat"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendDocument
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendDocument
chat:123456 JSON:"action": "upload_document"
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?bashbottestscript/sendChatAction
URL:https://my-json-server.typicode.com/topkecleon/telegram-bot-bash/getMe?123456789:BASHBOTTESTSCRIPTbashbottestscript_/sendChatAction

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev-7-g0153928
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ V0.94-0-gbdb50c8
#### $$VERSION$$ v0.96-dev3-0-gdddd1ce
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh
@ -33,7 +33,6 @@ cp ${TESTDIR}/*commands.sh "${BASHBOT_ETC}" || exit 1
set -f
cp -r "${TESTDIR}/bashbot.sh" "${TESTDIR}/modules" "${BASHBOT_BIN}" || exit 1
TESTTOKEN="bashbottestscript"
TESTFILES="${TOKENFILE} ${ACLFILE} ${ADMINFILE}"

View File

@ -1 +1 @@
bashbottestscript
123456789:BASHBOTTESTSCRIPTbashbottestscript_