2016-01-02 19:35:15 +00:00
#!/bin/bash
2020-12-27 13:53:00 +00:00
##################################################################
#
# File: bashbot.sh
# Note: DO NOT EDIT! this file will be overwritten on update
2021-01-01 20:36:48 +00:00
# shellcheck disable=SC2140,SC2031,SC2120,SC1091,SC1117,SC2059
#
# Description: bashbot, the Telegram bot written in bash.
2019-03-28 15:51:33 +00:00
#
2020-12-27 13:53:00 +00:00
# Written by Drew (@topkecleon) KayM (@gnadelwartz).
2021-01-02 09:18:58 +00:00
# Also contributed: Daniil Gentili (@danog), JuanPotato, BigNerd95,
# TiagoDanin, iicc1, dcoomber
2020-12-27 13:53:00 +00:00
# https://github.com/topkecleon/telegram-bot-bash
#
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
2019-04-01 10:52:25 +00:00
#
2021-01-15 18:05:53 +00:00
# Usage: bashbot.sh BOTCOMMAND
2021-01-09 06:46:46 +00:00
BOTCOMMANDS = "-h help init start stop status suspendback resumeback killback"
2021-01-01 20:36:48 +00:00
#
2019-04-01 10:52:25 +00:00
# Exit Codes:
2020-12-27 13:53:00 +00:00
# 0 - success (hopefully)
# 1 - can't change to dir
# 2 - can't write to tmp, count or token
# 3 - user / command / file not found
# 4 - unknown command
2021-01-01 18:56:19 +00:00
# 5 - cannot start, stop or get status
2020-12-27 13:53:00 +00:00
# 6 - mandatory module not found
# 7 - can't get bottoken
# 8 - curl/wget missing
# 10 - not bash!
#
2021-01-24 12:04:20 +00:00
#### $$VERSION$$ v1.35-dev-2-g1fe22a0
2020-12-27 13:53:00 +00:00
##################################################################
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
2021-01-01 21:00:46 +00:00
printf "Error: Current shell does not support ARRAY's, may be busybox 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"
2021-01-04 22:08:09 +00:00
if [ -t 1 ] && [ -n " ${ TERM } " ] ; then
2020-12-27 10:26:38 +00:00
INTERACTIVE = 'yes'
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-27 11:38:52 +00:00
NN = " ${ NC } \n "
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
2021-01-01 16:14:59 +00:00
if [ " $( { LC_ALL = C.utf-8 printf "%b" "\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
2021-01-04 15:03:53 +00:00
# in UTF-8 äöü etc. are part of [:alnum:] and ranges (e.g. a-z), but we want ASCII a-z ranges!
# for more information see doc/4_expert.md#Character_classes
azazaz = 'abcdefghijklmnopqrstuvwxyz' # a-z :lower:
AZAZAZ = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' # A-Z :upper:
2021-01-04 15:10:43 +00:00
o9o9o9 = '0123456789' # 0-9 :digit:
2021-01-04 15:03:53 +00:00
azAZaz = " ${ azazaz } ${ AZAZAZ } " # a-zA-Z :alpha:
2021-01-04 15:10:43 +00:00
azAZo9 = " ${ azAZaz } ${ o9o9o9 } " # a-zA-z0-9 :alnum:
2021-01-04 15:03:53 +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( ) {
2021-01-05 15:17:34 +00:00
[ " $( type -t " $1 " ) " = "file" ]
2020-05-14 19:31:52 +00:00
}
# execute function if exists
_exec_if_function( ) {
2021-01-05 15:17:34 +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( ) {
2021-01-05 15:17:34 +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( ) {
2021-01-05 15:17:34 +00:00
local digit = " $2 " ; [ [ " $2 " = ~ ^[ ${ o9o9o9 } ] +$ ] ] || digit = "0"
2021-01-18 20:09:30 +00:00
: " $( LC_ALL = C printf " %. ${ digit } f " " $1 " 2>/dev/null) "
2021-01-20 18:50:19 +00:00
printf "%s" " ${ _ //,/. } " # make more LANG independent
2020-05-14 19:31:52 +00:00
}
2021-01-06 07:48:25 +00:00
# date is external, printf is much faster
_date( ) {
printf "%(%c)T\n" -1
}
2020-06-13 19:39:52 +00:00
setConfigKey( ) {
2021-01-04 15:10:43 +00:00
[ [ " $1 " = ~ ^[ -${ azAZo9 } ,._] +$ ] ] || 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( ) {
2021-01-04 15:10:43 +00:00
[ [ " $1 " = ~ ^[ -${ azAZo9 } ,._] +$ ] ] || return 3
2021-01-16 10:20:29 +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
}
2021-01-23 13:06:55 +00:00
# escape / remove text characters for json strings, eg. " -> \"
# $1 string
# output escaped string
JsonEscape( ) {
sed 's/\([-"`´ ,§$%&/(){}#@!?*.\t]\)/\\\1/g' <<< " $1 "
}
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( ) {
2021-01-05 15:17:34 +00:00
[ [ " $1 " = ~ ^[ ${ o9o9o9 } ] { 8,10} :[ ${ azAZo9 } _-] { 35} $ ] ] && return 0
2020-06-27 08:29:36 +00:00
return 1
}
2020-12-30 09:03:23 +00:00
# log $1 with date
2021-01-06 14:33:07 +00:00
log_error( ) { printf "%(%c)T: %s\n" -1 " $* " >>" ${ ERRORLOG } " ; }
log_debug( ) { printf "%(%c)T: %s\n" -1 " $* " >>" ${ DEBUGLOG } " ; }
log_update( ) { printf "%(%c)T: %s\n" -1 " $* " >>" ${ UPDATELOG } " ; }
2020-12-30 09:07:10 +00:00
# log $1 with date, special first \n
2021-01-06 14:33:07 +00:00
log_message( ) { printf "\n%(%c)T: %s\n" -1 " ${ 1 / \\ n / $'\n' } " >>" ${ MESSAGELOG } " ; }
2021-01-14 21:15:32 +00:00
# curl is preferred, try detect curl even not in PATH
# sets BASHBOT_CURL to point to curl
DETECTED_CURL = "curl"
detect_curl( ) {
local file warn = "Warning: Curl not detected, try fallback to wget! pls install curl or adjust BASHBOT_CURL/BASHBOT_WGET environment variables."
# custom curl command
[ -n " ${ BASHBOT_CURL } " ] && return 0
# use wget
[ -n " ${ BASHBOT_WGET } " ] && DETECTED_CURL = "wget" && return 1
# default use curl in PATH
BASHBOT_CURL = "curl"
_exists curl && return 0
# search in usual locations
for file in /usr/bin /bin /usr/local/bin; do
[ -x " ${ file } /curl " ] && BASHBOT_CURL = " ${ file } /curl " && return 0
done
# curl not in PATH and not in usual locations
DETECTED_CURL = "wget"
log_update " ${ warn } " ; [ -n " ${ BASHBOTDEBUG } " ] && log_debug " ${ warn } "
return 1
}
2020-12-27 13:53:00 +00:00
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
[ [ " ${ BASH_ARGV [0] } " = = *"debug" * ] ] && BASHBOTDEBUG = "yes"
2020-12-27 13:53:00 +00:00
2020-07-10 06:39:33 +00:00
# $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
2021-01-15 12:09:32 +00:00
local token where = " $1 " ; shift
2021-01-06 14:33:07 +00:00
printf "%(%c)T: debug_checks: %s: bashbot.sh %s\n" -1 " ${ where } " " ${ 1 ##*/ } "
2020-07-11 06:34:57 +00:00
# shellcheck disable=SC2094
2021-01-06 14:33:07 +00:00
[ -z " ${ DEBUGLOG } " ] && printf "%(%c)T: %s\n" -1 "DEBUGLOG not set! =========="
2021-01-06 07:48:25 +00:00
token = " $( getConfigKey "bottoken" ) "
2021-01-06 14:33:07 +00:00
[ -z " ${ token } " ] && printf "%(%c)T: %s\n" -1 "Bot token is missing! =========="
check_token " ${ token } " || printf "%(%c)T: %s\n%s\n" -1 "Invalid bot token! ==========" " ${ token } "
[ -z " $( getConfigKey "botadmin" ) " ] && printf "%(%c)T: %s\n" -1 "Bot admin is missing! =========="
2020-07-02 15:24:56 +00:00
# call user defined debug_checks if exists
2021-01-06 07:48:25 +00:00
_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
2021-01-02 05:17:02 +00:00
# some Linux distributions (e.g. Manjaro) doesn't seem to have C locale activated by default
2021-01-03 21:39:36 +00:00
if _exists locale && [ " $( locale -a | grep -c -e " ^C $" -e "^C.[uU][tT][fF]" ) " -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
2021-01-01 20:48:59 +00:00
[ [ " ${ SCRIPT } " != " ${ REALME } " || " $1 " = = "source" ] ] && SOURCE = "yes"
2019-05-23 10:26:53 +00:00
2021-01-04 22:08:09 +00:00
if [ -n " ${ BASHBOT_HOME } " ] ; then
SCRIPTDIR = " ${ BASHBOT_HOME } "
2020-06-04 14:10:58 +00:00
else
BASHBOT_HOME = " ${ SCRIPTDIR } "
2019-05-23 10:26:53 +00:00
fi
2021-01-04 22:08:09 +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 "
2021-01-20 18:50:19 +00:00
RUNUSER = " ${ USER } " # USER is overwritten by bashbot array :-(, save original
2019-03-31 10:52:11 +00:00
2021-01-01 20:36:48 +00:00
# provide help
case " $1 " in
2021-01-08 21:32:05 +00:00
"" ) [ -z " ${ SOURCE } " ] && printf " ${ ORANGE } Available commands: ${ GREY } ${ BOTCOMMANDS } ${ NN } " && exit
2021-01-01 23:40:42 +00:00
; ;
2021-01-09 21:25:15 +00:00
"-h" *) LOGO = " ${ BASHBOT_HOME :- . } /doc/bashbot.ascii "
2021-01-15 18:05:53 +00:00
{ [ -r " ${ LOGO } " ] && cat " ${ LOGO } "
2021-01-16 10:20:29 +00:00
sed -nE -e '/(NOT EDIT)|(shellcheck)/d' -e '3,/###/p' " $0 " ; } | more
2021-01-01 20:36:48 +00:00
exit; ;
"help" ) HELP = " ${ BASHBOT_HOME :- . } /README "
if [ -n " ${ INTERACTIVE } " ] ; then
2021-01-04 22:08:09 +00:00
_exists w3m && w3m " ${ HELP } .html " && exit
_exists lynx && lynx " ${ HELP } .html " && exit
_exists less && less " ${ HELP } .txt " && exit
2021-01-01 20:36:48 +00:00
fi
2021-01-04 22:08:09 +00:00
cat " ${ HELP } .txt "
2021-01-01 20:36:48 +00:00
exit; ;
esac
2020-12-27 13:53:00 +00:00
# OK, ENVIRONMENT is set up, let's do some additional tests
2021-01-04 22:08:09 +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-03-22 16:47:36 +00:00
fi
2021-01-01 23:11:23 +00:00
RUNDIR = "."
[ ! -w "." ] && printf " ${ ORANGE } WARNING: ${ RUNDIR } is not writeable! ${ NN } "
2019-03-18 13:45:19 +00:00
2020-12-27 13:53:00 +00:00
# check if JSON.sh is available
JSONSHFILE = " ${ BASHBOT_JSONSH :- ${ SCRIPTDIR } /JSON.sh/JSON.sh } "
[ ! -x " ${ JSONSHFILE } " ] && \
2021-01-01 20:40:51 +00:00
printf " ${ RED } ERROR: ${ NC } ${ JSONSHFILE } ${ RED } does not exist, are we in dev environment? ${ NN } ${ GREY } %s ${ NN } \n " \
2021-01-01 23:11:23 +00:00
"\$JSONSHFILE is set wrong or bashbot is not installed correctly, see doc/0_install.md" && exit 3
2020-12-27 13:53:00 +00:00
# file locations based on ENVIRONMENT
2020-06-19 10:49:18 +00:00
BOTCONFIG = " ${ BASHBOT_ETC :- . } /botconfig "
2020-05-14 18:33:30 +00:00
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-12-27 13:53:00 +00:00
# CREATE botconfig if not exist
2020-08-01 09:37:32 +00:00
# assume everything already set up correctly if TOKEN is set
2021-01-01 18:01:26 +00:00
if [ -z " ${ BOTTOKEN } " ] ; then
2020-06-19 10:54:05 +00:00
# BOTCONFIG does not exist, create
2021-01-01 18:01:26 +00:00
[ ! -f " ${ BOTCONFIG } .jssh " ] && printf '["bot_config_key"]\t"config_key_value"\n' >>" ${ BOTCONFIG } .jssh "
if [ -z " $( getConfigKey "bottoken" ) " ] ; then
# ask user for bot token
if [ -z " ${ INTERACTIVE } " ] && [ " $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
2021-01-01 18:01:26 +00:00
else
2021-01-01 20:48:59 +00:00
printf " ${ RED } ENTER BOT TOKEN... ${ NN } ${ 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-12-27 11:51:19 +00:00
printf "\n"
2021-01-01 18:01:26 +00:00
fi
[ -n " ${ token } " ] && printf '["bottoken"]\t"%s"\n' " ${ token } " >> " ${ BOTCONFIG } .jssh "
2020-05-14 18:33:30 +00:00
fi
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-12-27 13:58:34 +00:00
# ask user for bot admin
if [ -z " ${ INTERACTIVE } " ] ; 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
2021-01-01 20:48:59 +00:00
printf " ${ RED } ENTER BOT ADMIN... ${ NN } ${ ORANGE } PLEASE WRITE YOUR TELEGRAM ID HERE OR PRESS ENTER\nTO MAKE FIRST USER TYPING '/start' BOT ADMIN ${ NN } ?\b "
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-27 20:17:39 +00:00
printf " ${ GREY } Create initial ${ BOTACL } file. ${ NN } "
2019-05-20 08:50:51 +00:00
printf '\n' >" ${ BOTACL } "
2020-05-14 18:33:30 +00:00
fi
2021-01-01 18:01:26 +00:00
# check data dir file
if [ ! -w " ${ DATADIR } " ] ; then
2021-01-01 18:25:25 +00:00
printf " ${ RED } ERROR: ${ DATADIR } does not exist or is not writeable!. ${ NN } "
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-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-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-27 12:12:38 +00:00
mv " ${ BOTCONFIG } .jssh " " ${ BOTCONFIG } .jssh.bad "
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-27 12:12:38 +00:00
printf " \n ${ RED } Error: Can't recover from missing bot token! Remove ${ BOTCONFIG } .jssh and run ${ NC } bashbot.sh init\n "
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
2021-01-01 20:55:13 +00:00
printf " \n ${ ORANGE } Warning: Your bot token is incorrect, it should have the following format: ${ NC } \n%b%b " \
" <your_bot_id> ${ RED } : ${ NC } <35_alphanumeric_characters-hash> ${ RED } e.g. => ${ NC } 123456789 ${ RED } : ${ NC } Aa-Zz_0Aa-Zz_1Aa-Zz_2Aa-Zz_3Aa-Zz_4\n\n " \
" ${ GREY } Your bot token: ' ${ NC } ${ BOTTOKEN // : / ${ RED } : ${ NC } } '\n "
2020-12-27 11:34:39 +00:00
2021-01-04 15:10:43 +00:00
if [ [ ! " ${ BOTTOKEN } " = ~ ^[ ${ o9o9o9 } ] { 8,10} : ] ] ; then
2021-01-01 20:55:13 +00:00
printf " ${ GREY } \tHint: Bot id not a number or wrong len: ${ NC } $(( $( wc -c <<< " ${ BOTTOKEN % : * } " ) - 1 )) ${ GREY } but should be ${ NC } 8-10\n "
2020-12-27 11:34:39 +00:00
[ -n " $( getConfigKey "botid" ) " ] && printf " \t ${ GREEN } Did you mean: \" ${ NC } $( getConfigKey "botid" ) ${ GREEN } \" ? ${ NN } "
2020-12-05 13:11:21 +00:00
fi
2021-01-04 15:10:43 +00:00
[ [ ! " ${ BOTTOKEN } " = ~ :[ ${ azAZo9 } _-] { 35} $ ] ] && \
2021-01-01 20:55:13 +00:00
printf " ${ GREY } \tHint: Hash contains invalid character or has not len ${ NC } 35 ${ GREY } , hash len is ${ NC } $(( $( wc -c <<< " ${ BOTTOKEN #* : } " ) - 1 )) \n "
2020-12-27 11:34:39 +00:00
printf "\n"
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-05-14 18:33:30 +00:00
##################
# here we start with the real stuff
2021-01-20 18:50:19 +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 } "
2021-01-04 22:08:09 +00:00
ME_URL = ${ URL } '/getMe'
2019-04-12 18:49:58 +00:00
2020-06-12 19:18:32 +00:00
#################
# BASHBOT COMMON functions
2020-12-31 17:02:31 +00:00
declare -rx SCRIPT SCRIPTDIR MODULEDIR RUNDIR ADDONDIR BOTACL DATADIR COUNTFILE
2021-01-14 16:47:06 +00:00
declare -rx BOTTOKEN URL ME_URL
2019-05-28 19:12:02 +00:00
2019-05-28 18:50:19 +00:00
declare -ax CMD
2021-01-24 09:28:04 +00:00
declare -Ax UPD BOTSENT USER MESSAGE URLS CONTACT LOCATION CHAT FORWARD REPLYTO VENUE iQUERY iBUTTON
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
2021-01-20 17:20:03 +00:00
###############
# load modules
for module in " ${ MODULEDIR :- . } " /*.sh ; do
# shellcheck source=./modules/aliases.sh
if ! _is_function " $( basename " ${ module } " ) " && [ -r " ${ module } " ] ; then source " ${ module } " "source" ; fi
done
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 "
2021-01-01 23:11:23 +00:00
if [ -r " ${ COMMANDS } " ] ; then
# shellcheck source=./commands.sh
source " ${ COMMANDS } " "source"
else
[ -z " ${ SOURCE } " ] && printf " ${ RED } Warning: ${ COMMANDS } does not exist or is not readable!. ${ NN } "
2019-05-10 09:33:41 +00:00
fi
2021-01-06 07:48:25 +00:00
debug_checks " start SOURCE= ${ SOURCE :- no } " " $@ "
2019-05-10 09:33:41 +00:00
2020-06-10 06:20:48 +00:00
#####################
# BASHBOT INTERNAL functions
#
2020-06-12 19:18:32 +00:00
# do we have BSD sed
2021-01-01 23:11:23 +00:00
sed '1ia' </dev/null 2>/dev/null || printf " ${ ORANGE } Warning: You may run on a BSD style system without gnu utils ... ${ NN } "
2020-06-10 06:20:48 +00:00
#jsonDB is now mandatory
2021-01-01 23:32:32 +00:00
if ! _is_function jssh_newDB; then
printf " ${ RED } ERROR: Mandatory module jsonDB is missing or not readable! ${ NN } "
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 } } "
2021-01-04 22:08:09 +00:00
if [ [ " ${ file } " = *"/" * ] ] || [ [ " ${ file } " = "." * ] ] ; then file = " ${ empty } " ; fi
while [ -f " ${ DATADIR :- . } / ${ file } " ] ; do file = " ${ RANDOM } - ${ file } " ; done
2019-05-28 18:44:40 +00:00
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
2021-01-05 15:17:34 +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
2021-01-04 22:08:09 +00:00
declare -xr DELETE_URL = ${ URL } '/deleteMessage'
2019-03-11 14:41:21 +00:00
delete_message( ) {
2021-01-05 15:17:34 +00:00
[ -z " $3 " ] && log_update " Delete Message CHAT= $1 MSG_ID= $2 "
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
2021-01-14 18:49:01 +00:00
sendJson "" '"file_id": "' " $1 " '"' " ${ URL } /getFile "
2021-01-19 16:47:15 +00:00
printf "%s\n" " ${ URL } / ${ UPD [ "result,file_path" ] } "
2019-05-14 13:25:15 +00:00
}
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
2021-01-04 22:08:09 +00:00
TIMEOUT = " ${ BASHBOT_TIMEOUT :- 20 } "
[ [ " ${ TIMEOUT } " = ~ ^[ ${ o9o9o9 } ] +$ ] ] || TIMEOUT = "20"
2019-05-23 17:40:15 +00:00
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 = ""
2021-01-05 15:17:34 +00:00
if [ -n " $1 " ] ; then
chat = '"chat_id":' " $1 " ','
2021-01-20 18:50:19 +00:00
[ [ " $1 " = = *[ !${ o9o9o9 } -] * ] ] && 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
2021-01-05 15:17:34 +00:00
res = " $( sendJson_do " ${ json } " " $3 " ) "
2020-12-15 09:40:20 +00:00
# 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"
2021-01-14 16:47:06 +00:00
# $1 URL, $2 hack: log getJson if not ""
2020-12-15 09:40:20 +00:00
getJson( ) {
# 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 } " \
2021-01-05 15:17:34 +00:00
-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
2021-01-05 21:01:32 +00:00
[ -n " ${ BASHBOTDEBUG } " ] && \
log_update " sendUpload CHAT= $1 WHAT= $2 FILE= $3 CAPT= $5 "
# 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
2021-01-05 21:01:32 +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( ) {
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
2021-01-05 15:17:34 +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( ) {
2021-01-05 15:17:34 +00:00
local retry = " $1 " ; shift
[ [ " $1 " = ~ ^\ *[ ${ o9o9o9 } .] +\ *$ ] ] && sleep " $1 " ; shift
2021-01-06 14:33:07 +00:00
printf "%(%c)T: RETRY %s %s %s\n" -1 " ${ 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
2021-01-05 15:17:34 +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 = ( )
2021-01-15 18:26:04 +00:00
Json2Array 'UPD' <<< " $1 "
2020-12-15 19:53:42 +00:00
[ -n " ${ BASHBOTDEBUG } " ] && log_message " New Result ==========\n $1 "
2021-01-15 18:26:04 +00:00
BOTSENT[ OK] = " ${ UPD [ "ok" ] } "
2020-06-08 10:58:36 +00:00
if [ " ${ BOTSENT [OK] } " = "true" ] ; then
2021-01-19 16:47:15 +00:00
BOTSENT[ ID] = " ${ UPD [ "result,message_id" ] } "
BOTSENT[ CHAT] = " ${ UPD [ "result,chat,id" ] } "
2021-01-15 18:26:04 +00:00
[ -n " ${ UPD [ "result" ] } " ] && BOTSENT[ RESULT] = " ${ UPD [ "result" ] } "
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!
2021-01-06 14:33:07 +00:00
if [ -n " $1 " ] ; then
2021-01-15 18:26:04 +00:00
BOTSENT[ ERROR] = " ${ UPD [ "error_code" ] } "
BOTSENT[ DESCRIPTION] = " ${ UPD [ "description" ] } "
2021-01-19 16:47:15 +00:00
[ -n " ${ UPD [ "parameters,retry_after" ] } " ] && BOTSENT[ RETRY] = " ${ UPD [ "parameters,retry_after" ] } "
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]%* } "
2021-01-06 14:33:07 +00:00
printf "%(%c)T: RESULT=%s FUNC=%s CHAT[ID]=%s ERROR=%s DESC=%s ACTION=%s\n" -1\
2021-01-05 15:17:34 +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] )) "
2021-01-05 15:17:34 +00:00
printf "Retry %s in %s seconds ...\n" " $2 " " ${ BASHBOT_RETRY } "
sendJsonRetry " $2 " " ${ BASHBOT_RETRY } " " ${ @ : 3 } "
2020-09-26 17:52:06 +00:00
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
2021-01-06 14:33:07 +00:00
printf "%(%c)T: BASHBOT IP Address seems blocked!\n" -1
2020-09-26 17:52:06 +00:00
# user provided function to recover or notify block
if _exec_if_function bashbotBlockRecover; then
BASHBOT_RETRY = "2"
2021-01-05 15:17:34 +00:00
printf "bashbotBlockRecover returned true, retry %s ...\n" " $2 "
sendJsonRetry " $2 " " ${ BASHBOT_RETRY } " " ${ @ : 3 } "
2020-09-26 17:52:06 +00:00
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" \
2021-01-05 15:17:34 +00:00
" ${ BASHBOT_CURL } " " ${ BASHBOT_CURL_ARGS } " " $2 "
2020-09-26 17:52:06 +00:00
BASHBOT_RETRY = "2" ; BASHBOT_CURL = "curl" ; BASHBOT_CURL_ARGS = ""
2021-01-05 15:17:34 +00:00
sendJsonRetry " $2 " " ${ BASHBOT_RETRY } " " ${ @ : 3 } "
2020-09-26 17:52:06 +00:00
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
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
2021-01-04 22:08:09 +00:00
Json2Array 'BOTARRAY' <<< " $( getJson " ${ ME_URL } " | " ${ JSONSHFILE } " -b -n 2>/dev/null) "
2020-12-03 19:43:20 +00:00
[ -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( ) {
2021-01-15 12:09:32 +00:00
local remain U out = " $1 "
2019-05-14 15:56:23 +00:00
local regexp = '(.*)\\u[dD]([0-9a-fA-F]{3})\\u[dD]([0-9a-fA-F]{3})(.*)'
2021-01-04 22:08:09 +00:00
while [ [ " ${ out } " = ~ ${ regexp } ] ] ; do
2020-09-26 17:52:06 +00:00
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
2021-01-15 12:09:32 +00:00
printf "%b\n" " ${ out } ${ remain } "
2019-05-14 15:56:23 +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
2021-01-04 22:08:09 +00:00
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
2021-01-24 09:28:04 +00:00
if [ -n " ${ iQUERY [ID] } " ] ; then
process_inline_query " ${ num } " " ${ debug } "
printf "%(%c)T: Inline Query update received FROM=%s iQUERY=%s\n" -1\
" ${ iQUERY [USERNAME] : 0 : 20 } ( ${ iQUERY [USER_ID] } ) " " ${ iQUERY [0] } " >>" ${ UPDATELOG } "
elif [ -n " ${ iBUTTON [ID] } " ] ; then
process_inline_button " ${ num } " " ${ debug } "
2021-01-24 12:04:20 +00:00
printf "%(%c)T: Inline Button update received FROM=%s CHAT=%s CALLBACK=%s DATA:%s \n" -1\
" ${ iBUTTON [USERNAME] : 0 : 20 } ( ${ iBUTTON [USER_ID] } ) " " ${ iBUTTON [CHAT_ID] } " " ${ iBUTTON [ID] } " " ${ iBUTTON [DATA] } " >>" ${ UPDATELOG } "
2021-01-24 09:28:04 +00:00
else
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 } "
2021-01-06 14:33:07 +00:00
printf "%(%c)T: update received FROM=%s CHAT=%s CMD=%s\n" -1 " ${ 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
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
}
2021-01-04 22:08:09 +00:00
declare -Ax BASHBOT_EVENT_INLINE BASHBOT_EVENT_MESSAGE BASHBOT_EVENT_CMD BASHBOT_EVENT_REPLYTO BASHBOT_EVENT_FORWARD BASHBOT_EVENT_SEND
2020-09-06 16:54:50 +00:00
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
2021-01-04 22:08:09 +00:00
( ( EVENT_SEND++ ) ) ; [ " ${ EVENT_SEND } " -gt "5" ] && return
2019-06-04 16:04:52 +00:00
# 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 ##*, } "
2021-01-04 22:08:09 +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( ) {
2021-01-05 15:17:34 +00:00
local num = " $1 "
2020-06-29 09:21:56 +00:00
# unset everything to not have old values
2021-01-24 09:28:04 +00:00
CMD = ( ) ; iQUERY = ( ) ; iBUTTON = ( ) ; MESSAGE = ( ) ; CHAT = ( ) ; USER = ( ) ; CONTACT = ( ) ; LOCATION = ( ) ; unset CAPTION
2020-12-13 11:00:18 +00:00
REPLYTO = ( ) ; FORWARD = ( ) ; URLS = ( ) ; VENUE = ( ) ; SERVICE = ( ) ; NEWMEMBER = ( ) ; LEFTMEMBER = ( ) ; PINNED = ( ) ; MIGRATE = ( )
2021-01-19 16:47:15 +00:00
iQUERY[ ID] = " ${ UPD [ " result, ${ num } ,inline_query,id " ] } "
2021-01-24 12:04:20 +00:00
iBUTTON[ ID] = " ${ UPD [ " result, ${ num } ,callback_query,id " ] } "
2021-01-19 16:47:15 +00:00
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 " ] } "
2020-06-29 09:21:56 +00:00
# always true
return 0
}
2021-01-24 09:28:04 +00:00
process_inline_query( ) {
2021-01-05 15:17:34 +00:00
local num = " $1 "
2021-01-19 16:47:15 +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
}
2021-01-24 09:28:04 +00:00
process_inline_button( ) {
2021-01-24 11:30:56 +00:00
# debugging for impelemetation
2021-01-24 09:28:04 +00:00
local num = " $1 "
2021-01-24 12:04:20 +00:00
iBUTTON[ DATA] = " ${ UPD [ " result, ${ num } ,callback_query,data " ] } "
#iBUTTON[CHAT_INSTANCE]="${UPD["result,${num},callback_query,chat_instance"]}"
#iBUTTON[INLINE_ID]="${UPD["result,${num},callback_query,inline_message_id"]}"
iBUTTON[ CHAT_ID] = " ${ UPD [ " result, ${ num } ,callback_query,message,chat,id " ] } "
iBUTTON[ MESSAGE_ID] = " ${ UPD [ " result, ${ num } ,callback_query,message,message_id " ] } "
iBUTTON[ MEESSAGE] = " $( JsonDecode " ${ UPD [ " result, ${ num } ,callback_query,message,text " ] } " ) "
2021-01-24 11:30:56 +00:00
# XXX should we give back pressed button, all buttons or nothing?
2021-01-24 12:04:20 +00:00
iBUTTON[ USER_ID] = " ${ UPD [ " result, ${ num } ,callback_query,from,id " ] } "
iBUTTON[ FIRST_NAME] = " $( JsonDecode " ${ UPD [ " result, ${ num } ,callback_query,from,first_name " ] } " ) "
iBUTTON[ LAST_NAME] = " $( JsonDecode " ${ UPD [ " result, ${ num } ,callback_query,from,last_name " ] } " ) "
iBUTTON[ USERNAME] = " $( JsonDecode " ${ UPD [ " result, ${ num } ,callback_query,from,username " ] } " ) "
2021-01-24 09:28:04 +00:00
# always true
return 0
}
2019-04-21 11:45:51 +00:00
process_message( ) {
local num = " $1 "
2016-04-16 18:50:05 +00:00
# Message
2021-01-19 16:47:15 +00:00
MESSAGE[ 0] += " $( JsonDecode " ${ UPD [ " result, ${ num } ,message,text " ] } " | sed 's|\\/|/|g' ) "
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
2021-01-19 16:47:15 +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] } "
2021-01-19 16:47:15 +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
2021-01-19 16:47:15 +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
2021-01-19 16:47:15 +00:00
if [ -n " ${ UPD [ " result, ${ num } ,message,reply_to_message,from,id " ] } " ] ; then
REPLYTO[ UID] = " ${ UPD [ " result, ${ num } ,message,reply_to_message,from,id " ] } "
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
2021-01-19 16:47:15 +00:00
if [ -n " ${ UPD [ " result, ${ num } ,message,forward_from,id " ] } " ] ; then
FORWARD[ UID] = " ${ UPD [ " result, ${ num } ,message,forward_from,id " ] } "
2021-01-20 18:50:19 +00:00
FORWARD[ ID] = " ${ MESSAGE [ID] } " # same as message ID
2021-01-19 16:47:15 +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
2021-01-19 16:47:15 +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 " ] } " ) "
2020-06-14 07:10:43 +00:00
fi
2020-12-13 09:10:15 +00:00
# Contact, must have phone_number
2021-01-19 16:47:15 +00:00
if [ -n " ${ UPD [ " result, ${ num } ,message,contact,phone_number " ] } " ] ; then
CONTACT[ USER_ID] = " $( JsonDecode " ${ UPD [ " result, ${ num } ,message,contact,user_id " ] } " ) "
CONTACT[ FIRST_NAME] = " $( JsonDecode " ${ UPD [ " result, ${ num } ,message,contact,first_name " ] } " ) "
CONTACT[ LAST_NAME] = " $( JsonDecode " ${ UPD [ " result, ${ num } ,message,contact,last_name " ] } " ) "
CONTACT[ NUMBER] = " ${ UPD [ " result, ${ num } ,message,contact,phone_number " ] } "
CONTACT[ VCARD] = " ${ UPD [ " result, ${ num } ,message,contact,vcard " ] } "
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
2021-01-19 16:47:15 +00:00
if [ -n " ${ UPD [ " result, ${ num } ,message,venue,location,longitude " ] } " ] ; then
VENUE[ TITLE] = " $( JsonDecode " ${ UPD [ " result, ${ num } ,message,venue,title " ] } " ) "
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
2021-01-19 16:47:15 +00:00
CAPTION = " $( JsonDecode " ${ UPD [ " result, ${ num } ,message,caption " ] } " ) "
2016-01-17 16:46:24 +00:00
# Location
2021-01-19 16:47:15 +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
2021-01-19 16:47:15 +00:00
if [ -n " ${ UPD [ " result, ${ num } ,message,new_chat_member,id " ] } " ] ; then
SERVICE[ NEWMEMBER] = " ${ UPD [ " result, ${ num } ,message,new_chat_member,id " ] } "
2020-05-14 11:04:57 +00:00
NEWMEMBER[ ID] = " ${ SERVICE [NEWMEMBER] } "
2021-01-19 16:47:15 +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 " ] } " ) "
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
2021-01-19 16:47:15 +00:00
if [ -n " ${ UPD [ " result, ${ num } ,message,left_chat_member,id " ] } " ] ; then
SERVICE[ LEFTMEMBER] = " ${ UPD [ " result, ${ num } ,message,left_chat_member,id " ] } "
2020-06-15 17:44:46 +00:00
LEFTMEMBER[ ID] = " ${ SERVICE [LEFTMEBER] } "
2021-01-19 16:47:15 +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 " ] } " ) "
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
2021-01-19 16:47:15 +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] } "
2021-01-19 16:47:15 +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
2021-01-19 16:47:15 +00:00
if [ -n " ${ UPD [ " result, ${ num } ,message,pinned_message,message_id " ] } " ] ; then
SERVICE[ PINNED] = " ${ UPD [ " result, ${ num } ,message,pinned_message,message_id " ] } "
2020-06-29 11:29:47 +00:00
PINNED[ ID] = " ${ SERVICE [PINNED] } "
2021-01-19 16:47:15 +00:00
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
2021-01-19 16:47:15 +00:00
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 " ] } "
2021-01-23 12:58:45 +00:00
# CHAT is already migrated, so set new chat id
[ " ${ CHAT [ID] } " = " ${ MIGRATE [FROM] } " ] && CHAT[ ID] = " ${ MIGRATE [FROM] } "
2020-12-13 11:00:18 +00:00
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
2019-04-22 19:05:52 +00:00
start_bot( ) {
2020-12-31 17:11:37 +00:00
local DEBUGMSG 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
2021-01-05 15:17:34 +00:00
[ [ " $1 " = = *"debug" ] ] && exec & >>" ${ DEBUGLOG } "
log_debug " ${ DEBUGMSG } " ; DEBUGMSG = " $1 "
2021-01-17 08:55:13 +00:00
[ [ " ${ DEBUGMSG } " = = "xdebug" * ] ] && set -x
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
2021-01-04 22:08:09 +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
2021-01-06 07:48:25 +00:00
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
2020-12-31 17:11:37 +00:00
send_normal_message " $( getConfigKey "botadmin" ) " " 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
2021-01-17 08:55:13 +00:00
UPDATE = " $( getJson " ${ URL } /getUpdates?offset= ${ OFFSET } " 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++) )
2021-01-04 22:08:09 +00:00
if [ " ${ OFFSET } " != "1" ] ; then
2020-06-09 12:46:45 +00:00
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
2021-01-10 18:21:18 +00:00
local runuser chown touser botname DEBUG = " $1 "
2019-05-14 11:16:58 +00:00
# upgrade from old version
2020-12-27 14:12:35 +00:00
# currently no action
2020-12-26 20:18:18 +00:00
printf "Check for Update actions ...\n"
printf "Done.\n"
2020-12-27 14:12:35 +00:00
# load addons on startup
2020-12-26 20:18:18 +00:00
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"
2021-01-10 17:23:37 +00:00
# ask for bashbot user
runuser = " ${ RUNUSER } " ; [ " ${ UID } " = "0" ] && runuser = "nobody"
printf " Enter User to run bashbot [ ${ runuser } ]: "
2021-01-10 18:21:18 +00:00
read -r chown
[ -z " ${ chown } " ] && chown = " ${ runuser } " ; touser = " ${ chown % : * } "
2021-01-10 17:23:37 +00:00
# check user ...
if ! id " ${ touser } " & >/dev/null; then
printf " ${ RED } User \" ${ touser } \" does not exist! ${ NN } "
2019-04-22 19:05:52 +00:00
exit 3
2021-01-10 17:23:37 +00:00
elif [ [ " ${ UID } " != "0" && " ${ touser } " != " ${ runuser } " ] ] ; then
# different user but not root ...
2021-01-10 17:39:43 +00:00
printf " ${ ORANGE } You are not root, adjusting permissions may fail. Try \"sudo ./bashbot.sh init\" ${ NN } Press <CTRL+C> to stop or <Enter> to continue... " 1>& 2
[ -n " ${ INTERACTIVE } " ] && read -r runuser
2019-04-22 19:05:52 +00:00
fi
2021-01-10 17:23:37 +00:00
# adjust permissions
printf " Adjusting files and permissions for user \" ${ touser } \" ...\n "
chmod 711 .
chmod -R o-w ./*
chmod -R u+w " ${ COUNTFILE } " * " ${ BLOCKEDFILE } " * " ${ DATADIR } " logs " ${ LOGDIR } / " *.log 2>/dev/null
chmod -R o-r,o-w " ${ COUNTFILE } " * " ${ BLOCKEDFILE } " * " ${ DATADIR } " " ${ BOTACL } " 2>/dev/null
# jsshDB must writeable by owner
find . -name '*.jssh*' -exec chmod u+w \{ \} +
2021-01-10 18:21:18 +00:00
chown -Rf " ${ chown } " . ./*
2021-01-10 17:23:37 +00:00
printf "Done.\n"
# adjust values in bashbot.rc
2021-01-10 18:21:18 +00:00
if [ -w "bashbot.rc" ] ; then
printf "Adjust user and botname in bashbot.rc ...\n"
2021-01-16 11:59:11 +00:00
sed -i '/^[# ]*runas=/ s|runas=.*$|runas="' " ${ touser } " '"|' "bashbot.rc"
sed -i '/^[# ]*bashbot=/ s|bashbot=.*$|bashbot="cd ' " ${ PWD } " '; ' " ${ PWD } " '/' " ${ 0 ##*/ } " '"|' "bashbot.rc"
2021-01-10 18:21:18 +00:00
botname = " $( getConfigKey "botname" ) "
2021-01-16 11:59:11 +00:00
[ -n " ${ botname } " ] && sed -i '/^[# ]*name=/ s|name=.*$|name="' " ${ botname } " '"|' "bashbot.rc"
2021-01-10 18:21:18 +00:00
printf "Done.\n"
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-12-27 14:12:35 +00:00
# check if botconf 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"]'
2021-01-04 15:10:43 +00:00
if check_token " $( getConfigKey "bottoken" ) " && [ [ " $( getConfigKey "botadmin" ) " = ~ ^[ ${ o9o9o9 } ] +$ ] ] ; 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-27 14:12:35 +00:00
printf " ${ ORANGE } Bot config may incomplete, 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
# 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
2021-01-05 15:17:34 +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-27 10:26:38 +00:00
[ -n " ${ INTERACTIVE } " ] && 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" ) "
2021-01-04 22:08:09 +00:00
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-12-27 10:26:38 +00:00
[ -n " ${ INTERACTIVE } " ] && 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
2021-01-20 18:50:19 +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
2021-01-04 22:08:09 +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-12-27 10:18:42 +00:00
# stats deprecated
"stats" | "count" )
printf " ${ ORANGE } Stats is a separate command now, see bin/bashbot_stats.sh --help ${ NN } "
" ${ BASHBOT_HOME :- . } " /bin/bashbot_stats.sh --help
2019-04-04 13:25:27 +00:00
exit
2016-04-16 18:50:05 +00:00
; ;
2020-12-27 10:18:42 +00:00
# broadcast deprecated
2020-05-29 18:11:51 +00:00
'broadcast' )
2020-12-27 10:18:42 +00:00
printf " ${ ORANGE } Broadcast is a separate command now, see 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 }
2021-01-04 22:08:09 +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
2020-12-31 17:11:37 +00:00
send_normal_message " $( getConfigKey "botadmin" ) " " 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 } "
2021-01-03 21:39:36 +00:00
printf " ${ ORANGE } 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
2021-01-03 21:39:36 +00:00
printf " \n ${ ORANGE } WARNING: ${ SCRIPT } was started as ROOT (UID 0)! ${ NN } "
2020-12-26 20:18:18 +00:00
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