ups, deleted doc, fixed

This commit is contained in:
Kay Marquardt (Gnadelwartz) 2019-05-16 16:43:44 +02:00
parent a72f24ac9c
commit 085d85da35
9 changed files with 1701 additions and 0 deletions

74
doc/0_install.md Normal file
View File

@ -0,0 +1,74 @@
#### [Home](../README.md)
## Install bashbot
1. Go to the directory you want to install bashbot, e.g.
* your $HOME directory (install and run with your user-ID)
* /usr/local if you want to run as service
2. [Download latest release zip from github](https://github.com/topkecleon/telegram-bot-bash/releases) and extract all files.
3. Change into the directory ```telegram-bot-bash```
4. Create default commands with ```cp commands.sh.dist commands.sh; cp mycommands.sh.dist mycommands.sh```
5. Run ```./bashbot.sh init``` to setup the environment and enter your Bots token given by botfather.
Now your Bot is ready to start ...
**If you are new to Bot development read [Bots: An introduction for developers](https://core.telegram.org/bots)**
### Install from Github
As an alternative to download the zip files, you can clone the github repository to get the latest improvements/fixes.
1. Go to the directory you want to install bashbot, e.g.
* your $HOME directory (install and run with your user-ID)
* /usr/local if you want to run as service
2. Run ```git clone https://github.com/topkecleon/telegram-bot-bash.git```
3. Change into the directory ```telegram-bot-bash```
4. Run ``` test/ALL-tests.sh``` and if everthing finish OK ...
5. Run ```sudo ./bashbot.sh init``` to setup the environment and enter your Bots token given by botfather.
### Update bashbot
1. Go to the directory where you had installed bashbot, e.g.
* your $HOME directory
* /usr/local
2. [Download latest release zip from github](https://github.com/topkecleon/telegram-bot-bash/releases)
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
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.
### 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.
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'.
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
From Version 0.60 on keybord format for ```send_keyboard``` and ```send_message "mykeyboardstartshere ..."``` was changed.
Keybords are now defined in JSON Array notation e.g. "[ \\"yes\\" , \\"no\\" ]".
This has the advantage that you can create any type of keyboard supported by Telegram.
The old format is supported for backward compatibility, but may fail for corner cases.
*Example Keyboards*:
- yes no in two rows:
- OLD format: 'yes' 'no' *(two strings)*
- NEW format: '[ "yes" ] , [ "no" ]' *(two arrays with a string)*
- new layouts made easy with NEW format:
- Yes No in one row: '[ "yes" , "no" ]'
- Yes No plus Maybe in 2.row: '[ "yes" , "no" ] , [ "maybe" ]'
- numpad style keyboard: '[ "1" , "2" , "3" ] , [ "4" , "5" , "6" ] , [ "7" , "8" , "9" ] , [ "0" ]'
#### [Next Create Bot](1_firstbot.md)
#### $$VERSION$$ v0.80-dev2-11-gb55c171

69
doc/1_firstbot.md Normal file
View File

@ -0,0 +1,69 @@
#### [Home](../README.md)
## Create a Telegram Bot with botfather
**[BotFather is the one bot to rule them all](https://core.telegram.org/bots#3-how-do-i-create-a-bot). It will help you create new bots and change settings for existing ones.** [Commands known by Botfather](https://core.telegram.org/bots#generating-an-authorization-token)
### Creating a new Bot
1. Message @botfather https://telegram.me/botfather with the following
text: `/newbot`
If you don't know how to message by username, click the search
field on your Telegram app and type `@botfather`, you should be able
to initiate a conversation. Be careful not to send it to the wrong
contact, because some users has similar usernames to `botfather`.
![botfather initial conversation](http://i.imgur.com/aI26ixR.png)
2. @botfather replies with `Alright, a new bot. How are we going to
call it? Please choose a name for your bot.`
3. Type whatever name you want for your bot.
4. @botfather replies with `Good. Now let's choose a username for your
bot. It must end in bot. Like this, for example: TetrisBot or
tetris_bot.`
5. Type whatever username you want for your bot, minimum 5 characters,
and must end with `bot`. For example: `telesample_bot`
6. @botfather replies with:
Done! Congratulations on your new bot. You will find it at
telegram.me/telesample_bot. You can now add a description, about
section and profile picture for your bot, see /help for a list of
commands.
Use this token to access the HTTP API:
<b>123456789:AAG90e14-0f8-40183D-18491dDE</b>
For a description of the Bot API, see this page:
https://core.telegram.org/bots/api
7. Note down the 'token' mentioned above.
8. Type `/setprivacy` to @botfather.
![botfather later conversation](http://i.imgur.com/tWDVvh4.png)
9. @botfather replies with `Choose a bot to change group messages settings.`
10. Type `@telesample_bot` (change to the username you set at step 5
above, but start it with `@`)
11. @botfather replies with
'Enable' - your bot will only receive messages that either start
with the '/' symbol or mention the bot by username.
'Disable' - your bot will receive all messages that people send to groups.
Current status is: ENABLED
12. Type `Disable` to let your bot receive all messages sent to a
group. This step is up to you actually.
13. @botfather replies with `Success! The new status is: DISABLED. /help`
#### [Prev Installation](0_install.md)
#### [Next Getting started](2_usage.md)
#### $$VERSION$$ v0.80-dev2-1-g0b36bc5

186
doc/2_usage.md Normal file
View File

@ -0,0 +1,186 @@
#### [Home](../README.md)
## Gettting Started
The Bots standard commands are in ```commands.sh``` file. You must not add your commands to 'commands.sh', instead place them in ```mycommands.sh```, there you also find examples how to process messages and send out text. See [Best practices](5_practice.md) for more information.
Once you're done with editing 'mycommands.sh' start the Bot with ```./bashbot.sh start```.
To stop the Bot run ```./bashbot.sh kill```
If some thing doesn't work as it should, you can debug with ```./bashbot.sh startbot DEBUG``` where DEBUG can be 'debug', 'xdebug' or 'xdebugx'.
See [Bashbot Development](7_develop.md) for more information.
To use the functions provided in this script in other scripts simply source bashbot: ```source bashbot.sh```
Have FUN!
## Managing your own Bot
#### Note: running bashbot as root is highly danger and not recommended. See Expert use.
### Start / Stop
Start or Stop your Bot use the following commands:
```bash
./bashbot.sh start
```
```bash
./bashbot.sh kill
```
### User count
To count the total number of users that ever used the bot run the following command:
```bash
./bashbot.sh count
```
### Sending broadcasts to all users
To send a broadcast to all of users that ever used the bot run the following command:
```bash
./bashbot.sh broadcast "Hey! I just wanted to let you know that the bot's been updated!"
```
## Recieve data
Evertime a Message is recieved, you can read incoming data using the following variables:
### Regular Messages
* ```${MESSAGE}```: Current message
* ```${MESSAGE[ID]}```: ID of current message
* ```$CAPTION```: Captions
* ```$REPLYTO```: Original message wich was replied to
* ```$USER```: This array contains the First name, last name, username and user id of the sender of the current message.
* ```${USER[ID]}```: User id
* ```${USER[FIRST_NAME]}```: User's first name
* ```${USER[LAST_NAME]}```: User's last name
* ```${USER[USERNAME]}```: Username
* ```$CHAT```: This array contains the First name, last name, username, title and user id of the chat of the current message.
* ```${CHAT[ID]}```: Chat id
* ```${CHAT[FIRST_NAME]}```: Chat's first name
* ```${CHAT[LAST_NAME]}```: Chat's last name
* ```${CHAT[USERNAME]}```: Username
* ```${CHAT[TITLE]}```: Title
* ```${CHAT[TYPE]}```: Type
* ```${CHAT[ALL_MEMBERS_ARE_ADMINISTRATORS]}```: All members are administrators (true if true)
* ```$REPLYTO```: This array contains the First name, last name, username and user id of the ORIGINAL sender of the message REPLIED to.
* ```${REPLYTO[ID]}```: ID of message wich was replied to
* ```${REPLYTO[UID]}```: Original user's id
* ```${REPLYTO[FIRST_NAME]}```: Original user's first name
* ```${REPLYTO[LAST_NAME]}```: Original user's' last name
* ```${REPLYTO[USERNAME]}```: Original user's username
* ```$FORWARD```: This array contains the First name, last name, username and user id of the ORIGINAL sender of the FORWARDED message.
* ```${FORWARD[ID]}```: Same as MESSAGE[ID] if message is forwarded
* ```${FORWARD[UID]}```: Original user's id
* ```${FORWARD[FIRST_NAME]}```: Original user's first name
* ```${FORWARD[LAST_NAME]}```: Original user's' last name
* ```${FORWARD[USERNAME]}```: Original user's username
* ```$URLS```: This array contains documents, audio files, voice recordings and stickers as URL.
* ```${URLS[AUDIO]}```: Audio files
* ```${URLS[VIDEO]}```: Videos
* ```${URLS[PHOTO]}```: Photos (maximum quality)
* ```${URLS[VOICE]}```: Voice recordings
* ```${URLS[STICKER]}```: Stickers
* ```${URLS[DOCUMENT]}```: Any other file
* ```$CONTACT```: This array contains info about contacts sent in a chat.
* ```${CONTACT[ID]}```: User id
* ```${CONTACT[NUMBER]}```: Phone number
* ```${CONTACT[FIRST_NAME]}```: First name
* ```${CONTACT[LAST_NAME]}```: Last name
* ```${CONTACT[VCARD]}```: User's complete Vcard
* ```$LOCATION```: This array contains info about locations sent in a chat.
* ```${LOCATION[LONGITUDE]}```: Longitude
* ```${LOCATION[LATITUDE]}```: Latitude
* ```$VENUE```: This array contains info about venue (a place) sent in a chat.
* ```${VENUE[TITLE]}```: Name of the place
* ```${VENUE[ADDRESS]}```: Address of the place
* ```${VENUE[LONGITUDE]}```: Longitude
* ```${VENUE[LATITUDE]}```: Latitude
* ```${VENUE[FOURSQUARE]}```: Fouresquare ID
### Inline queries
Evertime a Message is recieved, you can read incoming data using the following variables:
* ```${iQUERY}```: Current inline query
* ```$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
* ```${iQUERY[FIRST_NAME]}```: User's first name
* ```${iQUERY[LAST_NAME]}```: User's last name
## Usage of bashbot functions
#### sending messages
To send messages use the ```send_xxx_message``` functions.
To send regular text without any markdown use:
```bash
send_text_message "${CHAT[ID]}" "lol"
```
To send text with markdown:
```bash
send_markdown_message "${CHAT[ID]}" "lol *bold*"
```
To send text with html:
```bash
send_html_message "${CHAT[ID]}" "lol <b>bold</b>"
```
To forward messages use the ```forward``` function:
```bash
forward "${CHAT[ID]}" "from_chat_id" "message_id"
```
If your Bot is Admin in a Chat you can delete every message, if not you can delete only your messages.
To delete a message with a known ${MESSAGE[ID]} you can simple use:
```bash
delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
```
#### send_message
In addition there is a universal send_massage function which can output any type of message.
This function is used to process output from external scrips like interactive chats or background jobs.
**For safety and performance reasons I recommend to use send_xxxx_message functions above for sending messages**
```bash
send_message "${CHAT[ID]}" "lol"
```
To send html or markdown put the following strings before the text, depending on the parsing mode you want to enable:
```bash
send_message "${CHAT[ID]}" "markdown_parse_mode lol *bold*"
```
```bash
send_message "${CHAT[ID]}" "html_parse_mode lol <b>bold</b>"
```
This function also allows a third parameter that disables additional function parsing (for safety use this when reprinting user input):
```bash
send_message "${CHAT[ID]}" "lol" "safe"
```
**See also [Interactive chats](3_advanced.md#Interactive-Chats)**
#### Send files, locations, keyboards.
To send images, videos, voice files, photos etc. use the ```send_photo``` function (remember to change the safety Regex @ line 14 of command.sh to allow sending files only from certain directories):
```bash
send_file "${CHAT[ID]}" "/home/user/doge.jpg" "Lool"
```
To send custom keyboards use the ```send_keyboard``` function:
```bash
send_keyboard "${CHAT[ID]}" "Text that will appear in chat?" '[ "Yep" , "No" ]' # note the simgle quotes!
send_keyboard "${CHAT[ID]}" "Text that will appear in chat?" "[ \\"Yep\\" , \\"No\\" ]" # within double quotes you must excape the inside double quots
```
To send locations use the ```send_location``` function:
```bash
send_location "${CHAT[ID]}" "Latitude" "Longitude"
```
To send venues use the ```send_venue``` function:
```bash
send_venue "${CHAT[ID]}" "Latitude" "Longitude" "Title" "Address" "optional foursquare id"
```
To send a chat action use the ```send_action``` function.
Allowed values: 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 locations.
```bash
send_action "${CHAT[ID]}" "action"
```
**See also [Bashbot function reference](6_reference.md#Interactive_Chats)**
#### [Prev Create Bot](1_firstbot.md)
#### [Next Advanced Usage](3_advanced.md)
#### $$VERSION$$ v0.80-dev2-1-g0b36bc5

184
doc/3_advanced.md Normal file
View File

@ -0,0 +1,184 @@
#### [Home](../README.md)
## Advanced Features
### Access control
Bashbot offers functions to check what Telegram capabilities like 'chat admin' or 'chat creator' the given user has:
```bash
# return true if user is admin/owner of the bot
# -> botadmin is stored in file './botadmin'
user_is_botadmin "user"
# return true if user is creator or admin of a chat
user_is_admin "chat" "user"
# return true if user is creator of a chat or it's a one to one chat
user_is_creator "chat" "user"
# examples:
user_is_botadmin "${USER[ID]}" && send_markdown_message "${CHAT[ID]}" "You are *BOTADMIN*."
user_is_admin "${CHAT[ID]}" "${USER[ID]}" && send_markdown_message "${CHAT[ID]}" "You are *CHATADMIN*."
```
In addition you can check individual capabilities of users as you must define in the file ```./botacl```:
```bash
# file: botacl
# a user not listed here, will return false from 'user_is_allowed'
#
# Format:
# user:ressource:chat
# allow user 123456789 access to all resources in all chats
123456789:*:*
# allow user 12131415 to start bot in all chats
12131415:start:*
# allow user 987654321 only to start bot in chat 98979695
987654321:start:98979695
# * are only allowed on the right hand side and not for user!
# the following exaples are NOT valid!
*:*:*
*:start:*
*:*:98979695
```
You must use the function ```user_is_allowed``` to check if a user has the capability to do something. Example: Check if user has capability to start bot.
```bash
case "$MESSAGE" in
################################################
# GLOBAL commands start here, only edit messages
'/start'*)
user_is_botadmin "${USER[ID]}" && send_markdown_message "${CHAT[ID]}" "You are *BOTADMIN*."
if user_is_allowed "${USER[ID]}" "start" "${CHAT[ID]}" ; then
bot_help "${CHAT[ID]}"
else
send_normal_message "${CHAT[ID]}" "You are not allowed to start Bot."
;;
esac
```
**See also [Bashbot User Access Control functions](6_reference.md#User-Access-Control)**
### Interactive Chats
To create interactive chats, write *(or edit the 'exmaples/question.sh' script)* a bash *(or C or python)* script, make it executable
and then use the 'startproc' function to start the script.
The output of the script will be sent to the user and user input will be sent to the script.
To stop the script use the function 'killprog'
The output of the script will be processed by 'send_messages' to enable you to not only send text, but also keyboards, files, locations and more.
Each newline in the output will start an new message to the user, to have line breaks in your message you can use 'mynewlinestartshere'.
To open up a keyboard in an interactive script, print out the keyboard layout in the following way:
```bash
echo "Text that will appear in chat? mykeyboardstartshere [ \"Yep, sure\" , \"No, highly unlikely\" ]"
```
Same goes for files:
```bash
echo "Text that will appear in chat? myfilelocationstartshere /home/user/doge.jpg"
```
And buttons:
```bash
echo "Text that will appear in chat. mybtextstartshere Klick me myburlstartshere https://dealz.rrr.de"
```
And locations:
```bash
echo "Text that will appear in chat. mylatstartshere 45 mylongstartshere 45"
```
And venues:
```bash
echo "Text that will appear in chat. mylatstartshere 45 mylongstartshere 45 mytitlestartshere my home myaddressstartshere Diagon Alley N. 37"
```
You can combine them:
```bash
echo "Text that will appear in chat? mykeyboardstartshere [ \"Yep, sure\" , \"No, highly unlikely\" ] myfilelocationstartshere /home/user/doge.jpg mylatstartshere 45 mylongstartshere 45"
```
Please note that you can either send a location or a venue, not both. To send a venue add the mytitlestartshere and the myaddressstartshere keywords.
New in v0.6: To insert a linebreak in your message you can insert ```mynewlinestartshere``` in your echo command:
```bash
echo "Text that will appear in one message mynewlinestartshere with this text on a new line"
```
New in v0.7: In case you must extend a message already containing a location, a file, a keyboard etc.,
with additionial text simply add ``` mytextstartshere additional text``` at the end of the string:
```bash
out="Text that will appear mylatstartshere 45 mylongstartshere 45"
[[ "$out" != *'in chat'* ]] && out="$out mytextstartshere in chat."
echo "$out"
```
Note: Interactive Chats run independent from main bot and continue running until your script exits or you /cancel if from your Bot.
### Background Jobs
A background job is similar to an interactive chat, but runs in the background and does only output massages and does not get user input. In contrast to interactive chats it's possible to run multiple background jobs. To create a background job write a script or edit 'examples/notify.sh' script and use the funtion ```background``` to start it:
```bash
background "examples/notify.sh" "jobname"
```
All output of the script will be sent to the user, to stop a background job use:
```bash
killback "jobname"
```
You can also suspend and resume the last running background jobs from outside bashbot, e.g. in your startup schripts:
```bash
./bashbot.sh suspendback
./bashbot.sh resumeback
```
If you want to kill all background jobs permantly run:
```bash
./bashbot.sh killback
```
Note: Background Jobs run independent from main bot and continue running until your script exits or you stop if from your Bot. Backgound Jobs will continue running if your Bot is stopeda and must be terminated, e.g. by ```bashbot.sh killback```
### Inline queries
**Inline queries** allow users to send commands to your bot from every chat without going to a private chat. An inline query is started if the user type the bots name, e.g. @myBot. Everything after @myBot is immediatly send to the bot.
In order to enable **inline mode**, send `/setinline` command to [@BotFather](https://telegram.me/botfather) and provide the placeholder text that the user will see in the input field after typing your bots name.
The following commands allows you to send ansers to *inline queries*. To enable bashbot to process inline queries set ```INLINE="1"``` in 'mycommands.sh'.
To send messsages or links through an *inline query*:
```bash
answer_inline_query "${iQUERY[ID]}" "article" "Title of the result" "Content of the message to be sent"
```
To send photos in jpeg format and less than 5MB, from a website through an *inline query*:
```bash
answer_inline_query "${iQUERY[ID]}" "photo" "A valid URL of the photo" "URL of the thumbnail"
```
To send standard gifs from a website (less than 1MB) through an *inline query*:
```bash
answer_inline_query "${iQUERY[ID]}" "gif" "gif url"
```
To send mpeg4 gifs from a website (less than 1MB) through an *inline query*:
```bash
answer_inline_query "${iQUERY[ID]}" "mpeg4_gif" "mpeg4 gif url"
```
To send videos from a website through an *inline query*:
```bash
answer_inline_query "${iQUERY[ID]}" "video" "valid video url" "Select one mime type: text/html or video/mp4" "URL of the thumbnail" "Title for the result"
```
To send photos stored in Telegram servers through an *inline query*:
```bash
answer_inline_query "${iQUERY[ID]}" "cached_photo" "identifier for the photo"
```
To send gifs stored in Telegram servers through an *inline query*:
```bash
answer_inline_query "${iQUERY[ID]}" "cached_gif" "identifier for the gif"
```
To send mpeg4 gifs stored in Telegram servers through an *inline query*:
```bash
answer_inline_query "${iQUERY[ID]}" "cached_mpeg4_gif" "identifier for the gif"
```
To send stickers through an *inline query*:
```bash
answer_inline_query "${iQUERY[ID]}" "cached_sticker" "identifier for the sticker"
```
See also [answer_inline_multi, answer_inline_compose](6_reference.md#answer_inline_multi) and [mycommands.sh](../mycommands.sh) for more information.
#### [Prev Getting started](2_usage.md)
#### [Next Expert Use](4_expert.md)
#### $$VERSION$$ v0.80-dev2-1-g0b36bc5

108
doc/4_expert.md Normal file
View File

@ -0,0 +1,108 @@
#### [Home](../README.md)
## Expert Use
### Handling UTF-8 character sets
UTF-8 is a variable length encoding of Unicode. UTF-8 is recommended as the default encoding in JSON, XML and HTML, also Telegram make use of it.
The first 128 characters are regular ASCII, so it's a superset of and compatible with ASCII environments. The next 1,920 characters need
two bytes for encoding and covers almost all ```Latin``` alphabets, also ```Greek```, ```Cyrillic```,
```Hebrew```, ```Arabic``` and more. See [Wikipedia](https://en.wikipedia.org/wiki/UTF-8) for more details.
#### Setting up your Environment
In general ```bash``` and ```GNU``` utitities are UTF-8 aware if you to setup your environment
and your scripts accordingly:
1. Your Terminal and Editor must support UTF-8:
Set Terminal and Editor locale to UTF-8, eg. in ```Settings/Configuration``` select UTF-8 (Unicode) as Charset.
2. Set ```Shell``` environment to UTF-8 in your ```.profile``` and your scripts. The usual settings are:
```bash
export 'LC_ALL=C.UTF-8'
export 'LANG=C.UTF-8'
export 'LANGUAGE=C.UTF-8'
```
If you use other languages, eg. german or US english, change the shell settings to:
```bash
export 'LC_ALL=de_DE.UTF-8'
export 'LANG=de_DE.UTF-8'
export 'LANGUAGE=de_DE.UTF-8'
```
```bash
export 'LC_ALL=en_US.UTF-8'
export 'LANG=de_en_US.UTF-8'
export 'LANGUAGE=den_US.UTF-8'
```
3. make shure your bot scripts use the correct settings, eg. include the lines above at the beginning of your scripts
To display all availible locales on your system run ```locale -a | more```. [Gentoo Wiki](https://wiki.gentoo.org/wiki/UTF-8)
#### Bashbot UTF-8 Support
Bashbot handles all messages transparently, regardless of the charset in use. The only exception is when converting from JSON data to strings.
Telegram use JSON to send / recieve data. JSON encodes strings as follow: Characters not ASCII *(>127)* are escaped as sequences of ```\uxxxx``` to be regular ASCII. In addition multibyte characters, *e.g. Emoticons or Arabic characters*, are send in double byte UTF-16 notation.
The Emoticons ``` 😁 😘 ❤️ 😊 👍 ``` are encoded as: ``` \uD83D\uDE01 \uD83D\uDE18 \u2764\uFE0F \uD83D\uDE0A \uD83D\uDC4D ```
**This "mixed" JSON encoding needs special handling and can not decoded from** ```echo -e``` or ```printf '%s\\n'```
Most complete support for decoding of multibyte characters can only be provided if python is installed on your system.
**Without phyton bashbot falls back to an internal, pure bash implementation which may not work for some corner cases**.
### Run as other user or system service
Bashbot is desingned to run manually by the user who installed it. Nevertheless it's possible to run it by an other user-ID, as a system service or sceduled from cron. This is onyl recommended for experiend linux users.
Setup the environment for the user you want to run bashbot and enter desired username, e.g. nobody :
```bash
sudo ./bashbot.sh init
```
Edit the file ```bashbot.rc``` and edit the following lines to fit your configuration:
```bash
#######################
# Configuration Section
# edit the next line to fit the user you want to run bashbot, e.g. nobody:
runas="nobody"
# uncomment one of the following lines
# runcmd="su $runas -s /bin/bash -c " # runasuser with su
# runcmd="runuser $runas -s /bin/bash -c " # runasuser with runuser
# edit the values of the following lines to fit your config:
start="/usr/local/telegram-bot-bash/bashbot.sh" # location of your bashbot.sh script
name='' # your bot name as given to botfather, e.g. mysomething_bot
# END Configuration
#######################
```
From now on use 'bashbot.rc' to manage your bot:
```bash
sudo ./bashbot.rc start
```
Type ```ps -ef | grep bashbot``` to verify your Bot is running as the desired user.
If your Bot is started by 'bashbot.rc', you must use 'bashbot.rc' also to manage your Bot! The following commands are availible:
```bash
sudo ./bashbot.rc start
sudo ./bashbot.rc stop
sudo ./bashbot.rc status
sudo ./bashbot.rc suspendback
sudo ./bashbot.rc resumeback
sudo ./bashbot.rc killback
```
To change back the environment to your user-ID run ```sudo ./bashbot.sh init``` again and enter your user name.
To use bashbot as a system servive include a working ```bashbot.rc``` in your init system (systemd, /etc/init.d).
### Scedule bashbot from Cron
An example crontab is provided in ```examples/bashbot.cron```.
- If you are running bashbot with your user-ID, copy the examples lines to your crontab and remove username ```nobody```.
- if you run bashbot as an other user or a system service edit ```examples/bashbot.cron``` to fit your needs and replace username```nobody``` with the username you want to run bashbot. copy the modified file to ```/etc/cron.d/bashbot```
#### [Prev Expert Use](4_expert.md)
#### [Next Best Practice](5_practice.md)
#### $$VERSION$$ v0.80-dev2-1-g0b36bc5

157
doc/5_practice.md Normal file
View File

@ -0,0 +1,157 @@
#### [Home](../README.md)
## Best Practices
### New to bot development?
If you are new to Bot development read [Bots: An introduction for developers](https://core.telegram.org/bots) and consult [Telegram Bot API Documentation](https://core.telegram.org/bots/api/).
In addition you should know about [BotFather, the one bot to rule them all](https://core.telegram.org/bots#3-how-do-i-create-a-bot). It will help you create new bots and change settings for existing ones. [Commands known by Botfather](https://core.telegram.org/bots#generating-an-authorization-token)
If you dont't have a github account, it may time to [sepup a free account now](https://github.com/pricing)
### Add commands to mycommands.sh only
To ease updates never change ```bashbot.sh```, instead your commands and functions must go to ```mycommands.sh``` . Insert your Bot commands in the ```case ... esac``` block of the 'mycommands()' function:
```bash
# file: mycommands.sh
# your additional bahsbot 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
}
```
### Reuse or disable global commands
If you want to disable or reuse a global bashbot command comment it out in 'commands.sh' by placing a '#' in front of
every line from ```'/command')``` to ```;;```.
**Learn more about [Bot commands](https://core.telegram.org/bots#commands).**
**Note: Never disable the catchall command ```*)``` in 'commands.sh'!!**
```bash
# file: commands.sh
case "$MESSAGE" in
################################################
# GLOBAL commands start here, edit messages only
#'/start'*)
# send_action "${CHAT[ID]}" "typing"
# _is_botadmin && _markdown_message "You are *BOTADMIN*."
# if _is_allowed "start" ; then
# _markdown_message "${bot_help}"
# else
# _message "You are not allowed to start Bot."
# fi
# ;;
*) # 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 mycommands && mycommands
;;
esac
```
### Seperate logic from commands
If a command need more than 2-3 lines of code, you should use a function to seperate logic from command. Place your functions in ```mycommands.sh``` and call the from your command. Example:
```bash
# file: mycommands.sh
# your additional bahsbot commands
mycommands() {
case "$MESSAGE" in
'/process'*) # logic for /process 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](https://www.shellcheck.net/) or [install it on your system](https://github.com/koalaman/shellcheck#installing).
All bashbot scripts are linted by shellcheck.
Shellcheck examples:
```bash
$ 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=' assigment and can be replaced by ```TEXT="${TEXT}${WORD}"```
```bash
$ 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 substitions 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 :-)
#### [Prev Best Practice](5_practice.md)
#### [Next Functions Reference](6_reference.md)
#### $$VERSION$$ v0.80-dev2-1-g0b36bc5

596
doc/6_reference.md Normal file
View File

@ -0,0 +1,596 @@
#### [Home](../README.md)
## Bashbot function reference
### Send, forward, delete messages
##### send_action
```send_action``` shows users what your bot is currently doing.
*usage:* send_action "${CHAT[ID]}" "action"
*"action":* ```typing```, ```upload_photo```, ```record_video```, ```upload_video```, ```record_audio```, ```upload_audio```, ```upload_document```, ```find_location```.
*alias:* _action "action"
*example:*
```bash
send_action "${CHAT[ID]}" "typing"
send_action "${CHAT[ID]}" "record_audio"
```
##### send_normal_message
```send_normal_message``` sends text only messages to the given chat.
*usage:* send_normal_message "${CHAT[ID]}" "message"
*alias:* _normal_message "message"
*example:*
```bash
send_normal_message "${CHAT[ID]}" "this is a text message"
```
##### send_markdown_message
```send_markdown_message``` sends markdown style messages to the given chat.
Telegram supports a [reduced set of Markdown](https://core.telegram.org/bots/api#markdown-style) only
*usage:* send_markdown_message "${CHAT[ID]}" "markdown message"
*alias:* _markdown "message"
*example:*
```bash
send_markdown_message "${CHAT[ID]}" "this is a markdown message, next word is *bold*"
send_markdown_message "${CHAT[ID]}" "*bold* _italic_ [text](link)"
```
##### send_html_message
```send_html_message``` sends HTML style messages to the given chat.
Telegram supports a [reduced set of HTML](https://core.telegram.org/bots/api#html-style) only
*usage:* send_html_message "${CHAT[ID]}" "html message"
*alias:* _html_message "message"
*example:*
```bash
send_normal_message "${CHAT[ID]}" "this is a markdown message, next word is <b>bold</b>"
send_normal_message "${CHAT[ID]}" "<b>bold</b> <i>italic><i> <em>italic>/em> <a href="link">Text</a>"
```
##### forward_message
```forward_mesage``` forwards a messsage to the given chat.
*usage:* forward_message "chat_to" "chat_from" "${MESSAGE[ID]}"
*old call:* forward "${CHAT[ID]}" "$FROMCHAT" "${MESSAGE[ID]}"
*alias:* _forward "$FROMCHAT" "${MESSAGE[ID]}"
See also [Text formating options](https://core.telegram.org/bots/api#formatting-options)
----
##### delete_message
If your Bot is admin of a Chat he can delete every message, if not he can delete only his messages.
*usage:* delete_message "${CHAT[ID]}" "${MESSAGE[ID]}"
*alias:* _del_message "${MESSAGE[ID]}"
See also [deleteMessage limitations](https://core.telegram.org/bots/api#deletemessage)
----
### File, Location, Venue, Keyboard
##### send_file
send_file allows you to send different type's of files, e.g. photos, stickers, audio, media, etc. [see more](https://core.telegram.org/bots/api#sending-files)
*usage:* send_file "${CHAT[ID]}" "file" "caption"
*example:*
```bash
send_file "${CHAT[ID]}" "/home/user/doge.jpg" "Lool"
send_file "${CHAT[ID]}" "https://www.domain,com/something.gif" "Something"
```
##### send_location
*usage:* send_location "${CHAT[ID]}" "Latitude" "Longitude"
##### send_venue
*usage:* send_venue "${CHAT[ID]}" "Latitude" "Longitude" "Title" "Address" "foursquare id (optional)"
----
##### send_keyboard
Note: since version 0.6 send_keyboard was changed to use native "JSON Array" notation as used from Telegram. Example Keybord Array definitions:
- yes no in two rows:
- OLD format: 'yes' 'no' (two strings)
- NEW format: '[ "yes" ] , [ "no" ]' (two arrays with a string)
- new layouts made easy with NEW format:
- Yes No in one row: '[ "yes" , "no" ]'
- Yes No plus Maybe in 2.row: '[ "yes" , "no" ] , [ "maybe" ]'
- numpad style keyboard: '[ "1" , "2" , "3" ] , [ "4" , "5" , "6" ] , [ "7" , "8" , "9" ] , [ "0" ]'
*usage:* send_keyboard "chat-id" "message" "keyboard"
*alias:* _keyboard "message" "keyboard"
*example:*
```bash
send_keyboard "${CHAT[ID]}" "Say yes or no" "[ \\"yes\" , \\"no\" ]""
send_keyboard "${CHAT[ID]}" "Say yes or no" "[ \\"yes\\" ] , [ \\"no\\" ]"
send_keyboard "${CHAT[ID]}" "Enter digit" "[ \\"1\\" , \\"2\\" , \\"3\\" ] , [ \\"4\\" , \\"5\\" , \\"6\\" ] , [ \\"7\\" , \\"8\\" , \\"9\\" ] , [ \\"0\\" ]"
```
##### remove_keyboard
*usage:* remove_keybord "$CHAT[ID]" "message"
*alias:* _del_keyboard "message"
*See also: [Keyboard Markup](https://core.telegram.org/bots/api/#replykeyboardmarkup)*
----
##### send_button
*usage:* send_button "chat-id" "message" "text" "URL"
*alias:* _button "text" "URL"
*example:*
```bash
send_button "${CHAT[ID]}" "MAKE MONEY FAST!!!" "Visit my Shop" "https://dealz.rrr.de"
```
##### send_inline_keyboard
This allows to place multiple inline buttons in a row. The inline buttons must specified as a JSON array in the following format:
```[ {"text":"text1", "url":"url1"}, ... {"text":"textN", "url":"urlN"} ]```
Each button consists of a pair of text and URL values, sourrounded by '{ }', multiple buttons are seperated by '**,**' and everthing is wrapped in '[ ]'.
*usage:* send_inline_keyboard "chat-id" "message" "[ {"text":"text", "url":"url"} ...]"
*alias:* _inline_keyboard "[{"text":"text", "url":"url"} ...]"
*example:*
```bash
send_inline_keyboard "${CHAT[ID]}" "MAKE MONEY FAST!!!" '[{"text":"Visit my Shop", url"":"https://dealz.rrr.de"}]'
send_inline_keyboard "${CHAT[ID]}" "" '[{"text":"button 1", url"":"url 1"}, {"text":"button 2", url"":"url 2"} ]'
send_inline_keyboard "${CHAT[ID]}" "" '[{"text":"b 1", url"":"u 1"}, {"text":"b 2", url"":"u 2"}, {"text":"b 2", url"":"u 2"} ]'
```
*See also [Inline keyboard markup](https://core.telegram.org/bots/api/#inlinekeyboardmarkup)*
----
### User Access Control
##### kick_chat_member
If your Bot is a chat admin he can kick and ban a user.
*usage:* kick_chat_member "${CHAT[ID]}" "${USER[ID]}"
*alias:* _kick_user "${USER[ID]}"
##### unban_chat_member
If your Bot is a chat admine can unban a kicked user.
*usage:* unban_chat_member "${CHAT[ID]}" "${USER[ID]}"
*alias:* _unban "${USER[ID]}"
##### leave_chat
Your Bot will leave the chat.
*usage:* leave_chat "${CHAT[ID]}"
*alias:* _leave
```bash
if _is_admin ; then
send_markdown_message "${CHAT[ID]}" "*LEAVING CHAT...*"
leave_chat "${CHAT[ID]}"
fi
```
'See also [kick Chat Member](https://core.telegram.org/bots/api/#kickchatmember)*
----
##### user_is_botadmin
Return true (0) if user is admin of bot, user id if botadmin is read from file './botadmin'.
*usage:* user_is_botadmin "${USER[ID]}"
*alias:* _is_botadmin
*example:*
```bash
_is_botadmin && send_markdown_message "${CHAT[ID]}" "You are *BOTADMIN*."
```
##### user_is_creator
Return true (0) if user is creator of given chat or chat is a private chat.
*usage:* user_is_creator "${CHAT[ID]}" "${USER[ID]}"
*alias:* _is_creator
##### user_is_admin
Return true (0) if user is admin or creator of given chat.
*usage:* user_is_admin "${CHAT[ID]}" "${USER[ID]}"
*alias:* _is_admin
*example:*
```bash
if _is_admin ; then
send_markdown_message "${CHAT[ID]}" "*LEAVING CHAT...*"
leave_chat "${CHAT[ID]}"
fi
```
*See also [Chat Member](https://core.telegram.org/bots/api/#chatmember)*
##### user_is_allowed
Bahsbot supports User Access Control, see [Advanced Usage](3_advanced.md)
*usage:* user_is_allowed "${USER[ID]}" "what" "${CHAT[ID]}"
*example:*
```bash
if ! user_is_allowed "${USER[ID]}" "start" "${CHAT[ID]}" ; then
send_normal_message "${CHAT[ID]}" "You are not allowed to start Bot."
fi
```
----
### Inline Queries - answer direct queries to bot
You must include ```source modules/inline.sh``` in 'commands.sh' to have the following functions availible.
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.
##### answer_inline_query
answer_inline_query is provided for backward compatibility with older versions of bashbot.
It send back only one response to an inline query.
*usage:* answer_inline_query "$i{QUERY[ID]}" "type" "type arg 1" ... "type arg n"
*example:* - see [Advanced Usage](3_advanced.md#Inline-queries)
##### answer_inline_multi
anser_inline_multi allows you to send back a list of responses. responses must be seperated by ','.
*usage:* answer_inline_multi "${iQUERY[ID]}" "res, res, ... res"
*example:*
```bash
# note the starting " and ending " !!
answer_inline_multi "${iQUERY[ID]}" "
$(inline_query_compose "1" "photo" "https://avatars0.githubusercontent.com/u/13046303") ,
...
$(inline_query_compose "n" "photo" "https://avatars1.githubusercontent.com/u/4593242")
"
```
#### inline_query_compose
inline_query_compose composes one response element to to send back.
*usage:* inline_query_compose ID type args ....
```
ID = unique ID for this response, 1-64 byte long
type = type of answer, e.g. article, photo, video, location ...
args = mandatory arguments in the order they are described in telegram documentation
```
Currently the following types and arguments are implemented (optional arguments in parenthesis)
```
"article"|"message" title message (markup description)
"photo" photo_URL (thumb_URL title description caption)
"gif" photo_URL (thumb_URL title caption)
"mpeg4_gif" mpeg_URL (thumb_URL title caption)
"video" video_URL mime_type thumb_URL title (caption)
"audio" audio_URL title (caption)
"voice" voice_URL title (caption)
"document" title document_URL mime_type (caption description)
"location" latitude longitude title
"venue" latitude longitude title (adress foursquare)
"contact" phone first (last thumb)
"cached_photo" file (title description caption)
"cached_gif" file (title caption)
"cached_mpeg4_gif" file (title caption)
"cached_sticker" file
"cached_document" title file (description caption)
"cached_video" file title (description caption)
"cached_voice" file title (caption)
"cached_audio" file title (caption)
```
see [InlineQueryResult for more information](https://core.telegram.org/bots/api#inlinequeryresult) about response types and their arguments.
----
### Background and Interactive jobs
You must include ```source modules/background.sh``` in 'commands.sh' to have the following functions availible.
##### startproc
```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"
*example:*
```bash
startproc 'examples/calc.sh'
```
##### checkproc
Return true (0) if an interactive script is running in the chat.
*usage:* checkprog
*example:*
```bash
checkproc
if [ "$res" -gt 0 ] ; then
startproc "examples/calc.sh"
else
send_normal_message "${CHAT[ID]}" "Calc already running ..."
fi
```
##### killproc
Kill the interactive script running in the chat
*usage:* killproc
*example:*
```bash
checkprog
if [ "$res" -eq 0 ]; then
killproc && send_message "${CHAT[ID]}" "Command canceled."
else
send_message "${CHAT[ID]}" "Command is not running."
fi
```
----
##### background
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"
*example:*
```bash
background "examples/notify.sh" "notify"
```
##### checkback
Return true (0) if an background job is active in the given chat.
*usage:* checkback "jobname"
*example:*
```bash
checkback "notify"
if [ "$res" -gt 0 ] ; then
send_normal_message "${CHAT[ID]}" "Start notify"
background "examples/notify.sh" "notify"
else
send_normal_message "${CHAT[ID]}" "Process notify already running."
fi
```
##### killback
*usage:* killback "jobname"
*example:*
```bash
checkback "notify"
if [ "$res" -eq 0 ] ; then
send_normal_message "${CHAT[ID]}" "Kill notify"
killback "notify"
else
send_normal_message "${CHAT[ID]}" "Process notify not run."
fi
```
----
##### 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)
----
### Aliases - shortcuts for often used funtions
You must include ```source modules/aliases.sh``` in 'commands.sh' to have the following functions availible.
##### _is_botadmin
*usage:* _is_botadmin
*alias for:* user_is_botadmin "${USER[ID]}"
##### _is_admin
*usage:* _is_admin
*alias for:* user_is_admin "${CHAT[ID]}" "${USER[ID]}"
##### _is_allowed
*usage:* _is_allowed "what"
*alias for:* user_is_allowed "${USER[ID]}" "what" "${CHAT[ID]}"
----
##### _kick_user
*usage:* _kick_user "${USER[ID]}"
*alias for:* kick_chat_member "${CHAT[ID]}" "${USER[ID]}"
##### _unban
*usage:* _unban "${USER[ID]}"
*alias for:* unban_chat_member "${CHAT[ID]}" "${USER[ID]}"
##### _leave
*usage:* _leave
*alias for:* leave_chat "${CHAT[ID]}"
----
##### _message
*usage:* _message "message"
*alias for:* send_normal_message "${CHAT[ID]}" "message"
##### _normal_message
*usage:* _normal_message "message"
*alias for:* send_normal_message "${CHAT[ID]}" "message"
##### _html_message
*usage:* _html_message "message"
*alias for:* send_html_message "${CHAT[ID]}" "message"
##### _markdown_message
*usage:* _markdown_message "message"
*alias for:* send_markdown_message "${CHAT[ID]}" "message"
----
#### _inline_button
*usage:* _inline_button "${1}" "${2}"
*alias for:* send_inline_button "${CHAT[ID]}" "" "${1}" "${2}"
#### _inline_keyboard
*usage:* _inline_keyboard "${1}"
*alias for:* _inline_keyboard "${CHAT[ID]}" "" "${1}"
#### _keyboard_numpad
*usage:* _keyboard_numpad
*alias for:* send_keyboard "${CHAT[ID]}" "" '["1","2","3"],["4","5","6"],["7","8","9"],["-","0","."]' "yes"
#### _keyboard_yesno
*usage:* _keyboard_yesno
*alias for:* send_keyboard '["yes","no"]'
#### _del_keyboard
*usage:* _del_keyboard
*alias for:* remove_keyboard "${CHAT[ID]}" ""
### Helper functions
##### _is_function
Returns true if the given function exist, can be used to check if a module is loaded.
*usage* _is_function function
*example:*
```bash
_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.
##### get_file
*usage:* url="$(get_file "${CHAT[ID]}" "message")"
----
##### send_text
*usage:* send_text "${CHAT[ID]}" "message"
----
##### JsonDecode
Outputs decoded string to STDOUT
*usage:* JsonDecode "string"
##### JsonGetString
Reads JSON fro STDIN and Outputs found String to STDOUT
*usage:* JsonGetString `"path","to","string"`
##### JsonGetValue
Reads JSON fro STDIN and Outputs found Value to STDOUT
*usage:* JsonGetValue `"path","to","value"`
----
##### get_chat_member_status
*usage:* get_chat_member_status "${CHAT[ID]}" "${USER[ID]}"
this may get an official function ...
----
##### process_client
Every Message sent to your Bot is processd by this function. It parse the send JSON and assign the found Values to bash variables.
##### process_updates
If new updates are availible, this functions gets the JSON from Telegram and dispatch it.
----
##### getBotName
The name of your bot is availible as bash variable "$ME", there is no need to call this function if Bot is running.
*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.80-dev2-1-g0b36bc5

192
doc/7_develop.md Normal file
View File

@ -0,0 +1,192 @@
#### [Home](../README.md)
## Notes for bashbot developers
This section is about help and best practices for new bashbot developers. The main focus on is creating new versions of bashbot, not on develop your individual bot. Nevertheless the rules and tools described here can also help you with your bot development.
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.
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.
```
"debug" redirects all output to "DEBUG.log", in addtion every update is logged in "MESSAGE.LOG" and "INLINE.log"
"debugterm" same as debug but output and errors are sent to terminal
"xdebug" same as debug plus set bash option '-x' to log any executed command
"xdebugterm" same as xdebug but output and errors are sent to terminal
```
### Create a stripped down Version of your Bot
Currently bashbot is more a bot development environment than a bot, containing examples, developer scripts, modules, documentation and more.
You don't need all these files after you're finished with your cool new bot.
Let's create a stripped down version:
- delete all modules you do not need from 'modules', e.g. 'modules/inline.sh' if you don't use inline queries
- delete not needed standard commands and messages from 'commands.sh'
- delete not needed commands and functions from 'mycommands.sh'
- run ```dev/make-standalone.sh``` to create a a stripped down version of your bo
Now have a look at the directory 'standalone', here you find the files 'bashbot.sh' and 'commands.sh' containing everything to run your bot.
[Download make-standalone.sh](https://github.com/topkecleon/telegram-bot-bash/blob/master/dev/make-standalone.sh) from github.
### Setup your develop environment
1. install git, install [shellcheck](5_practice.md#Test-your-Bot-with-shellcheck)
2. setup your [environment for UTF-8](4_expert.md#Setting-up-your-Environment)
3. clone your bashbot fork to a new directory ```git clone https://github.com/<YOURNAME>/telegram-bot-bash.git```, replace ```<YOURNAME>``` with your username on github
4. create and change to your develop branch ```git checkout -b <YOURBRANCH>```, replace ```<YOURBRANCH>``` with the name you want to name it, e.g. 'develop'
5. give your (dev) fork a new version tag: ```git tag vx.xx```(optional)
6. setup github hooks by running ```dev/install-hooks.sh``` (optional)
### Test, Add, Push changes
A typical bashbot develop loop looks as follow:
1. start developing - *change, copy, edit bashbot files ...*
2. after changing a bash sript: ```shellcheck -x scipt.sh```
3. ```dev/all-tests.sh``` - *in case if errors back to 2.*
4. ```dev/git-add.sh``` - *check for changed files, update version string, run git add*
5. ```git commit -m "COMMIT MESSAGE"; git push```
**If you setup your dev environment with hooks and use the scripts above, versioning, addding and testing is done automatically.**
### common commands
We state bashbot is a bash only bot, but this is not true. bashbot is a bash script using bash features PLUS external commands.
Usually bash is used in a unix/linux environment where many (GNU) commands are availible, but if commands are missing, bashbot may not work.
To avoid this and make bashbot working on as many platforms as possible - from embedded linux to mainframe - I recommed to restrict
ourself to the common commands provided by bash and coreutils/busybox/toybox.
See [Bash Builtins](https://www.gnu.org/software/bash/manual/html_node/Shell-Builtin-Commands.html),
[coreutils](https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands),
[busybox](https://en.wikipedia.org/wiki/BusyBox#Commands) and [toybox](https://landley.net/toybox/help.html)
Availible commands in bash, coreutils, busybox and toybox. Do you find curl on the list?
```bash
.*, [*, [[*, basename, break, builtin*, bzcat, caller*, cat, cd*, chattr,
chgrp, chmod, chown, clear, command*, continue *, cp, cut, date, declare*,
dc, dd, df, diff, dirname, du, echo*, eval*, exec*, exit *, expr*, find,
fuser, getopt*, grep, hash*, head, hexdump, id, kill, killall, last, length,
less, let*, ln, local*, logname, ls, lsattr, lsmod, man, mapfile*, md5sum, mkdir,
mkfifo, mknod, more, mv, nice, nohup, passwd, patch, printf*, ps, pwd*, read*,
readarray*, readonly* return*, rm, rmdir, sed, seq, sha1sum, shift*, sleep,
source*, sort, split, stat, strings, su, sync, tail, tar, tee, test,
time, times*, timeout, touch, tr, trap*, true, umask*, usleep, uudecode,
uuencode, wc, wget, which, who, whoami, xargs, yes
```
commands marked with \* are bash builtins, all others are external programms. Calling an external programm is more expensive then using bulitins
or using an internal replacement. Here are some examples of internal replacement for external commands:
```bash
HOST="$(hostname)" -> HOST="$HOSTNAME"
seq 1 100 -> {0..100}
data="$(cat file)" -> data="$(<"file")"
DIR="$(dirname $0) -> DIR=""${0%/*}/""
IAM="($basename $0)" -> IAM="${0##*/}*
VAR="$(( 1 + 2 ))" -> (( var=1+2 ))
INDEX="$(( ${INDEX} + 1 ))" -> (( INDEX++ ))
```
For more examples see [Pure bash bible](https://github.com/dylanaraps/pure-bash-bible)
### Prepare a new version
After some development it may time to create a new version for the users. a new version can be in sub version upgrade, e.g. for fixes and smaller additions or
a new release version for new features. To mark a new version use ```git tag NEWVERSION``` and run ```dev/version.sh``` to update all version strings.
Usually I start with pre versions and when everything looks good I push out a release candidate (rc) and finally the new version.
```
v0.x-devx -> v0.x-prex -> v0.x-rc -> v0.x ... 0.x+1-dev ...
```
If you release a new Version run ```dev/make-distribution.sh``` to create the zip and tar.gz archives in the dist directory and attach them to the github release. Do not forget to delete directory dist afterwards.
### Versioning
Bashbot is tagged with version numbers. If you start a new development cycle you can tag your fork with a version higher than the current version.
E.g. if you fork 'v0.60' the next develop version should tagged as ```git tag "v0.61-dev"``` for fixes or ```git tag "v0.70-dev"``` for new features.
To get the current version name of your develepment fork run ```git describe --tags```. The output looks like ```v0.70-dev-6-g3fb7796``` where your version tag is followed by the number of commits since you tag your branch and followed by the latest commit hash. see also [comments in version.sh](../dev/version.sh)
To update the Version Number in files run ```dev/version.sh files```, it will update the line '#### $$VERSION$$ ###' in all files to the current version name.
To update version in all files run 'dev/version.sh' without parameter.
### Shellcheck
For a shell script running as a service it's important to be paranoid about quoting, globbing and other common problems. So it's a must to run shellchek on all shell scripts before you commit a change. this is automated by a git hook activated in Setup step 6.
To run shellcheck for a single script run ```shellcheck -x script.sh```, to check all schripts run ```dev/hooks/pre-commit.sh```.
## bashbot tests
Starting with version 0.70 bashbot has a test suite. To start testsuite run ```dev/all-tests.sh```. all-tests.sh will return 'SUCCESS' only if all tests pass.
### enabling / disabling tests
All tests are placed in the directory ```test```. To disable a test remove the execute flag from the '*-test.sh' script, to (re)enable a test make the script executable again.
### creating new tests
To create a new test run ```test/ADD-test-new.sh``` and answer the questions, it will create the usually needed files and dirs:
Each test consists of a script script named after ```p-name-test.sh``` *(where p is test pass 'a-z' and name the name
of your test)* and an optional dir ```p-name-test/``` *(script name minus '.sh')* for additional files.
Tests with no dependency to other tests will run in pass 'a', tests which need an initialized bahsbot environment must run in pass 'd' or later.
A temporary test environment is created when 'ALL-tests.sh' starts and deleted after all tests are finished.
The file ```ALL-tests.inc.sh``` must be included from all tests and provide the test environment as shell variables:
```bash
# Test Evironment
TESTME="$(basename "$0")"
DIRME="$(pwd)"
TESTDIR="$1"
LOGFILE="${TESTDIR}/${TESTME}.log"
REFDIR="${TESTME%.sh}"
TESTNAME="${REFDIR//-/ }"
# common filenames
TOKENFILE="token"
ACLFILE="botacl"
COUNTFILE="count"
ADMINFILE="botadmin"
DATADIR="data-bot-bash"
# SUCCESS NOSUCCES -> echo "${SUCCESS}" or echo "${NOSUCCESS}"
SUCCESS=" OK"
NOSUCCESS=" FAILED!"
# default input, reference and output files
INPUTFILE="${DIRME}/${REFDIR}/${REFDIR}.input"
REFFILE="${DIRME}/${REFDIR}/${REFDIR}.result"
OUTPUTFILE="${TESTDIR}/${REFDIR}.out"
```
Example test
```bash
#!/usr/bin/env bash
# file: b-example-test.sh
# include common functions and definitions
# shellcheck source=test/ALL-tests.inc.sh
source "./ALL-tests.inc.sh"
if [ -f "${TESTDIR}/bashbot.sh" ]; then
echo "${SUCCESS} bashbot.sh exist!"
exit 0
else
echo "${NOSUCCESS} ${TESTDIR}/bashbot.sh missing!"
exit 1
fi
```
#### [Prev Function Reference](6_reference.md)
#### [Next Bashbot Environment](8_custom.md)
#### $$VERSION$$ v0.80-dev2-15-geb0cde5

135
doc/8_custom.md Normal file
View File

@ -0,0 +1,135 @@
#### [Home](../README.md)
## Customize bashbots environment
This section describe how you can customize bashbot to your needs by setting environment variables.
### Change file locations
In standard setup bashbot is self containing, this means you can place 'telegram-bot-bash' any location
and run it from there. All files - programm, config, data etc - will reside in 'telegram-bot-bash'.
If you want to have other locations for config, data etc, define and export the following environment variables.
**Note: all specified directories and files must exist or running 'bashbot.sh' will fail.**
#### BASHBOT_ETC
Location of the files ```commands.sh```, ```mycommands.sh```, ```token```, ```botadmin```, ```botacl``` ...
```bash
unset BASHBOT_ETC # keep in telegram-bot-bash (default)
export BASHBOT_ETC "" # keep in telegram-bot-bash
export BASHBOT_ETC "/etc/bashbot" # unix like config location
export BASHBOT_ETC "/etc/bashbot/bot1" # multibot configuration bot 1
export BASHBOT_ETC "/etc/bashbot/bot2" # multibot configuration bot 2
```
e.g. /etc/bashbot
#### BASHBOT_VAR
Location of runtime data ```data-bot-bash```, ```count```
```bash
unset BASHBOT_VAR # keep in telegram-bot-bash (default)
export BASHBOT_VAR "" # keep in telegram-bot-bash
export BASHBOT_VAR "/var/spool/bashbot" # unix like config location
export BASHBOT_VAR "/var/spool/bashbot/bot1" # multibot configuration bot 1
export BASHBOT_VAR "/var/spool/bashbot/bot2" # multibot configuration bot 2
```
#### BASHBOT_JSONSH
Full path to JSON.sh script, default: './JSON.sh/JSON.sh', must end with '/JSON.sh'.
```bash
unset BASHBOT_JSONSH # telegram-bot-bash/JSON.sh/JSON.sh (default)
export BASHBOT_JSONSH "" # telegram-bot-bash/JSON.sh/JSON.sh
export BASHBOT_JSONSH "/usr/local/bin/JSON.sh" # installed in /usr/local/bin
```
### Change config values
#### BASHBOT_URL
Uses given URL instead of offical telegram API URL, useful if you have your own telegram server or for testing.
```bash
unset BASHBOT_URL # use Telegram URL https://api.telegram.org/bot<token> (default)
export BASHBOT_URL "" # use use Telegram https://api.telegram.org/bot<token>
export BASHBOT_URL "https://my.url.com/bot" # use your URL https://my.url.com/bot<token>
```
#### BASHBOT_TOKEN
#### BASHBOT_WGET
Bashbot uses ```curl``` to communicate with telegram server. if ```curl``` is not availible ```wget``` is used.
If 'BASHBOT_WGET' is set to any value (not undefined or not empty) wget is used even is curl is availible.
```bash
unset BASHBOT_WGET # use curl (default)
export BASHBOT_WGET "" # use curl
export BASHBOT_WGET "yes" # use wget
export BASHBOT_WGET "no" # use wget!
```
#### BASHBOT_SLEEP
Instead of polling permanently or with a fixed delay, bashbot offers a simple adaptive polling.
If messages are recieved bashbot polls with no dealy. If no messages are availible bashbot add 100ms delay
for every poll until the maximum of BASHBOT_SLEEP ms.
```bash
unset BASHBOT_SLEEP # 5000ms (default)
export BASHBOT_SLEEP "" # 5000ms
export BASHBOT_SLEEP "1000" # 1s maximum sleep
export BASHBOT_SLEEP "10000" # 10s maximum sleep
export BASHBOT_SLEEP "1" # values < 1000 disables sleep (not recommended)
```
### Testet configs as of v.07 release
**Note: Environment variables are not stored, you must setup them before every call to bashbot.sh, e.g. from a script.**
#### simple Unix like config, for one bot. bashbot is installed in '/usr/local/telegram-bot-bash'
```bash
# Note: all dirs and files must exist!
export BASHBOT_ETC "/etc/bashbot"
export BASHBOT_VAR "/var/spool/bashbot"
/usr/local/telegram-bot-bash/bashbot.sh start
```
#### Unix like config for one bot. bashbot.sh is installed in '/usr/bin'
```bash
# Note: all dirs and files must exist!
export BASHBOT_ETC "/etc/bashbot"
export BASHBOT_VAR "/var/spool/bashbot"
export BASHBOT_JSONSH "/var/spool/bashbot"
/usr/local/bin/bashbot.sh start
```
#### simple multibot config, everything is keept inside 'telegram-bot-bash' dir
```bash
# config for running Bot 1
# Note: all dirs and files must exist!
export BASHBOT_ETC "./mybot1"
export BASHBOT_VAR "./mybot1"
/usr/local/telegram-bot-bash/bashbot.sh start
```
```bash
# config for running Bot 2
# Note: all dirs and files must exist!
export BASHBOT_ETC "./mybot2"
export BASHBOT_VAR "./mybot2"
/usr/local/telegram-bot-bash/bashbot.sh start
```
#### [Prev Notes for Developers](7_develop.md)
#### $$VERSION$$ v0.80-dev2-14-gaacdc76