Merge pull request #177 from topkecleon/develop

Prepare 1.45 release with final webhook and get-file support
This commit is contained in:
Kay Marquardt 2021-03-11 12:16:57 +01:00 committed by GitHub
commit 94aefbe4d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
88 changed files with 538 additions and 277 deletions

View File

@ -145,6 +145,7 @@
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@ -341,7 +342,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 what's send to your Bot.</p>
<p>Bash scripts in general are not designed to be bulletproof, so consider this Bot as a proof of concept. Bash programmers often struggle with 'quoting hell' and globbing, see <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 untrusted sources (messages, files, network) you must be as careful as possible (e.g. set IFS appropriately, disable globbing with <code>set -f</code> and quote everything). In addition remove unused scripts and examples from your Bot (e.g. everything in <code>example/</code>) and disable/remove all unused bot commands.</p>
<p>It's important to escape or remove <code>$</code> in input from user, files or network (<em>as bashbot does</em>). One of the powerful features of Unix shells is variable and command substitution using <code>${}</code> and <code>$()</code> can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped <code>$</code> is included in untrusted input (e.g. <code>$$</code> or <code>$(rm -rf /*)</code>).</p>
<p>It's important to escape or remove <code>$</code> and ` in input from user, files or network (<em>as bashbot does</em>). One of the powerful features of Unix shells is variable and command substitution using <code>${var}</code>, <code>$(cmd)</code> and `cmd` can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped <code>$</code> or ` is included in untrusted input (e.g. <code>$$</code> or <code>$(rm -rf /*)</code>).</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 extensively in bashbot development to ensure a high code quality (e.g. it's not allowed to push changes without passing all shellcheck tests). In addition bashbot has a <a href="doc/7_develop.md">test suite</a> to check if important functionality is working as expected.</p>
<h3>Use printf whenever possible</h3>
<p>If you're writing a script that accepts external input (e.g. from the user as arguments or the file system), you shouldn't use echo to display it. <a href="https://unix.stackexchange.com/a/6581">Use printf whenever possible</a>.</p>
@ -392,6 +393,6 @@ It features background tasks and interactive chats, and can serve as an interfac
<p>@Gnadelwartz</p>
<h2>That's it all guys!</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$$ v1.41-0-gad1b91f</h4>
<h4>$$VERSION$$ v1.5-0-g8adca9b</h4>
</body>
</html>

View File

@ -146,8 +146,9 @@ Whenever you are processing input from untrusted sources (messages, files, netwo
(e.g. set IFS appropriately, disable globbing with `set -f` and quote everything). In addition remove unused scripts and examples
from your Bot (e.g. everything in `example/`) and disable/remove all unused bot commands.
It's important to escape or remove `$` in input from user, files or network (_as bashbot does_).
One of the powerful features of Unix shells is variable and command substitution using `${}` and `$()` can lead to remote code execution (RCE) or remote information disclosure (RID) bugs if unescaped `$` is included in untrusted input (e.g. `$$` or `$(rm -rf /*)`).
It's important to escape or remove `$` and \` in input from user, files or network (_as bashbot does_).
One of the powerful features of Unix shells is variable and command substitution using `${var}`, `$(cmd)` and \`cmd\` can lead to remote
code execution (RCE) or remote information disclosure (RID) bugs if unescaped `$` or \` is included in untrusted input (e.g. `$$` or `$(rm -rf /*)`).
A powerful tool to improve your scripts is `shellcheck`. You can [use it online](https://www.shellcheck.net/) or
[install shellcheck locally](https://github.com/koalaman/shellcheck#installing). Shellcheck is used extensively in bashbot development
@ -241,4 +242,4 @@ See `mycommnds.sh.dist` for an example.
If you feel that there's something missing or if you found a bug, feel free to submit a pull request!
#### $$VERSION$$ v1.41-0-gad1b91f
#### $$VERSION$$ v1.5-0-g8adca9b

View File

@ -200,10 +200,11 @@ Whenever you are processing input from untrusted sources (messages, files, netwo
must be as careful as possible (e.g. set IFS appropriately, disable globbing with set -
f and quote everything). In addition remove unused scripts and examples from your Bot
(e.g. everything in example/) and disable/remove all unused bot commands.
It's important to escape or remove $ in input from user, files or network (as bashbot
does). One of the powerful features of Unix shells is variable and command substitution
using ${} and $() can lead to remote code execution (RCE) or remote information disclosure
(RID) bugs if unescaped $ is included in untrusted input (e.g. $$ or $(rm -rf /*)).
It's important to escape or remove $ and ` in input from user, files or network (as
bashbot does). One of the powerful features of Unix shells is variable and command
substitution using ${var}, $(cmd) and `cmd` can lead to remote code execution (RCE) or
remote information disclosure (RID) bugs if unescaped $ or ` is included in untrusted
input (e.g. $$ or $(rm -rf /*)).
A powerful tool to improve your scripts is shellcheck. You can use it online [https://
www.shellcheck.net/] or install shellcheck locally [https://github.com/koalaman/
shellcheck#installing]. Shellcheck is used extensively in bashbot development to ensure a
@ -318,5 +319,5 @@ That's it all guys!
If you feel that there's something missing or if you found a bug, feel free to submit a
pull request!
$$VERSION$$ v1.41-0-gad1b91f
$$VERSION$$ v1.5-0-g8adca9b

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$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
# used events:
#

View File

@ -4,7 +4,7 @@
# Addons can register to bashbot events at startup
# by providing their name and a callback per event
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#
# If an event occurs each registered event function is called.
#

View File

@ -5,9 +5,10 @@
#
# tested on: ubuntu, opensuse, debian
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
# shellcheck disable=SC2009
# shellcheck disable=SC2181
# shellcheck disable=SC2250
#
### BEGIN INIT INFO
@ -31,13 +32,17 @@ runas="nobody"
# uncomment one of the example lines to fit your system
# runcmd="su ${runas} -s /bin/bash -c " # runasuser with *su*
# runcmd="runuser ${runas} -s /bin/bash -c " # runasuser with *runuser*
# runcmd="/usr/sbin/runuser ${runas} -s /bin/bash -c " # runasuser with *runuser*
# edit the values of the following lines to fit your config:
# your bot installation dir
bashbot="cd /usr/local/telegram-bot-bash; /usr/local/telegram-bot-bash/bashbot.sh"
# your bot name as given to botfather, e.g. mysomething_bot
name=""
# your bot installation dir
bashbotdir="/usr/local/telegram-bot-bash"
databotdir="${bashbotdir}/data-bot-bash"
# programs to run
bashbot="cd ${bashbotdir}; ${bashbotdir}/bashbot.sh"
webhook="cd ${bashbotdir}; nohup ${bashbotdir}/bin/process_batch.sh --startbot --watch ${databotdir}/webhook-fifo-${name}"
# set additionl parameter, e.g. debug
mode=""
@ -48,29 +53,54 @@ mode=""
case "$1" in
'start')
# shellcheck disable=SC2250
$runcmd "$bashbot start $mode" # >/dev/null 2>&1 </dev/null
RETVAL=$?
;;
'starthook')
printf "Starting bashbot in webhook mode ... "
$runcmd "$webhook $mode </dev/null &>>${bashbotdir}/logs/WEBHOOK.log &" # >/dev/null 2>&1 </dev/null
sleep 1
$0 status
RETVAL=$?
;;
'stop')
# shellcheck disable=SC2250
$runcmd "$bashbot stop $mode"
RETVAL=$?
;;
'stophook')
printf "Stopping bashbot webhook mode ... "
KILLID="$(ps -f -u "${runas}" | grep "process_batch.sh --startbot" | sed -E 's/[^0-9]+([0-9]+).*/\1/')"
if [ -n "${KILLID}" ]; then
$runcmd "kill $(printf "%s" "${KILLID}" | tr -s "\r\n" " " )"
sleep 1
$0 status
fi
RETVAL=$?
;;
'status')
ps -f -u "${runas}" | grep "${name}" | grep -qF "bashbot.sh startbot"
if [ "$?" = "0" ]; then
printf "bashbot (%s) is running\n" "${name}"
printf "bashbot (%s) is running in poll mode\n" "${name}"
RETVAL=0
else
printf "bashbot (%s) is stopped\n" "${name}"
RETVAL=1
ps -f -u "${runas}" | grep "${name}" | grep -qF "process_batch.sh --startbot"
if [ "$?" = "0" ]; then
printf "bashbot (%s) is running in webhook mode\n" "${name}"
RETVAL=0
else
printf "bashbot (%s) is stopped\n" "${name}"
RETVAL=1
fi
fi
;;
'restart'|'reload')
$0 stop; $0 start
RETVAL=$?
;;
'restarthook'|'reloadhook')
$0 stophook; $0 starthook
RETVAL=$?
;;
'restartback')
$0 suspendback; $0 resumeback
RETVAL=$?
@ -86,7 +116,8 @@ case "$1" in
fi
;;
*)
printf "%s\n" "Usage: $0 { start | stop | restart | reload | restartback | suspendback | resumeback | killback }"
printf "%s\n" "Usage: $0 [ start | stop | restart | starthook | stophook | restarthook ]"
printf "%s\n" " $0 [ status | restartback | suspendback | resumeback | killback ]"
RETVAL=1
;;
esac

View File

@ -30,7 +30,7 @@ BOTCOMMANDS="-h help init start stop status suspendback resumeback killb
# 8 - curl/wget missing
# 10 - not bash!
#
#### $$VERSION$$ v1.45-dev-26-g82a57a7
#### $$VERSION$$ v1.5-0-g8adca9b
##################################################################
# are we running in a terminal?
@ -106,7 +106,7 @@ JsonEscape(){
}
# clean \ from escaped json string
# $1 string, output cleaned string
cleanEscaped(){ # remove " all \ but \n\u \n or \r
cleanEscape(){ # remove " all \ but \n\u \n or \r
sed -E -e 's/\\"/+/g' -e 's/\\([^nu])/\1/g' -e 's/(\r|\n)//g' <<<"$1"
}
# check if $1 seems a valid token
@ -358,7 +358,7 @@ declare -rx BOTTOKEN URL ME_URL
declare -ax CMD
declare -Ax UPD BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO VENUE iQUERY iBUTTON
declare -Ax SERVICE NEWMEMBER LEFTMEMBER PINNED MIGRATE
export res CAPTION ME
export res CAPTION ME BOTADMIN
###############
@ -491,9 +491,8 @@ sendJson(){
# compose final json
json='{'"${chat} $(iconv -f utf-8 -t utf-8 -c <<<"$2")"'}'
if [ -n "${BASHBOTDEBUG}" ] ; then
log_update "sendJson (${DETECTED_CURL}) CHAT=${chat#*:} JSON=${2:0:100} URL=${3##*/}"
# mask " and \ , remove newline from json
log_message "DEBUG sendJson ==========\n$("${JSONSHFILE}" -b -n <<<"$(cleanEscaped "${json}")" 2>&1)"
log_update "sendJson (${DETECTED_CURL}) CHAT=${chat#*:} JSON=$(cleanEscape "${json:0:100}") URL=${3##*/}"
log_message "DEBUG sendJson ==========\n$("${JSONSHFILE}" -b -n <<<"$(cleanEscape "${json}")" 2>&1)"
fi
# chat id not a number
if [[ "${chat}" == *"NAN\"," ]]; then
@ -515,8 +514,8 @@ UPLOADDIR="${BASHBOT_UPLOAD:-${DATADIR}/upload}"
# return final file name or empty string on error
checkUploadFile() {
local err file="$2"
[[ "${file}" = *'..'* || "${file}" = '.'* ]] && err=1 # no directory traversal
if [[ "${file}" = '/'* ]] ; then
[[ "${file}" == *'..'* || "${file}" == '.'* ]] && err=1 # no directory traversal
if [[ "${file}" == '/'* ]] ; then
[[ ! "${file}" =~ ${FILE_REGEX} ]] && err=2 # absolute must match REGEX
else
file="${UPLOADDIR:-NOUPLOADDIR}/${file}" # others must be in UPLOADDIR
@ -537,6 +536,7 @@ checkUploadFile() {
[ -n "${BASHBOTDEBUG}" ] && log_debug "$3: CHAT=$1 FILE=$2 MSG=${BOTSENT[DESCRIPTION]}"
return 1
fi
printf "%s\n" "${file}"
}
@ -747,6 +747,16 @@ event_send() {
done
}
# cleanup activities on startup, called from startbot and resume background jobs
# $1 action, timestamp for action is saved in config
bot_cleanup() {
# cleanup countfile on startup
jssh_deleteKeyDB "CLEAN_COUNTER_DATABASE_ON_STARTUP" "${COUNTFILE}"
[ -f "${COUNTFILE}.jssh.flock" ] && rm -f "${COUNTFILE}.jssh.flock"
# store action time and cleanup botconfig on startup
[ -n "$1" ] && jssh_updateKeyDB "$1" "$(_date)" "${BOTCONFIG}"
[ -f "${BOTCONFIG}.jssh.flock" ] && rm -f "${BOTCONFIG}.jssh.flock"
}
# fallback version, full version is in bin/bashbot_init.in.sh
# initialize bot environment, user and permissions
@ -788,6 +798,8 @@ fi
# source the script with source as param to use functions in other scripts
# do not execute if read from other scripts
BOTADMIN="$(getConfigKey "botadmin")"
if [ -z "${SOURCE}" ]; then
##############
# internal options only for use from bashbot and developers
@ -829,7 +841,8 @@ if [ -z "${SOURCE}" ]; then
;;
# finally starts the read update loop, internal use only
"startbot" )
_exec_if_function start_bot "$2"
_exec_if_function start_bot "$2" "polling mode"
_exec_if_function get_updates "$2"
debug_checks "end startbot" "$@"
exit
;;
@ -899,7 +912,7 @@ if [ -z "${SOURCE}" ]; then
# shellcheck disable=SC2086
if kill ${BOTPID}; then
# inform botadmin about stop
send_normal_message "$(getConfigKey "botadmin")" "Bot ${ME} stopped ..." &
send_normal_message "${BOTADMIN}" "Bot ${ME} polling mode stopped ..." &
printf "${GREEN}OK. Bot stopped successfully.${NN}"
else
printf "${RED}An error occurred while stopping bot.${NN}"
@ -912,7 +925,7 @@ if [ -z "${SOURCE}" ]; then
exit
;;
# suspend, resume or kill background jobs
"suspendb"*|"resumeb"*|"killb"*)
"suspendb"*|"resumeb"*|'restartb'*|"killb"*)
_is_function job_control || { printf "${RED}Module background is not available!${NN}"; exit 3; }
ME="$(getConfigKey "botname")"
job_control "$1"

View File

@ -21,7 +21,7 @@ USAGE='any_command.sh [-h|--help] [--force|--reference] bot_command args ...'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 30.01.2021 10:24
#
#### $$VERSION$$ v1.45-dev-7-ga9ed559
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
@ -68,7 +68,7 @@ fi
# ready, do stuff here -----
COMMAND="$1"
if [ "$2" == "BOTADMIN" ]; then
ARG1="${BOT_ADMIN}"
ARG1="${BOTADMIN}"
else
ARG1="$2"
fi

View File

@ -13,7 +13,7 @@
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 18.12.2020 12:27
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
############
@ -21,8 +21,8 @@
export BASHBOT_HOME BASHBOT_ETC BASHBOT_VAR FILE_REGEX ME
# default: one dir up
BASHBOT_HOME="$(cd "${BASH_SOURCE[0]%/*}" >/dev/null 2>&1 && pwd)/../"
[ "${BASHBOT_HOME}" = "/../" ] && BASHBOT_HOME="../"
BASHBOT_HOME="$(cd "${BASH_SOURCE[0]%/*}/../" >/dev/null 2>&1 && pwd)"
[ "${BASHBOT_HOME}" = "" ] && BASHBOT_HOME="../"
# set you own BASHBOT_HOME if different, e.g.
# BASHBOT_HOME="/usr/local/telegram-bot-bash"
@ -59,11 +59,14 @@ UPLOADDIR="${BASHBOT_VAR%/bin*}"
FILE_REGEX="${UPLOADDIR}/.*"
# get and check ADMIN and NAME
BOT_ADMIN="$(getConfigKey "botadmin")"
BOT_NAME="$(getConfigKey "botname")"
ME="${BOT_NAME}"
[[ -z "${BOT_ADMIN}" || "${BOT_ADMIN}" == "?" ]] && printf "%s\n" "${ORANGE}Warning: Botadmin not set, send bot command${NC} /start"
[[ -z "${BOT_NAME}" ]] && printf "%s\n" "${ORANGE}Warning: Botname not set, run bashbot.sh botname"
BOTNAME="$(getConfigKey "botname")"
ME="${BOTNAME}"
[[ -z "${BOTADMIN}" || "${BOTADMIN}" == "?" ]] && printf "%s\n" "${ORANGE}Warning: Botadmin not set, send bot command${NC} /start"
[[ -z "${BOTNAME}" ]] && printf "%s\n" "${ORANGE}Warning: Botname not set, run bashbot.sh botname"
# default webhook pipe
export WEBHOOK="${DATADIR}/webhook-fifo-${ME}"
# output command result or Telegram response
print_result() { jssh_printDB "BOTSENT" | sort -r; }

View File

@ -11,7 +11,7 @@
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 27.01.2021 13:42
#
#### $$VERSION$$ v1.45-dev-3-g429c230
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# shellcheck disable=SC2059
@ -76,7 +76,7 @@ bot_init() {
[ -n "${INTERACTIVE}" ] && read -r runuser
fi
# check if mycommands exist
if [ ! -r "${BASHBOT_ETC:-.}/mycommands.sh" ]; then
if [[ ! -r "${BASHBOT_ETC:-.}/mycommands.sh" && -r ${BASHBOT_ETC:-.}/mycommands.sh.dist ]]; then
printf "Mycommands.sh not found, copy ${GREY}<C>lean file, <E>xamples or <N>one${NC} to mycommands.sh? (c/e/N) N\b"
read -r ANSWER
[[ "${ANSWER}" =~ ^[cC] ]] && cp -f "${BASHBOT_ETC:-.}/mycommands.sh.clean" "${BASHBOT_ETC:-.}/mycommands.sh"
@ -116,7 +116,7 @@ bot_init() {
if [ -w "bashbot.rc" ]; then
printf "Adjust user and botname in bashbot.rc ...\n"
sed -i '/^[# ]*runas=/ s|runas=.*$|runas="'"${touser}"'"|' "bashbot.rc"
sed -i '/^[# ]*bashbot=/ s|bashbot=.*$|bashbot="cd '"${PWD}"'; '"${PWD}"'/'"${0##*/}"'"|' "bashbot.rc"
sed -i '/^[# ]*bashbotdir=/ s|bashbotdir=.*$|bashbotdir="'"${PWD}"'"|' "bashbot.rc"
botname="$(getConfigKey "botname")"
[ -n "${botname}" ] && sed -i '/^[# ]*name=/ s|name=.*$|name="'"${botname}"'"|' "bashbot.rc"
printf "Done.\n"

View File

@ -17,7 +17,7 @@ USAGE='bashbot_stats.sh [-h|--help] [debug]'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 23.12.2020 20:34
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# set bashbot environment
@ -27,7 +27,7 @@ source "${0%/*}/bashbot_env.inc.sh" "$1"
####
# ready, do stuff here -----
echo -e "${GREEN}Hi I'm ${BOT_NAME}.${NC}"
echo -e "${GREEN}Hi I'm ${BOTNAME}.${NC}"
declare -A STATS
jssh_readDB_async "STATS" "${COUNTFILE}"
for MSG in ${!STATS[*]}

View File

@ -20,7 +20,7 @@ USAGE='delete_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" [debug]'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 03.01.2021 15:37
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
@ -34,7 +34,7 @@ print_help "$1"
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
CHAT="${BOTADMIN}"
else
CHAT="$1"
fi

View File

@ -26,7 +26,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "MESSAGE[ID]" "text|url" ...'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 21.01.2021 08:10
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
@ -40,7 +40,7 @@ print_help "$1"
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
CHAT="${BOTADMIN}"
else
CHAT="$1"
fi

View File

@ -23,7 +23,7 @@ USAGE='send_edit_message.sh [-h|--help] [format|caption] "CHAT[ID]" "MESSAGE[ID]
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 23.12.2020 16:52
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
@ -55,7 +55,7 @@ print_help "$1"
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
CHAT="${BOTADMIN}"
else
CHAT="$1"
fi

View File

@ -20,7 +20,7 @@ USAGE='kickban_user.sh [-h|--help] [-u|--unban] "CHAT[ID]" "USER[ID]" [debug]'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 25.01.2021 20:34
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####

96
bin/process_batch.sh Executable file
View File

@ -0,0 +1,96 @@
#!/bin/bash
# shellcheck disable=SC1090,SC2034,SC2059
#===============================================================================
#
# FILE: bin/process_batch.sh
#
USAGE='process_update.sh [-h|--help] [-s|--startbot] [-w|--watch] [-n|--lines n] [file] [debug]'
#
# DESCRIPTION: processes last 10 telegram updates in file, one update per line
#
# -s --startbot load addons, start TIMER, trigger startup actions
# -w --watch watch for new updates added to file
# -n --lines read only last "n" lines
# file to read updates from
# empty means read from webhook pipe
#
# -h - display short help
# --help - this help
#
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 27.02.2021 13:14
#
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
# parse args
COMMAND="process_multi_updates"
lines="-n 10"
opt=0
while [[ "${opt}" -lt 5 && "$1" == "-"* ]]
do
(( opt++ ))
case "$1" in
"-s"|"--startbot")
startbot="yes"
shift
;;
"-w"|"--watch")
follow="-f"
shift
;;
"-n"|"--lines")
lines="-n $2"
shift 2
;;
esac
done
# set bashbot environment
source "${0%/*}/bashbot_env.inc.sh" "debug" # debug
print_help "${1:-nix}"
# empty file is webhook
file="${WEBHOOK}"
[ -n "$1" ] && file="$1"
# start bot
if [ -n "${startbot}" ]; then
# warn when starting bot without pipe
[ -p "${file}" ] || printf "%(%c)T: %b\n" -1 "${ORANGE}Warning${NC}: File is not a pipe:${GREY} ${file##*/}${NC}"
start_bot "$2" "webhook"
printf "%(%c)T: %b\n" -1 "${GREEN}Bot start actions done, start reading updates ....${NC}"
fi
# check file exist
if [[ ! -r "${file}" || -d "${file}" ]]; then
printf "%(%c)T: %b\n" -1 "${RED}Error${NC}: File not readable:${GREY} ${file}${NC}."
exit 1
fi
####
# ready, do stuff here -----
# kill all sub processes on exit
trap 'kill $(jobs -p) 2>/dev/null; send_normal_message "'"${BOTADMIN}"'" "Bot '"${BOTNAME}"' webhook stopped ..."; printf "%(%c)T: %s\n" -1 "Bot in batch mode stopped!"' EXIT HUP QUIT
# wait after (first) update to avoid processing to many in parallel
UPDWAIT="0.5"
# use tail to read appended updates
# shellcheck disable=SC2086,SC2248
tail ${follow} ${lines} "${file}" |\
while IFS="" read -r input
do
# read json from stdin and convert update format
# replace any ID named BOTADMIN with ID of bot admin
: "${input//\"id\":BOTADMIN,/\"id\":${BOTADMIN},}"
json='{"result": ['"${_}"']}'
UPDATE="$(${JSONSHFILE} -b -n <<<"${json}" 2>/dev/null)"
# process telegram update
"${COMMAND}" "$2"
sleep "${UPDWAIT}"
UPDWAIT="0.05"
done

View File

@ -15,12 +15,12 @@ USAGE='process_update.sh [-h|--help] [debug] [<file]'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 30.01.2021 19:14
#
#### $$VERSION$$ v1.45-dev-30-g8efbfca
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
# parse args
COMMAND="process_update"
COMMAND="process_multi_updates"
# set bashbot environment
source "${0%/*}/bashbot_env.inc.sh" "debug" # debug
@ -31,15 +31,11 @@ print_help "${1:-nix}"
# ready, do stuff here -----
# read json from stdin and convert update format
# replace any ID named BOTADMIN with ID of bot admin
json='{"result": ['"$(cat)"']}'
json="${json//\"id\":BOTADMIN,/\"id\":${BOTADMIN},}"
UPDATE="$(${JSONSHFILE} -b -n <<<"${json}" 2>/dev/null)"
# escape bash $ expansion bug
UPDATE="${UPDATE//$/\\$}"
# assign to bashbot ARRAY
Json2Array 'UPD' <<<"${UPDATE}"
# process telegram update
"${COMMAND}" "0" "$1"
"${COMMAND}" "$1"

View File

@ -25,7 +25,7 @@ USAGE='promote_user.sh [-h|--help] "CHAT[ID]" "USER[ID]" "right[:true|false]" ..
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 25.01.2021 22:34
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####

View File

@ -28,7 +28,7 @@ USAGE='broadcast_message.sh [-h|--help] [--doit] [--groups|--both|--db=file] [fo
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 16.12.2020 16:14
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
@ -91,7 +91,7 @@ if [ -z "${SENDALL[*]}" ]; then
fi
# loop over users
printf "${GREEN}Sending broadcast message to ${SENDTO}${GROUPSALSO} of ${BOT_NAME} using database:${NC}${GREY} ${database##*/}"
printf "${GREEN}Sending broadcast message to ${SENDTO}${GROUPSALSO} of ${BOTNAME} using database:${NC}${GREY} ${database##*/}"
{ # dry run
[ -z "${DOIT}" ] && printf "${NC}\n${ORANGE}DRY RUN! use --doit as first argument to execute broadcast...${NC}\n"

View File

@ -26,7 +26,7 @@ USAGE='send_message.sh [-h|--help] "CHAT[ID]" "message" "text|url" ...'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 18.01.2021 11:34
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
@ -40,7 +40,7 @@ print_help "$1"
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
CHAT="${BOTADMIN}"
else
CHAT="$1"
fi

View File

@ -21,7 +21,7 @@ USAGE='send_dice.sh [-h|--help] "CHAT[ID]" "emoji" [debug]'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 07.02.2021 18:45
#
#### $$VERSION$$ v1.45-dev-8-g069570e
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
@ -35,7 +35,7 @@ print_help "$1"
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
CHAT="${BOTADMIN}"
else
CHAT="$1"
fi

View File

@ -1 +0,0 @@
edit_message.sh

View File

@ -25,7 +25,7 @@ USAGE='send_file.sh [-h|--help] "CHAT[ID]" "file|URL" "caption ...." [type] [deb
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 25.12.2020 20:24
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
@ -39,7 +39,7 @@ print_help "$1"
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
CHAT="${BOTADMIN}"
else
CHAT="$1"
fi

View File

@ -22,7 +22,7 @@ USAGE='send_message.sh [-h|--help] [format] "CHAT[ID]" "message ...." [debug]'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 16.12.2020 11:34
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
####
@ -50,7 +50,7 @@ print_help "$1"
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
CHAT="${BOTADMIN}"
else
CHAT="$1"
fi

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$$ v1.45-dev-9-g62b6b61
#### $$VERSION$$ v1.5-0-g8adca9b
#
# bashbot locale defaults to c.UTF-8, adjust locale in mycommands.sh if needed
@ -96,10 +96,9 @@ if [ -z "$1" ] || [[ "$1" == *"debug"* ]];then
###################
# if is bashbot is group admin it get commands sent to other bots
# set MEONLY=1 to ignore commands for other bots
if [[ "${MEONLY}" != "0" && "${MESSAGE}" == "/"* && "${MESSAGE%% *}" == *"@"* ]]; then
if [[ "${MEONLY}" != "0" && "${MESSAGE}" == "/"*"@"* ]]; then
# here we have a command with @xyz_bot added, check if it's our bot
MYCHECK="${MESSAGE%% *}"
[ "${MYCHECK}" != "${MYCHECK%%@${ME}}" ] && return
[ "${MESSAGE%%@*}" != "${MESSAGE%%@${ME}}" ] && return
fi
###################

View File

@ -5,7 +5,7 @@
#
# Description: run all tests, exit after failed test
#
#### $$VERSION$$ v1.45-dev-21-ge67e43d
#### $$VERSION$$ v1.5-0-g8adca9b
#############################################################
#shellcheck disable=SC1090

View File

@ -5,7 +5,7 @@
#
# Description: common stuff for all dev scripts
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#############################################################
# magic to ensure that we're always inside the root of our application,

View File

@ -3,7 +3,7 @@
#
# works together with git pre-push.sh and ADD all changed files since last push
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#shellcheck disable=SC1090
source "${0%/*}/dev.inc.sh"

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
############
# NOTE: you MUST run install-hooks.sh again when updating this file!

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
############
# NOTE: you MUST run install-hooks.sh again when updating this file!
@ -41,16 +41,17 @@ else
exit 1
fi
# get version strings
REMOTEVER="$(git ls-remote -t --refs 2>/dev/null | tail -1 | sed -e 's/.*\/v//' -e 's/-.*//')"
VERSION="$(git describe --tags | sed -e 's/-.*//' -e 's/v//' -e 's/,/./')"
[ -z "${REMOTEVER}" ] && REMOTEVER="${VERSION}"
# LOCAL version must greater than latest REMOTE release version
printf "Update Version of modified files\n"
if ! command -v bc &> /dev/null || (( $(printf "%s\n" "${VERSION} >= ${REMOTEVER}" | bc -l) )); then
# update version in bashbot files on push
set +f
[ -f "${LASTPUSH}" ] && LASTFILES="$(find ./* -newer "${LASTPUSH}")"
[ -f "${LASTPUSH}" ] && LASTFILES="$(find ./* -newer "${LASTPUSH}" ! -path "./DIST/*" ! -path "./STANDALONE/*")"
[ "${LASTFILES}" = "" ] && exit
printf " "
# shellcheck disable=SC2086
@ -64,7 +65,7 @@ fi
if command -v codespell &>/dev/null; then
printf "Running codespell\n............................\n"
codespell -q 3 --skip="*.zip,*gz,*.log,*.html,*.txt,.git*,jsonDB-keyboard" -L "ba"
codespell -q 3 --skip="*.zip,*gz,*.log,*.html,*.txt,.git*,jsonDB-keyboard,DIST,STANDALONE" -L "ba"
printf "if there are (to many) typo's shown, consider running:\ncodespell -i 3 -w --skip=\"*.log,*.html,*.txt,.git*,examples\" -L \"ba\"\n"
else
printf "consider installing codespell: pip install codespell\n"

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
############
# NOTE: you MUST run install-hooks.sh again when updating this file!

View File

@ -7,7 +7,7 @@
#
# Usage: source inject-json.sh
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
##############################################################
# download JSON.sh

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$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#shellcheck disable=SC1090
source "${0%/*}/dev.inc.sh"

View File

@ -7,7 +7,7 @@
#
# Options: --notest - skip tests
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
##############################################################
#shellcheck disable=SC1090
@ -20,6 +20,7 @@ DISTDIR="./DIST/${DISTNAME}"
DISTMKDIR="data-bot-bash logs bin bin/logs addons"
DISTFILES="bashbot.sh commands.sh mycommands.sh.clean bin doc examples scripts modules LICENSE README.md README.txt README.html"
DISTFILESDEV="dev/make-standalone.sh dev/inject-json.sh dev/make-html.sh dev/obfuscate.sh"
DISTFILESDIST="mycommands.sh mycommands.conf bashbot.rc $(echo "addons/"*.sh)"
# run tests first!
@ -39,6 +40,9 @@ mkdir -p "${DISTDIR}" 2>/dev/null
printf "Copy files\n"
# shellcheck disable=SC2086
cp -r ${DISTFILES} "${DISTDIR}"
mkdir -p "${DISTDIR}/dev"
# shellcheck disable=SC2086
cp ${DISTFILESDEV} "${DISTDIR}/dev"
cd "${DISTDIR}" || exit 1
printf "Create directories\n"

View File

@ -1,10 +1,13 @@
STANDALONE
data-bot-bash/*
webhook-fifo
test
webhook-fifo*
JSON.awk
bashbot.rc
mycommands.sh
mycommands.conf
awk-patch.sh
make-standalone.sh.include
*.jssh*
botacl
*.flock

View File

@ -7,7 +7,7 @@
#
# Usage: source make-hmtl
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
##############################################################
# check for correct dir

View File

@ -11,29 +11,53 @@
# If you your bot is finished you can use make-standalone.sh to create the
# the old all-in-one bashbot: bashbot.sh and commands.sh only!
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
###################################################################
# include git config and change to base dir
incfile="${0%/*}/dev.inc.sh"
#shellcheck disable=SC1090
source "${0%/*}/dev.inc.sh"
[ -f "${incfile}" ] && source "${incfile}"
# seems we are not in a dev env
if [ -z "${BASE_DIR}" ]; then
BASE_DIR="$(pwd)"
[[ "${BASE_DIR}" == *"/dev" ]] && BASE_DIR="${BASE_DIR%/*}"
# go to basedir
cd "${BASE_DIR}" || exit 1
fi
# see if if bashbot is in base dir
[ ! -f "bashbot.sh" ] && printf "bashbot.sh not found in %s\n" " $(pwd)" && exit 1
# run pre_commit if exist
[[ -f "dev/dev.inc.sh" && "$1" != "--notest" ]] && dev/hooks/pre-commit.sh
# files and dirs to copy
#DISTNAME="telegram-bot-bash"
DISTDIR="./STANDALONE"
DISTMKDIR="data-bot-bash logs bin bin/logs addons"
DISTFILES="bashbot.sh bashbot.rc commands.sh mycommands.sh dev/obfuscate.sh modules bin scripts LICENSE README.* doc botacl botconfig.jssh $(echo "addons/"*.sh)"
DISTMKDIR="data-bot-bash logs bin/logs addons"
DISTFILES="bashbot.sh commands.sh mycommands.sh modules scripts LICENSE README.* doc addons"
DISTBINFILES="bin/bashbot_env.inc.sh bin/bashbot_stats.sh bin/process_batch.sh bin/process_update.sh bin/send_broadcast.sh bin/send_message.sh"
# run pre_commit on files
[ "$1" != "--notest" ] && dev/hooks/pre-commit.sh
# add extra files, minimum mycommands.conf
extrafile="${BASE_DIR}/dev/${0##*/}.include"
[ ! -f "${extrafile}" ] && printf "bashbot.rc\nbotacl\nbotconfig.jssh\nmycommands.conf\ndev/obfuscate.sh\n" >"${extrafile}"
DISTFILES+=" $(<"${extrafile}")"
# create dir for distribution and copy files
printf "Create directories and copy files\n"
mkdir -p "${DISTDIR}" 2>/dev/null
mkdir -p "${DISTDIR}/bin" 2>/dev/null
# shellcheck disable=SC2086
cp -r ${DISTFILES} "${DISTDIR}" 2>/dev/null
cp -rp ${DISTFILES} "${DISTDIR}" 2>/dev/null
# shellcheck disable=SC2086
cp -p ${DISTBINFILES} "${DISTDIR}/bin" 2>/dev/null
cd "${DISTDIR}" || exit 1
# remove log files
find . -name '*.log' -delete
# shellcheck disable=SC2250
for dir in $DISTMKDIR
do
@ -67,7 +91,7 @@ printf "OK, now lets do the magic ...\n\t... create unified commands.sh\n"
mv $$commands.sh commands.sh
rm -f mycommands.sh
printf "\n... create unified bashbot.sh\n"
printf "\t... create unified bashbot.sh\n"
{
# first head of bashbot.sh

View File

@ -0,0 +1,5 @@
bashbot.rc
botacl
botconfig.jssh
mycommands.conf
dev/obfuscate.sh

View File

@ -2,7 +2,7 @@
#
# joke hack to obfuscate bashbot.min.sh
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
# shellcheck disable=SC2028,SC2016,SC1117
infile="bashbot.sh"

View File

@ -1,5 +1,5 @@
# list of additional files to check from shellcheck
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
bashbot.rc
mycommands.conf
mycommands.sh.clean

View File

@ -1,6 +1,6 @@
#!/bin/bash
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
# shellcheck disable=SC2016
#
# Easy Versioning in git:
@ -44,8 +44,14 @@ VERSION="$(git describe --tags --long)"
printf "Update to version %s ...\n" "${VERSION}"
# only regular files, ignore .dot files/dirs, e.g. .git .gitinore in BASEDIR
FILES="$(find ./* -type f)"
[ "$1" != "" ] && FILES="$*"
if [ -n "$1" ]; then
FILES="$*"
else
printf "Update version string in all files? (y/N)\b\b"
read -r answer
[[ "${answer}" != "y" && "${answer}" != "Y" ]] && exit
FILES="$(find ./* -type f ! -path "./DIST/*" ! -path "./STANDALONE/*")"
fi
# autogenerate REMADME.html REMADE.txt
if [[ "${FILES}" == *"README.md"* ]]; then

View File

@ -132,5 +132,5 @@ You must update to [Version 1.20](https://github.com/topkecleon/telegram-bot-bas
#### [Next Create Bot](1_firstbot.md)
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b

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$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b

View File

@ -30,7 +30,9 @@ Have FUN!
├── 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
├── JSON.sh # bashbot JSON parsers
│   ├── JSON.sh # sh implementation, https://github.com/dominictarr/JSON.sh
│   └── JSON.awk.dist # faster awk version, https://github.com/step-/JSON.awk
├── bin # ready to use scripts, use `scriptname --help` for help
│   ├── bashbot_stats.sh # does what it says ...
@ -44,7 +46,7 @@ Have FUN!
│   ├── kickban_user.sh # kick/unban user from given chat
│   ├── promote_user.sh # promote/dente user rights in given chat
│ │
│   ── bashbot_env.inc.sh # sourced from scripts, adapt locations if needed
│   ── bashbot_env.inc.sh # sourced from scripts, adapt locations if needed
│   └── bashbot_init.inc.sh # sourced from bashbot.sh init
├── scripts # place your bashbot interactive and background scripts here
@ -55,15 +57,15 @@ Have FUN!
├── 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 style JSON, mandatory
│   ├── background.sh # interactive and background functions
│   ├── chatMember.sh
│   └── sendMessage.sh # main send message functions, mandatory
│   ├── chatMember.sh # manage chat mambers
│   ├── jsshDB.sh # read and store JSON.sh style JSON, mandatory
│   ├── processUpdates.sh # process updates from telegram, mandatory (run bot)
│   └── sendMessage.sh # send message functions, mandatory
├── addons # optional addons, disabled 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
│   └── antiFlood.sh # simple addon taking actions based on # files and text sent to chat
├── bashbot.rc # start/stop script if you run bashbot as service
@ -127,7 +129,7 @@ bin/send_message.sh "CHAT[ID]" "Hey, I just wanted to let you know that the bot'
To replace a message already sent to one user or chat run the following command:
```bash
bin/send_edit_message.sh "CHAT[ID]" "12345" "Done!"
bin/edit_message.sh "CHAT[ID]" "12345" "Done!"
["OK"] "true"
["ID"] "12345"
@ -150,9 +152,14 @@ Note: to get help about a script in bin/ run `scriptname.sh --help`
Evertime a Telegram update is received, you can read incoming data using the following variables:
In case you need other update values, the array `UPD` contains complete Telegram response.
### Regular Messages
### Processing Messages
These Variables are always present in regular messages:
If an update is received from Telegram, the message is pre processed by Bashbot and the following bash variables are set for use in `mycommands.sh`.
These variables are always present if a message is pre processed:
* `${ME}`: Name of your bot
* `${BOTADMIN}`: User id of bot administrator
* `${MESSAGE}`: Current message text
* `${MESSAGE[ID]}`: ID of current message
@ -215,11 +222,10 @@ The following variables are set if the message contains optional parts:
### Service Messages
Service Messages are regular messages not itended for end users, instead they signal special events to the
client, e.g. new users.
Service Messages are updates not itended for end users, instead they signal special events in a chat, e.g. new users.
If a service message is received bashbot sets MESSAGE to the service message type as a command,
e.g. if a new user joins a chat MESSAGE is set to "/_new_chat_user".
If a service message is received bashbot pre processing sets `${MESSAGE}` according to the service message type,
e.g. if a new user joins a chat MESSAGE is set to `/_new_chat_user ...`.
* `$SERVICE`: This array contains info about received service messages.
* `${SERVICE}`: "yes" if service message is received
@ -255,10 +261,17 @@ e.g. if a new user joins a chat MESSAGE is set to "/_new_chat_user".
### Inline query messages
Inline query messages are special messages used for interaction with the user,
they contain the following variables only:
Inline query messages are special messages for direct interaction with your bot.
If an user starts an inline conversation an inline query is sent after each user keystroke.
* `${iQUERY}`: Current inline query
To receive inline messages you must set `inline=1` in `mycommands.conf` and in botfather.
THe message contatains all characters so far typed from the user.
An received inline query must be anserwered with `answer_inline_query`, see also (Inline Query)[6_reference.md#inline-query]
If an inline query is received only the following variables are available:
* `${iQUERY}`: Inline message typed so far by user
* `$iQUERY`: This array contains the ID, First name, last name, username and user id of the sender of the current inline query.
* `${iQUERY[ID]}`: Inline query ID
* `${iQUERY[USER_ID]}`: User's id
@ -266,9 +279,9 @@ they contain the following variables only:
* `${iQUERY[LAST_NAME]}`: User's last name
### Callback button messages
Callback button messages special messages swedn from callback buttons,
they contain the following variables only:
Callback button messages special messages swend from callback buttons, they contain the following variables only:
* `$iBUTTON`: This array contains the ID, First name, last name, username and user id of the user clicked on the button
* `${iBUTTON[ID]}`: Callback query ID
@ -287,6 +300,8 @@ they contain the following variables only:
After every `send_xxx` `get_xxx` call the array BOTSENT contains the most important values from Telegram response.
In case you need other response values , the array `UPD` contains complete Telegram response.
You can use the array values to check if a commands was successful and get returned values from Telegram.
### BOTSENT array
* `$BOTSENT`: This array contains the parsed results from the last transmission to telegram.
@ -377,5 +392,5 @@ send_action "${CHAT[ID]}" "action"
#### [Prev Create Bot](1_firstbot.md)
#### [Next Advanced Usage](3_advanced.md)
#### $$VERSION$$ v1.45-dev-17-ga7d85e3
#### $$VERSION$$ v1.5-0-g8adca9b

View File

@ -302,5 +302,5 @@ Note: If you disable automatic retry, se above, you disable also connection prob
#### [Prev Getting started](2_usage.md)
#### [Next Expert Use](4_expert.md)
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b

View File

@ -434,5 +434,5 @@ for every poll until the maximum of BASHBOT_SLEEP ms.
#### [Prev Advanced Use](3_advanced.md)
#### [Next Best Practice](5_practice.md)
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b

View File

@ -160,5 +160,5 @@ The second warning is about an unused variable, this is true because in our exam
#### [Prev Best Practice](5_practice.md)
#### [Next Functions Reference](6_reference.md)
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b

View File

@ -651,6 +651,15 @@ with description "Bad Request: chat description is not modified"
*usage:* set_chat_description "CHAT[ID]" "new chat description"
##### set_chat_photo
`set_chat_photo` sets a new profile photo for the chat, can't be changed for private chat.
Photo must be a local image file in a supported format (_.jpg, .jpeg, .png, .gif, .bmp, .tiff_)
Same location and naming restrictions as with `send_file` apply.
*usage:* set_chat_photo "CHAT[ID]" "file"
##### new_chat_invite
`new_chat_invite` generate a new invite link for a chat; any previously generated link is revoked.
Returns the new invite link as String on success.
@ -687,6 +696,13 @@ Returns the new invite link as String on success.
*usage:* delete_chat_stickers "CHAT[ID]"
##### set_chatadmin_title
`set_chatadmin_title` set a custom title for an administrator in a supergroup promoted by the bot.
Admin title can be 0-16 characters long, emoji are not allowed.
*usage:* set_chatadmin_title "CHAT[ID]" "USER[ID]" "admin title"
----
### User Access Control
@ -810,7 +826,7 @@ fi
----
### Inline Queries - answer direct queries to bot
### Inline Query
Inline Queries allows users to interact with your bot directly without sending extra commands.
As an answer to an inline query you can send back one or more results to the Telegram client.
The Telegram client will then show the results to the user and let him select one.
@ -991,11 +1007,11 @@ Usually a message is automatically forwarded from within `commands.sh`, but you
### jsshDB
Since output generated by `JSON.sh` is so easy to use in bash, bashbot uses the format for a simple keys/value file store also.
Output generated by `JSON.sh` can easily converted to bash associative arrays. Therefore Bashbot use this format for key/value file store too.
#### fast and slow operations
jsshDB files are flat text files containing key/value pairs in the `JSON.sh` format.
jsshDB files are flat text files containing key/value pairs in `JSON.sh` format.
Key/value pairs appearing later in the file overwrites earlier key/value pairs, Bashbot use this behavior to implement "fast replace" file operations.
"fast functions" add a new key/value pair to the end of a file without deleting an existing one, this is fast but over time the file grows to infinity.
@ -1026,9 +1042,13 @@ ARRAY["key"]="value"
ARRAY["key,subkey"]="value2"
```
For keys the following charatcsers are allowed: `a-z A-Z 0-9 _ .`, multiple keys must be separated by `,`.
Only the following characters are allowed for keys: `a-z A-Z 0-9 _ .`, multiple keys must be separated by `,`.
Keys contaiing other characters will be discarded when written to a file.
To delete (unset) a key/value pair in memory you can `unset ARRAY["abc"]` but this will not delete the key/value
pair when using `jssh_updateDB` to update a file. Therefore the special value `${JSSHDB_UNSET}` exists, see `jssh_updateDB`
```bash
ARRAY["abc"]="abc" # OK
ARRAY["abx###"]="abc" # works in bash but will not saved to file
@ -1041,7 +1061,6 @@ cat file.jssh
```
*Hint*: Try `tr -dc "[:alnum:],.\r\n"` to strip invalid characters from key.
```bash
# strip key containing invalid characters
KEY="123abcABC,.#?(<>123ÄÖ*%&§"
@ -1119,7 +1138,7 @@ Something wrong with data-bot-bash/../../../somevalues
##### jssh_writeDB
Write content of an ARRAY into jsshDB file. ARRAY name must be declared with `declare -A ARRAY` before calling writeDB.
"DB" file MUST exist or nothing is written.
if "DB" file does not exist nothing is written.
Note: Existing content is overwritten.
@ -1176,15 +1195,16 @@ jssh_printDB READVALUES
```
##### jssh_updateDB
Update/Add content of an ARRAY into a jsshDB file. ARRAY name must be declared with `declare -A ARRAY` before calling updateDB.
"DB" file MUST exist or nothing is written.
Note: Existing content not in ARRAY is kept in file.
`jssh_updateDB updates key/value pairs of an ARRAY in a jsshDB file. ARRAY name must be declared with `declare -A ARRAY` before calling updateDB.
if "DB" file does not exist nothing is written.
*usage:* jssh_updateDB "ARRAY" "filename"
*usage:* jssh_updateDB_async "ARRAY" "filename"
`jssh_updateDB` update new or changed keys/value pairs only, it will not delete an existing key/value pair.
To delete an existing key/value pair you must assign the "unset value" `${JSSJDB_UNSET}` to it instead.
*example:*
```bash
# continued example from writeDB
@ -1195,18 +1215,30 @@ MYVALUES["newvalue"]="this is new"
jssh_updateDB "MYVALUES" "${DATADIR:-.}/myvalues"
# show what's written
cat ${DATADIR:-.}/myvalues".jssh
["value1"] "value1"
["loveit"] "value2"
["whynot"] "value3"
["newvalue"] "this is new"
# now writeDB
cat "$DBfile"
jssh_writeDB "MYVALUES" "${DATADIR:-.}/myvalues"
#######
# update does not delete key/value pairs
# uset in bash and update file
unset MYVALUES["newvalue"]
jssh_updateDB "MYVALUES" "${DATADIR:-.}/myvalues"
# show what's written, ups!
cat "$DBfile"
["newvalue"] "this is new"
["value1"] "value1"
["loveit"] "value2"
["whynot"] "value3"
["newvalue"] "this is new" # value exists!
# use JSSHDB_UNSET value
MYVALUES["newvalue"]="${JSSHDB_UNSET}"
jssh_updateDB "MYVALUES" "${DATADIR:-.}/myvalues"
["value1"] "value1"
["loveit"] "value2"
["whynot"] "value3"
```
@ -1641,5 +1673,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca
#### [Prev Best Practice](5_practice.md)
#### [Next Notes for Developers](7_develop.md)
#### $$VERSION$$ v1.45-dev-9-g62b6b61
#### $$VERSION$$ v1.5-0-g8adca9b

View File

@ -387,5 +387,5 @@ fi
#### [Prev Function Reference](6_reference.md)
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b

View File

@ -60,6 +60,6 @@ plus use of keyboards in private chats. It's an extended version of mycommands.s
**Webhook** contains instructions on how use webhook API to get updates from telegram instead polling Telegram server.
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b

View File

@ -4,7 +4,7 @@
#
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
######
# parameters

View File

@ -2,7 +2,7 @@
# file: run_filename
# background job to display content of all new files in WATCHDIR
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
######
# parameters

View File

@ -2,7 +2,7 @@
# file: run_filename
# background job to display all new files in WATCHDIR
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
######
# parameters

View File

@ -4,7 +4,7 @@
#
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
######
# parameters

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)
# shellcheck disable=SC1117
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
# 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$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
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$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
SHELL=/bin/sh

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$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
########################################################################
######

View File

@ -10,7 +10,7 @@
# AUTHOR: KayM (), kay@rrr.de
# DATE: 19.12.2020 19:03
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# shellcheck disable=SC2154
# shellcheck disable=SC2034

View File

@ -13,7 +13,7 @@
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
########################################################################
######

View File

@ -10,7 +10,7 @@
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
########################################################################
######

View File

@ -1,7 +1,7 @@
# file: botacl
# a user not listed here, will return false from 'user_is_allowed'
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
# Format:
# user:resource: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$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#
# shellcheck disable=SC2154
# shellcheck disable=SC2034

View File

@ -1,63 +1,77 @@
#### [Examples](../README.md)
## Bashtbot webhook example
## Bashbot webhook example
### Webhooks
### Webhook
Bashbot default mode is to poll Telegram server for updates but Telegram offers also webhook
as a more efficient method to deliver updates.
If your server is reachable from the Internet you can use the webhook method described here.
Bashbot default mode is to poll Telegram server for updates but Telegram offers webhook as a more efficient method to deliver updates.
If your server is reachable from the Internet its possible to use the method described here.
Prerequisite for receiving Telegram updates with webhook is a valid SSL certificate, a self signed certificate will not be sufficient.
Webhook processing require special setup on server and Telegram side, therefore it's implemented as separate scripts and you need at least sudo rights to setup.
#### Setup Apache webhook
Prerequisite: An Apache webserver with a valid SLL certificate chain and php enabled.
Prerequisite: An Apache webserver with a valid SLL certificate chain and php enabled.\
This should work with other webservers also but it's not testet.
Prepare Apache to forward webhook to Bashbot:
Setup webhook with Apache:
- install bashbot as described in [Bashbot Installation](../../doc/0_install.md)
- create file `data-bot-bash/webhook-fifo-<botname>` (_<botname> as in `botconfig.jssh`_)
- run `bashbot.sh init` to setup bashbot to run as same user as Apache (_e.g. www_)
- go to apache web root and create directory `telegram/<your_bot_token>`
- copy all files from `examples/webhook` to new directory and change to it
- write bashbot installation directory as first line to file `BASHBOT_HOME`
- execute `php index.php`
- create file `data-bot-bash/webhook-fifo-<botname>` (_\<botname\> as in `botconfig.jssh`_)
- run `sudo bashbot.sh init` to setup bashbot to run as same user as web server (_e.g. www_)
- create a directory in web root: `telegram/<your_bot_token>` (_<your_bot_token> as `botconfig.jssh`_)
- give web server access to directory (_e.g.`chown www:www -R telegram`_)
- go into the new directory and copy all files from `examples/webhook` to it
- edit file `BASHBOT_HOME` to contain ithe Bashbot installation directory as first line (_other lines are ignored_)
- execute `php index.php` with user id of web server to test write access to `data-bot-bash/webhook-fifo-<botname>
Every call to webhook `https://<yourservername>/telegram/<your_bot_token>/` will execute
`index.php` and write received JSON to file `data-bot-bash/webhook-fifo-botname`.
E.g. the URL `https://<yourservername>/telegram/<your_bot_token>/?json={"test":"me"}`
will append `{"test":"me"}` to the file `data-bot-bash/webhook-fifo-<botname>`.
Calling `https://<yourservername>/telegram/<your_bot_token>/` will execute `index.php`
thus append received data to the file `data-bot-bash/webhook-fifo-<botname>`.
E.g. `https://<yourservername>/telegram/<your_bot_token>/?json={"test":"me"}` will append `{"test":"me"}`.
Now your Apache is ready to forward data to Bashbot.
Now your Server is ready to receive updates from Telegram.
#### Simple update processing
#### Default webhook processing
To configure `Simple update processing` delete the file `data-bot-bash/webhook-fifo-<botname>` after your webhook is working.
All webhook calls are now forwarded to `bin/process_update.sh` for processing.
This is the testet and supported default method for processing Telegram updates over webhook.
To start `Simple processing ` enable webhook on Telegram (_see below_).
To enable update processing delete the file `data-bot-bash/webhook-fifo-<botname>` if webhook is working as described above.
Incoming Telegram updates are now forwarded to the script `bin/process_update.sh` for processing.
Every incoming Telegram update load Bashbot once for processing one command. Even it seems overkill to load
Bashbot on every incoming update, it's more responsive and create less server load for low traffic bots.
On incoming Telegram updates the script is executed, it sources bashbot.sh and forward the update to Bashbot for processing.
Even it seems overhead to source Bashbot for every update, it's more responsive and create less load than Bashbot polling mode.
If your bot uses `addons` or `BASHBOT_EVENTs` you can't use `Simple processing`.
Nevertheles there are some limitations compared to polling mode:
- no startup actions
- no background* and interactive jobs
- `addons` and `TIMER_EVENTS` are not working
*Note:* `Simple processing` works without running `bashbot.sh start`.
\* Workaround for background jobs is to execute `./bashbot.sh resumeback` if a new background job was started.
#### Full webhook processing
#### High traffic processing
Full webhook processing use an external script to imitate Bashbot polling mode with webhook.
*Warning:* This method is not much testet and may not work in all cases.
#### CURRENTLY NOT IMPLEMENTED
1. Default webook method must work first!
2. run `bashbot.sh init` to setup bashbot to run with your user id
2. Create a named pipe: `mkfifo data-bot-bash/webhook-fifo-botname` and give the web server write access to it
3. execute `php index.php` with user id of web server to test write access to `data-bot-bash/webhook-fifo-<botname>
4. Start script for Bashbot webhook polling mode:\
`bin/process-batch.sh --startbot --watch data-bot-bash/webhook-fifo-<botname>`
High traffic processing writes Telegram updates to the named pipe `data-bot-bash/webhook-fifo`
and Bashbot poll them, this is much more efficient than polling Telegram server.
The script read updates from given file line by line and forward updates to Bashbot update processing. `--startbot` will run the startup actions
(_e.g. load addons, start TIMER, trigger first run_) and `--watch` will wait for new updates instead of exit on end of file.
Short form: 'bin/process-batch.sh -s -w'
To switch from `Simple processing` to `High traffic processing` start bashbot as `bashbot.sh start-webhook`.
Stop bashbot with `bashbot.sh stop` to switch back to `Simple processing`
If script works as expected, you may run Bashbot webook polling in background by using `./bachbot.rc starthook/stophook`.
To switch back to default processing delete fifo `data-bot-bash/webhook-fifo-<botname>` and stop `bin/process-batch.sh`.
#### Enable webhook on Telegram
#### Enable webhook on Telegram side
To get updates via webhook your server must be reachable from the internet and you must
instruct Telegram where to deliver updates, this is done by calling bashbot function `set_webhook`.
@ -73,8 +87,16 @@ After you enable webhook to deliver Telegram updates it's no more possible to po
To stop delivering of Telegram updates via webhook run `bin/any_command.sh delete_webhook`.
**Important**: Only https connections with a valid certificate chain are allowed as endpoint for webhook.
**Important**: Telegram will refuse to deliver updates if your webhook has no valid SSL certificate chain.
#### $$VERSION$$ v1.45-dev-28-g9958b5b
#### Bash webhook
A pure bash webhook implementation is not possible without extra software because Telegram delivers
webhook updates only over secure TLS connections with a valid SSL certificate chain.
`socat` looks like a tool to listen for Telegram updates from bash scripts, let's see ...
#### $$VERSION$$ v1.5-0-g8adca9b

View File

@ -11,7 +11,7 @@
* @license http://www.wtfpl.net/txt/copying/ WTFPLv2
* @since 30.01.2021 20:24
*
#### $$VERSION$$ v1.45-dev-28-g9958b5b
#### $$VERSION$$ v1.5-0-g8adca9b
***********************************************************/
// bashbot home dir
@ -66,7 +66,7 @@
if ($data == '') { $data = implode(" ",$_GET); }
}
// uncomment to save last received JSON
// file_put_contents($json_file, $data);
// file_put_contents($json_file, str_replace(array("\n", "\r"), '',$data). PHP_EOL));
// prepare for writing
if ($data == '') {

View File

@ -1,2 +1 @@
{"update_id":665220889,
"message":{"message_id":760,"from":{"id":586928566,"is_bot":false,"first_name":"Kay","last_name":"M","username":"KayM","language_code":"de"},"chat":{"id":589682731,"first_name":"Kay","last_name":"M","username":"KayM","type":"private"},"date":1612029749,"text":"/info","entities":[{"offset":0,"length":5,"type":"bot_command"}]}}
{"update_id":665220889,"message":{"message_id":760,"from":{"id":BOTADMIN,"is_bot":false,"first_name":"Kay","last_name":"M","username":"KayM","language_code":"de"},"chat":{"id":BOTADMIN,"first_name":"Kay","last_name":"M","username":"KayM","type":"private"},"date":1612029749,"text":"/info","entities":[{"offset":0,"length":5,"type":"bot_command"}]}}

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$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#
# will be automatically sourced from bashbot

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$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
# will be automatically sourced from bashbot

View File

@ -6,7 +6,7 @@
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
# shellcheck disable=SC1117,SC2059
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
# will be automatically sourced from bashbot
@ -46,6 +46,10 @@ start_back() {
printf '%s\n' "$1:$3:$2" >"${cmdfile}"
restart_back "$@"
}
# $1 chatid
# $2 program
# $3 jobname
# $4 $5 parameters
restart_back() {
local fifo; fifo="${DATADIR:-.}/$(procname "$1" "back-$3-")"
log_update "Start background job CHAT=$1 JOB=${fifo##*/} CMD=${2##*/} $4 $5"
@ -62,9 +66,9 @@ start_proc() {
[ -z "$2" ] && return
[ -x "${2%% *}" ] || return 1
local fifo; fifo="${DATADIR:-.}/$(procname "$1")"
log_update "Start interactive script CHAT=$1 JOB=${fifo##*/} CMD=$2 $3 $4"
check_proc "$1" && kill_proc "$1"
mkfifo "${fifo}"
log_update "Start interactive script CHAT=$1 JOB=${fifo##*/} CMD=$2 $3 $4"
nohup bash -c "{ $2 \"$4\" \"$5\" \"${fifo}\" | \"${SCRIPT}\" outproc \"$1\" \"${fifo}\"
rm \"${fifo}\"; [ -s \"${fifo}.log\" ] || rm -f \"${fifo}.log\"; }" &>>"${fifo}.log" &
}
@ -99,9 +103,11 @@ kill_proc() {
fifo="$(procname "$1" "$2")"
prid="$(proclist "${fifo}")"
fifo="${DATADIR:-.}/${fifo}"
log_update "Stop interactive / background CHAT=$1 JOB=${fifo##*/}"
# shellcheck disable=SC2086
[ -n "${prid}" ] && kill ${prid}
if [ -n "${prid}" ]; then
log_update "Stop interactive / background CHAT=$1 JOB=${fifo##*/}"
kill ${prid}
fi
[ -s "${fifo}.log" ] || rm -f "${fifo}.log"
[ -p "${fifo}" ] && rm -f "${fifo}";
}
@ -118,16 +124,15 @@ inproc() {
send_interactive "${CHAT[ID]}" "${MESSAGE[0]}"
}
# start stop all jobs
# $1 command
# killb*
# suspendb*
# resumeb*
# start stop all jobs
# $1 command # kill suspend resume restart
job_control() {
local BOT ADM content proc CHAT job fifo killall=""
BOT="$(getConfigKey "botname")"
ADM="$(getConfigKey "botadmin")"
ADM="${BOTADMIN}"
debug_checks "Enter job_control" "$1"
# cleanup on start
[[ "$1" == "re"* ]] && bot_cleanup "startback"
for FILE in "${DATADIR:-.}/"*-back.cmd; do
[ "${FILE}" = "${DATADIR:-.}/*-back.cmd" ] && printf "${RED}No background processes.${NN}" && break
content="$(< "${FILE}")"
@ -138,20 +143,20 @@ job_control() {
fifo="$(procname "${CHAT}" "${job}")"
debug_checks "Execute job_control" "$1" "${FILE##*/}"
case "$1" in
"resumeb"*|"backgr"*)
"resume"*|"restart"*)
printf "Restart Job: %s %s\n" "${proc}" " ${fifo##*/}"
restart_back "${CHAT}" "${proc}" "${job}"
# inform botadmin about stop
[ -n "${ADM}" ] && send_normal_message "${ADM}" "Bot ${BOT} restart background jobs ..." &
;;
"suspendb"*)
"suspend"*)
printf "Suspend Job: %s %s\n" "${proc}" " ${fifo##*/}"
kill_proc "${CHAT}" "${job}"
# inform botadmin about stop
[ -n "${ADM}" ] && send_normal_message "${ADM}" "Bot ${BOT} suspend background jobs ..." &
killall="y"
;;
"killb"*)
"kill"*)
printf "Kill Job: %s %s\n" "${proc}" " ${fifo##*/}"
kill_proc "${CHAT}" "${job}"
rm -f "${FILE}" # remove job

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$$ v1.45-dev-25-gb1f6a0b
#### $$VERSION$$ v1.5-0-g8adca9b
# will be automatically sourced from bashbot
@ -147,10 +147,9 @@ user_is_admin() {
# $1 user
user_is_botadmin() {
[ -z "$1" ] && return 1
local admin; admin="$(getConfigKey "botadmin")"; [ -z "${admin}" ] && return 1
[[ "${admin}" == "$1" || "${admin}" == "$2" ]] && return 0
#[[ "${admin}" = "@*" ]] && [[ "${admin}" = "$2" ]] && return 0
if [ "${admin}" = "?" ]; then setConfigKey "botadmin" "${1:-?}"; return 0; fi
[ -z "${BOTADMIN}" ] && return 1
[[ "${BOTADMIN}" == "$1" || "${BOTADMIN}" == "$2" ]] && return 0
if [ "${BOTADMIN}" = "?" ]; then setConfigKey "botadmin" "${1:-?}"; BOTADMIN="${1:-?}"; return 0; fi
return 1
}

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$$ v1.45-dev-30-g8efbfca
#### $$VERSION$$ v1.5-0-g8adca9b
#
# source from commands.sh to use jsonDB functions
#
@ -25,7 +25,9 @@ eval "$(basename "${BASH_SOURCE[0]}")(){ :; }"
# tinybox
# lockfile filename.flock is persistent and will be testet with flock for active lock (file open)
export JSSH_LOCKNAME=".flock"
export JSSHDB_LOCKNAME=".flock"
# an array value containing this string will not saveed to DB (unset)
export JSSHDB_UNSET="99999999999999999999_JSSHDB_UNSET_99999999999999999999"
# in UTF-8 äöü etc. are part of [:alnum:] and ranges (e.g. a-z), but we want ASCII a-z ranges!
# for more information see doc/4_expert.md#Character_classes
@ -64,7 +66,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
[ -z "${DB}" ] && return 1
[ ! -f "${DB}" ] && return 2
# shared lock, many processes can read, max wait 1s
{ flock -s -w 1 200; Json2Array "$1" <"${DB}"; } 200>"${DB}${JSSH_LOCKNAME}"
{ flock -s -w 1 200; Json2Array "$1" <"${DB}"; } 200>"${DB}${JSSHDB_LOCKNAME}"
}
# write ARRAY content to a file in JSON.sh format
@ -76,7 +78,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
[ -z "${DB}" ] && return 1
[ ! -f "${DB}" ] && return 2
# exclusive lock, no other process can read or write, maximum wait to get lock is 10s
{ flock -e -w 10 200; Array2Json "$1" >"${DB}"; } 200>"${DB}${JSSH_LOCKNAME}"
{ flock -e -w 10 200; Array2Json "$1" >"${DB}"; } 200>"${DB}${JSSHDB_LOCKNAME}"
}
# update/write ARRAY content in file without deleting keys not in ARRAY
@ -88,7 +90,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
[ -z "$2" ] && return 1
local DB="$2.jssh" # check in async
[ ! -f "${DB}" ] && return 2
{ flock -e -w 10 200; jssh_updateDB_async "$@"; } 200>"${DB}${JSSH_LOCKNAME}"
{ flock -e -w 10 200; jssh_updateDB_async "$@"; } 200>"${DB}${JSSHDB_LOCKNAME}"
}
# insert, update, apped key/value to jsshDB
@ -106,7 +108,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
{ flock -e -w 2 200
# it's append, but last one counts, its a simple DB ...
printf '["%s"]\t"%s"\n' "${1//,/\",\"}" "${2//\"/\\\"}" >>"${DB}"
} 200>"${DB}${JSSH_LOCKNAME}"
} 200>"${DB}${JSSHDB_LOCKNAME}"
}
@ -119,7 +121,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
[[ "$1" =~ ^${JSSH_KEYOK}+$ ]] || return 3
local DB="$2.jssh"
# start atomic delete here, exclusive max wait 10s
{ flock -e -w 10 200; jssh_deleteKeyDB_async "$@"; } 200>"${DB}${JSSH_LOCKNAME}"
{ flock -e -w 10 200; jssh_deleteKeyDB_async "$@"; } 200>"${DB}${JSSHDB_LOCKNAME}"
}
# get key/value from jsshDB
@ -133,7 +135,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
# start atomic delete here, exclusive max wait 1s
{ flock -s -w 1 200
[ -r "${DB}" ] && sed -n 's/\["'"$1"'"\]\t*"\(.*\)"/\1/p' "${DB}" | tail -n 1
} 200>"${DB}${JSSH_LOCKNAME}"
} 200>"${DB}${JSSHDB_LOCKNAME}"
}
@ -148,7 +150,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
[[ "$1" =~ ^${JSSH_KEYOK}+$ ]] || return 3
local DB="$2.jssh"
# start atomic delete here, exclusive max wait 5
{ flock -e -w 5 200; jssh_countKeyDB_async "$@"; } 200>"${DB}${JSSH_LOCKNAME}"
{ flock -e -w 5 200; jssh_countKeyDB_async "$@"; } 200>"${DB}${JSSHDB_LOCKNAME}"
}
# update key/value in place to jsshDB
@ -169,7 +171,7 @@ if [ "$(LC_ALL=C type -t "flock")" = "file" ]; then
jssh_clearDB() {
local DB; DB="$(jssh_checkDB "$1")"
[ -z "${DB}" ] && return 1
{ flock -e -w 10 200; printf '' >"${DB}"; } 200>"${DB}${JSSH_LOCKNAME}"
{ flock -e -w 10 200; printf '' >"${DB}"; } 200>"${DB}${JSSHDB_LOCKNAME}"
}
# updates Array if DB file has changed since last call
@ -356,7 +358,7 @@ Json2Array() {
# match ["....."]\t and replace \t with = and print delete ` quote true false escape not escaped $
# shellcheck disable=SC1091,SC1090
[ -z "$1" ] || source <( printf "$1"'=( %s )'\
"$(sed -E -n -e '/\["[-0-9a-zA-Z_,."]+"\]\+*\t/ s/\t/=/p' -e 's/`//g' -e 's/=(true|false)/="\1"/' -e 's/([^\]|^)\$/\1\\$/g')" )
"$(sed -E -n -e '/\["[-0-9a-zA-Z_,."]+"\]\+*\t/ s/\t/=/p' -e 's/[`´]//g' -e 's/=(true|false)/="\1"/' -e 's/([^\]|^)\$/\1\\$/g')" )
}
# get Config Key from jssh file without jsshDB
# output ARRAY as JSON.sh style data
@ -367,7 +369,7 @@ Array2Json() {
declare -n ARRAY="$1"
for key in "${!ARRAY[@]}"
do
[[ "${key}" =~ ^${JSSH_KEYOK}+$ ]] || continue
[[ ! "${key}" =~ ^${JSSH_KEYOK}+$ || "${ARRAY[${key}]}" == "${JSSHDB_UNSET}" ]] && continue
# in case value contains newline convert to \n
: "${ARRAY[${key}]//$'\n'/\\n}"
printf '["%s"]\t"%s"\n' "${key//,/\",\"}" "${_//\"/\\\"}"

View File

@ -4,7 +4,7 @@
# File: processUpdates.sh
# Note: DO NOT EDIT! this file will be overwritten on update
#
#### $$VERSION$$ v1.45-dev-30-g8efbfca
#### $$VERSION$$ v1.5-0-g8adca9b
##################################################################
##############
@ -43,18 +43,24 @@ delete_webhook() {
}
################
# processing of updates starts here
# processing of array of updates starts here
process_multi_updates() {
local max num debug="$1"
# get num array elements
max="$(grep -F ',"update_id"]' <<< "${UPDATE}" | tail -1 | cut -d , -f 2 )"
# escape bash $ expansion bug
UPDATE="${UPDATE//$/\\$}"
# convert updates to bash array
Json2Array 'UPD' <<<"${UPDATE}"
# iterate over array
for ((num=0; num<=max; num++)); do
process_update "${num}" "${debug}"
done
}
################
# processing of a single array item of update
# $1 array index
process_update() {
local num="$1" debug="$2"
pre_process_message "${num}"
@ -282,7 +288,7 @@ process_message() {
}
#########################
# main get updates loop, should never terminate
# bot startup actions, call before start polling or webhook loop
declare -A BASHBOTBLOCKED
start_bot() {
local DEBUGMSG
@ -290,12 +296,15 @@ start_bot() {
DEBUGMSG="Start BASHBOT updates in Mode \"${1:-normal}\" =========="
log_update "${DEBUGMSG}"
# redirect to Debug.log
# shellcheck disable=SC2153
[[ "$1" == *"debug" ]] && exec &>>"${DEBUGLOG}"
log_debug "${DEBUGMSG}"; DEBUGMSG="$1"
if [[ "$1" == *"debug" ]]; then
# shellcheck disable=SC2153
exec &>>"${DEBUGLOG}"
log_debug "${DEBUGMSG}";
fi
DEBUGMSG="$1"
[[ "${DEBUGMSG}" == "xdebug"* ]] && set -x
# cleaup old pipes and empty logfiles
find "${DATADIR}" -type p -delete
find "${DATADIR}" -type p -not -name "webhook-fifo-*" -delete
find "${DATADIR}" -size 0 -name "*.log" -delete
# load addons on startup
for addons in "${ADDONDIR:-.}"/*.sh ; do
@ -312,22 +321,15 @@ start_bot() {
# shellcheck disable=SC2064
trap "kill -9 $!; exit" EXIT INT HUP TERM QUIT
fi
# cleanup countfile on startup
jssh_deleteKeyDB "CLEAN_COUNTER_DATABASE_ON_STARTUP" "${COUNTFILE}"
[ -f "${COUNTFILE}.jssh.flock" ] && rm -f "${COUNTFILE}.jssh.flock"
# store start time and cleanup botconfig on startup
jssh_updateKeyDB "startup" "$(_date)" "${BOTCONFIG}"
[ -f "${BOTCONFIG}.jssh.flock" ] && rm -f "${BOTCONFIG}.jssh.flock"
# cleanup on start
bot_cleanup "startup"
# read blocked users
jssh_readDB_async "BASHBOTBLOCKED" "${BLOCKEDFILE}"
# inform botadmin about start
send_normal_message "$(getConfigKey "botadmin")" "Bot $(getConfigKey "botname") started ..." &
##########
# bot is ready, start processing updates ...
get_updates "${DEBUGMSG}"
send_normal_message "$(getConfigKey "botadmin")" "Bot ${ME} $2 started ..." &
}
# main polling updates loop, should never terminate
get_updates(){
local errsleep="200" DEBUG="$1" OFFSET=0
# adaptive sleep defaults

View File

@ -6,7 +6,7 @@
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
# shellcheck disable=SC1117
#### $$VERSION$$ v1.45-dev-24-g785e769
#### $$VERSION$$ v1.5-0-g8adca9b
# will be automatically sourced from bashbot
@ -102,6 +102,7 @@ edit_message_caption() {
delete_message() {
[ -z "$3" ] && log_update "Delete Message CHAT=$1 MSG_ID=$2"
sendJson "$1" '"message_id": '"$2"'' "${URL}/deleteMessage"
[ "${BOTSENT[OK]}" = "true" ] && BOTSENT[CHAT]="$1"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
}

View File

@ -12,7 +12,7 @@
# Author: KayM (gnadelwartz), kay@rrr.de
# Created: 09.01.2021 07:27
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#######################################################
##########

View File

@ -13,7 +13,7 @@
# License: WTFPLv2 http://www.wtfpl.net/txt/copying/
# Author: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.45-dev-27-g77ffbab
#### $$VERSION$$ v1.5-0-g8adca9b
#######################################################
# shellcheck disable=SC1117
@ -106,12 +106,12 @@ else
"${WELCOME_MSG} ${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]} (@${NEWMEMBER[USERNAME]})"
MYSENTID="${BOTSENT[ID]}"
{ sleep 5; delete_message "${CHAT[ID]}" "${MYSENTID}"; } &
[ -n "${REPORT_NEWMEMBER}" ] && send_normal_message "$(getConfigKey "botadmin")"\
[ -n "${REPORT_NEWMEMBER}" ] && send_normal_message "${BOTADMIN}"\
"New member: ${CHAT[TITLE]} (${CHAT[ID]}): ${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]} (@${NEWMEMBER[USERNAME]})"
fi
;;
'/_left_chat_member'*)
[ -n "${REPORT_LEFTMEMBER}" ] && send_normal_message "$(getConfigKey "botadmin")"\
[ -n "${REPORT_LEFTMEMBER}" ] && send_normal_message "${BOTADMIN}"\
"Left member: ${CHAT[TITLE]} (${CHAT[ID]}): ${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]} (@${LEFTMEMBER[USERNAME]})"
;;
'/_migrate_group'*)
@ -317,13 +317,13 @@ else
# called when delete Message failed
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
bashbotError_delete_message() {
log_debug "errorProcessing for delete_message failed: ERR=$2 CHAT=$3 MSGID=$6 ERTXT=$5"
log_debug "custom errorProcessing delete_message: ERR=$2 CHAT=$3 MSGID=$6 ERTXT=$5"
}
# called when error 403 is returned (and no func processing)
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
bashbotError_403() {
log_debug "errorProcessing for error 403 in FUNC=$1 CHAT=$3 USER=${4:-no-user} MSGID=$6 ERTXT=$5"
log_debug "custom errorProcessing error 403: FUNC=$1 CHAT=$3 USER=${4:-no-user} MSGID=$6 ERTXT=$5"
}
###########################

View File

@ -10,7 +10,7 @@
# License: WTFPLv2 http://www.wtfpl.net/txt/copying/
# Author: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#######################################################
# shellcheck disable=SC1117

View File

@ -12,7 +12,7 @@
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
########################################################################
######

View File

@ -10,7 +10,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# magic to ensure that we're always inside the root of our application,

View File

@ -11,7 +11,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.45-dev-21-ge67e43d
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# common variables

View File

@ -10,7 +10,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
../dev/hooks/pre-commit.sh

View File

@ -10,7 +10,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# include common functions and definitions

View File

@ -10,7 +10,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# include common functions and definitions

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -10,7 +10,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# include common functions and definitions

View File

@ -10,7 +10,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.45-dev-22-g6b07242
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# include common functions and definitions

View File

@ -10,7 +10,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# include common functions and definitions

View File

@ -10,7 +10,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# include common functions and definitions
@ -22,6 +22,9 @@ set +f
cd "${TESTDIR}" || exit 1
# reset BOTADMIN
printf '["botadmin"] "?"\n' >>"${ADMINFILE}" # auto mode
# source bashbot.sh function, uncomment if you want to test functions
# shellcheck source=./bashbot.sh
source "${TESTDIR}/bashbot.sh" source
@ -33,8 +36,6 @@ source "${TESTDIR}/commands.sh" source
# first user asking for botadmin will botadmin
printf "Check \"user_is_botadmin\" ...\n"
printf '["botadmin"] "?"\n' >>"${ADMINFILE}" # auto mode
printf "BOTADMIN ...\n"
user_is_botadmin "BOTADMIN" || exit 1 # should never fail
printf "NOBOTADMIN ...\n"

View File

@ -10,7 +10,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.5-0-g8adca9b
#===============================================================================
# include common functions and definitions