2016-01-02 19:35:15 +00:00
#!/bin/bash
2019-04-24 08:07:46 +00:00
# file: bashbot.sh
# do not edit, this file will be overwritten on update
2016-04-19 09:49:35 +00:00
2015-07-10 05:43:08 +00:00
# bashbot, the Telegram bot written in bash.
2020-08-01 09:37:32 +00:00
# Written by Drew (@topkecleon) KayM (@gnadelwartz).
# Also contributed: Daniil Gentili (@danogentili), JuanPotato, BigNerd95, TiagoDanin, iicc1.
2016-01-05 16:54:34 +00:00
# https://github.com/topkecleon/telegram-bot-bash
2016-04-19 09:49:35 +00:00
# Depends on JSON.sh (http://github.com/dominictarr/JSON.sh) (MIT/Apache),
2015-07-10 05:43:08 +00:00
# This file is public domain in the USA and all free countries.
2016-04-19 09:49:35 +00:00
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
2019-03-28 15:51:33 +00:00
#
2020-12-26 20:18:18 +00:00
#### $$VERSION$$ v1.21-dev-0-g2e878fd
2019-04-01 10:52:25 +00:00
#
# Exit Codes:
2020-06-23 14:35:50 +00:00
# - 0 success (hopefully)
2019-04-12 08:30:35 +00:00
# - 1 can't change to dir
2020-08-01 09:37:32 +00:00
# - 2 can't write to tmp, count or token
2019-04-23 11:24:34 +00:00
# - 3 user / command / file not found
2020-06-23 14:35:50 +00:00
# - 4 unknown command
2019-04-15 10:19:04 +00:00
# - 5 cannot connect to telegram bot
2020-06-01 07:54:35 +00:00
# - 6 mandatory module not found
2020-09-27 18:30:10 +00:00
# - 7 can't get bottoken
2020-11-29 16:20:57 +00:00
# - 8 curl/wget missing
2020-09-27 18:24:15 +00:00
# - 10 not bash!
2020-12-26 20:18:18 +00:00
# shellcheck disable=SC2140,SC2031,SC2120,SC1091,SC1117,SC2059
2019-03-22 16:47:36 +00:00
2020-09-27 18:24:15 +00:00
# emmbeded system may claim bash but it is not
# check for bash like ARRAY handlung
if ! ( unset a; set -A a a; eval "a=(a b)" ; eval '[ -n "${a[1]}" ]' ; ) > /dev/null 2>& 1; then
2020-12-26 20:18:18 +00:00
printf "Error: Current shell does not support ARRAY's, may be busbox ash shell. pls install a real bash!\n"
2020-09-27 18:24:15 +00:00
exit 10
fi
2020-06-23 14:35:50 +00:00
# are we running in a terminal?
2020-12-26 20:18:18 +00:00
NN = "\n"
2020-05-14 18:33:30 +00:00
if [ -t 1 ] && [ -n " $TERM " ] ; then
2019-03-29 16:52:00 +00:00
CLEAR = 'clear'
2019-03-28 13:24:08 +00:00
RED = '\e[31m'
GREEN = '\e[32m'
ORANGE = '\e[35m'
2020-05-18 12:57:53 +00:00
GREY = '\e[1;30m'
2019-03-28 13:24:08 +00:00
NC = '\e[0m'
2020-12-26 20:18:18 +00:00
NN = " ${ NN } "
2019-03-28 13:24:08 +00:00
fi
2020-12-24 08:19:54 +00:00
# telegram uses utf-8 characters, check if we have an utf-8 charset
if [ " ${ LANG } " = " ${ LANG %[Uu][Tt][Ff]* } " ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Warning: Telegram uses utf-8, but looks like you are using non utf-8 locale: ${ NC } ${ LANG } \n "
2020-12-24 08:19:54 +00:00
fi
2020-09-27 18:24:15 +00:00
# we need some bash 4+ features, check for old bash by feature
2020-12-24 08:19:54 +00:00
if [ " $( { LC_ALL = C.utf-8 echo -e "\u1111" ; } 2>/dev/null) " = "\u1111" ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Warning: Missing unicode '\uxxxx' support, missing C.utf-8 locale or to old bash version. ${ NN } "
2020-09-27 18:24:15 +00:00
fi
2020-12-07 14:50:56 +00:00
2020-05-14 19:31:52 +00:00
# some important helper functions
# returns true if command exist
2020-06-10 09:11:42 +00:00
_exists( ) {
2020-12-24 12:08:41 +00:00
[ " $( type -t " ${ 1 } " ) " = "file" ]
2020-05-14 19:31:52 +00:00
}
# execute function if exists
_exec_if_function( ) {
2020-12-24 12:08:41 +00:00
[ " $( type -t " ${ 1 } " ) " != "function" ] && return 1
2020-06-15 07:09:08 +00:00
" $@ "
2020-05-14 19:31:52 +00:00
}
# returns true if function exist
2020-06-10 09:11:42 +00:00
_is_function( ) {
2020-12-24 12:08:41 +00:00
[ " $( type -t " ${ 1 } " ) " = "function" ]
2020-06-10 09:11:42 +00:00
}
# round $1 in international notation! , returns float with $2 decimal digits
2020-08-01 09:37:32 +00:00
# if $2 is not given or is not a positive number zero is assumed
2020-06-10 09:11:42 +00:00
_round_float( ) {
local digit = " ${ 2 } " ; [ [ " ${ 2 } " = ~ ^[ 0-9] +$ ] ] || digit = "0"
2020-12-24 12:08:41 +00:00
{ LC_ALL = C.utf-8 printf " %. ${ digit } f " " ${ 1 } " ; } 2>/dev/null
2020-05-14 19:31:52 +00:00
}
2020-06-13 19:39:52 +00:00
setConfigKey( ) {
[ [ " $1 " = ~ ^[ -a-zA-Z0-9,._] +$ ] ] || return 3
2020-06-20 18:12:36 +00:00
[ -z " ${ BOTCONFIG } " ] && return 1
2020-06-19 10:49:18 +00:00
printf '["%s"]\t"%s"\n' " ${ 1 //,/ \" , \" } " " ${ 2 // \" / \\ \" } " >>" ${ BOTCONFIG } .jssh "
2020-06-01 07:54:35 +00:00
}
2020-06-12 19:18:32 +00:00
getConfigKey( ) {
[ [ " $1 " = ~ ^[ -a-zA-Z0-9,._] +$ ] ] || return 3
2020-06-19 10:49:18 +00:00
[ -r " ${ BOTCONFIG } .jssh " ] && sed -n 's/\["' " $1 " '"\]\t*"\(.*\)"/\1/p' <" ${ BOTCONFIG } .jssh " | tail -n 1
2020-06-01 07:54:35 +00:00
}
2020-08-01 09:37:32 +00:00
# check if $1 seems a valid token
2020-06-27 08:43:08 +00:00
# return true if token seems to be valid
2020-06-27 08:29:36 +00:00
check_token( ) {
[ [ " ${ 1 } " = ~ ^[ 0-9] { 8,10} :[ a-zA-Z0-9_-] { 35} $ ] ] && return 0
return 1
}
2020-08-01 09:37:32 +00:00
# log $1 to ERRORLOG with date
2020-12-15 23:09:32 +00:00
log_error( ) { printf "%s: %b\n" " $( date) " " $* " >>" ${ ERRORLOG } " ; }
log_debug( ) { printf "%s: %b\n" " $( date) " " $* " >>" ${ DEBUGLOG } " ; }
log_message( ) { printf "\n%s: %b\n" " $( date) " " $* " >>" ${ MESSAGELOG } " ; }
log_update( ) { printf "%s: %b\n" " $( date) " " $* " >>" ${ UPDATELOG } " ; }
2020-06-27 08:29:36 +00:00
# additional tests if we run in debug mode
2020-06-30 05:26:16 +00:00
export BASHBOTDEBUG
2020-07-10 06:39:33 +00:00
# debug should always last argument
[ [ " ${ BASH_ARGV [0] } " = = *"debug" * ] ] && BASHBOTDEBUG = "yes"
# $1 where $2 command $3 may debug
2020-07-11 06:34:57 +00:00
# shellcheck disable=SC2094
2020-12-15 16:19:09 +00:00
debug_checks( ) { {
2020-07-09 20:31:58 +00:00
[ -z " ${ BASHBOTDEBUG } " ] && return
2020-06-27 08:29:36 +00:00
local DATE WHERE MYTOKEN; DATE = " $( date) " ; WHERE = " ${ 1 } " ; shift
2020-07-04 07:18:28 +00:00
printf "%s: debug_checks: %s: bashbot.sh %s\n" " ${ DATE } " " ${ WHERE } " " ${ @##*/ } "
2020-07-11 06:34:57 +00:00
# shellcheck disable=SC2094
[ -z " ${ DEBUGLOG } " ] && printf "%s: %s\n" " ${ DATE } " "DEBUGLOG not set! =========="
2020-06-27 08:29:36 +00:00
MYTOKEN = " $( getConfigKey "bottoken" ) "
2020-06-28 06:52:02 +00:00
[ -z " ${ MYTOKEN } " ] && printf "%s: %s\n" " ${ DATE } " "Bot token is missing! =========="
check_token " ${ MYTOKEN } " || printf "%s: %s\n" " ${ DATE } " "Invalid bot token! =========="
[ -z " $( getConfigKey "botadmin" ) " ] && printf "%s: %s\n" " ${ DATE } " "Bot admin is missing! =========="
2020-07-02 15:24:56 +00:00
# call user defined debug_checks if exists
_exec_if_function my_debug_checks " ${ DATE } " " ${ WHERE } " " $* "
2020-12-15 16:19:09 +00:00
} >>" ${ DEBUGLOG } "
}
2020-05-14 19:31:52 +00:00
2020-12-07 14:50:56 +00:00
# some linux, e.g. manajro seems not to have C locale activated by default
if _exists locale && [ " $( locale -a | grep -c -e " ^C $" -e " ^C.utf8 $" ) " -lt 2 ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Warning: locale ${ NC } ${ GREY } C ${ NC } ${ ORANGE } and/or ${ NC } ${ GREY } C.utf8 ${ NC } ${ ORANGE } seems missing, use \" ${ NC } ${ GREY } locale -a ${ NC } ${ ORANGE } \" to show what locales are installed on your system. ${ NN } "
2020-12-07 14:50:56 +00:00
fi
2019-04-23 11:07:20 +00:00
# get location and name of bashbot.sh
SCRIPT = " $0 "
2019-05-23 17:40:15 +00:00
REALME = " ${ BASH_SOURCE [0] } "
SCRIPTDIR = " $( dirname " ${ REALME } " ) "
RUNDIR = " $( dirname " $0 " ) "
MODULEDIR = " ${ SCRIPTDIR } /modules "
2020-05-14 17:47:37 +00:00
# adjust locations based on source and real name
2019-05-23 17:40:15 +00:00
if [ " ${ SCRIPT } " != " ${ REALME } " ] || [ " $1 " = "source" ] ; then
SOURCE = "yes"
fi
2019-05-23 10:26:53 +00:00
2020-12-24 08:24:02 +00:00
BOTCOMMANDS = "start, stop, status, help, init, suspendback, resumeback, killback"
2020-12-26 20:18:18 +00:00
[ [ -z " $1 " && -z " ${ SOURCE } " ] ] && printf " ${ ORANGE } Available commands: ${ GREY } ${ BOTCOMMANDS } ${ NN } " && exit
2020-06-19 16:47:18 +00:00
if [ " $1 " = "help" ] ; then
2020-08-05 06:08:50 +00:00
HELP = " ${ BASHBOT_HOME :- . } /README "
2020-06-19 16:47:18 +00:00
if [ -n " ${ CLEAR } " ] ; then
_exists w3m && w3m " $HELP .html " && exit
_exists lynx && lynx " $HELP .html " && exit
_exists less && less " $HELP .txt " && exit
fi
cat " $HELP .txt "
exit
fi
2020-05-14 18:33:30 +00:00
if [ -n " $BASHBOT_HOME " ] ; then
2019-05-23 10:26:53 +00:00
SCRIPTDIR = " $BASHBOT_HOME "
2020-06-04 14:10:58 +00:00
else
BASHBOT_HOME = " ${ SCRIPTDIR } "
2019-05-23 10:26:53 +00:00
fi
2020-06-04 14:10:58 +00:00
[ -z " ${ BASHBOT_ETC } " ] && BASHBOT_ETC = " $BASHBOT_HOME "
[ -z " ${ BASHBOT_VAR } " ] && BASHBOT_VAR = " $BASHBOT_HOME "
2019-05-23 10:26:53 +00:00
2020-06-06 07:21:56 +00:00
ADDONDIR = " ${ BASHBOT_ETC :- . } /addons "
2020-08-01 09:37:32 +00:00
RUNUSER = " ${ USER } " # USER is overwritten by bashbot array :-(, save original
2019-03-31 10:52:11 +00:00
2020-09-26 17:52:06 +00:00
# OK everything setup, lets start
2020-06-19 16:47:18 +00:00
if [ [ -z " ${ SOURCE } " && -z " $BASHBOT_HOME " ] ] && ! cd " ${ RUNDIR } " ; then
2020-12-26 20:18:18 +00:00
printf " ${ RED } ERROR: Can't change to ${ RUNDIR } ... ${ NN } "
2019-03-31 10:52:11 +00:00
exit 1
2019-05-31 20:33:59 +00:00
else
RUNDIR = "."
2019-03-31 10:52:11 +00:00
fi
2019-03-28 13:24:08 +00:00
2019-03-22 16:47:36 +00:00
if [ ! -w "." ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } WARNING: ${ RUNDIR } is not writeable! ${ NN } "
2019-03-22 16:47:36 +00:00
ls -ld .
fi
2019-03-18 13:45:19 +00:00
2020-05-14 18:33:30 +00:00
# Setup and check environment if BOTTOKEN is NOT set
2020-06-19 10:49:18 +00:00
BOTCONFIG = " ${ BASHBOT_ETC :- . } /botconfig "
2019-04-23 11:07:20 +00:00
TOKENFILE = " ${ BASHBOT_ETC :- . } /token "
2020-05-14 18:33:30 +00:00
BOTADMIN = " ${ BASHBOT_ETC :- . } /botadmin "
BOTACL = " ${ BASHBOT_ETC :- . } /botacl "
DATADIR = " ${ BASHBOT_VAR :- . } /data-bot-bash "
2020-05-29 18:11:51 +00:00
BLOCKEDFILE = " ${ BASHBOT_VAR :- . } /blocked "
2020-05-14 18:33:30 +00:00
COUNTFILE = " ${ BASHBOT_VAR :- . } /count "
2020-06-06 12:48:01 +00:00
LOGDIR = " ${ RUNDIR :- . } /logs "
2020-08-01 09:37:32 +00:00
# assume everything already set up correctly if TOKEN is set
2020-12-18 14:16:15 +00:00
if [ [ -z " ${ BOTTOKEN } " && ! -f " ${ BOTCONFIG } .jssh " ] ] ; then
2020-06-19 10:54:05 +00:00
# BOTCONFIG does not exist, create
2020-12-18 14:16:15 +00:00
printf '["bot_config_key"]\t"config_key_value"\n' >>" ${ BOTCONFIG } .jssh "
# convert old token
if [ -r " ${ TOKENFILE } " ] ; then
token = " $( < " ${ TOKENFILE } " ) "
# no old token, ask user
elif [ -z " ${ CLEAR } " ] && [ " $1 " != "init" ] ; then
2020-12-26 20:18:18 +00:00
printf " Running headless, set BOTTOKEN or run ${ SCRIPT } init first!\n "
2019-04-12 09:27:20 +00:00
exit 2
2020-12-18 14:16:15 +00:00
else
2019-05-19 08:52:44 +00:00
${ CLEAR }
2020-12-26 20:18:18 +00:00
printf " ${ RED } TOKEN MISSING. ${ NN } "
printf " ${ ORANGE } PLEASE WRITE YOUR TOKEN HERE OR PRESS CTRL+C TO ABORT ${ NN } "
2020-06-13 19:39:52 +00:00
read -r token
2020-05-14 18:33:30 +00:00
fi
2020-12-18 14:16:15 +00:00
[ -n " ${ token } " ] && printf '["bottoken"]\t"%s"\n' " ${ token } " >> " ${ BOTCONFIG } .jssh "
2020-05-18 12:57:53 +00:00
2020-09-26 17:52:06 +00:00
# no botadmin, setup botadmin
2020-06-13 19:39:52 +00:00
if [ -z " $( getConfigKey "botadmin" ) " ] ; then
2020-06-19 10:54:05 +00:00
# convert old admin
2020-06-13 19:39:52 +00:00
if [ -r " ${ BOTADMIN } " ] ; then
admin = " $( < " ${ BOTADMIN } " ) "
elif [ -z " ${ CLEAR } " ] ; then
2020-12-26 20:18:18 +00:00
printf "Running headless, set botadmin to AUTO MODE!\n"
2020-05-14 18:33:30 +00:00
else
2019-05-19 08:52:44 +00:00
${ CLEAR }
2020-12-26 20:18:18 +00:00
printf " ${ RED } BOTADMIN MISSING. ${ NN } "
printf " ${ ORANGE } PLEASE WRITE YOUR TELEGRAM ID HERE OR ENTER '?' ${ NN } "
printf " ${ ORANGE } TO MAKE FIRST USER TYPING '/start' TO BOTADMIN ${ NN } "
2019-05-20 08:50:51 +00:00
read -r admin
2020-05-14 18:33:30 +00:00
fi
2020-06-13 19:39:52 +00:00
[ -z " ${ admin } " ] && admin = '?'
2020-06-19 10:49:18 +00:00
printf '["botadmin"]\t"%s"\n' " ${ admin } " >> " ${ BOTCONFIG } .jssh "
2020-05-14 18:33:30 +00:00
fi
# setup botacl file
if [ ! -f " ${ BOTACL } " ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Create empty ${ BOTACL } file. ${ NC } "
2019-05-20 08:50:51 +00:00
printf '\n' >" ${ BOTACL } "
2020-05-14 18:33:30 +00:00
fi
# setup data dir file
if [ ! -d " ${ DATADIR } " ] ; then
2019-05-28 18:44:40 +00:00
mkdir " ${ DATADIR } "
2020-05-14 18:33:30 +00:00
elif [ ! -w " ${ DATADIR } " ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ RED } ERROR: Can't write to ${ DATADIR } !. ${ NN } "
2019-05-28 18:44:40 +00:00
ls -ld " ${ DATADIR } "
2019-04-01 10:52:25 +00:00
exit 2
2020-05-14 18:33:30 +00:00
fi
2020-05-29 18:11:51 +00:00
# setup count file
if [ ! -f " ${ COUNTFILE } .jssh " ] ; then
2020-06-20 18:12:36 +00:00
printf '["counted_user_chat_id"]\t"num_messages_seen"\n' >> " ${ COUNTFILE } .jssh "
2020-06-05 07:01:20 +00:00
# convert old file on creation
2020-06-01 07:54:35 +00:00
if [ -r " ${ COUNTFILE } " ] ; then
sed 's/COUNT/\[\"/;s/$/\"\]\t\"1\"/' < " ${ COUNTFILE } " >> " ${ COUNTFILE } .jssh "
fi
2020-05-29 18:11:51 +00:00
elif [ ! -w " ${ COUNTFILE } .jssh " ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ RED } ERROR: Can't write to ${ COUNTFILE } !. ${ NN } "
2020-05-29 18:11:51 +00:00
ls -l " ${ COUNTFILE } .jssh "
2019-04-01 10:52:25 +00:00
exit 2
2020-05-14 18:33:30 +00:00
fi
2020-05-29 18:11:51 +00:00
# setup blocked file
if [ ! -f " ${ BLOCKEDFILE } .jssh " ] ; then
2020-06-20 18:12:36 +00:00
printf '["blocked_user_or_chat_id"]\t"name and reason"\n' >>" ${ BLOCKEDFILE } .jssh "
2020-05-29 18:11:51 +00:00
fi
2019-03-22 16:47:36 +00:00
fi
2020-05-29 18:11:51 +00:00
2020-12-15 16:19:09 +00:00
if [ [ ! -d " ${ LOGDIR } " || ! -w " ${ LOGDIR } " ] ] ; then
2020-07-09 11:41:09 +00:00
LOGDIR = " ${ RUNDIR :- . } "
fi
DEBUGLOG = " ${ LOGDIR } /DEBUG.log "
ERRORLOG = " ${ LOGDIR } /ERROR.log "
UPDATELOG = " ${ LOGDIR } /BASHBOT.log "
2020-12-15 09:12:18 +00:00
MESSAGELOG = " ${ LOGDIR } /MESSAGE.log "
2020-07-09 11:41:09 +00:00
2020-07-11 06:34:57 +00:00
debug_checks " start SOURCE= ${ SOURCE :- no } " " $@ "
2020-06-12 19:18:32 +00:00
# read BOTTOKEN from bot database if not set
2020-06-19 10:54:05 +00:00
if [ -z " ${ BOTTOKEN } " ] ; then
BOTTOKEN = " $( getConfigKey "bottoken" ) "
2020-06-19 11:15:50 +00:00
if [ -z " ${ BOTTOKEN } " ] ; then
2020-12-18 14:24:21 +00:00
BOTERROR = "Warning: can't get bot token, try to recover working config..."
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } ${ BOTERROR } ${ NC } "
2020-09-26 17:52:06 +00:00
if [ -r " ${ BOTCONFIG } .jssh.ok " ] ; then
log_error " ${ BOTERROR } "
2020-12-26 20:18:18 +00:00
cp " ${ BOTCONFIG } .jssh.ok " " ${ BOTCONFIG } .jssh " ; printf "OK\n"
2020-09-26 17:52:06 +00:00
BOTTOKEN = " $( getConfigKey "bottoken" ) "
else
2020-12-26 20:18:18 +00:00
printf " \n ${ RED } Error: Missing bot token! remove ${ BOTCONFIG } .jssh and run \"bashbot.sh init\" may fix it. ${ NN } "
2020-09-26 17:52:06 +00:00
exit 7
fi
2020-06-19 10:54:05 +00:00
fi
2020-05-18 12:57:53 +00:00
fi
2020-06-19 10:54:05 +00:00
2020-05-19 12:58:29 +00:00
# BOTTOKEN format checks
2020-06-27 10:43:46 +00:00
if ! check_token " ${ BOTTOKEN } " ; then
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Warning: your bottoken may incorrect. it should have the following format: ${ NN } "
printf " ${ GREY } 123456789 ${ RED } : ${ GREY } Aa-Zz_0Aa-Zz_1Aa-Zz_2Aa-Zz_3Aa-Zz_4 ${ ORANGE } => ${ NC } "
printf " ${ GREY } 8-10 digits ${ RED } : ${ GREY } 35 alphanumeric characters + '_-' ${ NN } "
printf " ${ ORANGE } Your current token is: ' ${ GREY } ^ $( cat -ve <<< " ${ BOTTOKEN // : / ${ RED } : ${ GREY } } " ) ${ ORANGE } ' ${ NN } "
2020-12-05 13:11:21 +00:00
if [ [ ! " ${ BOTTOKEN } " = ~ ^[ 0-9] { 8,10} : ] ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Possible problem in the digits part, len is $(( $( wc -c <<< " ${ BOTTOKEN % : * } " ) - 1 )) ${ NN } "
[ -n " $( getConfigKey "botid" ) " ] && printf " ${ GREY } Did you mean: \" ${ NC } $( getConfigKey "botid" ) ${ GREY } \" ? ${ NN } "
2020-12-05 13:11:21 +00:00
fi
2020-05-19 12:58:29 +00:00
[ [ ! " ${ BOTTOKEN } " = ~ :[ a-zA-Z0-9_-] { 35} $ ] ] && \
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Possible problem in the characters part, len is $(( $( wc -c <<< " ${ BOTTOKEN #* : } " ) - 1 )) ${ NN } "
2020-05-18 12:57:53 +00:00
fi
2019-03-22 16:47:36 +00:00
2020-05-20 14:38:56 +00:00
2020-12-05 13:11:21 +00:00
2020-05-14 18:33:30 +00:00
##################
# here we start with the real stuff
2020-06-11 06:33:59 +00:00
BASHBOT_RETRY = "" # retry by default
2019-04-12 18:49:58 +00:00
2020-06-10 06:20:48 +00:00
URL = " ${ BASHBOT_URL :- https : //api.telegram.org/bot } ${ BOTTOKEN } "
2019-04-12 18:49:58 +00:00
ME_URL = $URL '/getMe'
UPD_URL = $URL '/getUpdates?offset='
2019-04-26 11:19:34 +00:00
GETFILE_URL = $URL '/getFile'
2019-04-23 16:11:24 +00:00
2020-06-12 19:18:32 +00:00
#################
# BASHBOT COMMON functions
2019-05-28 19:12:02 +00:00
declare -rx SCRIPT SCRIPTDIR MODULEDIR RUNDIR ADDONDIR TOKENFILE BOTADMIN BOTACL DATADIR COUNTFILE
declare -rx BOTTOKEN URL ME_URL UPD_URL GETFILE_URL
2019-05-28 18:50:19 +00:00
declare -ax CMD
2020-06-29 11:29:47 +00:00
declare -Ax UPD BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO VENUE iQUERY
2020-12-13 11:00:18 +00:00
declare -Ax SERVICE NEWMEMBER LEFTMEMBER PINNED MIGRATE
2020-12-14 19:35:45 +00:00
export res CAPTION ME
2019-04-12 18:49:58 +00:00
2019-05-26 19:25:01 +00:00
2020-06-08 10:58:36 +00:00
##################
2020-09-26 17:52:06 +00:00
# read commands file if we are not sourced
2019-05-10 09:33:41 +00:00
COMMANDS = " ${ BASHBOT_ETC :- . } /commands.sh "
2020-06-19 16:47:18 +00:00
if [ -z " ${ SOURCE } " ] ; then
2019-05-10 09:33:41 +00:00
if [ ! -f " ${ COMMANDS } " ] || [ ! -r " ${ COMMANDS } " ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ RED } ERROR: ${ COMMANDS } does not exist or is not readable!. ${ NN } "
2019-05-10 09:33:41 +00:00
ls -l " ${ COMMANDS } "
exit 3
fi
fi
2020-06-10 12:02:29 +00:00
# shellcheck source=./commands.sh
[ -r " ${ COMMANDS } " ] && source " ${ COMMANDS } " "source"
2019-05-10 09:33:41 +00:00
2020-06-10 06:20:48 +00:00
###############
# load modules
for modules in " ${ MODULEDIR :- . } " /*.sh ; do
# shellcheck source=./modules/aliases.sh
if ! _is_function " $( basename " ${ modules } " ) " && [ -r " ${ modules } " ] ; then source " ${ modules } " "source" ; fi
done
#####################
# BASHBOT INTERNAL functions
#
2020-06-12 19:18:32 +00:00
# do we have BSD sed
if ! sed '1ia' </dev/null 2>/dev/null; then
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Warning: You may run on a BSD style system without gnu utils ... ${ NN } "
2020-06-12 19:18:32 +00:00
fi
2020-06-10 06:20:48 +00:00
#jsonDB is now mandatory
if ! _is_function jssh_newDB ; then
2020-12-26 20:18:18 +00:00
printf " ${ RED } ERROR: Mandatory module jsonDB is missing or not readable! ${ NN } "
2020-06-10 06:20:48 +00:00
exit 6
fi
2020-06-12 19:18:32 +00:00
2019-05-28 18:44:40 +00:00
# $1 URL, $2 filename in DATADIR
2019-05-20 16:42:21 +00:00
# outputs final filename
download( ) {
local empty = "no.file" file = " ${ 2 :- ${ empty } } "
if [ [ " $file " = *"/" * ] ] || [ [ " $file " = "." * ] ] ; then file = " ${ empty } " ; fi
2019-05-28 18:44:40 +00:00
while [ -f " ${ DATADIR :- . } / ${ file } " ] ; do file = " $RAMDOM - ${ file } " ; done
getJson " $1 " >" ${ DATADIR :- . } / ${ file } " || return
printf '%s\n' " ${ DATADIR :- . } / ${ file } "
2019-05-20 16:42:21 +00:00
}
2019-05-19 08:52:44 +00:00
# $1 postfix, e.g. chatid
# $2 prefix, back- or startbot-
procname( ) {
2019-05-20 08:50:51 +00:00
printf '%s\n' " $2 ${ ME } _ $1 "
2019-05-19 08:52:44 +00:00
}
2020-09-26 17:52:06 +00:00
# $1 string to search for programme incl. parameters
# returns a list of PIDs of all current bot processes matching $1
2019-05-19 08:52:44 +00:00
proclist( ) {
# shellcheck disable=SC2009
2019-05-21 08:53:52 +00:00
ps -fu " ${ UID } " | grep -F " $1 " | grep -v ' grep' | grep -F " ${ ME } " | sed 's/\s\+/\t/g' | cut -f 2
2019-05-19 08:52:44 +00:00
}
2020-09-26 17:52:06 +00:00
# $1 string to search for programme to kill
2019-05-21 08:53:52 +00:00
killallproc( ) {
local procid; procid = " $( proclist " $1 " ) "
2020-05-14 18:33:30 +00:00
if [ -n " ${ procid } " ] ; then
2019-05-21 08:53:52 +00:00
# shellcheck disable=SC2046
kill $( proclist " $1 " )
sleep 1
procid = " $( proclist " $1 " ) "
# shellcheck disable=SC2046
2020-05-14 18:33:30 +00:00
[ -n " ${ procid } " ] && kill $( proclist -9 " $1 " )
2019-05-21 08:53:52 +00:00
fi
2020-06-28 06:52:02 +00:00
debug_checks "end killallproc" " ${ 1 } "
2019-05-21 08:53:52 +00:00
}
2020-09-26 17:52:06 +00:00
# $ chat $2 msg_id $3 nolog
2019-05-28 19:12:02 +00:00
declare -xr DELETE_URL = $URL '/deleteMessage'
2019-03-11 14:41:21 +00:00
delete_message( ) {
2020-12-15 19:53:42 +00:00
[ -z " $3 " ] && log_update " Delete Message CHAT= ${ 1 } MSG_ID= ${ 2 } "
2019-06-03 14:46:32 +00:00
sendJson " ${ 1 } " '"message_id": ' " ${ 2 } " '' " ${ DELETE_URL } "
2019-03-11 14:41:21 +00:00
}
2019-05-14 13:25:15 +00:00
get_file( ) {
2020-05-14 18:33:30 +00:00
[ -z " $1 " ] && return
2019-05-30 17:52:14 +00:00
sendJson "" '"file_id": "' " ${ 1 } " '"' " ${ GETFILE_URL } "
printf '%s\n' " ${ URL } " /" $( JsonGetString <<< " ${ res } " '"result","file_path"' ) "
2019-05-14 13:25:15 +00:00
}
2020-11-29 16:20:57 +00:00
# curl is preferred, try detect curl even not in PATH
2020-11-29 08:40:45 +00:00
# return TRUE if curl is found or custom curl detected
# return FALSE if no curl is found or wget is forced by BASHBOT_WGET
# sets BASHBOT_CURL to point to curl
2020-12-18 13:23:20 +00:00
DETECTED_CURL = "curl"
2020-11-28 11:30:32 +00:00
function detect_curl( ) {
# custom curl command
[ -n " ${ BASHBOT_CURL } " ] && return 0
# use wget
2020-12-18 13:23:20 +00:00
if [ -n " ${ BASHBOT_WGET } " ] ; then
DETECTED_CURL = "wget"
return 1
fi
2020-11-29 08:40:45 +00:00
# default use curl in PATH
2020-11-28 11:30:32 +00:00
BASHBOT_CURL = "curl"
_exists curl && return 0
2020-11-29 08:40:45 +00:00
# search in usual locations
2020-11-28 11:30:32 +00:00
local file
for file in /usr/bin /bin /usr/local/bin; do
if [ -x " ${ file } /curl " ] ; then
BASHBOT_CURL = " ${ file } /curl "
return 0
fi
done
2020-11-29 08:40:45 +00:00
# curl not in PATH and not in usual locations
2020-12-18 13:23:20 +00:00
DETECTED_CURL = "wget"
2020-11-29 08:40:45 +00:00
local warn = "Warning: Curl not detected, try fallback to wget! pls install curl or adjust BASHBOT_CURL/BASHBOT_WGET environment variables."
2020-12-15 19:53:42 +00:00
log_update " ${ warn } " ; [ -n " ${ BASHBOTDEBUG } " ] && log_debug " ${ warn } "
2020-11-28 11:30:32 +00:00
return 1
}
2020-11-28 16:36:34 +00:00
# iconv used to filter out broken utf characters, if not installed fake it
if ! _exists iconv; then
2020-12-15 19:53:42 +00:00
log_update "Warning: iconv not installed, pls imstall iconv!"
2020-11-28 16:36:34 +00:00
function iconv( ) { cat; }
fi
2019-05-23 17:40:15 +00:00
TIMEOUT = " ${ BASHBOT_TIMEOUT } "
[ [ " $TIMEOUT " = ~ ^[ 0-9] +$ ] ] || TIMEOUT = "20"
2020-12-15 09:40:20 +00:00
# usage: sendJson "chat" "JSON" "URL"
sendJson( ) {
2020-12-15 09:07:43 +00:00
local json chat = ""
2020-12-15 09:12:18 +00:00
if [ -n " ${ 1 } " ] ; then
chat = '"chat_id":' " ${ 1 } " ','
2020-12-18 13:47:53 +00:00
[ [ " ${ 1 } " = = *[ !0-9-] * ] ] && chat = '"chat_id":"' " ${ 1 } " ' NAN",' # chat id not a number!
2020-12-15 09:12:18 +00:00
fi
2020-12-18 13:23:20 +00:00
# compose final json
2020-12-15 09:07:43 +00:00
json = '{' " ${ chat } $( iconv -f utf-8 -t utf-8 -c <<< " $2 " ) " '}'
if [ -n " ${ BASHBOTDEBUG } " ] ; then
2020-12-19 07:03:55 +00:00
log_update " sendJson ( ${ DETECTED_CURL } ) CHAT= ${ chat #* : } JSON= ${ 2 : 0 : 100 } URL= ${ 3 ##*/ } "
2020-12-15 19:53:42 +00:00
log_message " DEBUG sendJson ==========\n $( " ${ JSONSHFILE } " -b -n <<< " ${ json } " 2>& 1) "
2020-12-15 09:07:43 +00:00
fi
2020-12-18 13:47:53 +00:00
# chat id not a number
if [ [ " ${ chat } " = = *"NAN\"," ] ] ; then
2020-12-18 13:23:20 +00:00
sendJsonResult " $( printf '["ok"]\tfalse\n["error_code"]\t400\n["description"]\t"Bad Request: chat id not a number"\n' ) " \
"sendJson (NAN)" " $@ "
2020-12-18 13:47:53 +00:00
return
2020-12-18 13:23:20 +00:00
fi
2020-12-15 09:40:20 +00:00
# OK here we go ...
# route to curl/wget specific function
res = " $( sendJson_do " ${ json } " " ${ 3 } " ) "
# check telegram response
2020-12-18 13:23:20 +00:00
sendJsonResult " ${ res } " " sendJson ( ${ DETECTED_CURL } ) " " $@ "
2020-06-26 07:07:00 +00:00
[ -n " ${ BASHBOT_EVENT_SEND [*] } " ] && event_send "send" " ${ @ } " &
2020-12-15 09:40:20 +00:00
}
#
# curl / wget specific functions
#
if detect_curl ; then
# here we have curl ----
[ -z " ${ BASHBOT_CURL } " ] && BASHBOT_CURL = "curl"
getJson( ) {
2020-12-15 19:53:42 +00:00
[ [ -n " ${ BASHBOTDEBUG } " && -n " ${ 3 } " ] ] && log_debug " getJson (curl) URL= ${ 1 ##*/ } "
2020-12-15 09:40:20 +00:00
# shellcheck disable=SC2086
" ${ BASHBOT_CURL } " -sL -k ${ BASHBOT_CURL_ARGS } -m " ${ TIMEOUT } " " $1 "
}
# curl variant for sendJson
# usage: "JSON" "URL"
sendJson_do( ) {
# shellcheck disable=SC2086
" ${ BASHBOT_CURL } " -s -k ${ BASHBOT_CURL_ARGS } -m " ${ TIMEOUT } " \
-d " ${ 1 } " -X POST " ${ 2 } " -H "Content-Type: application/json" | " ${ JSONSHFILE } " -b -n 2>/dev/null
2019-05-14 13:25:15 +00:00
}
2020-09-26 17:52:06 +00:00
#$1 Chat, $2 what, $3 file, $4 URL, $5 caption
2019-05-20 15:26:21 +00:00
sendUpload( ) {
[ " $# " -lt 4 ] && return
2020-05-14 18:33:30 +00:00
if [ -n " $5 " ] ; then
2020-07-24 10:58:04 +00:00
[ -n " ${ BASHBOTDEBUG } " ] && \
2020-12-25 19:57:05 +00:00
log_update " sendUpload CHAT= ${ 1 } WHAT= ${ 2 } FILE= ${ 3 } CAPT= ${ 5 } "
2019-05-23 17:40:15 +00:00
# shellcheck disable=SC2086
2020-06-07 17:06:02 +00:00
res = " $( " ${ BASHBOT_CURL } " -s -k ${ BASHBOT_CURL_ARGS } " $4 " -F " chat_id= $1 " \
2020-10-16 08:53:08 +00:00
-F " $2 =@ $3 ; ${ 3 ##*/ } " -F " caption= $5 " | " ${ JSONSHFILE } " -b -n 2>/dev/null ) "
2019-05-20 15:26:21 +00:00
else
2019-05-23 17:40:15 +00:00
# shellcheck disable=SC2086
2020-06-07 17:06:02 +00:00
res = " $( " ${ BASHBOT_CURL } " -s -k ${ BASHBOT_CURL_ARGS } " $4 " -F " chat_id= $1 " \
2020-10-16 08:53:08 +00:00
-F " $2 =@ $3 ; ${ 3 ##*/ } " | " ${ JSONSHFILE } " -b -n 2>/dev/null ) "
2019-05-20 15:26:21 +00:00
fi
2020-06-08 10:58:36 +00:00
sendJsonResult " ${ res } " "sendUpload (curl)" " $@ "
2020-06-26 07:07:00 +00:00
[ -n " ${ BASHBOT_EVENT_SEND [*] } " ] && event_send "upload" " $@ " &
2019-05-20 15:26:21 +00:00
}
2019-05-14 13:25:15 +00:00
else
2020-11-29 16:20:57 +00:00
# NO curl, try wget
if _exists wget; then
getJson( ) {
2020-12-15 19:53:42 +00:00
[ [ -n " ${ BASHBOTDEBUG } " && -z " ${ 3 } " ] ] && log_debug " getJson (wget) URL= ${ 1 ##*/ } "
2019-05-23 17:40:15 +00:00
# shellcheck disable=SC2086
2019-06-19 09:56:31 +00:00
wget --no-check-certificate -t 2 -T " ${ TIMEOUT } " ${ BASHBOT_WGET_ARGS } -qO - " $1 "
2020-11-29 16:20:57 +00:00
}
2020-12-15 09:40:20 +00:00
# curl variant for sendJson
# usage: "JSON" "URL"
sendJson_do( ) {
2019-05-23 17:40:15 +00:00
# shellcheck disable=SC2086
2020-12-15 09:40:20 +00:00
wget --no-check-certificate -t 2 -T " ${ TIMEOUT } " ${ BASHBOT_WGET_ARGS } -qO - --post-data= " ${ 1 } " \
--header= 'Content-Type:application/json' " ${ 2 } " | " ${ JSONSHFILE } " -b -n 2>/dev/null
2020-11-29 16:20:57 +00:00
}
sendUpload( ) {
2020-06-27 08:43:08 +00:00
log_error "Sorry, wget does not support file upload"
2019-05-20 15:26:21 +00:00
BOTSENT[ OK] = "false"
2020-06-26 07:07:00 +00:00
[ -n " ${ BASHBOT_EVENT_SEND [*] } " ] && event_send "upload" " $@ " &
2020-11-29 16:20:57 +00:00
}
else
# ups, no curl AND no wget
if [ -n " ${ BASHBOT_WGET } " ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ RED } Error: You set BASHBOT_WGET but no wget found! ${ NN } "
2020-11-29 16:20:57 +00:00
else
2020-12-26 20:18:18 +00:00
printf " ${ RED } Error: curl and wget not found, install curl! ${ NN } "
2020-11-29 16:20:57 +00:00
fi
exit 8
fi
2019-05-14 13:25:15 +00:00
fi
2020-06-08 19:47:36 +00:00
# retry sendJson
2020-06-09 06:47:13 +00:00
# $1 function $2 sleep $3 ... $n arguments
2020-06-08 19:47:36 +00:00
sendJsonRetry( ) {
local retry = " ${ 1 } " ; shift
2020-06-09 09:57:25 +00:00
[ [ " ${ 1 } " = ~ ^\ *[ 0-9.] +\ *$ ] ] && sleep " ${ 1 } " ; shift
2020-06-10 16:52:26 +00:00
printf "%s: RETRY %s %s %s\n" " $( date) " " ${ retry } " " ${ 1 } " " ${ 2 : 0 : 60 } "
2020-06-08 19:47:36 +00:00
case " ${ retry } " in
'sendJson' *)
sendJson " $@ "
; ;
'sendUpload' *)
sendUpload " $@ "
; ;
2020-06-26 07:11:10 +00:00
'send_album' *)
send_album " $@ "
; ;
2020-06-08 19:47:36 +00:00
*)
2020-06-27 08:43:08 +00:00
log_error " Error: unknown function ${ retry } , cannot retry "
2020-06-10 13:56:34 +00:00
return
2020-06-08 19:47:36 +00:00
; ;
esac
2020-06-27 08:43:08 +00:00
[ " ${ BOTSENT [OK] } " = "true" ] && log_error " Retry OK: ${ retry } ${ 1 } ${ 2 : 0 : 60 } "
2020-06-10 13:56:34 +00:00
} >>" ${ ERRORLOG } "
2020-06-08 19:47:36 +00:00
# process sendJson result
2020-06-09 06:47:13 +00:00
# stdout is written to ERROR.log
# $1 result $2 function $3 .. $n original arguments, $3 is Chat_id
2020-06-08 10:58:36 +00:00
sendJsonResult( ) {
2020-06-20 18:12:36 +00:00
local offset = 0
2020-06-08 18:51:15 +00:00
BOTSENT = ( )
2020-12-15 19:53:42 +00:00
[ -n " ${ BASHBOTDEBUG } " ] && log_message " New Result ==========\n $1 "
2020-06-08 18:51:15 +00:00
BOTSENT[ OK] = " $( JsonGetLine '"ok"' <<< " ${ 1 } " ) "
2020-06-08 10:58:36 +00:00
if [ " ${ BOTSENT [OK] } " = "true" ] ; then
2020-06-08 18:51:15 +00:00
BOTSENT[ ID] = " $( JsonGetValue '"result","message_id"' <<< " ${ 1 } " ) "
2020-06-08 10:58:36 +00:00
return
2020-06-23 14:35:50 +00:00
# hot path everything OK!
2020-06-08 10:58:36 +00:00
else
2020-06-08 18:51:15 +00:00
# oops something went wrong!
2020-12-18 13:47:53 +00:00
if [ " ${ 1 } " != "" ] ; then
2020-09-26 17:52:06 +00:00
BOTSENT[ ERROR] = " $( JsonGetValue '"error_code"' <<< " ${ 1 } " ) "
BOTSENT[ DESCRIPTION] = " $( JsonGetString '"description"' <<< " ${ 1 } " ) "
2020-12-16 12:45:59 +00:00
grep -qs -F '"parameters","retry_after"' <<< " ${ 1 } " && \
BOTSENT[ RETRY] = " $( JsonGetValue '"parameters","retry_after"' <<< " ${ 1 } " ) "
2020-06-08 10:58:36 +00:00
else
2020-09-26 17:52:06 +00:00
BOTSENT[ OK] = "false"
BOTSENT[ ERROR] = "999"
BOTSENT[ DESCRIPTION] = "Send to telegram not possible, timeout/broken/no connection"
2020-06-08 10:58:36 +00:00
fi
2020-06-08 18:51:15 +00:00
# log error
2020-06-20 18:12:36 +00:00
[ [ " ${ BOTSENT [ERROR] } " = "400" && " ${ BOTSENT [DESCRIPTION] } " = = *"starting at byte offset" * ] ] && \
offset = " ${ BOTSENT [DESCRIPTION]%* } "
2020-06-10 16:26:51 +00:00
printf "%s: RESULT=%s FUNC=%s CHAT[ID]=%s ERROR=%s DESC=%s ACTION=%s\n" " $( date) " \
2020-06-20 18:12:36 +00:00
" ${ BOTSENT [OK] } " " ${ 2 } " " ${ 3 } " " ${ BOTSENT [ERROR] } " " ${ BOTSENT [DESCRIPTION] } " " ${ 4 : ${ offset } : 100 } "
2020-06-09 10:27:28 +00:00
# warm path, do not retry on error, also if we use wegt
2020-06-11 06:33:59 +00:00
[ -n " ${ BASHBOT_RETRY } ${ BASHBOT_WGET } " ] && return
2020-06-08 19:47:36 +00:00
2020-06-09 06:47:13 +00:00
# OK, we can retry sendJson, let's see what's failed
2020-09-26 17:52:06 +00:00
# throttled, telegram say we send too many messages
2020-06-08 18:51:15 +00:00
if [ -n " ${ BOTSENT [RETRY] } " ] ; then
2020-09-26 17:52:06 +00:00
BASHBOT_RETRY = " $(( + + BOTSENT[ RETRY] )) "
printf "Retry %s in %s seconds ...\n" " ${ 2 } " " ${ BASHBOT_RETRY } "
sendJsonRetry " ${ 2 } " " ${ BASHBOT_RETRY } " " ${ @ : 3 } "
unset BASHBOT_RETRY
return
2020-06-08 18:51:15 +00:00
fi
2020-06-08 19:47:36 +00:00
# timeout, failed connection or blocked
2020-06-08 18:51:15 +00:00
if [ " ${ BOTSENT [ERROR] } " = = "999" ] ; then
# check if default curl and args are OK
2020-09-26 17:52:06 +00:00
if ! curl -sL -k -m 2 " ${ URL } " >/dev/null 2>& 1 ; then
printf "%s: BASHBOT IP Address seems blocked!\n" " $( date) "
# user provided function to recover or notify block
if _exec_if_function bashbotBlockRecover; then
BASHBOT_RETRY = "2"
printf "bashbotBlockRecover returned true, retry %s ...\n" " ${ 2 } "
sendJsonRetry " ${ 2 } " " ${ BASHBOT_RETRY } " " ${ @ : 3 } "
unset BASHBOT_RETRY
fi
2020-06-08 18:51:15 +00:00
return
2020-09-26 17:52:06 +00:00
fi
2020-06-09 09:57:25 +00:00
# are not blocked, default curl and args are working
2020-09-26 17:52:06 +00:00
if [ -n " ${ BASHBOT_CURL_ARGS } " ] || [ " ${ BASHBOT_CURL } " != "curl" ] ; then
printf "Problem with \"%s %s\"? retry %s with default config ...\n" \
" ${ BASHBOT_CURL } " " ${ BASHBOT_CURL_ARGS } " " ${ 2 } "
BASHBOT_RETRY = "2" ; BASHBOT_CURL = "curl" ; BASHBOT_CURL_ARGS = ""
sendJsonRetry " ${ 2 } " " ${ BASHBOT_RETRY } " " ${ @ : 3 } "
unset BASHBOT_RETRY
fi
2020-06-08 18:51:15 +00:00
fi
2020-06-08 10:58:36 +00:00
fi
2020-06-09 06:47:13 +00:00
} >>" ${ ERRORLOG } "
2020-06-08 10:58:36 +00:00
2020-06-23 14:35:50 +00:00
# escape / remove text characters for json strings, eg. " -> \"
2020-01-18 13:41:09 +00:00
# $1 string
# output escaped string
2020-06-08 10:58:36 +00:00
JsonEscape( ) {
2020-06-15 12:14:34 +00:00
sed 's/\([-"`´ ,§$%&/(){}#@!?*.\t]\)/\\\1/g' <<< " $1 "
2020-01-18 13:41:09 +00:00
}
2019-05-09 14:48:38 +00:00
# convert common telegram entities to JSON
# title caption description markup inlinekeyboard
title2Json( ) {
local title caption desc markup keyboard
2020-05-14 18:33:30 +00:00
[ -n " $1 " ] && title = ',"title":"' $( JsonEscape " $1 " ) '"'
[ -n " $2 " ] && caption = ',"caption":"' $( JsonEscape " $2 " ) '"'
[ -n " $3 " ] && desc = ',"description":"' $( JsonEscape " $3 " ) '"'
2020-06-15 12:22:28 +00:00
[ -n " $4 " ] && markup = ',"parse_mode":"' " $4 " '"'
2020-05-14 18:33:30 +00:00
[ -n " $5 " ] && keyboard = ',"reply_markup":"' $( JsonEscape " $5 " ) '"'
2020-06-09 07:15:36 +00:00
printf '%s\n' " ${ title } ${ caption } ${ desc } ${ markup } ${ keyboard } "
2019-05-09 14:48:38 +00:00
}
2020-12-03 19:43:20 +00:00
# get bot name and id from telegram
2019-05-14 13:25:15 +00:00
getBotName( ) {
2020-12-03 13:07:39 +00:00
declare -A BOTARRAY
2020-12-03 19:43:20 +00:00
Json2Array 'BOTARRAY' <<< " $( getJson " $ME_URL " | " ${ JSONSHFILE } " -b -n 2>/dev/null) "
[ -z " ${ BOTARRAY [ "result" , "username" ] } " ] && return 1
2020-12-03 13:07:39 +00:00
# save botname and id
setConfigKey "botname" " ${ BOTARRAY [ "result" , "username" ] } "
setConfigKey "botid" " ${ BOTARRAY [ "result" , "id" ] } "
2020-12-26 20:18:18 +00:00
printf " ${ BOTARRAY [ "result" , "username" ] } \n "
2016-01-06 16:11:56 +00:00
}
2020-06-23 14:35:50 +00:00
# pure bash implementation, done by KayM (@gnadelwartz)
2019-05-14 15:56:23 +00:00
# see https://stackoverflow.com/a/55666449/9381171
JsonDecode( ) {
2020-09-26 17:52:06 +00:00
local out = " $1 " remain = "" U = ""
2019-05-14 15:56:23 +00:00
local regexp = '(.*)\\u[dD]([0-9a-fA-F]{3})\\u[dD]([0-9a-fA-F]{3})(.*)'
2020-09-26 17:52:06 +00:00
while [ [ " ${ out } " = ~ $regexp ] ] ; do
U = $(( ( ( 0 xd${ BASH_REMATCH [2] } & 0 x3ff) <<10 ) | ( 0xd${BASH_REMATCH[3]} & 0x3ff ) + 0x10 000 ))
remain = " $( printf '\\U%8.8x' " ${ U } " ) ${ BASH_REMATCH [4] } ${ remain } "
out = " ${ BASH_REMATCH [1] } "
done
2020-06-09 07:15:36 +00:00
# this echo must stay for correct decoding!
2020-09-26 17:52:06 +00:00
echo -e " ${ out } ${ remain } "
2019-05-14 15:56:23 +00:00
}
2019-05-14 13:25:15 +00:00
JsonGetString( ) {
sed -n -e '0,/\[' " $1 " '\]/ s/\[' " $1 " '\][ \t]"\(.*\)"$/\1/p'
}
JsonGetLine( ) {
sed -n -e '0,/\[' " $1 " '\]/ s/\[' " $1 " '\][ \t]//p'
}
JsonGetValue( ) {
sed -n -e '0,/\[' " $1 " '\]/ s/\[' " $1 " '\][ \t]\([0-9.,]*\).*/\1/p'
2019-04-23 18:37:15 +00:00
}
2019-05-14 13:25:15 +00:00
################
# processing of updates starts here
2016-10-24 22:13:52 +00:00
process_updates( ) {
2019-05-19 08:52:44 +00:00
local max num debug = " $1 "
2020-12-15 23:09:32 +00:00
max = " $( grep -F ',"update_id"]' <<< " ${ UPDATE } " | tail -1 | cut -d , -f 2 ) "
2019-05-27 12:30:21 +00:00
Json2Array 'UPD' <<< " ${ UPDATE } "
2019-05-19 08:52:44 +00:00
for ( ( num = 0; num<= max; num++) ) ; do
process_client " $num " " ${ debug } "
2016-10-24 22:13:52 +00:00
done
}
2020-06-29 09:21:56 +00:00
2019-04-21 11:45:51 +00:00
process_client( ) {
2019-05-19 08:52:44 +00:00
local num = " $1 " debug = " $2 "
2020-06-29 09:21:56 +00:00
pre_process_message " ${ num } "
2020-06-11 09:32:52 +00:00
# log message on debug
2020-12-15 23:09:32 +00:00
[ [ -n " ${ debug } " ] ] && log_message " New Message ==========\n $( grep -F '["result",' " ${ num } " <<< " ${ UPDATE } " ) "
2020-05-29 18:11:51 +00:00
2020-09-26 17:52:06 +00:00
# check for users / groups to ignore
2020-06-15 08:42:36 +00:00
jssh_updateArray_async "BASHBOTBLOCKED" " ${ BLOCKEDFILE } "
[ -n " ${ USER [ID] } " ] && [ [ -n " ${ BASHBOTBLOCKED [ ${ USER [ID] } ] } " || -n " ${ BASHBOTBLOCKED [ ${ CHAT [ID] } ] } " ] ] && return
2020-06-11 23:17:15 +00:00
# process per message type
2020-05-14 18:33:30 +00:00
if [ -z " ${ iQUERY [ID] } " ] ; then
2020-06-16 21:05:52 +00:00
if grep -qs -e '\["result",' " ${ num } " ',"edited_message"' <<< " ${ UPDATE } " ; then
# edited message
UPDATE = " ${ UPDATE //, ${ num } , \" edited_message \" ,/, ${ num } , \" message \" , } "
Json2Array 'UPD' <<< " ${ UPDATE } "
2020-06-29 09:21:56 +00:00
MESSAGE[ 0] = "/_edited_message "
2020-06-16 21:05:52 +00:00
fi
2019-05-19 08:52:44 +00:00
process_message " ${ num } " " ${ debug } "
2020-06-12 19:18:32 +00:00
printf "%s: update received FROM=%s CHAT=%s CMD=%s\n" " $( date) " " ${ USER [USERNAME] : 0 : 20 } ( ${ USER [ID] } ) " \
2020-06-12 21:41:47 +00:00
" ${ CHAT [USERNAME] : 0 : 20 } ${ CHAT [TITLE] : 0 : 30 } ( ${ CHAT [ID] } ) " \
" ${ MESSAGE : 0 : 30 } ${ CAPTION : 0 : 30 } ${ URLS [*] : 0 : 30 } " >>" ${ UPDATELOG } "
2019-05-02 10:33:10 +00:00
else
2019-05-28 19:28:58 +00:00
process_inline " ${ num } " " ${ debug } "
2020-06-12 19:18:32 +00:00
printf "%s: iQuery received FROM=%s iQUERY=%s\n" " $( date) " \
" ${ iQUERY [USERNAME] : 0 : 20 } ( ${ iQUERY [USER_ID] } ) " " ${ iQUERY [0] } " >>" ${ UPDATELOG } "
2019-05-02 10:33:10 +00:00
fi
2019-05-25 17:31:20 +00:00
#####
# process inline and message events
2020-06-23 14:35:50 +00:00
# first classic command dispatcher
2019-05-12 15:51:52 +00:00
# shellcheck source=./commands.sh
2019-05-25 17:31:20 +00:00
source " ${ COMMANDS } " " ${ debug } " &
# then all registered addons
2020-05-14 18:33:30 +00:00
if [ -z " ${ iQUERY [ID] } " ] ; then
2019-05-25 17:31:20 +00:00
event_message " ${ debug } "
2019-05-26 15:40:51 +00:00
else
2019-05-28 19:28:58 +00:00
event_inline " ${ debug } "
2019-05-25 17:31:20 +00:00
fi
# last count users
2020-06-05 07:01:20 +00:00
jssh_countKeyDB_async " ${ CHAT [ID] } " " ${ COUNTFILE } "
2019-05-25 17:31:20 +00:00
}
2020-09-06 16:54:50 +00:00
declare -Ax BASHBOT_EVENT_INLINE BASHBOT_EVENT_MESSAGE BASHBOT_EVENT_CMD BASHBOT_EVENT_REPLY BASHBOT_EVENT_FORWARD BASHBOT_EVENT_SEND
declare -Ax BASHBOT_EVENT_CONTACT BASHBOT_EVENT_LOCATION BASHBOT_EVENT_FILE BASHBOT_EVENT_TEXT BASHBOT_EVENT_TIMER BASHBOT_BLOCKED
2019-05-29 11:49:05 +00:00
2019-05-29 15:33:31 +00:00
start_timer( ) {
# send alarm every ~60 s
while :; do
sleep 59.5
kill -ALRM $$
done ;
}
2019-06-04 16:04:52 +00:00
EVENT_SEND = "0"
event_send( ) {
# max recursion level 5 to avoid fork bombs
( ( EVENT_SEND++ ) ) ; [ " $EVENT_SEND " -gt "5" ] && return
# shellcheck disable=SC2153
for key in " ${ !BASHBOT_EVENT_SEND[@] } "
do
_exec_if_function " ${ BASHBOT_EVENT_SEND [ ${ key } ] } " " $@ "
done
}
2019-05-29 11:49:05 +00:00
EVENT_TIMER = "0"
event_timer( ) {
2019-06-03 18:34:43 +00:00
local key timer debug = " $1 "
2019-06-01 10:41:12 +00:00
( ( EVENT_TIMER++ ) )
2019-05-29 11:49:05 +00:00
# shellcheck disable=SC2153
2019-06-03 18:34:43 +00:00
for key in " ${ !BASHBOT_EVENT_TIMER[@] } "
2019-05-29 11:49:05 +00:00
do
2019-06-03 18:34:43 +00:00
timer = " ${ key ##*, } "
2019-06-01 10:41:12 +00:00
[ [ ! " $timer " = ~ ^-*[ 1-9] [ 0-9] *$ ] ] && continue
2019-05-29 11:49:05 +00:00
if [ " $(( EVENT_TIMER % timer )) " = "0" ] ; then
2019-06-03 18:34:43 +00:00
_exec_if_function " ${ BASHBOT_EVENT_TIMER [ ${ key } ] } " "timer" " ${ key } " " ${ debug } "
2019-05-29 11:49:05 +00:00
[ " $(( EVENT_TIMER % timer )) " -lt "0" ] && \
2019-06-03 18:34:43 +00:00
unset BASHBOT_EVENT_TIMER[ " ${ key } " ]
2019-05-29 11:49:05 +00:00
fi
done
}
2019-05-27 10:27:09 +00:00
2019-05-25 17:31:20 +00:00
event_inline( ) {
2019-06-03 18:34:43 +00:00
local key debug = " $1 "
2019-05-25 17:31:20 +00:00
# shellcheck disable=SC2153
2019-06-03 18:34:43 +00:00
for key in " ${ !BASHBOT_EVENT_INLINE[@] } "
2019-05-25 17:31:20 +00:00
do
2019-06-03 18:34:43 +00:00
_exec_if_function " ${ BASHBOT_EVENT_INLINE [ ${ key } ] } " "inline" " ${ key } " " ${ debug } "
2019-05-25 17:31:20 +00:00
done
}
event_message( ) {
2019-06-03 18:34:43 +00:00
local key debug = " $1 "
2019-05-25 17:31:20 +00:00
# ${MESSAEG[*]} event_message
# shellcheck disable=SC2153
2019-06-03 18:34:43 +00:00
for key in " ${ !BASHBOT_EVENT_MESSAGE[@] } "
2019-05-25 17:31:20 +00:00
do
2020-06-23 14:35:50 +00:00
_exec_if_function " ${ BASHBOT_EVENT_MESSAGE [ ${ key } ] } " "message" " ${ key } " " ${ debug } "
2019-05-25 17:31:20 +00:00
done
2019-05-27 10:27:09 +00:00
# ${TEXT[*]} event_text
2020-05-14 18:33:30 +00:00
if [ -n " ${ MESSAGE [0] } " ] ; then
2019-05-27 10:27:09 +00:00
# shellcheck disable=SC2153
2019-06-03 18:34:43 +00:00
for key in " ${ !BASHBOT_EVENT_TEXT[@] } "
2019-05-27 10:27:09 +00:00
do
2019-06-03 18:34:43 +00:00
_exec_if_function " ${ BASHBOT_EVENT_TEXT [ ${ key } ] } " "text" " ${ key } " " ${ debug } "
2019-05-27 10:27:09 +00:00
done
# ${CMD[*]} event_cmd
2020-05-14 18:33:30 +00:00
if [ -n " ${ CMD [0] } " ] ; then
2019-05-27 10:27:09 +00:00
# shellcheck disable=SC2153
2019-06-03 18:34:43 +00:00
for key in " ${ !BASHBOT_EVENT_CMD[@] } "
2019-05-27 10:27:09 +00:00
do
2019-06-03 18:34:43 +00:00
_exec_if_function " ${ BASHBOT_EVENT_CMD [ ${ key } ] } " "command" " ${ key } " " ${ debug } "
2019-05-27 10:27:09 +00:00
done
fi
fi
2019-05-25 17:31:20 +00:00
# ${REPLYTO[*]} event_replyto
2020-05-14 18:33:30 +00:00
if [ -n " ${ REPLYTO [UID] } " ] ; then
2019-05-25 17:31:20 +00:00
# shellcheck disable=SC2153
2019-06-03 18:34:43 +00:00
for key in " ${ !BASHBOT_EVENT_REPLYTO[@] } "
2019-05-25 17:31:20 +00:00
do
2019-06-03 18:34:43 +00:00
_exec_if_function " ${ BASHBOT_EVENT_REPLYTO [ ${ key } ] } " "replyto" " ${ key } " " ${ debug } "
2019-05-25 17:31:20 +00:00
done
fi
# ${FORWARD[*]} event_forward
2020-05-14 18:33:30 +00:00
if [ -n " ${ FORWARD [UID] } " ] ; then
2019-05-25 17:31:20 +00:00
# shellcheck disable=SC2153
2019-06-03 18:34:43 +00:00
for key in " ${ !BASHBOT_EVENT_FORWARD[@] } "
2019-05-25 17:31:20 +00:00
do
2019-06-03 18:34:43 +00:00
_exec_if_function && " ${ BASHBOT_EVENT_FORWARD [ ${ key } ] } " "forward" " ${ key } " " ${ debug } "
2019-05-25 17:31:20 +00:00
done
fi
# ${CONTACT[*]} event_contact
2020-05-14 18:33:30 +00:00
if [ -n " ${ CONTACT [FIRST_NAME] } " ] ; then
2019-05-25 17:31:20 +00:00
# shellcheck disable=SC2153
2019-06-03 18:34:43 +00:00
for key in " ${ !BASHBOT_EVENT_CONTACT[@] } "
2019-05-25 17:31:20 +00:00
do
2019-06-03 18:34:43 +00:00
_exec_if_function " ${ BASHBOT_EVENT_CONTACT [ ${ key } ] } " "contact" " ${ key } " " ${ debug } "
2019-05-25 17:31:20 +00:00
done
fi
# ${VENUE[*]} event_location
2020-06-23 14:35:50 +00:00
# ${LOCATION[*]} event_location
2020-05-14 18:33:30 +00:00
if [ -n " ${ LOCATION [LONGITUDE] } " ] || [ -n " ${ VENUE [TITLE] } " ] ; then
2019-05-25 17:31:20 +00:00
# shellcheck disable=SC2153
2019-06-03 18:34:43 +00:00
for key in " ${ !BASHBOT_EVENT_LOCATION[@] } "
2019-05-25 17:31:20 +00:00
do
2019-06-03 18:34:43 +00:00
_exec_if_function " ${ BASHBOT_EVENT_LOCATION [ ${ key } ] } " "location" " ${ key } " " ${ debug } "
2019-05-25 17:31:20 +00:00
done
fi
# ${URLS[*]} event_file
2019-05-30 17:52:14 +00:00
# NOTE: compare again #URLS -1 blanks!
if [ [ " ${ URLS [*] } " != " " ] ] ; then
2019-05-25 17:31:20 +00:00
# shellcheck disable=SC2153
2019-06-03 18:34:43 +00:00
for key in " ${ !BASHBOT_EVENT_FILE[@] } "
2019-05-25 17:31:20 +00:00
do
2019-06-03 18:34:43 +00:00
_exec_if_function " ${ BASHBOT_EVENT_FILE [ ${ key } ] } " "file" " ${ key } " " ${ debug } "
2019-05-25 17:31:20 +00:00
done
fi
2019-04-21 11:45:51 +00:00
}
2020-06-29 09:21:56 +00:00
pre_process_message( ) {
local num = " ${ 1 } "
# unset everything to not have old values
CMD = ( ) ; iQUERY = ( ) ; MESSAGE = ( ) ; CHAT = ( ) ; USER = ( ) ; CONTACT = ( ) ; LOCATION = ( ) ; unset CAPTION
2020-12-13 11:00:18 +00:00
REPLYTO = ( ) ; FORWARD = ( ) ; URLS = ( ) ; VENUE = ( ) ; SERVICE = ( ) ; NEWMEMBER = ( ) ; LEFTMEMBER = ( ) ; PINNED = ( ) ; MIGRATE = ( )
2020-06-29 09:21:56 +00:00
iQUERY[ ID] = " ${ UPD [ "result" , ${ num } , "inline_query" , "id" ] } "
CHAT[ ID] = " ${ UPD [ "result" , ${ num } , "message" , "chat" , "id" ] } "
USER[ ID] = " ${ UPD [ "result" , ${ num } , "message" , "from" , "id" ] } "
[ -z " ${ CHAT [ID] } " ] && CHAT[ ID] = " ${ UPD [ "result" , ${ num } , "edited_message" , "chat" , "id" ] } "
[ -z " ${ USER [ID] } " ] && USER[ ID] = " ${ UPD [ "result" , ${ num } , "edited_message" , "from" , "id" ] } "
# always true
return 0
}
2019-05-11 16:36:40 +00:00
process_inline( ) {
local num = " ${ 1 } "
2019-05-22 16:43:20 +00:00
iQUERY[ 0] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "inline_query" , "query" ] } " ) "
iQUERY[ USER_ID] = " ${ UPD [ "result" , ${ num } , "inline_query" , "from" , "id" ] } "
iQUERY[ FIRST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "inline_query" , "from" , "first_name" ] } " ) "
iQUERY[ LAST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "inline_query" , "from" , "last_name" ] } " ) "
iQUERY[ USERNAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "inline_query" , "from" , "username" ] } " ) "
2020-06-29 09:21:56 +00:00
# always true
return 0
2019-05-11 16:36:40 +00:00
}
2019-04-21 11:45:51 +00:00
process_message( ) {
local num = " $1 "
2016-04-16 18:50:05 +00:00
# Message
2020-07-20 14:08:21 +00:00
MESSAGE[ 0] += " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "text" ] } " | sed 's|\\/|/|g' ) "
2019-05-22 16:43:20 +00:00
MESSAGE[ ID] = " ${ UPD [ "result" , ${ num } , "message" , "message_id" ] } "
2016-10-24 22:13:52 +00:00
2020-09-26 17:52:06 +00:00
# Chat ID is now parsed when update is received
2019-05-22 16:43:20 +00:00
CHAT[ LAST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "chat" , "last_name" ] } " ) "
CHAT[ FIRST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "chat" , "first_name" ] } " ) "
CHAT[ USERNAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "chat" , "username" ] } " ) "
2020-06-13 09:05:28 +00:00
# set real name as username if empty
2020-06-14 07:10:43 +00:00
[ -z " ${ CHAT [USERNAME] } " ] && CHAT[ USERNAME] = " ${ CHAT [FIRST_NAME] } ${ CHAT [LAST_NAME] } "
2019-05-22 16:43:20 +00:00
CHAT[ TITLE] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "chat" , "title" ] } " ) "
CHAT[ TYPE] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "chat" , "type" ] } " ) "
CHAT[ ALL_ADMIN] = " ${ UPD [ "result" , ${ num } , "message" , "chat" , "all_members_are_administrators" ] } "
2016-04-19 09:49:35 +00:00
2020-09-26 17:52:06 +00:00
# user ID is now parsed when update is received
2020-05-29 18:11:51 +00:00
#USER[ID]="${UPD["result",${num},"message","from","id"]}"
2019-05-22 16:43:20 +00:00
USER[ FIRST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "from" , "first_name" ] } " ) "
USER[ LAST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "from" , "last_name" ] } " ) "
USER[ USERNAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "from" , "username" ] } " ) "
2020-06-15 17:44:46 +00:00
# set real name as username if empty
[ -z " ${ USER [USERNAME] } " ] && USER[ USERNAME] = " ${ USER [FIRST_NAME] } ${ USER [LAST_NAME] } "
2016-01-17 16:46:24 +00:00
2019-03-22 19:30:22 +00:00
# in reply to message from
2020-12-13 08:57:57 +00:00
if [ -n " ${ UPD [ "result" , ${ num } , "message" , "reply_to_message" , "from" , "id" ] } " ] ; then
2020-06-15 17:44:46 +00:00
REPLYTO[ UID] = " ${ UPD [ "result" , ${ num } , "message" , "reply_to_message" , "from" , "id" ] } "
2019-05-22 16:43:20 +00:00
REPLYTO[ 0] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "reply_to_message" , "text" ] } " ) "
REPLYTO[ ID] = " ${ UPD [ "result" , ${ num } , "message" , "reply_to_message" , "message_id" ] } "
REPLYTO[ FIRST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "reply_to_message" , "from" , "first_name" ] } " ) "
REPLYTO[ LAST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "reply_to_message" , "from" , "last_name" ] } " ) "
REPLYTO[ USERNAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "reply_to_message" , "from" , "username" ] } " ) "
2019-03-22 19:41:34 +00:00
fi
2019-03-22 19:30:22 +00:00
# forwarded message from
2020-12-13 08:57:57 +00:00
if [ -n " ${ UPD [ "result" , ${ num } , "message" , "forward_from" , "id" ] } " ] ; then
2020-06-15 17:44:46 +00:00
FORWARD[ UID] = " ${ UPD [ "result" , ${ num } , "message" , "forward_from" , "id" ] } "
2019-03-22 19:41:34 +00:00
FORWARD[ ID] = " ${ MESSAGE [ID] } " # same as message ID
2019-05-22 16:43:20 +00:00
FORWARD[ FIRST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "forward_from" , "first_name" ] } " ) "
FORWARD[ LAST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "forward_from" , "last_name" ] } " ) "
FORWARD[ USERNAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "forward_from" , "username" ] } " ) "
2019-03-22 19:41:34 +00:00
fi
2019-03-22 19:30:22 +00:00
2020-12-13 08:57:57 +00:00
# get file URL from telegram, check for any of them!
2020-06-29 10:25:55 +00:00
if grep -qs -e '\["result",' " ${ num } " ',"message","[avpsd].*,"file_id"\]' <<< " ${ UPDATE } " ; then
2020-06-14 07:10:43 +00:00
URLS[ AUDIO] = " $( get_file " ${ UPD [ "result" , ${ num } , "message" , "audio" , "file_id" ] } " ) "
URLS[ DOCUMENT] = " $( get_file " ${ UPD [ "result" , ${ num } , "message" , "document" , "file_id" ] } " ) "
URLS[ PHOTO] = " $( get_file " ${ UPD [ "result" , ${ num } , "message" , "photo" ,0, "file_id" ] } " ) "
URLS[ STICKER] = " $( get_file " ${ UPD [ "result" , ${ num } , "message" , "sticker" , "file_id" ] } " ) "
URLS[ VIDEO] = " $( get_file " ${ UPD [ "result" , ${ num } , "message" , "video" , "file_id" ] } " ) "
URLS[ VOICE] = " $( get_file " ${ UPD [ "result" , ${ num } , "message" , "voice" , "file_id" ] } " ) "
fi
2020-12-13 09:10:15 +00:00
# Contact, must have phone_number
if [ -n " ${ UPD [ "result" , ${ num } , "message" , "contact" , "phone_number" ] } " ] ; then
2019-05-22 16:43:20 +00:00
CONTACT[ USER_ID] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "contact" , "user_id" ] } " ) "
2020-12-13 08:57:57 +00:00
CONTACT[ FIRST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "contact" , "first_name" ] } " ) "
2019-05-22 16:43:20 +00:00
CONTACT[ LAST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "contact" , "last_name" ] } " ) "
CONTACT[ NUMBER] = " ${ UPD [ "result" , ${ num } , "message" , "contact" , "phone_number" ] } "
CONTACT[ VCARD] = " $( JsonGetString '"result",' " ${ num } " ',"message","contact","vcard"' <<< " ${ UPDATE } " ) "
2019-05-22 08:01:39 +00:00
fi
2019-04-23 17:00:17 +00:00
2020-12-13 09:10:15 +00:00
# venue, must have a position
if [ -n " ${ UPD [ "result" , ${ num } , "message" , "venue" , "location" , "longitude" ] } " ] ; then
2020-06-15 17:44:46 +00:00
VENUE[ TITLE] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "venue" , "title" ] } " ) "
2019-05-22 16:43:20 +00:00
VENUE[ ADDRESS] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "venue" , "address" ] } " ) "
VENUE[ LONGITUDE] = " ${ UPD [ "result" , ${ num } , "message" , "venue" , "location" , "longitude" ] } "
VENUE[ LATITUDE] = " ${ UPD [ "result" , ${ num } , "message" , "venue" , "location" , "latitude" ] } "
VENUE[ FOURSQUARE] = " ${ UPD [ "result" , ${ num } , "message" , "venue" , "foursquare_id" ] } "
2019-05-22 08:01:39 +00:00
fi
2016-01-17 16:46:24 +00:00
# Caption
2019-05-22 16:43:20 +00:00
CAPTION = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "caption" ] } " ) "
2016-01-17 16:46:24 +00:00
# Location
2019-05-22 16:43:20 +00:00
LOCATION[ LONGITUDE] = " ${ UPD [ "result" , ${ num } , "message" , "location" , "longitude" ] } "
LOCATION[ LATITUDE] = " ${ UPD [ "result" , ${ num } , "message" , "location" , "latitude" ] } "
2019-05-25 15:02:25 +00:00
2020-12-13 07:53:29 +00:00
# service messages, group or channel only!
if [ [ " ${ CHAT [ID] } " = = "-" * ] ] ; then
2020-12-13 09:24:26 +00:00
# new chat member
2020-12-13 08:57:57 +00:00
if [ -n " ${ UPD [ "result" , ${ num } , "message" , "new_chat_member" , "id" ] } " ] ; then
2020-06-15 17:44:46 +00:00
SERVICE[ NEWMEMBER] = " ${ UPD [ "result" , ${ num } , "message" , "new_chat_member" , "id" ] } "
2020-05-14 11:04:57 +00:00
NEWMEMBER[ ID] = " ${ SERVICE [NEWMEMBER] } "
2020-06-17 06:38:44 +00:00
NEWMEMBER[ FIRST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "new_chat_member" , "first_name" ] } " ) "
NEWMEMBER[ LAST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "new_chat_member" , "last_name" ] } " ) "
NEWMEMBER[ USERNAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "new_chat_member" , "username" ] } " ) "
2020-05-14 11:04:57 +00:00
NEWMEMBER[ ISBOT] = " ${ UPD [ "result" , ${ num } , "message" , "new_chat_member" , "is_bot" ] } "
2020-06-29 06:14:39 +00:00
[ -z " ${ MESSAGE [0] } " ] && \
MESSAGE[ 0] = " /_new_chat_member ${ NEWMEMBER [ID] } ${ NEWMEMBER [USERNAME] : = ${ NEWMEMBER [FIRST_NAME] } ${ NEWMEMBER [LAST_NAME] } } "
2020-12-13 07:53:29 +00:00
fi
2020-12-13 09:24:26 +00:00
# left chat member
2020-12-13 08:57:57 +00:00
if [ -n " ${ UPD [ "result" , ${ num } , "message" , "left_chat_member" , "id" ] } " ] ; then
2020-06-15 17:44:46 +00:00
SERVICE[ LEFTMEMBER] = " ${ UPD [ "result" , ${ num } , "message" , "left_chat_member" , "id" ] } "
LEFTMEMBER[ ID] = " ${ SERVICE [LEFTMEBER] } "
2020-06-17 06:38:44 +00:00
LEFTMEMBER[ FIRST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "left_chat_member" , "first_name" ] } " ) "
LEFTMEMBER[ LAST_NAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "left_chat_member" , "last_name" ] } " ) "
LEFTMEBER[ USERNAME] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "left_chat_member" , "username" ] } " ) "
2020-06-15 17:44:46 +00:00
LEFTMEMBER[ ISBOT] = " ${ UPD [ "result" , ${ num } , "message" , "left_chat_member" , "is_bot" ] } "
2020-06-29 06:14:39 +00:00
[ -z " ${ MESSAGE [0] } " ] && \
2020-08-04 06:31:38 +00:00
MESSAGE[ 0] = " /_left_chat_member ${ LEFTMEMBER [ID] } ${ LEFTMEMBER [USERNAME] : = ${ LEFTMEMBER [FIRST_NAME] } ${ LEFTMEMBER [LAST_NAME] } } "
2020-12-13 07:53:29 +00:00
fi
2020-12-13 09:24:26 +00:00
# chat title / photo, check for any of them!
2020-12-13 07:53:29 +00:00
if grep -qs -e '\["result",' " ${ num } " ',"message","new_chat_[tp]' <<< " ${ UPDATE } " ; then
2020-06-17 06:38:44 +00:00
SERVICE[ NEWTITLE] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "new_chat_title" ] } " ) "
2020-06-29 06:14:39 +00:00
[ -z " ${ MESSAGE [0] } " ] && [ -n " ${ SERVICE [NEWTITLE] } " ] && \
MESSAGE[ 0] = " /_new_chat_title ${ USER [ID] } ${ SERVICE [NEWTITLE] } "
2020-06-17 06:38:44 +00:00
SERVICE[ NEWPHOTO] = " $( get_file " ${ UPD [ "result" , ${ num } , "message" , "new_chat_photo" ,0, "file_id" ] } " ) "
2020-06-29 06:14:39 +00:00
[ -z " ${ MESSAGE [0] } " ] && [ -n " ${ SERVICE [NEWPHOTO] } " ] && \
MESSAGE[ 0] = " /_new_chat_photo ${ USER [ID] } ${ SERVICE [NEWPHOTO] } "
2020-12-13 07:53:29 +00:00
fi
2020-12-13 09:24:26 +00:00
# pinned message
if [ -n " ${ UPD [ "result" , ${ num } , "message" , "pinned_message" , "message_id" ] } " ] ; then
2020-12-13 11:00:18 +00:00
SERVICE[ PINNED] = " ${ UPD [ "result" , ${ num } , "message" , "pinned_message" , "message_id" ] } "
2020-06-29 11:29:47 +00:00
PINNED[ ID] = " ${ SERVICE [PINNED] } "
PINNED[ MESSAGE] = " $( JsonDecode " ${ UPD [ "result" , ${ num } , "message" , "pinned_message" , "text" ] } " ) "
2020-12-13 11:00:18 +00:00
[ -z " ${ MESSAGE [0] } " ] && \
2020-06-29 11:29:47 +00:00
MESSAGE[ 0] = " /_new_pinned_message ${ USER [ID] } ${ PINNED [ID] } ${ PINNED [MESSAGE] } "
2020-12-13 07:53:29 +00:00
fi
2020-12-13 11:00:18 +00:00
# migrate to super group
if [ -n " ${ UPD [ "result" , ${ num } , "message" , "migrate_to_chat_id" ] } " ] ; then
MIGRATE[ TO] = " ${ UPD [ "result" , ${ num } , "message" , "migrate_to_chat_id" ] } "
MIGRATE[ FROM] = " ${ UPD [ "result" , ${ num } , "message" , "migrate_from_chat_id" ] } "
SERVICE[ MIGRATE] = " ${ MIGRATE [FROM] } ${ MIGRATE [TO] } "
[ -z " ${ MESSAGE [0] } " ] && \
2020-12-13 11:44:14 +00:00
MESSAGE[ 0] = " /_migrate_group ${ SERVICE [MIGRATE] } "
2020-12-13 11:00:18 +00:00
fi
2020-12-13 07:53:29 +00:00
# set SERVICE to yes if a service message was received
[ [ " ${ SERVICE [*] } " = ~ ^[ [ :blank:] ] *$ ] ] || SERVICE[ 0] = "yes"
2020-05-14 11:04:57 +00:00
fi
2019-05-27 10:27:09 +00:00
# split message in command and args
2020-06-27 16:51:17 +00:00
[ [ " ${ MESSAGE [0] } " = = "/" * ] ] && read -r CMD <<< " ${ MESSAGE [0] } " && CMD[ 0] = " ${ CMD [0]%%@* } "
# everything went well
return 0
2019-05-27 10:27:09 +00:00
}
2019-05-14 13:25:15 +00:00
#########################
2019-04-22 19:05:52 +00:00
# main get updates loop, should never terminate
2020-06-15 08:42:36 +00:00
declare -A BASHBOTBLOCKED
2020-11-29 09:50:05 +00:00
export BASHBOT_UPDATELOG = " ${ BASHBOT_UPDATELOG -nolog } " # allow to be ""
2019-04-22 19:05:52 +00:00
start_bot( ) {
2020-06-30 05:26:16 +00:00
local DEBUGMSG ADMIN OFFSET = 0
2020-06-23 14:35:50 +00:00
# adaptive sleep defaults
2020-06-23 18:57:38 +00:00
local nextsleep = "100"
2020-06-09 14:51:50 +00:00
local stepsleep = " ${ BASHBOT_SLEEP_STEP :- 100 } "
local maxsleep = " ${ BASHBOT_SLEEP :- 5000 } "
2020-06-14 07:10:43 +00:00
# startup message
2020-12-15 19:53:42 +00:00
DEBUGMSG = " Start BASHBOT updates in Mode \" ${ 1 :- normal } \" ========== "
log_update " ${ DEBUGMSG } "
2020-06-09 12:46:45 +00:00
# redirect to Debug.log
2020-06-14 11:57:36 +00:00
[ [ " ${ 1 } " = = *"debug" ] ] && exec & >>" ${ DEBUGLOG } "
2020-12-15 19:53:42 +00:00
log_debug " ${ DEBUGMSG } " ; DEBUGMSG = " ${ 1 } "
2020-11-29 14:57:26 +00:00
[ [ " ${ DEBUGMSG } " = = "xdebug" * ] ] && set -x && unset BASHBOT_UPDATELOG
2020-09-26 19:25:17 +00:00
# cleaup old pipes and empty logfiles
2019-05-28 18:44:40 +00:00
find " ${ DATADIR } " -type p -delete
find " ${ DATADIR } " -size 0 -name "*.log" -delete
2019-05-25 17:31:20 +00:00
# load addons on startup
2019-12-07 12:25:50 +00:00
for addons in " ${ ADDONDIR :- . } " /*.sh ; do
2019-05-25 17:31:20 +00:00
# shellcheck source=./modules/aliases.sh
2020-06-30 05:26:16 +00:00
[ -r " ${ addons } " ] && source " ${ addons } " "startbot" " ${ DEBUGMSG } "
2019-05-25 17:31:20 +00:00
done
2020-05-14 11:04:57 +00:00
# shellcheck source=./commands.sh
source " ${ COMMANDS } " "startbot"
2019-05-29 15:33:31 +00:00
# start timer events
2020-06-09 14:51:50 +00:00
if [ -n " ${ BASHBOT_START_TIMER } " ] ; then
2019-05-29 15:33:31 +00:00
# shellcheck disable=SC2064
2020-06-30 05:26:16 +00:00
trap " event_timer $DEBUGMSG " ALRM
2019-05-29 15:33:31 +00:00
start_timer &
# shellcheck disable=SC2064
trap " kill -9 $! ; exit " EXIT INT HUP TERM QUIT
fi
2020-06-10 07:32:53 +00:00
# cleanup countfile on startup
2020-06-10 07:48:37 +00:00
jssh_deleteKeyDB "CLEAN_COUNTER_DATABASE_ON_STARTUP" " ${ COUNTFILE } "
2020-06-11 10:37:36 +00:00
[ -f " ${ COUNTFILE } .jssh.flock " ] && rm -f " ${ COUNTFILE } .jssh.flock "
2020-08-06 06:34:59 +00:00
# store start time and cleanup botconfig on startup
jssh_updateKeyDB "startup" " $( date) " " ${ BOTCONFIG } "
2020-06-19 10:49:18 +00:00
[ -f " ${ BOTCONFIG } .jssh.flock " ] && rm -f " ${ BOTCONFIG } .jssh.flock "
2020-08-06 06:34:59 +00:00
# read blocked users
2020-06-15 08:42:36 +00:00
jssh_readDB_async "BASHBOTBLOCKED" " ${ BLOCKEDFILE } "
2020-06-15 06:39:52 +00:00
# inform botadmin about start
ADMIN = " $( getConfigKey "botadmin" ) "
2020-06-17 03:44:01 +00:00
[ -n " ${ ADMIN } " ] && send_normal_message " ${ ADMIN } " " Bot $( getConfigKey "botname" ) started ... " &
2020-06-10 07:32:53 +00:00
##########
# bot is ready, start processing updates ...
2019-05-14 11:16:58 +00:00
while true; do
2020-06-09 12:46:45 +00:00
# adaptive sleep in ms rounded to next 0.1 s
2020-06-10 13:56:34 +00:00
sleep " $( _round_float " ${ nextsleep } e-3 " "1" ) "
2020-06-09 12:46:45 +00:00
# get next update
2020-11-29 09:50:05 +00:00
UPDATE = " $( getJson " ${ UPD_URL } ${ OFFSET } " " ${ BASHBOT_UPDATELOG } " 2>/dev/null | " ${ JSONSHFILE } " -b -n 2>/dev/null | iconv -f utf-8 -t utf-8 -c) "
2020-09-26 19:25:17 +00:00
# did we get an response?
2020-06-09 12:46:45 +00:00
if [ -n " ${ UPDATE } " ] ; then
# we got something, do processing
2020-06-12 19:18:32 +00:00
[ " ${ OFFSET } " = "-999" ] && [ " ${ nextsleep } " -gt " $(( maxsleep*2)) " ] && \
2020-06-27 08:43:08 +00:00
log_error "Recovered from timeout/broken/no connection, continue with telegram updates"
2020-06-09 12:46:45 +00:00
# escape bash $ expansion bug
2020-06-12 08:00:52 +00:00
( ( nextsleep += stepsleep , nextsleep = nextsleep>maxsleep ?maxsleep:nextsleep) )
2020-06-09 12:46:45 +00:00
UPDATE = " ${ UPDATE // $/ \\ $} "
# Offset
OFFSET = " $( grep <<< " ${ UPDATE } " '\["result",[0-9]*,"update_id"\]' | tail -1 | cut -f 2) "
( ( OFFSET++) )
if [ " $OFFSET " != "1" ] ; then
nextsleep = "100"
2020-06-30 05:26:16 +00:00
process_updates " ${ DEBUGMSG } "
2020-06-09 12:46:45 +00:00
fi
else
2020-09-26 17:52:06 +00:00
# oops, something bad happened, wait maxsleep*10
2020-06-11 23:17:15 +00:00
( ( nextsleep = nextsleep*2 , nextsleep = nextsleep>maxsleep*10 ?maxsleep*10:nextsleep ) )
2020-12-14 13:00:23 +00:00
# second time, report problem
if [ " ${ OFFSET } " = "-999" ] ; then
log_error " Repeated timeout/broken/no connection on telegram update, sleep $( _round_float " ${ nextsleep } e-3 " ) s "
# try to recover
if _is_function bashbotBlockRecover && [ -z " $( getJson " ${ ME_URL } " ) " ] ; then
log_error "Try to recover, calling bashbotBlockRecover ..."
2020-12-15 19:53:42 +00:00
bashbotBlockRecover >>" ${ ERRORLOG } "
2020-12-14 13:00:23 +00:00
fi
fi
2020-06-11 23:17:15 +00:00
OFFSET = "-999"
2019-04-22 19:05:52 +00:00
fi
done
}
# initialize bot environment, user and permissions
bot_init( ) {
2020-06-08 14:04:45 +00:00
[ -n " ${ BASHBOT_HOME } " ] && cd " ${ BASHBOT_HOME } " || exit 1
2019-05-25 17:31:20 +00:00
local DEBUG = " $1 "
2019-05-14 11:16:58 +00:00
# upgrade from old version
2020-12-26 20:18:18 +00:00
printf "Check for Update actions ...\n"
2019-04-23 16:11:24 +00:00
local OLDTMP = " ${ BASHBOT_VAR :- . } /tmp-bot-bash "
2019-05-28 18:44:40 +00:00
[ -d " ${ OLDTMP } " ] && { mv -n " ${ OLDTMP } / " * " ${ DATADIR } " ; rmdir " ${ OLDTMP } " ; }
2020-05-14 17:47:37 +00:00
# no more existing modules
2019-05-14 11:16:58 +00:00
[ -f "modules/inline.sh" ] && rm -f "modules/inline.sh"
2019-05-25 17:31:20 +00:00
# load addons on startup
2020-12-26 20:18:18 +00:00
printf "Done.\n"
printf "Initialize modules and addons ...\n"
2019-12-07 12:25:50 +00:00
for addons in " ${ ADDONDIR :- . } " /*.sh ; do
2019-05-25 17:31:20 +00:00
# shellcheck source=./modules/aliases.sh
[ -r " ${ addons } " ] && source " ${ addons } " "init" " ${ DEBUG } "
done
2020-12-26 20:18:18 +00:00
printf "Done.\n"
2020-07-09 11:41:09 +00:00
if [ [ ! -d "logs" ] ] ; then
2020-12-26 20:18:18 +00:00
printf "Move Logfiles ...\n"
2020-07-09 20:31:58 +00:00
mkdir logs 2>/dev/null
for MVLOG in DEBUG.log MESSAGE.log ERROR.log BASHBOT.log
do
[ -f " ${ MVLOG } " ] && mv " ${ MVLOG } " logs 2>/dev/null
done
2020-12-26 20:18:18 +00:00
printf "Done.\n"
2020-07-09 11:41:09 +00:00
fi
2020-09-26 17:52:06 +00:00
# setup bashbot
2019-05-19 13:03:44 +00:00
[ [ " ${ UID } " -eq "0" ] ] && RUNUSER = "nobody"
2020-12-26 20:18:18 +00:00
printf " Enter User to run bashbot [ $RUNUSER ]: "
2019-04-22 19:05:52 +00:00
read -r TOUSER
2020-05-14 18:33:30 +00:00
[ -z " $TOUSER " ] && TOUSER = " $RUNUSER "
2019-05-20 08:50:51 +00:00
if ! id " $TOUSER " & >/dev/null; then
2020-12-26 20:18:18 +00:00
printf " ${ RED } User \" $TOUSER \" not found! ${ NN } "
2019-04-22 19:05:52 +00:00
exit 3
else
2019-05-20 13:43:37 +00:00
# shellcheck disable=SC2009
oldbot = " $( ps -fu " $TOUSER " | grep startbot | grep -v -e 'grep' -e '\-startbot' ) "
2020-05-14 18:33:30 +00:00
[ -n " ${ oldbot } " ] && \
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Warning: At least one not upgraded TMUX bot is running! You must stop it with kill command: ${ NN } ${ oldbot } \n "
printf " Adjusting files and permissions for user \" ${ TOUSER } \" ...\n "
2019-05-01 09:46:57 +00:00
[ -w "bashbot.rc" ] && sed -i '/^[# ]*runas=/ s/runas=.*$/runas="' $TOUSER '"/' "bashbot.rc"
2019-04-22 19:05:52 +00:00
chown -R " $TOUSER " . ./*
chmod 711 .
2020-06-01 07:54:35 +00:00
chmod -R o-w ./*
2020-07-09 11:41:09 +00:00
chmod -R u+w " ${ COUNTFILE } " * " ${ BLOCKEDFILE } " * " ${ DATADIR } " " ${ BOTADMIN } " logs " ${ LOGDIR } / " *.log 2>/dev/null
2020-06-01 07:54:35 +00:00
chmod -R o-r,o-w " ${ COUNTFILE } " * " ${ BLOCKEDFILE } " * " ${ DATADIR } " " ${ TOKENFILE } " " ${ BOTADMIN } " " ${ BOTACL } " 2>/dev/null
2019-06-03 14:05:02 +00:00
# jsshDB must writeable by owner
2020-06-19 10:54:05 +00:00
find . -name '*.jssh*' -exec chmod u+w \{ \} +
2020-12-26 20:18:18 +00:00
printf "Done.\n"
2019-04-22 19:05:52 +00:00
fi
2020-12-03 13:52:35 +00:00
# ask to check bottoken online
if [ -z " $( getConfigKey "botid" ) " ] ; then
2020-12-26 20:18:18 +00:00
printf "Seems to be your first init. Should I verify your bot token online? (y/N) N\b"
2020-12-03 13:52:35 +00:00
read -r ANSWER
if [ [ " ${ ANSWER } " = ~ ^[ Yy] ] ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ GREEN } Contacting telegram to verify your bot token ... ${ NN } "
2020-12-03 13:52:35 +00:00
$0 botname
fi
fi
2020-06-25 15:15:49 +00:00
# check if botconf if seems valid
2020-12-26 20:18:18 +00:00
printf " ${ GREEN } This is your bot config: ${ NN } "
2020-06-25 15:15:49 +00:00
sed 's/^/\t/' " ${ BOTCONFIG } .jssh " | grep -vF '["bot_config_key"]'
if [ [ " $( getConfigKey "bottoken" ) " = ~ ^[ 0-9] { 8,10} :[ a-zA-Z0-9_-] { 35} $ && " $( getConfigKey "botadmin" ) " = ~ ^[ 0-9] +$ ] ] ; then
2020-12-26 20:18:18 +00:00
printf "Bot config seems to be valid. Should I make a backup copy? (Y/n) Y\b"
2020-06-25 15:15:49 +00:00
read -r ANSWER
if [ [ -z " ${ ANSWER } " || " ${ ANSWER } " = ~ ^[ ^Nn] ] ] ; then
2020-12-26 20:18:18 +00:00
printf " Copy bot config to ${ BOTCONFIG } .jssh.ok ...\n "
2020-06-27 10:43:46 +00:00
cp " ${ BOTCONFIG } .jssh " " ${ BOTCONFIG } .jssh.ok "
2020-06-25 15:15:49 +00:00
fi
else
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Bot config may not complete, pls check. ${ NN } "
2020-06-25 15:15:49 +00:00
fi
2020-06-10 06:20:48 +00:00
# show result
2020-06-29 09:21:56 +00:00
ls -ld " ${ DATADIR } " " ${ LOGDIR } " ./*.jssh* ./*.sh 2>/dev/null
2019-04-22 19:05:52 +00:00
}
2019-05-26 15:03:58 +00:00
if ! _is_function send_message ; then
2020-12-26 20:18:18 +00:00
printf " ${ RED } ERROR: send_message is not available, did you deactivate ${ MODULEDIR } /sendMessage.sh? ${ NN } "
2019-05-26 15:03:58 +00:00
exit 1
fi
2020-12-15 15:36:27 +00:00
# get location of JSON.sh, download if not exist
2020-06-04 14:10:58 +00:00
JSONSHFILE = " ${ BASHBOT_JSONSH :- ${ SCRIPTDIR } /JSON.sh/JSON.sh } "
2020-12-26 20:18:18 +00:00
[ [ " ${ JSONSHFILE } " != *"/JSON.sh" ] ] && printf " ${ RED } ERROR: \" ${ JSONSHFILE } \" ends not with \"JSONS.sh\". ${ NN } " && exit 3
2019-05-14 13:25:15 +00:00
if [ ! -f " ${ JSONSHFILE } " ] ; then
2020-12-26 20:18:18 +00:00
printf " Seems to be first run, Downloading ${ JSONSHFILE } ...\n "
2020-06-10 06:20:48 +00:00
[ " ${ SCRIPTDIR } /JSON.sh/JSON.sh " = " ${ JSONSHFILE } " ] && \
mkdir " ${ SCRIPTDIR } /JSON.sh " 2>/dev/null && chmod +w " ${ SCRIPTDIR } /JSON.sh "
2019-05-14 13:25:15 +00:00
getJson "https://cdn.jsdelivr.net/gh/dominictarr/JSON.sh/JSON.sh" >" ${ JSONSHFILE } "
chmod +x " ${ JSONSHFILE } "
fi
2019-04-15 10:19:04 +00:00
2020-12-15 15:36:27 +00:00
# check if JSON.awk exist and has x flag
JSONAWKFILE = " ${ JSONSHFILE %.sh } .awk "
if [ -x " ${ JSONAWKFILE } " ] && _exists awk ; then
JSONSHFILE = "JsonAwk" ; JsonAwk( ) { " ${ JSONAWKFILE } " -v "BRIEF=8" -v "STRICT=0" -; }
fi
2016-03-20 21:34:55 +00:00
# source the script with source as param to use functions in other scripts
2019-04-20 14:26:16 +00:00
# do not execute if read from other scripts
2020-06-19 16:47:18 +00:00
if [ -z " ${ SOURCE } " ] ; then
2019-04-22 19:05:52 +00:00
##############
# internal options only for use from bashbot and developers
2020-11-29 14:34:00 +00:00
# shellcheck disable=SC2221,SC2222
2020-06-27 08:29:36 +00:00
case " ${ 1 } " in
2020-09-26 17:52:06 +00:00
# update botname when starting only
2020-06-22 12:10:36 +00:00
"botname" | "start" *)
2020-06-12 19:18:32 +00:00
ME = " $( getBotName) "
if [ -n " ${ ME } " ] ; then
2020-09-26 17:52:06 +00:00
# ok we have a connection and got botname, save it
2020-12-26 20:18:18 +00:00
[ -n " ${ CLEAR } " ] && printf " ${ GREY } Bottoken is valid ... ${ NN } "
2020-06-19 10:49:18 +00:00
jssh_updateKeyDB "botname" " ${ ME } " " ${ BOTCONFIG } "
rm -f " ${ BOTCONFIG } .jssh.flock "
2020-06-12 19:18:32 +00:00
else
2020-12-26 20:18:18 +00:00
printf " ${ GREY } Info: Can't get Botname from Telegram, try cached one ... ${ NN } "
2020-06-12 19:18:32 +00:00
ME = " $( getConfigKey "botname" ) "
if [ -z " $ME " ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ RED } ERROR: No cached botname, can't continue! ... ${ NN } "
2020-06-12 19:18:32 +00:00
exit 1
fi
fi
2020-06-13 07:30:30 +00:00
[ -n " ${ CLEAR } " ] && printf "Bot Name: %s\n" " ${ ME } "
2020-06-12 19:18:32 +00:00
[ " $1 " = "botname" ] && exit
2020-06-12 21:41:47 +00:00
; ; &
2020-06-23 14:35:50 +00:00
# used to send output of background and interactive to chats
2020-06-12 19:18:32 +00:00
"outproc" ) # $2 chat_id $3 identifier of job, internal use only!
2020-12-26 20:18:18 +00:00
[ -z " $3 " ] && printf "No job identifier\n" && exit 3
[ -z " $2 " ] && printf "No chat to send to\n" && exit 3
2020-06-19 10:54:05 +00:00
ME = " $( getConfigKey "botname" ) "
2020-06-12 19:18:32 +00:00
# read until terminated
2019-05-19 15:31:55 +00:00
while read -r line ; do
2020-05-14 18:33:30 +00:00
[ -n " $line " ] && send_message " $2 " " $line "
2019-05-18 18:25:18 +00:00
done
2020-06-12 19:18:32 +00:00
# cleanup datadir, keep logfile if not empty
2019-05-28 18:44:40 +00:00
rm -f -r " ${ DATADIR :- . } / $3 "
[ -s " ${ DATADIR :- . } / $3 .log " ] || rm -f " ${ DATADIR :- . } / $3 .log "
2020-06-27 08:29:36 +00:00
debug_checks "end outproc" " $@ "
2019-04-22 19:05:52 +00:00
exit
; ;
2020-09-26 17:52:06 +00:00
# finally starts the read update loop, internal use only1
2019-04-22 19:05:52 +00:00
"startbot" )
2019-04-22 19:50:38 +00:00
start_bot " $2 "
2020-06-27 08:29:36 +00:00
debug_checks "end startbot" " $@ "
2019-04-22 19:05:52 +00:00
exit
2016-04-16 18:50:05 +00:00
; ;
2020-06-12 19:18:32 +00:00
# run after every update to update files and adjust permissions
"init" )
2019-05-25 17:31:20 +00:00
bot_init " $2 "
2020-06-27 08:29:36 +00:00
debug_checks "end init" " $@ "
2019-04-22 19:05:52 +00:00
exit
; ;
2020-09-26 17:52:06 +00:00
# print usage stats
2020-06-12 21:41:47 +00:00
"stats" )
2020-12-23 20:14:56 +00:00
echo -e " ${ ORANGE } stats deprecated, see bin/bashbot_stats --help ${ NC } "
2020-06-19 10:54:05 +00:00
ME = " $( getConfigKey "botname" ) "
2020-05-29 18:11:51 +00:00
declare -A STATS
2020-06-05 07:01:20 +00:00
jssh_readDB_async "STATS" " ${ COUNTFILE } "
for MSG in ${ !STATS[*] }
do
[ [ ! " ${ MSG } " = ~ ^[ 0-9-] *$ ] ] && continue
( ( USERS++ ) )
done
for MSG in ${ STATS [*] }
do
( ( MESSAGES += MSG ) )
done
2020-07-23 07:14:38 +00:00
if [ " ${ USERS } " != "" ] ; then
echo " A total of ${ MESSAGES } messages from ${ USERS } users are processed. "
else
echo "No one used your bot so far ..."
fi
jssh_readDB_async "STATS" " ${ BLOCKEDFILE } "
for MSG in ${ !STATS[*] }
do
[ [ ! " ${ MSG } " = ~ ^[ 0-9-] *$ ] ] && continue
( ( BLOCKS++ ) )
done
if [ " ${ BLOCKS } " != "" ] ; then
echo -e " Note: ${ BLOCKS } users are blocked by your bot: ${ GREY } "
sort -r " ${ BLOCKEDFILE } .jssh "
echo -e " ${ NC } \c "
fi
2020-08-15 07:42:20 +00:00
# show user created bot stats
_exec_if_function my_bashbot_stats " $@ "
2020-06-27 08:29:36 +00:00
debug_checks " end $1 " " $@ "
2019-04-04 13:25:27 +00:00
exit
2016-04-16 18:50:05 +00:00
; ;
2020-09-26 17:52:06 +00:00
# send message to all users
2020-05-29 18:11:51 +00:00
'broadcast' )
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } Broadcast is a separate command now, see ${ BASHBOT_HOME :- . } /bin/send_broadcast.sh --help ${ NN } "
2020-12-17 07:58:32 +00:00
" ${ BASHBOT_HOME :- . } " /bin/send_broadcast.sh --help
2020-05-29 18:11:51 +00:00
exit
2016-04-16 18:50:05 +00:00
; ;
2020-09-26 17:52:06 +00:00
# does what it says
2019-05-19 13:03:44 +00:00
"status" )
2020-06-19 10:54:05 +00:00
ME = " $( getConfigKey "botname" ) "
SESSION = " ${ ME :- _bot } -startbot "
BOTPID = " $( proclist " ${ SESSION } " ) "
2020-05-14 18:33:30 +00:00
if [ -n " ${ BOTPID } " ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ GREEN } Bot is running with UID ${ RUNUSER } . ${ NN } "
2019-05-19 13:03:44 +00:00
exit
else
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } No Bot running with UID ${ RUNUSER } . ${ NN } "
2019-05-19 13:03:44 +00:00
exit 5
fi
2020-06-27 08:29:36 +00:00
debug_checks "end status" " $@ "
2019-05-19 13:03:44 +00:00
; ;
2020-09-26 17:52:06 +00:00
# start bot as background job and check if bot is running
2016-04-17 12:13:28 +00:00
"start" )
2020-06-19 10:54:05 +00:00
# shellcheck disable=SC2086
SESSION = " ${ ME :- _bot } -startbot "
BOTPID = " $( proclist " ${ SESSION } " ) "
2019-05-19 13:03:44 +00:00
# shellcheck disable=SC2086
2020-05-14 18:33:30 +00:00
[ -n " ${ BOTPID } " ] && kill ${ BOTPID }
2019-05-19 13:03:44 +00:00
nohup " $SCRIPT " "startbot" " $2 " " ${ SESSION } " & >/dev/null &
2020-06-12 19:18:32 +00:00
printf "Session Name: %s\n" " ${ SESSION } "
sleep 1
2020-05-14 18:33:30 +00:00
if [ -n " $( proclist " ${ SESSION } " ) " ] ; then
2020-12-26 20:18:18 +00:00
printf " ${ GREEN } Bot started successfully. ${ NN } "
2019-05-19 13:03:44 +00:00
else
2020-12-26 20:18:18 +00:00
printf " ${ RED } An error occurred while starting the bot. ${ NN } "
2019-05-19 13:03:44 +00:00
exit 5
fi
2020-06-27 08:29:36 +00:00
debug_checks "end start" " $@ "
2016-04-17 12:13:28 +00:00
; ;
2020-06-12 19:18:32 +00:00
# does what it says
"stop" )
2020-06-19 10:54:05 +00:00
ME = " $( getConfigKey "botname" ) "
SESSION = " ${ ME :- _bot } -startbot "
BOTPID = " $( proclist " ${ SESSION } " ) "
2020-05-14 18:33:30 +00:00
if [ -n " ${ BOTPID } " ] ; then
2019-05-19 13:03:44 +00:00
# shellcheck disable=SC2086
if kill ${ BOTPID } ; then
2020-06-15 18:07:43 +00:00
# inform botadmin about stop
ADMIN = " $( getConfigKey "botadmin" ) "
2020-06-19 15:39:53 +00:00
[ -n " ${ ADMIN } " ] && send_normal_message " ${ ADMIN } " " Bot ${ ME } stopped ... " &
2020-12-26 20:18:18 +00:00
printf " ${ GREEN } OK. Bot stopped successfully. ${ NN } "
2019-05-19 13:03:44 +00:00
else
2020-12-26 20:18:18 +00:00
printf " ${ RED } An error occurred while stopping bot. ${ NN } "
2019-05-19 13:03:44 +00:00
exit 5
fi
2020-06-12 21:41:47 +00:00
else
2020-12-26 20:18:18 +00:00
printf " ${ ORANGE } No Bot running with UID ${ RUNUSER } . ${ NN } "
2019-05-19 13:03:44 +00:00
fi
2020-06-27 08:29:36 +00:00
debug_checks "end stop" " $@ "
2019-05-19 13:03:44 +00:00
exit
2019-03-25 10:15:07 +00:00
; ;
2020-06-23 14:35:50 +00:00
# suspend, resume or kill background jobs
2020-06-12 19:18:32 +00:00
"suspendb" *| "resumeb" *| "killb" *)
2020-12-26 20:18:18 +00:00
_is_function job_control || { printf " ${ RED } Module background is not available! ${ NN } " ; exit 3; }
2020-06-22 12:10:36 +00:00
ME = " $( getConfigKey "botname" ) "
2019-05-20 19:40:14 +00:00
job_control " $1 "
2020-06-27 08:29:36 +00:00
debug_checks " end background $1 " " $@ "
2019-03-18 21:19:44 +00:00
; ;
2016-04-19 09:49:35 +00:00
*)
2020-12-26 20:18:18 +00:00
printf " ${ RED } ${ REALME ##*/ } : unknown command ${ NN } "
printf " ${ RED } Available commands: ${ GREY } ${ BOTCOMMANDS } ${ NN } " && exit
2019-05-23 17:40:15 +00:00
exit 4
2016-04-17 12:13:28 +00:00
; ;
2019-04-20 14:26:16 +00:00
esac
2016-06-05 10:41:49 +00:00
2019-04-20 14:26:16 +00:00
# warn if root
2019-05-19 13:03:44 +00:00
if [ [ " ${ UID } " -eq "0" ] ] ; then
2020-12-26 20:18:18 +00:00
printf " \\n ${ ORANGE } WARNING: ${ SCRIPT } was started as ROOT (UID 0)! ${ NN } "
printf " ${ ORANGE } You are at HIGH RISK when running a Telegram BOT with root privileges! ${ NN } "
2019-04-20 14:26:16 +00:00
fi
fi # end source