5.4 KiB
Home
Best Practices
New to bot development?
If you are new to Bot development read Bots: An introduction for developers and consult Telegram Bot API Documentation.
In addition you should know about BotFather, the one bot to rule them all. It will help you create new bots and change settings for existing ones. Commands known by Botfather
If you don't have a github account, it may time to setup a free account now
Add commands to mycommands.sh only
Do not change bashbot.sh
and commands.sh
, instead place your commands in to mycommands.sh
.
To start with a clean/minimal bot copy mycommands.sh.clean
to mycommands.sh
and start editing
the message strings and place commands in thecase ... esac
block of the function mycommands():
# file: mycommands.sh
# your additional bashbot commands
# uncomment the following lines to overwrite info and help messages
bashbot_info='This is *MY* variant of _bashbot_, the Telegram bot written entirely in bash.
'
bashbot_help='*Available commands*:
/echo message - _echo the given messsage_
'
# NOTE: command can have @botname attached, you must add * in case tests...
mycommands() {
case "$MESSAGE" in
'/echo'*) # example echo command
send_normal_message "${CHAT[ID]}" "$MESSAGE"
;;
# .....
esac
}
DIsable, replace and extend global commands
Global bashbot command processing, e.g. /start, /info etc. is disabled if you return a non zero value from mycommands.sh
,
see /start example below.
To replace a global bashbot command add the same command to mycommands.sh
and place return 1
at the end of
the case block, see /kickme example below.
If a command is available as a global command and in mycommands.sh
, plus you return a zero value (nothing or 0)
both command sections are processed. Thus you can extend global commands with additional actions, see /info example below
Learn more about Bot commands.
# file: mycommands.sh
case "$MESSAGE" in
##########
# disable start command
'/start'*) # disable all commands starting with leave
return 1
;;
# replace command with your own actions
'/kickme'*) # this will replace the /kickme command
send_markdown_mesage "${CHAT[ID]}" "*This bot will not kick you!*"
return 1
;;
# extend global command
'/info'*) # output date in front of regular info
send_normal_message "${CHAT[ID]}" "$(date)"
return 0
;;
esac
Separate logic from commands
If a command need more than 2-3 lines of code, you should use a function to separate logic from command. Place your functions in mycommands.sh
and call the from your command. Example:
# file: mycommands.sh
# your additional bashbot commands
mycommands() {
case "$MESSAGE" in
'/doit'*) # logic for /doit is done in process_message
result="$(process_message "$MESSAGE")"
send_normal_message "${CHAT[ID]}" "$result"
;;
esac
}
# place your functions here
process_message() {
local ARGS="${1#/* }" # remove command
local TEXT OUTPUT=""
# process every word in MESSAGE, avoid globbing
set -f
for WORD in $ARGS
do
# process links
if [[ "$WORD" == "https://"* ]]; then
REPORT="$(dosomething_with_link "$WORD")"
# no link, add as text
else
TEXT="$(echo "${TEXT} $WORD")"
continue
fi
# compose result
OUTPUT="* ${REPORT} ${WORD} ${TEXT}"
TEXT=""
done
# return result, reset globbing in case we had no ARGS
echo "${OUTPUT}${TEXT}"
}
Test your Bot with shellcheck
Shellcheck is a static linter for shell scripts providing excellent tips and hints for shell coding pittfalls. You can use it online or install it on your system. All bashbot scripts are linted by shellcheck.
Shellcheck examples:
$ shellcheck -x mybotcommands.inc.sh
Line 17:
TEXT="$(echo "${TEXT} $WORD")"
^-- SC2116: Useless echo? Instead of 'cmd $(echo foo)', just use 'cmd foo'.
As you can see my mybotcommands.inc.sh
contains an useless echo command in 'TEXT=' assignment and can be replaced by TEXT="${TEXT}${WORD}"
$ shellcheck -x examples/notify
OK
$ shellcheck -x examples/question
OK
$ shellcheck -x commands.sh
OK
$ shellcheck -x bashbot.sh
In bashbot.sh line 123:
text="$(echo "$text" | sed 's/ mynewlinestartshere /\r\n/g')" # hack for linebreaks in startproc scripts
^-- SC2001: See if you can use ${variable//search/replace} instead.
In bashbot.sh line 490:
CONTACT[USER_ID]="$(sed -n -e '/\["result",'$PROCESS_NUMBER',"message","contact","user_id"\]/ s/.*\][ \t]"\(.*\)"$/\1/p' <"$TMP")"
^-- SC2034: CONTACT appears unused. Verify it or export it.
The example show two warnings in bashbots scripts. The first is a hint you may use shell substitutions instead of sed, this is fixed and much faster as the "echo | sed" solution. The second warning is about an unused variable, this is true because in our examples CONTACT is not used but assigned in case you want to use it :-)