From c33082e585f9ec7c517fcc9b10b1b8829a1ba2a0 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Sat, 16 Apr 2016 20:50:05 +0200 Subject: [PATCH] Fixed bugs (now you can run multiple background session in multiple bots), added option to count users, added option to parse markdown and html using send_message, updated documentation and decided to put the sending loop for interactive chats in the background using tmux so that if I have to update the bot interactive sessions will continue to send out messages. Also changed the file name and the location (/tmp/ of the fifos for interactive chats) and added option to broadcast messages to all users. --- README.md | 27 ++++++++++++++++-- bashbot.sh | 82 ++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 80 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 278eab7..acadd7e 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ Clone the repository: git clone https://github.com/topkecleon/telegram-bot-bash ``` -Paste the token on line 12 (instead of tokenhere). +Paste the token on line 15 (instead of tokenhere). Then start editing the commands. ### Recieve data @@ -104,9 +104,16 @@ To send messages use the ```send_message``` function: ``` send_message "${USER[ID]}" "lol" ``` +To send html or markdown put the following strings before the text, depending on the parsing mode you want to enable: +``` +send_message "${USER[ID]}" "markdown_parse_mode lol bold" +``` +``` +send_message "${USER[ID]}" "html_parse_mode lol bold" +``` This function also allows a third parameter that disables additional function parsing (for safety use this when reprinting user input): ``` -send_message "${USER[ID]}" "lol" "text" +send_message "${USER[ID]}" "lol" "safe" ``` To send images, videos, voice files, photos ecc use the ```send_photo``` function (remember to change the safety Regex @ line 94 to allow sending files only from certain directories): ``` @@ -157,6 +164,22 @@ If some thing doesn't work as it should, debug with ```bash -x bashbot.sh```. To use the functions provided in this script in other scripts source bashbot.sh: ```source bashbot.sh source``` +## 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!" +``` + + + + That's it! If you feel that there's something missing or if you found a bug, feel free to submit a pull request! diff --git a/bashbot.sh b/bashbot.sh index 87e2ba3..5c8f998 100755 --- a/bashbot.sh +++ b/bashbot.sh @@ -13,6 +13,7 @@ # If you're in Europe, and public domain does not exist, then haha. TOKEN='tokenhere' + URL='https://api.telegram.org/bot'$TOKEN # Set INLINE to 1 in order to receive inline queries. @@ -31,6 +32,9 @@ LOCATION_URL=$URL'/sendLocation' ACTION_URL=$URL'/sendChatAction' FORWARD_URL=$URL'/forwardMessage' INLINE_QUERY=$URL'/answerInlineQuery' +ME_URL=$URL'/getMe' +ME=$(curl -s $ME_URL | ./JSON.sh -s | egrep '\["result","username"\]' | cut -f 2 | cut -d '"' -f 2) + FILE_URL='https://api.telegram.org/file/bot'$TOKEN'/' UPD_URL=$URL'/getUpdates?offset=' @@ -41,7 +45,8 @@ declare -A USER MESSAGE URLS CONTACT LOCATION send_message() { local chat="$1" local text="$(echo "$2" | sed 's/ mykeyboardstartshere.*//g;s/ myfilelocationstartshere.*//g;s/ mylatstartshere.*//g;s/ mylongstartshere.*//g')" - [ "$3" != "text" ] && { + local arg="$3" + [ "$3" != "safe" ] && { local keyboard="$(echo "$2" | sed '/mykeyboardstartshere /!d;s/.*mykeyboardstartshere //g;s/ myfilelocationstartshere.*//g;s/ mylatstartshere.*//g;s/ mylongstartshere.*//g')" local file="$(echo "$2" | sed '/myfilelocationstartshere /!d;s/.*myfilelocationstartshere //g;s/ mykeyboardstartshere.*//g;s/ mylatstartshere.*//g;s/ mylongstartshere.*//g')" @@ -64,19 +69,23 @@ send_message() { fi if [ "$sent" != "y" ];then - res=$(curl -s "$MSG_URL" -F "chat_id=$chat" -F "text=$text") + send_text "$chat" "$text" fi } +send_text() { + echo "$2" | grep -q '^html_parse_mode' && local add="-F \"parse_mode=html\"" + echo "$2" | grep -q '^markdown_parse_mode' && local add="-F \"parse_mode=markdown\"" + res=$(curl -s "$MSG_URL" -F "chat_id=$1" -F "text=$2" $add) +} + send_markdown_message() { res=$(curl -s "$MSG_URL" -F "chat_id=$1" -F "text=$2" -F "parse_mode=markdown") } answer_inline_query() { - case $2 in - "article") InlineQueryResult='[{"type":"'$2'","id":"$RANDOM","title":"'$3'","message_text":"'$4'"}]' ;; @@ -106,10 +115,10 @@ answer_inline_query() { ;; "venue") InlineQueryResult='[{"type":"'$2'","id":"$RANDOM","latitude":"'$3'","longitude":"'$4'","title":"'$5'","address":"'$6'"}]' - ;; + ;; "contact") InlineQueryResult='[{"type":"'$2'","id":"$RANDOM","phone_number":"'$3'","first_name":"'$4'"}]' - ;; + ;; # Cached media stored in Telegram server @@ -224,18 +233,13 @@ forward() { startproc() { killproc - mkfifo $copname - TMUX= tmux new-session -d -s $copname "$* &>$copname; echo >$copname; sleep 5; rm -r $copname" - while [ -p "$copname" ];do - read -t 10 line - [ "$line" != "" ] && send_message "${USER[ID]}" "$line" - line= - done <$copname + mkfifo /tmp/$copname + TMUX= tmux new-session -d -s $copname "$* &>/tmp/$copname; echo imprettydarnsuredatdisisdaendofdacmd>/tmp/$copname" + TMUX= tmux new-session -d -s sendprocess_$copname "bash bashbot.sh outproc ${USER[ID]} $copname" } killproc() { - (rm -r $copname - tmux kill-session -t $copname)2>/dev/null + (tmux kill-session -t $copname; echo imprettydarnsuredatdisisdaendofdacmd>/tmp/$copname; sleep 1; tmux kill-session -t send$copname; rm -r /tmp/$copname)2>/dev/null } inproc() { @@ -244,10 +248,14 @@ inproc() { } process_client() { + # Message + MESSAGE=$(echo "$res" | egrep '\["result",0,"message","text"\]' | cut -f 2 | cut -d '"' -f 2) + # User + USER[ID]=$(echo "$res" | egrep '\["result",0,"message","chat","id"\]' | cut -f 2) USER[FIRST_NAME]=$(echo "$res" | egrep '\["result",0,"message","chat","first_name"\]' | cut -f 2 | cut -d '"' -f 2) USER[LAST_NAME]=$(echo "$res" | egrep '\["result",0,"message","chat","last_name"\]' | cut -f 2 | cut -d '"' -f 2) - USER[USERNAME]=$(echo "$res" | sed 's/^.*\(username.*\)/\1/g' | cut -d '"' -f3) + USER[USERNAME]=$(echo "$res" | egrep '\["result",0,"message","chat","username"\]' | cut -f 2 | cut -d '"' -f 2) # Audio URLS[AUDIO]=$(get_file $(echo "$res" | egrep '\["result",0,"message","audio","file_id"\]' | cut -f 2 | cut -d '"' -f 2)) @@ -277,9 +285,9 @@ process_client() { NAME="$(basename ${URLS[*]} &>/dev/null)" # Tmux - copname="CO${USER[ID]}" + copname="$ME"_"${USER[USERNAME]}" - if ! tmux ls | grep -q $copname; then + if ! tmux ls | grep -v send | grep -q $copname; then [ ! -z ${URLS[*]} ] && { curl -s ${URLS[*]} -o $NAME send_file "${USER[ID]}" "$NAME" "$CAPTION" @@ -316,7 +324,7 @@ process_client() { case $MESSAGE in '/question') - startproc "./question"& + startproc "./question" ;; '/info') send_message "${USER[ID]}" "This is bashbot, the Telegram bot written entirely in bash." @@ -338,7 +346,7 @@ Contribute to the project: https://github.com/topkecleon/telegram-bot-bash '') ;; *) - send_message "${USER[ID]}" "$MESSAGE" "text" + send_message "${USER[ID]}" "$MESSAGE" "safe" esac else case $MESSAGE in @@ -349,25 +357,45 @@ Contribute to the project: https://github.com/topkecleon/telegram-bot-bash *) inproc;; esac fi + if [ "$MESSAGE" = "/start" ]; then + tmpcount="COUNT${USER[ID]}" + cat count | grep -q "$tmpcount" || echo "$tmpcount">>count + fi + # To get user count execute bash bashbot.sh count } # source the script with source as param to use functions in other scripts -while [ "$1" != "source" ]; do { +while [ "$1" == "" ]; do { res=$(curl -s $UPD_URL$OFFSET | ./JSON.sh -s) - # Target - USER[ID]=$(echo "$res" | egrep '\["result",0,"message","chat","id"\]' | cut -f 2) # Offset OFFSET=$(echo "$res" | egrep '\["result",0,"update_id"\]' | cut -f 2) - # Message - MESSAGE=$(echo "$res" | egrep '\["result",0,"message","text"\]' | cut -f 2 | cut -d '"' -f 2) - OFFSET=$((OFFSET+1)) if [ $OFFSET != 1 ]; then process_client& - fi }; done + + +case "$1" in + "outproc") + until [ "$line" = "imprettydarnsuredatdisisdaendofdacmd" ];do + line= + read -t 10 line + [ "$line" != "" -a "$line" != "imprettydarnsuredatdisisdaendofdacmd" ] && send_message "$2" "$line" + done