Merge pull request #100 from topkecleon/develop

Bashbot v0.80 - #100!
This commit is contained in:
Kay Marquardt 2019-05-21 14:46:45 +02:00 committed by GitHub
commit b096ea3e98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 526 additions and 237 deletions

View File

@ -18,7 +18,7 @@
<p>Contributions by JuanPotato, BigNerd95, TiagoDanin, and iicc1.</p>
<p>Released to the public domain wherever applicable. Elsewhere, consider it released under the <a href="http://www.wtfpl.net/txt/copying/">WTFPLv2</a>.</p>
<h2 id="prerequisites">Prerequisites</h2>
<p>Depends on <a href="http://github.com/tmux/tmux">tmux</a>. Uses <a href="http://github.com/dominictarr/JSON.sh">JSON.sh</a>.</p>
<p>Uses <a href="http://github.com/dominictarr/JSON.sh">JSON.sh</a>, but no more TMUX.</p>
<p>Even bashbot is written in bash, it depends on commands typically availible in a Unix/Linux Environment. More concret on the common commands provided by <a href="https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands">coreutils</a>, <a href="https://en.wikipedia.org/wiki/BusyBox#Commands">busybox</a> or <a href="https://landley.net/toybox/help.html">toybox</a>, see <a href="doc/7_develop.md#common-commands">Developer Notes</a></p>
<p>Bashbot <a href="https://github.com/topkecleon/telegram-bot-bash">Documentation</a> and <a href="https://github.com/topkecleon/telegram-bot-bash/releases">Downloads</a> are availible on www.github.com</p>
<h2 id="documentation">Documentation</h2>
@ -79,9 +79,6 @@
<li><a href="doc/8_custom.md">Customize bashbot environment</a></li>
<li><a href="examples/README.md">Examples</a></li>
</ul>
<h4 id="you-dont-like-the-many-bashbot-files">You dont like the many bashbot files?</h4>
<p>At the beginning bashbot was simply the file <code>bashbot.sh</code> I can copy everywhere and run the bot. Now we have commands.sh, mycommands.sh, modules/*.sh and much more.</p>
<p>Hey no Problem, if you are finished with your cool bot simply run <code>dev/make-standalone.sh</code> to create a stripped down Version containing only bashbot.sh and commands.sh! For more information see <a href="doc/7_develop.md">Create a stripped down Version of your Bot</a></p>
<h2 id="security-considerations">Security Considerations</h2>
<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>
@ -94,6 +91,7 @@
<p><strong>Your Bot configuration must no be readable from other users.</strong> Everyone who can read your Bots token can act as your Bot and has access to all chats your Bot is in!</p>
<p>Everyone with read access to your Bot files can extract your Bots data. Especially your Bot Token in <code>token</code> must be protected against other users. No one exept you must have write access to the Bot files. The Bot must be restricted to have write access to <code>count</code> and <code>tmp-bot-bash</code> only, all other files must be write protected.</p>
<p>To set access rights for your bashbot installation to a reasonable default run <code>sudo ./bashbot.sh init</code> after every update or change to your installation directory.</p>
<h2 id="faq">FAQ</h2>
<h3 id="is-this-bot-insecure">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>
<h3 id="why-bash-and-not-the-much-better-xyz">Why Bash and not the much better xyz?</h3>
@ -104,9 +102,12 @@
<li>no need to install or learn a new programming language, library or framework</li>
<li>no database, not event driven, not OO …</li>
</ul>
<h3 id="can-i-have-the-single-bashbot.sh-file-back">Can I have the single bashbot.sh file back?</h3>
<p>At the beginning bashbot was simply the file <code>bashbot.sh</code> you can copy everywhere and run the bot. Now we have commands.sh, mycommands.sh, modules/*.sh and much more.</p>
<p>Hey no Problem, if you are finished with your cool bot run <code>dev/make-standalone.sh</code> to create a stripped down Version of your bot containing only bashbot.sh and commands.sh! For more information see <a href="doc/7_develop.md">Create a stripped down Version of your Bot</a></p>
<p><span class="citation">@Gnadelwartz</span></p>
<h2 id="thats-it">Thats it!</h2>
<p>If you feel that theres something missing or if you found a bug, feel free to submit a pull request!</p>
<h4 id="version-v0.76-1-ge8a1fd0"><br /><span class="math display"><em>V</em><em>E</em><em>R</em><em>S</em><em>I</em><em>O</em><em>N</em></span><br /> v0.76-1-ge8a1fd0</h4>
<h4 id="version-v0.80-pre-11-g8669cfb"><br /><span class="math display"><em>V</em><em>E</em><em>R</em><em>S</em><em>I</em><em>O</em><em>N</em></span><br /> v0.80-pre-11-g8669cfb</h4>
</body>
</html>

View File

@ -9,8 +9,7 @@ Released to the public domain wherever applicable.
Elsewhere, consider it released under the [WTFPLv2](http://www.wtfpl.net/txt/copying/).
## Prerequisites
Depends on [tmux](http://github.com/tmux/tmux).
Uses [JSON.sh](http://github.com/dominictarr/JSON.sh).
Uses [JSON.sh](http://github.com/dominictarr/JSON.sh), but no more TMUX.
Even bashbot is written in bash, it depends on commands typically availible in a Unix/Linux Environment.
More concret on the common commands provided by [coreutils](https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands), [busybox](https://en.wikipedia.org/wiki/BusyBox#Commands) or [toybox](https://landley.net/toybox/help.html), see [Developer Notes](doc/7_develop.md#common-commands)
@ -60,12 +59,6 @@ Bashbot [Documentation](https://github.com/topkecleon/telegram-bot-bash) and [Do
* [Examples](examples/README.md)
#### You don't like the many bashbot files?
At the beginning bashbot was simply the file ```bashbot.sh``` I can copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more.
Hey no Problem, if you are finished with your cool bot simply run ```dev/make-standalone.sh``` to create a stripped down Version containing only
'bashbot.sh' and 'commands.sh'! For more information see [Create a stripped down Version of your Bot](doc/7_develop.md)
## Security Considerations
Running a Telegram Bot means it is connected to the public and you never know whats send to your Bot.
@ -90,6 +83,8 @@ Everyone with read access to your Bot files can extract your Bots data. Especial
To set access rights for your bashbot installation to a reasonable default run ```sudo ./bashbot.sh init``` after every update or change to your installation directory.
## FAQ
### 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 ...
@ -101,10 +96,17 @@ Well, thats a damn good question ... may be because I'm an Unix/Linux admin from
- no need to install or learn a new programming language, library or framework
- no database, not event driven, not OO ...
### Can I have the single bashbot.sh file back?
At the beginning bashbot was simply the file ```bashbot.sh``` you can copy everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh', 'modules/*.sh' and much more.
Hey no Problem, if you are finished with your cool bot run ```dev/make-standalone.sh``` to create a stripped down Version of your bot containing only
'bashbot.sh' and 'commands.sh'! For more information see [Create a stripped down Version of your Bot](doc/7_develop.md)
@Gnadelwartz
## That's it!
If you feel that there's something missing or if you found a bug, feel free to submit a pull request!
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-11-g8669cfb

View File

@ -13,8 +13,7 @@ Elsewhere, consider it released under the
[WTFPLv2](http://www.wtfpl.net/txt/copying/).
## Prerequisites
Depends on [tmux](http://github.com/tmux/tmux).
Uses [JSON.sh](http://github.com/dominictarr/JSON.sh).
Uses [JSON.sh](http://github.com/dominictarr/JSON.sh), but no more TMUX.
Even bashbot is written in bash, it depends on commands typically availible in
a Unix/Linux Environment.
@ -72,16 +71,6 @@ all](https://core.telegram.org/bots#3-how-do-i-create-a-bot)
* [Examples](examples/README.md)
#### You don't like the many bashbot files?
At the beginning bashbot was simply the file ```bashbot.sh``` I can copy
everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh',
'modules/*.sh' and much more.
Hey no Problem, if you are finished with your cool bot simply run
```dev/make-standalone.sh``` to create a stripped down Version containing only
'bashbot.sh' and 'commands.sh'! For more information see [Create a stripped
down Version of your Bot](doc/7_develop.md)
## Security Considerations
Running a Telegram Bot means it is connected to the public and you never know
whats send to your Bot.
@ -132,6 +121,8 @@ To set access rights for your bashbot installation to a reasonable default run
```sudo ./bashbot.sh init``` after every update or change to your installation
directory.
## FAQ
### 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
@ -148,6 +139,18 @@ health status
- no need to install or learn a new programming language, library or framework
- no database, not event driven, not OO ...
### Can I have the single bashbot.sh file back?
At the beginning bashbot was simply the file ```bashbot.sh``` you can copy
everywhere and run the bot. Now we have 'commands.sh', 'mycommands.sh',
'modules/*.sh' and much more.
Hey no Problem, if you are finished with your cool bot run
```dev/make-standalone.sh``` to create a stripped down Version of your bot
containing only
'bashbot.sh' and 'commands.sh'! For more information see [Create a stripped
down Version of your Bot](doc/7_develop.md)
@Gnadelwartz
## That's it!
@ -155,4 +158,4 @@ health status
If you feel that there's something missing or if you found a bug, feel free to
submit a pull request!
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-11-g8669cfb

View File

@ -1,7 +1,7 @@
#!/bin/sh
# description: Start or stop telegram-bash-bot
#
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# shellcheck disable=SC2009
# shellcheck disable=SC2181

View File

@ -8,11 +8,10 @@
# https://github.com/topkecleon/telegram-bot-bash
# Depends on JSON.sh (http://github.com/dominictarr/JSON.sh) (MIT/Apache),
# and on tmux (http://github.com/tmux/tmux) (BSD).
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-11-g8669cfb
#
# Exit Codes:
# - 0 sucess (hopefully)
@ -62,7 +61,7 @@ if [ ! -f "${TOKENFILE}" ]; then
echo -e "${RED}TOKEN MISSING.${NC}"
echo -e "${ORANGE}PLEASE WRITE YOUR TOKEN HERE OR PRESS CTRL+C TO ABORT${NC}"
read -r token
echo "${token}" > "${TOKENFILE}"
printf '%s\n' "${token}" > "${TOKENFILE}"
fi
fi
@ -70,29 +69,28 @@ BOTADMIN="${BASHBOT_ETC:-.}/botadmin"
if [ ! -f "${BOTADMIN}" ]; then
if [ "${CLEAR}" = "" ]; then
echo "Running headless, set botadmin to AUTO MODE!"
echo '?' > "${BOTADMIN}"
printf '%s\n' '?' > "${BOTADMIN}"
else
${CLEAR}
echo -e "${RED}BOTADMIN MISSING.${NC}"
echo -e "${ORANGE}PLEASE WRITE YOUR TELEGRAM ID HERE OR ENTER '?'${NC}"
echo -e "${ORANGE}TO MAKE FIRST USER TYPING '/start' TO BOTADMIN${NC}"
read -r token
echo "${token}" > "${BOTADMIN}"
[ "${token}" = "" ] && echo '?' > "${BOTADMIN}"
read -r admin
printf '%S\n' "${admin}" > "${BOTADMIN}"
[ "${admin}" = "" ] && printf '%s\n' '?' > "${BOTADMIN}"
fi
fi
BOTACL="${BASHBOT_ETC:-.}/botacl"
if [ ! -f "${BOTACL}" ]; then
echo -e "${ORANGE}Create empty ${BOTACL} file.${NC}"
echo "" >"${BOTACL}"
printf '\n' >"${BOTACL}"
fi
TMPDIR="${BASHBOT_VAR:-.}/data-bot-bash"
if [ ! -d "${TMPDIR}" ]; then
mkdir "${TMPDIR}"
elif [ ! -w "${TMPDIR}" ]; then
${CLEAR}
echo -e "${RED}ERROR: Can't write to ${TMPDIR}!.${NC}"
ls -ld "${TMPDIR}"
exit 2
@ -100,9 +98,8 @@ fi
COUNTFILE="${BASHBOT_VAR:-.}/count"
if [ ! -f "${COUNTFILE}" ]; then
echo "" >"${COUNTFILE}"
printf '\n' >"${COUNTFILE}"
elif [ ! -w "${COUNTFILE}" ]; then
${CLEAR}
echo -e "${RED}ERROR: Can't write to ${COUNTFILE}!.${NC}"
ls -l "${COUNTFILE}"
exit 2
@ -124,7 +121,6 @@ export res BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO VENUE
COMMANDS="${BASHBOT_ETC:-.}/commands.sh"
if [ "$1" != "source" ]; then
if [ ! -f "${COMMANDS}" ] || [ ! -r "${COMMANDS}" ]; then
${CLEAR}
echo -e "${RED}ERROR: ${COMMANDS} does not exist or is not readable!.${NC}"
ls -l "${COMMANDS}"
exit 3
@ -134,6 +130,44 @@ if [ "$1" != "source" ]; then
fi
# internal functions
# $1 URL, $2 filename in TMPDIR
# outputs final filename
download() {
local empty="no.file" file="${2:-${empty}}"
if [[ "$file" = *"/"* ]] || [[ "$file" = "."* ]]; then file="${empty}"; fi
while [ -f "${TMPDIR:-.}/${file}" ] ; do file="$RAMDOM-${file}"; done
getJson "$1" >"${TMPDIR:-.}/${file}" || return
printf '%s\n' "${TMPDIR:-.}/${file}"
}
# $1 postfix, e.g. chatid
# $2 prefix, back- or startbot-
procname(){
printf '%s\n' "$2${ME}_$1"
}
# $1 sting to search for proramm incl. parameters
# retruns a list of PIDs of all current bot proceeses matching $1
proclist() {
# shellcheck disable=SC2009
ps -fu "${UID}" | grep -F "$1" | grep -v ' grep'| grep -F "${ME}" | sed 's/\s\+/\t/g' | cut -f 2
}
# $1 sting to search for proramm to kill
killallproc() {
local procid; procid="$(proclist "$1")"
if [ "${procid}" != "" ] ; then
# shellcheck disable=SC2046
kill $(proclist "$1")
sleep 1
procid="$(proclist "$1")"
# shellcheck disable=SC2046
[ "${procid}" != "" ] && kill $(proclist -9 "$1")
fi
}
# returns true if command exist
_exists()
{
@ -173,6 +207,16 @@ if [ "${BASHBOT_WGET}" = "" ] && _exists curl ; then
BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "$res")"
BOTSENT[ID]="$(JsonGetValue '"result","message_id"' <<< "$res")"
}
#$1 Chat, $2 what , $3 file, $4 URL, $5 caption
sendUpload() {
[ "$#" -lt 4 ] && return
if [ "$5" != "" ]; then
res="$(curl -s "$4" -F "chat_id=$1" -F "$2=@$3;${3##*/}" -F "caption=$5" | "${JSONSHFILE}" -s -b -n )"
else
res="$(curl -s "$4" -F "chat_id=$1" -F "$2=@$3;${3##*/}" | "${JSONSHFILE}" -s -b -n )"
fi
BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "$res")"
}
else
# simple curl or wget call outputs result to stdout
getJson(){
@ -187,6 +231,10 @@ else
BOTSENT[OK]="$(JsonGetLine '"ok"' <<< "$res")"
BOTSENT[ID]="$(JsonGetValue '"result","message_id"' <<< "$res")"
}
sendUpload() {
sendJson "$1" '"text":"Sorry, wget does not support file upload"' "${MSG_URL}"
BOTSENT[OK]="false"
}
fi
# convert common telegram entities to JSON
@ -233,26 +281,26 @@ JsonGetValue() {
################
# processing of updates starts here
process_updates() {
MAX_PROCESS_NUMBER="$(sed <<< "${UPDATE}" '/\["result",[0-9]*\]/!d' | tail -1 | sed 's/\["result",//g;s/\].*//g')"
for ((PROCESS_NUMBER=0; PROCESS_NUMBER<=MAX_PROCESS_NUMBER; PROCESS_NUMBER++)); do
process_client "$1"
local max num debug="$1"
max="$(sed <<< "${UPDATE}" '/\["result",[0-9]*\]/!d' | tail -1 | sed 's/\["result",//g;s/\].*//g')"
for ((num=0; num<=max; num++)); do
process_client "$num" "${debug}"
done
}
process_client() {
iQUERY[ID]="$(JsonGetString <<<"${UPDATE}" '"result",'"${PROCESS_NUMBER}"',"inline_query","id"')"
local num="$1" debug="$2"
iQUERY[ID]="$(JsonGetString <<<"${UPDATE}" '"result",'"${num}"',"inline_query","id"')"
if [ "${iQUERY[ID]}" = "" ]; then
[[ "$1" = *"debug"* ]] && echo "$UPDATE" >>"MESSAGE.log"
process_message "$PROCESS_NUMBER" "$1"
[[ "${debug}" = *"debug"* ]] && cat <<< "$UPDATE" >>"MESSAGE.log"
process_message "${num}" "${debug}"
else
[[ "$1" = *"debug"* ]] && echo "$UPDATE" >>"INLINE.log"
[ "$INLINE" != "0" ] && _is_function process_inline && process_inline "$PROCESS_NUMBER" "$1"
[[ "${debug}" = *"debug"* ]] && cat <<< "$UPDATE" >>"INLINE.log"
[ "$INLINE" != "0" ] && _is_function process_inline && process_inline "${num}" "${debug}"
fi
# Tmux
copname="$ME"_"${CHAT[ID]}"
# shellcheck source=./commands.sh
source "${COMMANDS}" "$1"
source "${COMMANDS}" "${debug}"
tmpcount="COUNT${CHAT[ID]}"
grep -q "$tmpcount" <"${COUNTFILE}" >/dev/null 2>&1 || echo "$tmpcount">>"${COUNTFILE}"
grep -q "$tmpcount" <"${COUNTFILE}" &>/dev/null || cat <<< "$tmpcount" >>"${COUNTFILE}"
# To get user count execute bash bashbot.sh count
}
process_inline() {
@ -266,7 +314,7 @@ process_inline() {
process_message() {
local num="$1"
local TMP="${TMPDIR:-.}/$RANDOM$RANDOM-MESSAGE"
echo "$UPDATE" >"$TMP"
cat <<< "$UPDATE" >"$TMP"
# Message
MESSAGE[0]="$(JsonDecode "$(JsonGetString '"result",'"${num}"',"message","text"' <"$TMP")" | sed 's#\\/#/#g')"
MESSAGE[ID]="$(JsonGetValue '"result",'"${num}"',"message","message_id"' <"$TMP" )"
@ -319,8 +367,8 @@ process_message() {
URLS[VOICE]="$(get_file "$(JsonGetString '"result",'"${num}"',"message","voice","file_id"' <"$TMP")")"
# Contact
CONTACT[USER_ID]="$(JsonDecode "$(JsonGetString '"result",'"${num}"',"message","contact","user_id"' <"$TMP")")"
CONTACT[FIRST_NAME]="$(JsonDecode "$(JsonGetString '"result",'"${num}"',"message","contact","first_name"' <"$TMP")")"
CONTACT[USER_ID]="$(JsonDecode "$(JsonGetString '"result",'"${num}"',"message","contact","user_id"' <"$TMP")")"
CONTACT[LAST_NAME]="$(JsonDecode "$(JsonGetString '"result",'"${num}"',"message","contact","last_name"' <"$TMP")")"
CONTACT[NUMBER]="$(JsonGetString '"result",'"${num}"',"message","contact","phone_number"' <"$TMP")"
CONTACT[VCARD]="$(JsonGetString '"result",'"${num}"',"message","contact","vcard"' <"$TMP")"
@ -338,7 +386,7 @@ process_message() {
# Location
LOCATION[LONGITUDE]="$(JsonGetValue '"result",'"${num}"',"message","location","longitude"' <"$TMP")"
LOCATION[LATITUDE]="$(JsonGetValue '"result",'"${num}"',"message","location","latitude"' <"$TMP")"
NAME="$(echo "${URLS[*]}" | sed 's/.*\///g')"
NAME="$(sed 's/.*\///g' <<< "${URLS[*]}")"
rm "$TMP"
}
@ -354,6 +402,10 @@ start_bot() {
[[ "${DEBUG}" = *"debug" ]] && exec &>>"DEBUG.log"
[ "${DEBUG}" != "" ] && date && echo "Start BASHBOT in Mode \"${DEBUG}\""
[[ "${DEBUG}" = "xdebug"* ]] && set -x
#cleaup old pipes and empty logfiles
find "${TMPDIR}" -type p -delete
find "${TMPDIR}" -size 0 -name "*.log" -delete
while true; do
UPDATE="$(getJson "$UPD_URL$OFFSET" | "${JSONSHFILE}" -s -b -n)"
@ -379,14 +431,18 @@ bot_init() {
[ -d "${OLDTMP}" ] && { mv -n "${OLDTMP}/"* "${TMPDIR}"; rmdir "${OLDTMP}"; }
[ -f "modules/inline.sh" ] && rm -f "modules/inline.sh"
#setup bashbot
[[ "$(id -u)" -eq "0" ]] && RUNUSER="nobody"
[[ "${UID}" -eq "0" ]] && RUNUSER="nobody"
echo -n "Enter User to run basbot [$RUNUSER]: "
read -r TOUSER
[ "$TOUSER" = "" ] && TOUSER="$RUNUSER"
if ! id "$TOUSER" >/dev/null 2>&1; then
if ! id "$TOUSER" &>/dev/null; then
echo -e "${RED}User \"$TOUSER\" not found!${NC}"
exit 3
else
# shellcheck disable=SC2009
oldbot="$(ps -fu "$TOUSER" | grep startbot | grep -v -e 'grep' -e '\-startbot' )"
[ "${oldbot}" != "" ] && \
echo -e "${ORANGE}Warning: At least one not upgraded TMUX bot is running! You must stop it with kill command:${NC}\\n${oldbot}"
echo "Adjusting user \"${TOUSER}\" files and permissions ..."
[ -w "bashbot.rc" ] && sed -i '/^[# ]*runas=/ s/runas=.*$/runas="'$TOUSER'"/' "bashbot.rc"
chown -R "$TOUSER" . ./*
@ -429,12 +485,11 @@ if [ "$1" != "source" ]; then
"outproc") # forward output from interactive and jobs to chat
[ "$3" = "" ] && echo "No file to read from" && exit 3
[ "$2" = "" ] && echo "No chat to send to" && exit 3
until [ "$line" = "imprettydarnsuredatdisisdaendofdacmd" ];do
line=""
read -r -t 10 line
[ "$line" != "" ] && [ "$line" != "imprettydarnsuredatdisisdaendofdacmd" ] && send_message "$2" "$line"
done <"${TMPDIR:-.}/$3"
while read -r line ;do
[ "$line" != "" ] && send_message "$2" "$line"
done
rm -f -r "${TMPDIR:-.}/$3"
[ -s "${TMPDIR:-.}/$3.log" ] || rm -f "${TMPDIR:-.}/$3.log"
exit
;;
"startbot" )
@ -448,15 +503,14 @@ if [ "$1" != "source" ]; then
bot_init
exit
;;
"attach")
tmux attach -t "$ME"
exit
;;
esac
###############
# "official" arguments as shown to users
SESSION="$ME-startbot"
BOTPID="$(proclist "${SESSION}")"
case "$1" in
"count")
echo "A total of $(wc -l <"${COUNTFILE}") users used me."
@ -469,68 +523,57 @@ if [ "$1" != "source" ]; then
shift
while read -r f; do send_markdown_message "${f//COUNT}" "$*"; $sleep; done <"${COUNTFILE}"
;;
"status")
if [ "${BOTPID}" != "" ]; then
echo -e "${GREEN}Bot is running.${NC}"
exit
else
echo -e "${ORANGE}Bot not running.${NC}"
exit 5
fi
;;
"start")
${CLEAR}
tmux kill-session -t "$ME" &>/dev/null
tmux new-session -d -s "$ME" "bash $SCRIPT startbot" && echo -e "${GREEN}Bot started successfully.${NC}"
echo "Tmux session name $ME" || echo -e "${RED}An error occurred while starting the bot. ${NC}"
# shellcheck disable=SC2086
[ "${BOTPID}" != "" ] && kill ${BOTPID}
nohup "$SCRIPT" "startbot" "$2" "${SESSION}" &>/dev/null &
echo "Session Name: ${SESSION}"
if [ "$(proclist "${SESSION}")" != "" ]; then
echo -e "${GREEN}Bot started successfully.${NC}"
else
echo -e "${RED}An error occurred while starting the bot.${NC}"
exit 5
fi
;;
"kill")
${CLEAR}
tmux kill-session -t "$ME" &>/dev/null
"kill"|"stop")
if [ "${BOTPID}" != "" ]; then
# shellcheck disable=SC2086
if kill ${BOTPID}; then
echo -e "${GREEN}OK. Bot stopped successfully.${NC}"
;;
"background" | "resumeback")
${CLEAR}
echo -e "${GREEN}Restart background processes ...${NC}"
for FILE in "${TMPDIR:-.}/"*-back.cmd; do
if [ "${FILE}" = "${TMPDIR:-.}/*-back.cmd" ]; then
echo -e "${RED}No background processes to start.${NC}"; break
else
RESTART="$(< "${FILE}")"
CHAT[ID]="${RESTART%%:*}"
JOB="${RESTART#*:}"
PROG="${JOB#*:}"
JOB="${JOB%:*}"
fifo="back-${JOB}-${ME}_${CHAT[ID]}" # compose fifo from jobname, $ME (botname) and CHAT[ID]
echo "restartbackground ${PROG} ${fifo}"
( tmux kill-session -t "${fifo}"; tmux kill-session -t "sendprocess_${fifo}"; rm -f -r "${TMPDIR:-.}/${fifo}") 2>/dev/null
mkfifo "${TMPDIR:-.}/${fifo}"
tmux new-session -d -s "${fifo}" "${PROG} &>${TMPDIR:-.}/${fifo}; echo imprettydarnsuredatdisisdaendofdacmd>${TMPDIR:-.}/${fifo}"
tmux new-session -d -s "sendprocess_${fifo}" "bash $SCRIPT outproc ${CHAT[ID]} ${fifo}"
echo -e "${RED}An error occured while stopping bot.${NC}"
exit 5
fi
done
fi
exit
;;
"killback" | "suspendback")
${CLEAR}
echo -e "${GREEN}Stopping background processes ...${NC}"
for FILE in "${TMPDIR:-.}/"*-back.cmd; do
if [ "${FILE}" = "${TMPDIR:-.}/*-back.cmd" ]; then
echo -e "${RED}No background processes.${NC}"; break
else
REMOVE="$(< "${FILE}")"
JOB="${REMOVE#*:}"
fifo="back-${JOB%:*}-${ME}_${REMOVE%%:*}"
echo "killbackground ${fifo}"
[ "$1" = "killback" ] && rm -f "${FILE}" # remove job
( tmux kill-session -t "${fifo}"; tmux kill-session -t "sendprocess_${fifo}"; rm -f -r "${TMPDIR:-.}/${fifo}") 2>/dev/null
fi
done
"resumeb"* | "killb"* | "suspendb"*)
_is_function job_control || { echo -e "${RED}Module background is not availible!${NC}"; exit 3; }
job_control "$1"
;;
"help")
${CLEAR}
less "README.txt"
exit
;;
*)
echo -e "${RED}${ME}: BAD REQUEST${NC}"
echo -e "${RED}Available arguments: start, kill, count, broadcast, help, suspendback, resumeback, killback${NC}"
echo -e "${RED}Available arguments: start, stop, kill, status, count, broadcast, help, suspendback, resumeback, killback${NC}"
exit 4
;;
esac
# warn if root
if [[ "$(id -u)" -eq "0" ]] ; then
if [[ "${UID}" -eq "0" ]] ; then
echo -e "\\n${ORANGE}WARNING: ${SCRIPT} was started as ROOT (UID 0)!${NC}"
echo -e "${ORANGE}You are at HIGH RISK when processing user input with root privilegs!${NC}"
fi

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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
#
# adjust your language setting here, e.g.when run from other user or cron.
@ -107,7 +107,7 @@ if [ "${1}" != "source" ];then
if [ "$res" -eq 0 ] ; then killproc && _message "Command canceled.";else _message "No command is currently running.";fi
;;
*) # forward messages to optional dispatcher
_is_function startproc && if tmux ls | grep -v send | grep -q "$copname"; then inproc; fi # interactive running
_is_function send_interactive && send_interactive "${CHAT[ID]}" "${MESSAGE}"
_is_function mycommands && mycommands
;;
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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# 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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# 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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
############
# NOTE: you MUST run install-hooks.sh again when updating this file!

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
############
# 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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# 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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-11-g8669cfb
# magic to ensure that we're always inside the root of our application,
# no matter from which directory we'll run script
@ -38,7 +38,7 @@ cd "${DISTDIR}" || exit 1
# additional stuff
mv "bashbot.rc" "bashbot.rc.dist"
mv "commands.sh" "commands.sh.dist"
# mv "commands.sh" "commands.sh.dist" # will be overwritten from v0.80 on
mv "mycommands.sh" "mycommands.sh.dist"
JSONSHFILE="JSON.sh/JSON.sh"

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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# 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,3 +1,3 @@
# list of additional files to check from shellcheck
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
bashbot.rc

View File

@ -1,6 +1,6 @@
#!/bin/bash
#
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# shellcheck disable=SC2016
#
# Easy Versioning in git:

View File

@ -35,19 +35,34 @@ As an alternative to download the zip files, you can clone the github repository
3. Extract all files to your existing bashbot dir
**Note: all files execpt 'mycommands.sh' and 'commands.sh' may overwritten!**
4. Save your your current 'commands.sh' and run ```cp commands.sh.dist commands.sh```
5. Run ```sudo ./bashbot.sh init``` to setup your environment after the update
5. Stop all running instances of bashbot at this point latest
6. Run ```sudo ./bashbot.sh init``` to setup your environment after the update
If you modified 'commands.sh' re apply all changes to the new 'commands.sh'. To avoid this all your modifications
must be done in 'mycommands.sh' only.
Now you can restart your bashbot instances.
### Notes on Updates
#### Location of tmp / data dir
From version 0.70 on the tmp dir is renamed to 'data-bot-bash' to reflect the fact that not only temporary files are stored. an existing 'tmp-bot-bash' will be automatically renamed after update.
#### removal of TMUX
From version 0.80 on TMUX is no longer needed and the bachsbot command 'attach' is deleted. Old function 'inproc'
is replaced by 'send_interactive'. send_interactive does checks if an interactive job is running internaly.
Pls check if you make use of inproc and remove it including the old checks, e.g.
```bash
if tmux ls | grep -v send | grep -q "$copname"; then inproc; fi
# or
[ checkprog ] && inproc
```
must be replaced by ```send_interactive "${CHATD[ID]}" "${MESSAGE}"```
### Do not edit commands.sh
From version 0.60 on your commands must be placed in 'mycommands.sh'. If you update from a version with your commands
in 'commands.sh' move all your commands and functions to 'mycommands.sh'.
#### Location of var / tmp / data dirs
From version 0.70 on the tmp dir is renamed to 'data-bot-bash' to reflect the fact that not only temporary files are stored. an existing 'tmp-bot-bash' will be automatically renamed after update.
From version 0.50 on the temporary files are no more placed in '/tmp'. instead a dedicated tmp dir is used.
#### Changes to send_keyboard in v0.6
@ -70,5 +85,5 @@ The old format is supported for backward compatibility, but may fail for corner
#### [Next Create Bot](1_firstbot.md)
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d

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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d

View File

@ -182,5 +182,5 @@ send_action "${CHAT[ID]}" "action"
#### [Prev Create Bot](1_firstbot.md)
#### [Next Advanced Usage](3_advanced.md)
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d

View File

@ -180,5 +180,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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d

View File

@ -104,5 +104,5 @@ An example crontab is provided in ```examples/bashbot.cron```.
#### [Prev Expert Use](4_expert.md)
#### [Next Best Practice](5_practice.md)
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d

View File

@ -61,7 +61,7 @@ every line from ```'/command')``` to ```;;```.
# ;;
*) # forward other messages to optional dispatcher
_is_function startproc && if tmux ls | grep -v send | grep -q "$copname"; then inproc; fi # interactive running
_is_function send_interactive && send_interactive "${CHAT[ID]}" "${MESSAGE}"
_is_function mycommands && mycommands
;;
esac
@ -153,5 +153,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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-7-g300553f

View File

@ -84,6 +84,17 @@ See also [deleteMessage limitations](https://core.telegram.org/bots/api#deleteme
----
##### send_message
```send_message``` sends any type of message to the given chat. Type of output is steered by keywords within the message.
The main use case for send_message is to process the output of interactive chats and background jobs. **For regular Bot commands I recommend using of the dedicated send_xxx_message() functions from above.**
*usage:* send_message "${CHAT[ID]}" "message"
*example:* - see [Usage](2_usage.md#send_message) and [Advanced Usage](3_advanced.md#Interactive-Chats)
----
### File, Location, Venue, Keyboard
@ -330,40 +341,45 @@ see [InlineQueryResult for more information](https://core.telegram.org/bots/api#
### Background and Interactive jobs
You must include ```source modules/background.sh``` in 'commands.sh' to have the following functions availible.
##### startproc
##### start_proc
```startproc``` starts a script, the output of the script is sent to the user or chat, user input will be sent back to the script. see [Advanced Usage](3_advanced.md#Interactive-Chats)
*usage:* startproc "script"
*usage:* start_proc "${CHAT[ID]}" "script"
*alias:* startproc "script"
*example:*
```bash
startproc 'examples/calc.sh'
```
##### checkproc
##### check_proc
Return true (0) if an interactive script is running in the chat.
*usage:* checkprog
*usage:* check_prog "${CHAT[ID]}"
*alias:* checkprog
*example:*
```bash
checkproc
if [ "$res" -gt 0 ] ; then
if ! check_proc "${CHAT[ID]}" ; then
startproc "examples/calc.sh"
else
send_normal_message "${CHAT[ID]}" "Calc already running ..."
fi
```
##### killproc
##### kill_proc
Kill the interactive script running in the chat
*usage:* killproc
*usage:* kill_proc "${CHAT[ID]}"
*alias:* killproc
*example:*
```bash
checkprog
if [ "$res" -eq 0 ]; then
if check_proc "${CHAT[ID]}" ; then
killproc && send_message "${CHAT[ID]}" "Command canceled."
else
send_message "${CHAT[ID]}" "Command is not running."
@ -372,27 +388,30 @@ fi
----
##### background
##### start_back
Starts a script as a background job and attaches a jobname to it. All output from a background job is sent to the associated chat.
In contrast to interactive chats, background jobs do not recieve user input and can run forever. In addition you can suspend and restart running jobs, e.g. after reboot.
*usage:* background "script" "jobname"
*usage:* start_back "${CHAT[ID]}" "script" "jobname"
*alias:* background "script" "jobname"
*example:*
```bash
background "examples/notify.sh" "notify"
```
##### checkback
##### check_back
Return true (0) if an background job is active in the given chat.
*usage:* checkback "jobname"
*usage:* check_back "${CHAT[ID]}" "jobname"
*alias:* checkback "jobname"
*example:*
```bash
checkback "notify"
if [ "$res" -gt 0 ] ; then
if ! checkback "notify" ; then
send_normal_message "${CHAT[ID]}" "Start notify"
background "examples/notify.sh" "notify"
else
@ -400,8 +419,11 @@ else
fi
```
##### killback
*usage:* killback "jobname"
##### kill_back
*usage:* kill_back "${CHAT[ID]}" "jobname"
*alias:* killback "jobname"
*example:*
```bash
@ -416,16 +438,13 @@ fi
----
##### send_message
```send_message``` sends any type of message to the given chat. Type of output is steered by keywords within the message.
##### send_interactive
Form version 0.80 on forward_message is used to forward messages to interactive job. It replaces the old 'inproc' commands used for TMUX.
Usually message is automatically forwarded in 'commands.sh', but you can forward messages wihle processing also or send your own messages.
The main use case for send_message is to process the output of interactive chats and background jobs. **For regular Bot commands I recommend using of the dedicated send_xxx_message() functions from above.**
*usage:* send_interactive "${CHAT[ID]}" "message"
*usage:* send_message "${CHAT[ID]}" "message"
*example:* - see [Usage](2_usage.md#send_message) and [Advanced Usage](3_advanced.md#Interactive-Chats)
----
*replaces:*' incproc
### Aliases - shortcuts for often used funtions
You must include ```source modules/aliases.sh``` in 'commands.sh' to have the following functions availible.
@ -525,6 +544,30 @@ You must include ```source modules/aliases.sh``` in 'commands.sh' to have the f
### Helper functions
##### download
Download the fiven URL ans returns the final filename in TMPDIR. If the given filename exists,the filename is prefixed with a
random number. filename is not allowed to contain '/' or '..'.
*usage:* download URL filename
*example:*
```bash
file="$(download "https://avatars.githubusercontent.com/u/13046303" "avatar.jpg")"
echo "$file" -> ./data-bot-bash/avatar.jpg
file="$(download "https://avatars.githubusercontent.com/u/13046303" "avatar.jpg")"
echo "$file" -> ./data-bot-bash/12345-avatar.jpg
```
##### _exists
Returns true if the given function exist, can be used to check if a module is loaded.
*usage* _exists command
*example:*
```bash
_exists "curl" && _message "Command curl is not installed!"
```
##### _is_function
Returns true if the given function exist, can be used to check if a module is loaded.
@ -535,11 +578,60 @@ Returns true if the given function exist, can be used to check if a module is lo
_is_function "background" && _message "you can run background jobs!"
```
----
### Bashbot internal functions
These functions are for internal use only and must not used in your bot commands.
##### procname
Returns PrefixBotname_Postfix
*usage:* procname postfix prefix
*example:*
```bash
# returns botname, if already set
procname
# returns unique identifier for everthing related to chat
procname "${CHAT[ID]}"
# returns unique identifier for job, regardless of chat
procname "" "back-jobname-"
# returns unique identifier for a job related to a chat
# e.g. fifo, cmd and logfile name
procname "${CHAT[ID]}" "back-jobname-"
```
##### proclist
Returns process IDs of current bot processes containing string 'pattern' in name or argument.
*usage:* proclist pattern
*example:*
```bash
# list PIDs of all background processes
proclist "back-"
# list PIDs of all processes of a job
proclist "back-jobname-"
# list PIDs of all processes for a chat
proclist "_${CHAT[ID]}"
# list PIDs of all bot processes
proclist
```
##### killallproc
kill all current bot processes containing string 'pattern' in name or argument
*usage:* killallproc pattern
*example:*
```bash
# kill all background processes
killallproc "back-"
# kill all processes for a chat
killallproc "_${CHAT[ID]}"
# kill all bot processes, including YOURSELF!
killallproc
```
##### get_file
*usage:* url="$(get_file "${CHAT[ID]}" "message")"
@ -586,11 +678,8 @@ The name of your bot is availible as bash variable "$ME", there is no need to ca
*usage:* ME="$(getBotNiname)"
##### inproc
Send Input from Telegram to waiting Interactive Chat.
#### [Prev Best Practice](5_practice.md)
#### [Next Notes for Developers](7_develop.md)
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-11-g8669cfb

View File

@ -5,7 +5,7 @@ This section is about help and best practices for new bashbot developers. The ma
bashbot development is done on github. If you want to provide fixes or new features [fork bashbot on githup](https://help.github.com/en/articles/fork-a-repo) and provide changes as [pull request on github](https://help.github.com/en/articles/creating-a-pull-request).
### Debugging Bashbot
In normal mode of operation all bashbot output is discarded one more correct sent to TMUX console.
In normal mode of operation all bashbot output is discarded.
To get these messages (and more) you can start bashbot in the current shell ```./bashbot.sh startbot```. Now you can see all output or erros from bashbot.
In addition you can change the change the level of verbosity by adding a third argument after startbot.
```
@ -188,5 +188,5 @@ fi
#### [Prev Function Reference](6_reference.md)
#### [Next Bashbot Environment](8_custom.md)
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d

View File

@ -131,5 +131,5 @@ for every poll until the maximum of BASHBOT_SLEEP ms.
#### [Prev Notes for Developers](7_develop.md)
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d

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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d

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$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment

View File

@ -2,7 +2,7 @@
# file: run_filename
# background job to display content of all new files in WATCHDIR
#
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment

View File

@ -2,7 +2,7 @@
# file: run_filename
# background job to display all new files in WATCHDIR
#
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment

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$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# 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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
SHELL=/bin/sh

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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment

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$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment

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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# adjust your language setting here
# https://github.com/topkecleon/telegram-bot-bash#setting-up-your-environment
@ -26,6 +26,7 @@ until [ "$SUCCESS" = "y" ] ;do
case $answer in
'Yass!') echo "Goody! mykeyboardendshere";SUCCESS=y;;
'No') echo "Well that's weird. mykeyboardendshere";SUCCESS=y;;
'') echo "empty answer!" && exit;;
*) SUCCESS=n;;
esac
done

View File

@ -1,7 +1,7 @@
# file: botacl
# a user not listed here, will return false from 'user_is_allowed'
#
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# 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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
#
# 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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-6-gd34c22f
#
# 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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# source from commands.sh to use the inline functions
@ -97,6 +97,6 @@ inline_query_compose(){
;;
esac
echo "${JSON}"
printf '%s\n' "${JSON}"
}

View File

@ -5,48 +5,138 @@
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-11-g8669cfb
# source from commands.sh if you want ro use interactive or background jobs
######
# interactive and background functions
# old syntax as aliases
background() {
echo "${CHAT[ID]}:$2:$1" >"${TMPDIR:-.}/${copname:--}$2-back.cmd"
startproc "$1" "back-$2-"
start_back "${CHAT[ID]}" "$1" "$2"
}
startproc() {
killproc "$2"
local fifo="$2${copname}"
mkfifo "${TMPDIR:-.}/${fifo}"
tmux new-session -d -s "${fifo}" "$1 &>${TMPDIR:-.}/${fifo}; echo imprettydarnsuredatdisisdaendofdacmd>${TMPDIR:-.}/${fifo}"
tmux new-session -d -s "sendprocess_${fifo}" "bash $SCRIPT outproc ${CHAT[ID]} ${fifo}"
start_proc "${CHAT[ID]}" "$1" "$2"
}
checkback() {
checkproc "back-$1-"
check_back "${CHAT[ID]}" "$1"
}
checkproc() {
check_proc "${CHAT[ID]}" "$1"
}
killback() {
kill_back "${CHAT[ID]}" "$1"
}
killproc() {
kill_proc "${CHAT[ID]}" "$1"
}
checkproc() {
tmux ls | grep -q "$1${copname}"
# inline and backgound functions
# $1 chatid
# $2 program
# $3 jobname
start_back() {
local fifo; fifo="${TMPDIR:-.}/$(procname "$1")"
printf '%s\n' "$1:$3:$2" >"${fifo}$3-back.cmd"
start_proc "$1" "$2" "back-$3-"
}
# $1 chatid
# $2 program
# $3 prefix
start_proc() {
[ "$2" = "" ] && return
[ -x "${2%% *}" ] || return 1
local fifo; fifo="${TMPDIR:-.}/$(procname "$1" "$3")"
kill_proc "$1" "$3"
mkfifo "${fifo}"
nohup bash -c "{ tail -f < \"${fifo}\" | $2 \"\" \"\" \"$fifo\" | \"${SCRIPT}\" outproc \"${1}\" \"${fifo}\"
rm \"${fifo}\"; [ -s \"${fifo}.log\" ] || rm -f \"${fifo}.log\"; }" &>>"${fifo}.log" &
}
# $1 chatid
# $2 jobname
check_back() {
check_proc "$1" "back-$2-"
}
# $1 chatid
# $2 prefix
check_proc() {
[ "$(proclist "$(procname "$1" "$2")")" != "" ]
# shellcheck disable=SC2034
res=$?; return $?
}
killback() {
killproc "back-$1-"
rm -f "${TMPDIR:-.}/${copname}$1-back.cmd"
# $1 chatid
# $2 jobname
kill_back() {
kill_proc "$1" "back-$2-"
rm -f "${TMPDIR:-.}/$(procname "$1")$2-back.cmd"
}
killproc() {
local fifo="$1${copname}"
(tmux kill-session -t "${fifo}"; echo imprettydarnsuredatdisisdaendofdacmd>"${TMPDIR:-.}/${fifo}"; tmux kill-session -t "sendprocess_${fifo}"; rm -f -r "${TMPDIR:-.}/${fifo}")2>/dev/null
# $1 chatid
# $2 prefix
kill_proc() {
local fifo prid
fifo="$(procname "$1" "$2")"
prid="$(proclist "${fifo}")"
fifo="${TMPDIR:-.}/${fifo}"
# shellcheck disable=SC2086
[ "${prid}" != "" ] && kill ${prid}
[ -s "${fifo}.log" ] || rm -f "${fifo}.log"
[ -p "${fifo}" ] && rm -f "${fifo}";
}
# $1 chat
# $2 message
send_interactive() {
local fifo; fifo="${TMPDIR:-.}/$(procname "$1")"
[ -p "${fifo}" ] && printf '%s\n' "$2" >"${fifo}" & # not blocking!
}
# old style but may not work because of local checks
inproc() {
tmux send-keys -t "$copname" "${MESSAGE[0]} ${URLS[*]}
"
send_interactive "${CHAT[ID]}" "${MESSAGE}"
}
# start stopp all jobs
# $1 command
# killb*
# suspendb*
# resumeb*
job_control() {
local content proc CHAT job fifo killall=""
for FILE in "${TMPDIR:-.}/"*-back.cmd; do
[ "${FILE}" = "${TMPDIR:-.}/*-back.cmd" ] && echo -e "${RED}No background processes.${NC}" && break
content="$(< "${FILE}")"
CHAT="${content%%:*}"
job="${content#*:}"
proc="${job#*:}"
job="back-${job%:*}-"
fifo="$(procname "${CHAT}" "${job}")"
case "$1" in
"resumeb"*|"backgr"*)
echo "Restart Job: ${proc} ${fifo}"
start_proc "${CHAT}" "${proc}" "${job}"
;;
"suspendb"*)
echo "Suspend Job: ${proc} ${fifo}"
kill_proc "${CHAT}" "${job}"
killall="y"
;;
"killb"*)
echo "Kill Job: ${proc} ${fifo}"
kill_proc "${CHAT}" "${job}"
rm -f "${FILE}" # remove job
killall="y"
;;
esac
done
# kill all requestet. kill ALL background jobs, even not listed in data-bot-bash
[ "${killall}" = "y" ] && killallproc "back-"
}

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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# source from commands.sh to use the member functions
@ -48,7 +48,7 @@ user_is_botadmin() {
local admin; admin="$(head -n 1 "${BOTADMIN}")"
[ "${admin}" = "${1}" ] && return 0
[[ "${admin}" = "@*" ]] && [[ "${admin}" = "${2}" ]] && return 0
if [ "${admin}" = "?" ]; then echo "${1:-?}" >"${BOTADMIN}"; return 0; fi
if [ "${admin}" = "?" ]; then printf '%s\n' "${1:-?}" >"${BOTADMIN}"; 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$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-4-gd1a3372
# source from commands.sh to use the sendMessage functions
@ -48,12 +48,12 @@ send_html_message() {
old_send_keyboard() {
local text='"text":"'"${2}"'"'
shift 2
local keyboard=init
OLDIFS=$IFS
IFS=$(echo -en "\"")
local keyboard="init"
OLDIFS="$IFS"
IFS="\""
for f in "$@" ;do [ "$f" != " " ] && keyboard="$keyboard, [\"$f\"]";done
IFS=$OLDIFS
keyboard=${keyboard/init, /}
IFS="$OLDIFS"
keyboard="${keyboard/init, /}"
sendJson "${1}" "${text}"', "reply_markup": {"keyboard": [ '"${keyboard}"' ],"one_time_keyboard": true}' "$MSG_URL"
}
@ -87,19 +87,25 @@ send_button() {
UPLOADDIR="${BASHBOT_UPLOAD:-${TMPDIR}/upload}"
# for now this can only send local files with curl!
# extend to allow send files by URL or telegram ID
send_file() {
[ "$2" = "" ] && return
local file="$2"
local CAPTION=',"caption":"'$3'"'; [ "$3" = "" ] && CAPTION=""
[[ "$2" = "http"* ]] && return # currently we do not support URL
upload_file "${@}"
}
upload_file(){
local CUR_URL WHAT STATUS file="$2"
# file access checks ...
[[ "$file" = *'..'* ]] && return # no directory traversal
[[ "$file" = '.'* ]] && return # no hidden or relative files
if [[ "$file" = '/'* ]] ; then
[[ "$file" =~ $FILE_REGEX ]] || return # absulute must match REGEX
[[ ! "$file" =~ $FILE_REGEX ]] && return # absulute must match REGEX
else
file="${UPLOADDIR:-NOUPLOADDIR}/${file}" # othiers must be in UPLOADDIR
fi
[ -r "$file" ] || return # and file must exits of course
[ ! -r "$file" ] && return # and file must exits of course
local ext="${file##*.}"
case $ext in
@ -136,8 +142,7 @@ send_file() {
;;
esac
send_action "${1}" "$STATUS"
# shellcheck disable=SC2034
sendJson "${1}" '"'"$WHAT"'":"'"$2"'"'"$CAPTION"'"' "$CUR_URL"
sendUpload "$1" "${WHAT}" "${file}" "${CUR_URL}" "$3"
}
# typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for location

View File

@ -2,7 +2,7 @@
# files: mycommands.sh.dist
# copy to mycommands.sh and add all your commands and functions here ...
#
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-2-g9482bd6
#
# uncomment the following lines to overwrite info and help messages
@ -30,7 +30,7 @@ if [ "$1" != "source" ];then
'/question'*) # start interactive questions
checkproc
if [ "$res" -gt 0 ] ; then
startproc "examples/question.sh"
startproc "examples/question.sh" || _message "Can't start question."
else
send_normal_message "${CHAT[ID]}" "$MESSAGE already running ..."
fi
@ -39,7 +39,7 @@ if [ "$1" != "source" ];then
'/run_notify'*) # start notify background job
myback="notify"; checkback "$myback"
if [ "$res" -gt 0 ] ; then
background "examples/notify.sh 60" "$myback" # notify every 60 seconds
background "examples/notify.sh 60" "$myback" || _message "Can't start notify."
else
send_normal_message "${CHAT[ID]}" "Background command $myback already running ..."
fi

View File

@ -2,7 +2,7 @@
#
# ADD a new test skeleton to test dir, but does not activate test
#
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# 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.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# common variables
export TESTME DIRME TESTDIR LOGFILE REFDIR TESTNAME

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
../dev/hooks/pre-commit.sh

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
# file: b-example-test.sh
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-4-gd1a3372
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh
@ -28,15 +28,30 @@ sendEmpty() {
sendJson() {
printf 'chat:%s\tJSON:%s\nURL:%s\n\n' "${1}" "${2}" "${3}"
}
sendUpload() {
#JSON:"document":"/tmp/allowed/this_is_my.doc","caption":"Text plus absolute file will appear in chat""
printf 'chat:%s\tJSON:"%s":"%s","caption":"%s"\nURL:%s\n\n' "${1}" "${2}" "${3}" "${5}" "${4}"
}
# send text input to send_message
echo -n " Send line ..."
# create dummy files for upload
ALLOW='/tmp/allowed'
FILE_REGEX="$ALLOW/.*"
[ -d "$ALLOW" ] || mkdir "$ALLOW"
touch "$ALLOW/this_is_my.gif" "$ALLOW/this_is_my.doc"
touch "$TMPDIR/this_is_my.gif" "$TMPDIR/this_is_my.doc"
while read -r line ; do
echo -n "."
set -x
send_message "123456" "$line" >>"${OUTPUTFILE}"
done < "${INPUTFILE}" #2>>"${LOGFILE}"
set +x
done < "${INPUTFILE}" 2>>"${LOGFILE}"
[ -d "$ALLOW" ] && rm -rf "$ALLOW"
echo " done."
{ diff -c "${REFFILE}" "${OUTPUTFILE}" || exit 1; } | cat -v

View File

@ -14,3 +14,13 @@ Text plus vuene will appear in chat mylatstartshere la10 mylongstartshere lo20 m
# test for new inline button
Text plus keyboard will appear in chat mybtextstartshere Button Text myburlstartshere https://www...
STABILO 88/240 Fineliner point 88 mynewlinestartshere mynewlinestartshere [https://images-na.ssl-images-amazon.com/images/I/41oypA3kmHL.l_SX300.jpg] mynewlinestartshere mybtextstartshere Bei Amazon ansehen ... myburlstartshere https://www.amazon.de/dp/B014TN3JYW mytextstartshere second part of text mynewlinestartshere plus newline.
# test for sendfile
Text plus absolute file will appear in chat myfilelocationstartshere /tmp/allowed/this_is_my.gif
Text plus absolute file will appear in chat myfilelocationstartshere /tmp/allowed/this_is_my.doc
Text plus relative file will appear in chat myfilelocationstartshere this_is_my.gif
Text plus relative file will appear in chat myfilelocationstartshere this_is_my.doc
THIS IS OUTSIDE allowed myfilelocationstartshere /home/user/NOTallowed/this_is_my.dif
THIS DOES NOT EXIST myfilelocationstartshere /tmp/allowed/this_does_not_exist.gif
THIS DOES NOT EXIST myfilelocationstartshere this_does_not_exist.gif

View File

@ -47,3 +47,18 @@ second part of text
plus newline.", "reply_markup": {"inline_keyboard": [ [ {"text":"Bei Amazon ansehen ...", "url":"https://www.amazon.de/dp/B014TN3JYW"}] ]}
URL:https://api.telegram.org/botbashbottestscript/sendMessage
chat:123456 JSON:"text":"# test for sendfile"
URL:https://api.telegram.org/botbashbottestscript/sendMessage
chat:123456 JSON:"action": "upload_photo"
URL:https://api.telegram.org/botbashbottestscript/sendChatAction
chat:123456 JSON:"photo":"/tmp/allowed/this_is_my.gif","caption":"Text plus absolute file will appear in chat"
URL:https://api.telegram.org/botbashbottestscript/sendPhoto
chat:123456 JSON:"action": "upload_document"
URL:https://api.telegram.org/botbashbottestscript/sendChatAction
chat:123456 JSON:"document":"/tmp/allowed/this_is_my.doc","caption":"Text plus absolute file will appear in chat"
URL:https://api.telegram.org/botbashbottestscript/sendDocument

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
#### $$VERSION$$ v0.76-1-ge8a1fd0
#### $$VERSION$$ v0.80-pre-0-gdd7c66d
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh