Merge branch 'develop' into master

This commit is contained in:
Kay Marquardt 2021-02-17 09:42:35 +01:00 committed by GitHub
commit aee7bae141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 747 additions and 267 deletions

View File

@ -392,6 +392,6 @@ It features background tasks and interactive chats, and can serve as an interfac
<p>@Gnadelwartz</p> <p>@Gnadelwartz</p>
<h2>That's it all guys!</h2> <h2>That's it all guys!</h2>
<p>If you feel that there's something missing or if you found a bug, feel free to submit a pull request!</p> <p>If you feel that there's something missing or if you found a bug, feel free to submit a pull request!</p>
<h4>$$VERSION$$ v1.40-dev-34-g1440d56</h4> <h4>$$VERSION$$ v1.41-0-gad1b91f</h4>
</body> </body>
</html> </html>

View File

@ -241,4 +241,4 @@ See `mycommnds.sh.dist` for an example.
If you feel that there's something missing or if you found a bug, feel free to submit a pull request! If you feel that there's something missing or if you found a bug, feel free to submit a pull request!
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.41-0-gad1b91f

View File

@ -318,5 +318,5 @@ That's it all guys!
If you feel that there's something missing or if you found a bug, feel free to submit a If you feel that there's something missing or if you found a bug, feel free to submit a
pull request! pull request!
$$VERSION$$ v1.40-dev-34-g1440d56 $$VERSION$$ v1.41-0-gad1b91f

View File

@ -30,7 +30,7 @@ BOTCOMMANDS="-h help init start stop status suspendback resumeback killb
# 8 - curl/wget missing # 8 - curl/wget missing
# 10 - not bash! # 10 - not bash!
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-26-g82a57a7
################################################################## ##################################################################
# are we running in a terminal? # are we running in a terminal?
@ -99,11 +99,15 @@ getConfigKey() {
[[ "$1" =~ ^[-${azAZo9},._]+$ ]] || return 3 [[ "$1" =~ ^[-${azAZo9},._]+$ ]] || return 3
[ -r "${BOTCONFIG}.jssh" ] && sed -n 's/\["'"$1"'"\]\t*"\(.*\)"/\1/p' "${BOTCONFIG}.jssh" | tail -n 1 [ -r "${BOTCONFIG}.jssh" ] && sed -n 's/\["'"$1"'"\]\t*"\(.*\)"/\1/p' "${BOTCONFIG}.jssh" | tail -n 1
} }
# escape / remove text characters for json strings, eg. " -> \" # escape characters in json strings for telegram
# $1 string # $1 string, output escaped string
# output escaped string
JsonEscape(){ JsonEscape(){
sed 's/\([-"`´,§$%&/(){}#@!?*.\t]\)/\\\1/g' <<< "$1" sed -E -e 's/\r//g' -e 's/([-"`´,§$%&/(){}#@!?*.\t])/\\\1/g' <<< "${1//$'\n'/\\n}"
}
# clean \ from escaped json string
# $1 string, output cleaned string
cleanEscaped(){ # remove " all \ but \n\u \n or \r
sed -E -e 's/\\"/+/g' -e 's/\\([^nu])/\1/g' -e 's/(\r|\n)//g' <<<"$1"
} }
# check if $1 seems a valid token # check if $1 seems a valid token
# return true if token seems to be valid # return true if token seems to be valid
@ -157,7 +161,7 @@ debug_checks(){ {
[ -z "$(getConfigKey "botadmin")" ] && printf "%(%c)T: %s\n" -1 "Bot admin is missing! ==========" [ -z "$(getConfigKey "botadmin")" ] && printf "%(%c)T: %s\n" -1 "Bot admin is missing! =========="
# call user defined debug_checks if exists # call user defined debug_checks if exists
_exec_if_function my_debug_checks "$(_date)" "${where}" "$*" _exec_if_function my_debug_checks "$(_date)" "${where}" "$*"
} >>"${DEBUGLOG}" } 2>/dev/null >>"${DEBUGLOG}"
} }
# some Linux distributions (e.g. Manjaro) doesn't seem to have C locale activated by default # some Linux distributions (e.g. Manjaro) doesn't seem to have C locale activated by default
@ -174,10 +178,10 @@ RUNDIR="$(dirname "$0")"
MODULEDIR="${SCRIPTDIR}/modules" MODULEDIR="${SCRIPTDIR}/modules"
# adjust stuff for source, use return from source without source # adjust stuff for source, use return from source without source
alias exit_source='exit' exit_source() { exit "$1"; }
if [[ "${SCRIPT}" != "${REALME}" || "$1" == "source" ]]; then if [[ "${SCRIPT}" != "${REALME}" || "$1" == "source" ]]; then
SOURCE="yes" SOURCE="yes"
[ -z "$1" ] && alias exit_source='printf "Exit from source ...\n";return' [ -z "$1" ] && exit_source() { printf "Exit from source ...\n"; return "$1"; }
fi fi
# emmbeded system may claim bash but it is not # emmbeded system may claim bash but it is not
@ -271,6 +275,7 @@ if [ -z "${BOTTOKEN}" ]; then
[ -z "${admin}" ] && admin='?' [ -z "${admin}" ] && admin='?'
printf '["botadmin"]\t"%s"\n' "${admin}" >> "${BOTCONFIG}.jssh" printf '["botadmin"]\t"%s"\n' "${admin}" >> "${BOTCONFIG}.jssh"
fi fi
# setup botacl file # setup botacl file
if [ ! -f "${BOTACL}" ]; then if [ ! -f "${BOTACL}" ]; then
printf "${GREY}Create initial ${BOTACL} file.${NN}" printf "${GREY}Create initial ${BOTACL} file.${NN}"
@ -279,15 +284,14 @@ if [ -z "${BOTTOKEN}" ]; then
# check data dir file # check data dir file
if [ ! -w "${DATADIR}" ]; then if [ ! -w "${DATADIR}" ]; then
printf "${RED}ERROR: ${DATADIR} does not exist or is not writeable!.${NN}" printf "${RED}ERROR: ${DATADIR} does not exist or is not writeable!.${NN}"
exit_source 2 [ "$1" != "init" ] && exit_source 2 # skip on init
fi fi
# setup count file # setup count file
if [ ! -f "${COUNTFILE}.jssh" ]; then if [ ! -f "${COUNTFILE}.jssh" ]; then
printf '["counted_user_chat_id"]\t"num_messages_seen"\n' >> "${COUNTFILE}.jssh" printf '["counted_user_chat_id"]\t"num_messages_seen"\n' >> "${COUNTFILE}.jssh"
elif [ ! -w "${COUNTFILE}.jssh" ]; then elif [ ! -w "${COUNTFILE}.jssh" ]; then
printf "${RED}ERROR: Can't write to ${COUNTFILE}!.${NN}" printf "${RED}WARNING: Can't write to ${COUNTFILE}!.${NN}"
ls -l "${COUNTFILE}.jssh" ls -l "${COUNTFILE}.jssh"
exit_source 2
fi fi
# setup blocked file # setup blocked file
if [ ! -f "${BLOCKEDFILE}.jssh" ]; then if [ ! -f "${BLOCKEDFILE}.jssh" ]; then
@ -342,6 +346,7 @@ fi
BASHBOT_RETRY="" # retry by default BASHBOT_RETRY="" # retry by default
URL="${BASHBOT_URL:-https://api.telegram.org/bot}${BOTTOKEN}" URL="${BASHBOT_URL:-https://api.telegram.org/bot}${BOTTOKEN}"
FILEURL="${URL%%/bot*}/file/bot${BOTTOKEN}"
ME_URL=${URL}'/getMe' ME_URL=${URL}'/getMe'
################# #################
@ -388,16 +393,6 @@ if ! _is_function jssh_newDB; then
exit_source 6 exit_source 6
fi fi
# $1 URL, $2 filename in DATADIR
# outputs final filename
download() {
local empty="no.file" file="${2:-${empty}}"
if [[ "${file}" = *"/"* ]] || [[ "${file}" = "."* ]]; then file="${empty}"; fi
while [ -f "${DATADIR:-.}/${file}" ] ; do file="${RANDOM}-${file}"; done
getJson "$1" >"${DATADIR:-.}/${file}" || return
printf '%s\n' "${DATADIR:-.}/${file}"
}
# $1 postfix, e.g. chatid # $1 postfix, e.g. chatid
# $2 prefix, back- or startbot- # $2 prefix, back- or startbot-
procname(){ procname(){
@ -425,19 +420,56 @@ killallproc() {
debug_checks "end killallproc" "$1" debug_checks "end killallproc" "$1"
} }
# URL path for file id, $1 file_id
# $ chat $2 msg_id $3 nolog # use download_file "path" to download file
declare -xr DELETE_URL=${URL}'/deleteMessage'
delete_message() {
[ -z "$3" ] && log_update "Delete Message CHAT=$1 MSG_ID=$2"
sendJson "$1" '"message_id": '"$2"'' "${DELETE_URL}"
}
# get download url for file id, $1 file_id
get_file() { get_file() {
[ -z "$1" ] && return [ -z "$1" ] && return
sendJson "" '"file_id": "'"$1"'"' "${URL}/getFile" sendJson "" '"file_id": "'"$1"'"' "${URL}/getFile"
printf "%s\n" "${URL}/${UPD["result,file_path"]}" printf "%s\n" "${UPD["result,file_path"]}"
}
# download file to DATADIR
# $1 URL path, $2 proposed filename (may modified/ignored)
# outputs final filename
# keep old function name for backward compatibility
alias download="download_file"
download_file() {
local url="$1" file="${2:-$1}"
# old mode if full URL is given
if [[ "${1}" =~ ^https*:// ]]; then
# random filename if not given for http
if [ -z "$2" ]; then
: "$(mktemp -u -p . "XXXXXXXXXX" 2>/dev/null)"
file="download-${_#./}"
fi
else
# prefix https://api.telegram...
url="${FILEURL}/${url}"
fi
# filename: replace "/" with "-", use mktemp if exist
file="${DATADIR:-.}/${file//\//-}"
[ -f "${file}" ] && file="$(mktemp -p "${DATADIR:-.}" "XXXXX-${file##*/}" )"
getJson "${url}" >"${file}" || return
# output absolute file path
printf "%s\n" "$(cd "${file%/*}" >/dev/null 2>&1 && pwd)/${file##*/}"
}
# notify mycommands about errors while sending
# $1 calling function $2 error $3 chat $4 user $5 error message $6 ... remaining args to calling function
# calls function based on error: bashbotError{function} basbotError{error}
# if no specific function exist try to call bashbotProcessError
processError(){
local func="$1" err="$2"
[[ "${err}" != "4"* ]] && return 1
# check for bashbotError${func} provided in mycommands
# shellcheck disable=SC2082
if _is_function "bashbotError_${func}"; then
"bashbotError_${func}" "$@"
# check for bashbotError${err} provided in mycommands
elif _is_function "bashbotError_${err}"; then
"bashbotError_${err}" "$@"
# noting found, try bashbotProcessError
else
_exec_if_function bashbotProcessError "$@"
fi
} }
# iconv used to filter out broken utf characters, if not installed fake it # iconv used to filter out broken utf characters, if not installed fake it
@ -461,7 +493,7 @@ sendJson(){
if [ -n "${BASHBOTDEBUG}" ] ; then if [ -n "${BASHBOTDEBUG}" ] ; then
log_update "sendJson (${DETECTED_CURL}) CHAT=${chat#*:} JSON=${2:0:100} URL=${3##*/}" log_update "sendJson (${DETECTED_CURL}) CHAT=${chat#*:} JSON=${2:0:100} URL=${3##*/}"
# mask " and \ , remove newline from json # mask " and \ , remove newline from json
log_message "DEBUG sendJson ==========\n$("${JSONSHFILE}" -b -n <<<"$(sed -E -e 's/\\"/+/g' -e 's/\\/\\\\/g' -e 's/(\r|\n)//g' <<<"${json}")" 2>&1)" log_message "DEBUG sendJson ==========\n$("${JSONSHFILE}" -b -n <<<"$(cleanEscaped "${json}")" 2>&1)"
fi fi
# chat id not a number # chat id not a number
if [[ "${chat}" == *"NAN\"," ]]; then if [[ "${chat}" == *"NAN\"," ]]; then
@ -477,6 +509,36 @@ sendJson(){
[ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "${@}" & [ -n "${BASHBOT_EVENT_SEND[*]}" ] && event_send "send" "${@}" &
} }
UPLOADDIR="${BASHBOT_UPLOAD:-${DATADIR}/upload}"
# $1 chat $2 file, $3 calling function
# return final file name or empty string on error
checkUploadFile() {
local err file="$2"
[[ "${file}" = *'..'* || "${file}" = '.'* ]] && err=1 # no directory traversal
if [[ "${file}" = '/'* ]] ; then
[[ ! "${file}" =~ ${FILE_REGEX} ]] && err=2 # absolute must match REGEX
else
file="${UPLOADDIR:-NOUPLOADDIR}/${file}" # others must be in UPLOADDIR
fi
[ ! -r "${file}" ] && err=3 # and file must exits of course
# file path error, generate error response
if [ -n "${err}" ]; then
BOTSENT=(); BOTSENT[OK]="false"
case "${err}" in
1) BOTSENT[ERROR]="Path to file $2 contains to much '../' or starts with '.'";;
2) BOTSENT[ERROR]="Path to file $2 does not match regex: ${FILE_REGEX} ";;
3) if [[ "$2" == "/"* ]];then
BOTSENT[ERROR]="File not found: $2"
else
BOTSENT[ERROR]="File not found: ${UPLOADDIR}/$2"
fi;;
esac
[ -n "${BASHBOTDEBUG}" ] && log_debug "$3: CHAT=$1 FILE=$2 MSG=${BOTSENT[DESCRIPTION]}"
return 1
fi
}
# #
# curl / wget specific functions # curl / wget specific functions

View File

@ -21,7 +21,7 @@ USAGE='any_command.sh [-h|--help] [--force|--reference] bot_command args ...'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de # AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 30.01.2021 10:24 # CREATED: 30.01.2021 10:24
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-7-ga9ed559
#=============================================================================== #===============================================================================
#### ####

View File

@ -5,13 +5,13 @@
# #
# USAGE: source bashbot_init.inc.sh # USAGE: source bashbot_init.inc.sh
# #
# DESCRIPTION: extend / overwrite bashbot initialisation # DESCRIPTION: extend / overwrite bashbot initialisation
# #
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de # AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 27.01.2021 13:42 # CREATED: 27.01.2021 13:42
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-3-g429c230
#=============================================================================== #===============================================================================
# shellcheck disable=SC2059 # shellcheck disable=SC2059
@ -54,17 +54,23 @@ bot_init() {
[ -r "${addons}" ] && source "${addons}" "init" "${DEBUG}" [ -r "${addons}" ] && source "${addons}" "init" "${DEBUG}"
done done
printf "Done.\n" printf "Done.\n"
# ask for bashbot user # guess bashbot from botconfig.jssh owner:group
# shellcheck disable=SC2153 [ -f "${BOTCONFIG}.jssh" ] && runuser="$(stat -c '%U' "${BOTCONFIG}.jssh"):$(stat -c '%G' "${BOTCONFIG}.jssh")"
runuser="${RUNUSER}"; [ "${UID}" = "0" ] && runuser="nobody" # empty or ":" use user running init, nobody for root
if [ "${#runuser}" -lt 3 ]; then
# shellcheck disable=SC2153
runuser="${RUNUSER}"
[ "${UID}" = "0" ] && runuser="nobody"
fi
printf "Enter User to run bashbot [${runuser}]: " printf "Enter User to run bashbot [${runuser}]: "
read -r chown read -r chown
[ -z "${chown}" ] && chown="${runuser}"; touser="${chown%:*}" [ -z "${chown}" ] && chown="${runuser}"
touser="${chown%:*}"
# check user ... # check user ...
if ! id "${touser}" &>/dev/null; then if ! id "${touser}" &>/dev/null; then
printf "${RED}User \"${touser}\" does not exist!${NN}" printf "${RED}User \"${touser}\" does not exist!${NN}"
exit 3 exit 3
elif [[ "${UID}" != "0" && "${touser}" != "${runuser}" ]]; then elif [ "${UID}" != "0" ]; then
# different user but not root ... # different user but not root ...
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 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 [ -n "${INTERACTIVE}" ] && read -r runuser
@ -98,13 +104,13 @@ bot_init() {
fi fi
# adjust permissions # adjust permissions
printf "Adjusting files and permissions for user \"${touser}\" ...\n" printf "Adjusting files and permissions for user \"${touser}\" ...\n"
chown -Rf "${chown}" . ./*
chmod 711 . chmod 711 .
chmod -R o-w ./* chmod -R o-w ./*
chmod -R u+w "${COUNTFILE}"* "${BLOCKEDFILE}"* "${DATADIR}" logs "${LOGDIR}/"*.log 2>/dev/null 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 chmod -R o-r,o-w "${COUNTFILE}"* "${BLOCKEDFILE}"* "${DATADIR}" "${BOTACL}" 2>/dev/null
# jsshDB must writeable by owner # jsshDB must writeable by owner
find . -name '*.jssh*' -exec chmod u+w \{\} + find . -name '*.jssh*' -exec chmod u+w \{\} +
chown -Rf "${chown}" . ./*
printf "Done.\n" printf "Done.\n"
# adjust values in bashbot.rc # adjust values in bashbot.rc
if [ -w "bashbot.rc" ]; then if [ -w "bashbot.rc" ]; then

View File

@ -15,7 +15,7 @@ USAGE='process_update.sh [-h|--help] [debug] [<file]'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de # AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 30.01.2021 19:14 # CREATED: 30.01.2021 19:14
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-30-g8efbfca
#=============================================================================== #===============================================================================
#### ####

47
bin/send_dice.sh Executable file
View File

@ -0,0 +1,47 @@
#!/bin/bash
# shellcheck disable=SC1090,SC2034
#===============================================================================
#
# FILE: bin/send_dice.sh
#
USAGE='send_dice.sh [-h|--help] "CHAT[ID]" "emoji" [debug]'
#
# DESCRIPTION: send an animated emoji (dice) to given chat
#
# OPTIONS: CHAT[ID] - ID number of CHAT or BOTADMIN to send to yourself
# emoji - must be one of: “🎲”, “🎯”, “🏀”, “⚽”, or “🎰”
# ":game_die:" ":dart:" ":basketball:" ":soccer:" :slot_machine:"
#
# -h - display short help
# --help - this help
#
# Set BASHBOT_HOME to your installation directory
#
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 07.02.2021 18:45
#
#### $$VERSION$$ v1.45-dev-8-g069570e
#===============================================================================
####
# parse args
SEND="send_dice"
# set bashbot environment
source "${0%/*}/bashbot_env.inc.sh" "${3:-debug}" # $5 debug
print_help "$1"
####
# ready, do stuff here -----
if [ "$1" == "BOTADMIN" ]; then
CHAT="${BOT_ADMIN}"
else
CHAT="$1"
fi
# send message in selected format
"${SEND}" "${CHAT}" "$2"
# output send message result
print_result

View File

@ -15,7 +15,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-9-g62b6b61
# #
# bashbot locale defaults to c.UTF-8, adjust locale in mycommands.sh if needed # bashbot locale defaults to c.UTF-8, adjust locale in mycommands.sh if needed
@ -42,10 +42,12 @@ bashbot_help='
*• /start*: _Start bot and get this message_. *• /start*: _Start bot and get this message_.
*• /help*: _Get this message_. *• /help*: _Get this message_.
*• /info*: _Get shorter info message about this bot_. *• /info*: _Get shorter info message about this bot_.
*• /question*: _Start interactive chat (mycommands.dist)_.
*• /cancel*: _Cancel any currently running interactive chat_.
*• /kickme*: _You will be autokicked from the group_. *• /kickme*: _You will be autokicked from the group_.
*• /leavechat*: _The bot will leave the group with this command _. *• /leavechat*: _The bot will leave the group with this command _.
Additional commands from mycommands.dist ...
*• /game*: _throw a die_.
*• /question*: _Start interactive chat_.
*• /cancel*: _Cancel any currently running interactive chat_.
Written by Drew (@topkecleon) and KayM (@gnadelwartz). Written by Drew (@topkecleon) and KayM (@gnadelwartz).
Get the code in my [GitHub](http://github.com/topkecleon/telegram-bot-bash) Get the code in my [GitHub](http://github.com/topkecleon/telegram-bot-bash)
' '

View File

@ -5,7 +5,7 @@
# #
# Description: run all tests, exit after failed test # Description: run all tests, exit after failed test
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-21-ge67e43d
############################################################# #############################################################
#shellcheck disable=SC1090 #shellcheck disable=SC1090

View File

@ -172,6 +172,8 @@ These Variables are always present in regular messages:
The following variables are set if the message contains optional parts: The following variables are set if the message contains optional parts:
* `MESSAGE[CAPTION]`: Picture, Audio, Video, File Captions
* `MESSAGE[DICE]`: Animated DICE Emoji DICE values is contained in `MESSAGE[RESULT]`
* `$REPLYTO`: Original message which was replied to * `$REPLYTO`: Original message which was replied to
* `$REPLYTO`: This array contains the First name, last name, username and user id of the ORIGINAL sender of the message REPLIED to. * `$REPLYTO`: This array contains the First name, last name, username and user id of the ORIGINAL sender of the message REPLIED to.
* `${REPLYTO[ID]}`: ID of message which was replied to * `${REPLYTO[ID]}`: ID of message which was replied to
@ -185,14 +187,15 @@ The following variables are set if the message contains optional parts:
* `${FORWARD[FIRST_NAME]}`: Original user's first name * `${FORWARD[FIRST_NAME]}`: Original user's first name
* `${FORWARD[LAST_NAME]}`: Original user's' last name * `${FORWARD[LAST_NAME]}`: Original user's' last name
* `${FORWARD[USERNAME]}`: Original user's username * `${FORWARD[USERNAME]}`: Original user's username
* `$CAPTION`: Picture, Audio, Video, File Captions * `$URLS`: This array contains the `path` on Telegram server for files send to chat, e.g. photo, video, audio file.
* `$URLS`: This array contains documents, audio files, voice recordings and stickers as URL. * `${URLS[AUDIO]}`: Path to audio file
* `${URLS[AUDIO]}`: Audio files * `${URLS[VIDEO]}`: Path to video
* `${URLS[VIDEO]}`: Videos * `${URLS[PHOTO]}`: Path to photo (maximum quality)
* `${URLS[PHOTO]}`: Photos (maximum quality) * `${URLS[VOICE]}`: Path to voice recording
* `${URLS[VOICE]}`: Voice recordings * `${URLS[STICKER]}`: Path to sticker
* `${URLS[STICKER]}`: Stickers * `${URLS[DOCUMENT]}`: Path to any other file
* `${URLS[DOCUMENT]}`: Any other file **Important:** This is NOT a full URL, you must use `download_file "${URLS[xxx]}"` or prefix path with telegram api url for manual download
(_e.g. `getJson "${URL}/${URLS[xxx]}" >file`_).
* `$CONTACT`: This array contains info about contacts sent in a chat. * `$CONTACT`: This array contains info about contacts sent in a chat.
* `${CONTACT[ID]}`: User id * `${CONTACT[ID]}`: User id
* `${CONTACT[NUMBER]}`: Phone number * `${CONTACT[NUMBER]}`: Phone number
@ -238,6 +241,8 @@ e.g. if a new user joins a chat MESSAGE is set to "/_new_chat_user".
* `${MESSAGE}`: /_new_chat_title SENDER TEXT * `${MESSAGE}`: /_new_chat_title SENDER TEXT
* `${SERVICE[NEWPHOTO]}`: New Chat Picture * `${SERVICE[NEWPHOTO]}`: New Chat Picture
* `${MESSAGE}`: /_new_chat_picture SENDER URL * `${MESSAGE}`: /_new_chat_picture SENDER URL
**Important:** SERVICE[NEWPHOTO] is NOT a full URL, you must use `download_file "${SERVICE[NEWPHOTO]}"` or prefix path with telegram api url for manual download
(_e.g. `getJson "${FILEURL}/${SERVICE[NEWPHOTO]}" >file`_).
* `${SERVICE[PINNED]}`: Pinned MESSAGE ID * `${SERVICE[PINNED]}`: Pinned MESSAGE ID
* `${MESSAGE}`: /_new_pinned_message SENDER ID * `${MESSAGE}`: /_new_pinned_message SENDER ID
* `${PINNED[ID]}`: Id of pinned message * `${PINNED[ID]}`: Id of pinned message
@ -372,5 +377,5 @@ send_action "${CHAT[ID]}" "action"
#### [Prev Create Bot](1_firstbot.md) #### [Prev Create Bot](1_firstbot.md)
#### [Next Advanced Usage](3_advanced.md) #### [Next Advanced Usage](3_advanced.md)
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-17-ga7d85e3

View File

@ -176,8 +176,22 @@ send_album "$(getConfigKey "botadmin")" "http://www.rrr.de/slider/main-image1.jp
##### send_sticker ##### send_sticker
`send_sticker` sends a sticker using a `file_id` to send a sticker that exists on the Telegram servers. `send_sticker` sends a sticker using a `file_id` to send a sticker that exists on the Telegram servers.
*usage:* send_sticker "$CHAT[ID]" "file_id" *usage:* send_sticker "CHAT[ID]" "file_id"
##### send_dice
`send_dice` send an animated emoji and returns a value (_e.g. points shown on die_).
*usage:* send_dice "CHAT[ID]" "emoji"
Emoji must be one of '🎲', '🎯', '🏀', '⚽', '🎰' or ":game_die:" ":dart:" ":basketball:" ":soccer:" :slot_machine:".
Dice can have values 1-6 for '🎲' and '🎯', values 1-5 for '🏀' and '⚽', and values 1-64 for '🎰'. Defaults to '🎲'
*example:*
```bash
# send die and output points
send_dice "${CHAT[ID]}" ":game_die:"
[ "${BOTSENT[OK]}" = "true" ] && send_markdownv2_message "${CHAT[ID]}" "*Congratulation* you got *${BOTSENT[RESULT]} Point(s)*."
```
---- ----
@ -534,6 +548,85 @@ edit_html_message "${CHAT[ID]}" "${saved-id}" "this is <b>html</b> text"
*usage:* edit_message_caption "CHAT[ID]" "MESSAGE-ID" "caption" *usage:* edit_message_caption "CHAT[ID]" "MESSAGE-ID" "caption"
----
### Get files from Telegram
##### download_file
`download_file` download a file to `DATADIR` and returns the local `path` to the file on disc, main use is to download files send to chats.
I tried to be as compatible as possible with old function `download`.
*usage:* download_file path_to_ile prosed_filename
*alias*: download
*Note:* You must use `download_file` to download `URLS[...]` or `SERVICE[NEWPHOTO]` URLs from Telegram server.
*example:*
```bash
########
# download from Telegram server
# photo received in a chat
photo="${URLS[PHOTO]}")"
echo "$photo" -> photo/file_1234.jpg
# first download
file="$(download_file "${photo}"
echo "$file" -> ./data-bot-bash/photo-file_1234.jpg
# second download
file="$(download_file "${photo}"
echo "$file" -> ./data-bot-bash/jkdfhi-photo-file_1234.jpg
ls data-bot-bash/*.jpg
photo-file_1234.jpg jkdfhi-photo-file_1234.jpg
########
# download from other sources (full URL)
file="$(download "https://avatars.githubusercontent.com/u/13046303")"
echo "$file" -> ./data-bot-bash/download-askjgftGJGdh1Z
file="$(download "https://avatars.githubusercontent.com/u/13046303" "avatar.jpg")"
echo "$file" -> ./data-bot-bash/avatar.jpg
file="$(download "https://avatars.githubusercontent.com/u/13046303" "avatar.jpg")"
echo "$file" -> ./data-bot-bash/jhsdf-avatar.jpg
ls data-bot-bash/
avatar.jpg jhsdf-avatar.jpg download-askjgftGJGdh1Z
#######
# manually download files to current directory (not recommended)
getJson "${FILEURL}/${photo}" >"downloaded_photo.jpg"
getJson "https://avatars.githubusercontent.com/u/13046303" >"avatar.jpg"
ls -F
JSON.sh/ bin/ modules/ data-bot-bash/
avatar.jpg bashbot.sh* botconfig.jssh commands.sh count.jssh downloaded_photo.jpg mycommands.sh ...
```
##### get_file
`get_file` get the `path` to a file on Telegram server by it's `file_id`. File `path` is only valid for use with your bot token.
*usage:* url="$(get_file "file_id")"
*example*:
```bash
# download file by file_id
file_id="kjhdsfhkj-kjshfbsdbfkjhsdkfjn"
path="$(get_file "${file_id}")"
file="$(download_file "${path}")"
# one line
file="$(download_file "$(get_file "${file_id}")")"
```
--- ---
### Manage Group ### Manage Group
@ -571,7 +664,6 @@ Returns the new invite link as String on success.
##### pin_chat_message ##### pin_chat_message
# $1 chat, $2 message_id
`pin_chat_message` add a message to the list of pinned messages in a chat. `pin_chat_message` add a message to the list of pinned messages in a chat.
*usage:* pin_chat_message "CHAT[ID]" "message_id" *usage:* pin_chat_message "CHAT[ID]" "message_id"
@ -1398,20 +1490,6 @@ Do not use them in other files e.g. `bashbot.sh`, modules, addons etc.
### Helper functions ### Helper functions
##### download
Download the given URL and returns the final filename in TMPDIR. If the given filename exists,the filename is prefixed with a
random number. Filename is not allowed to contain '/' or '..'.
*usage:* download URL filename
*example:*
```bash
file="$(download "https://avatars.githubusercontent.com/u/13046303" "avatar.jpg")"
echo "$file" -> ./data-bot-bash/avatar.jpg
file="$(download "https://avatars.githubusercontent.com/u/13046303" "avatar.jpg")"
echo "$file" -> ./data-bot-bash/12345-avatar.jpg
```
##### _exec_if_function ##### _exec_if_function
Returns true, even if the given function does not exist. Return false if function exist but returns false. Returns true, even if the given function does not exist. Return false if function exist but returns false.
@ -1506,26 +1584,11 @@ killallproc
---- ----
##### get_file
*usage:* url="$(get_file "CHAT[ID]" "message")"
----
##### JsonDecode ##### JsonDecode
Outputs decoded string to STDOUT Outputs decoded string to STDOUT
*usage:* JsonDecode "string" *usage:* JsonDecode "string"
##### JsonGetString
Reads JSON from STDIN and Outputs found String to STDOUT
*usage:* JsonGetString `"path","to","string"`
##### JsonGetValue
Reads JSON from STDIN and Outputs found Value to STDOUT
*usage:* JsonGetValue `"path","to","value"`
##### Json2Array ##### Json2Array
Read JSON.sh style data from STDIN and assign to given ARRAY Read JSON.sh style data from STDIN and assign to given ARRAY
@ -1578,5 +1641,5 @@ The name of your bot is available as bash variable "$ME", there is no need to ca
#### [Prev Best Practice](5_practice.md) #### [Prev Best Practice](5_practice.md)
#### [Next Notes for Developers](7_develop.md) #### [Next Notes for Developers](7_develop.md)
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-9-g62b6b61

View File

@ -16,7 +16,7 @@ Prerequisite: An Apache webserver with a valid SLL certificate chain and php ena
Prepare Apache to forward webhook to Bashbot: Prepare Apache to forward webhook to Bashbot:
- install bashbot as described in [Bashbot Installation](../../doc/0_install.md) - install bashbot as described in [Bashbot Installation](../../doc/0_install.md)
- create file `data-bot-bash/webhook-fifo` - create file `data-bot-bash/webhook-fifo-<botname>` (_<botname> as in `botconfig.jssh`_)
- run `bashbot.sh init` to setup bashbot to run as same user as Apache (_e.g. www_) - run `bashbot.sh init` to setup bashbot to run as same user as Apache (_e.g. www_)
- go to apache web root and create directory `telegram/<your_bot_token>` - go to apache web root and create directory `telegram/<your_bot_token>`
- copy all files from `examples/webhook` to new directory and change to it - copy all files from `examples/webhook` to new directory and change to it
@ -24,16 +24,16 @@ Prepare Apache to forward webhook to Bashbot:
- execute `php index.php` - execute `php index.php`
Every call to webhook `https://<yourservername>/telegram/<your_bot_token>/` will execute Every call to webhook `https://<yourservername>/telegram/<your_bot_token>/` will execute
`index.php` and write received JSON to file `data-bot-bash/webhook-fifo`. `index.php` and write received JSON to file `data-bot-bash/webhook-fifo-botname`.
E.g. the URL `https://<yourservername>/telegram/<your_bot_token>/?json={"test":"me"}` E.g. the URL `https://<yourservername>/telegram/<your_bot_token>/?json={"test":"me"}`
will append `{"test":"me"}` to the file `data-bot-bash/webhook-fifo`. will append `{"test":"me"}` to the file `data-bot-bash/webhook-fifo-<botname>`.
Now your Apache is ready to forward data to Bashbot. Now your Apache is ready to forward data to Bashbot.
#### Simple update processing #### Simple update processing
To configure `Simple update processing` delete the file `data-bot-bash/webhook-fifo` after your webhook is working. To configure `Simple update processing` delete the file `data-bot-bash/webhook-fifo-<botname>` after your webhook is working.
All webhook calls are now forwarded to `bin/process_update.sh` for processing. All webhook calls are now forwarded to `bin/process_update.sh` for processing.
To start `Simple processing ` enable webhook on Telegram (_see below_). To start `Simple processing ` enable webhook on Telegram (_see below_).
@ -76,5 +76,5 @@ To stop delivering of Telegram updates via webhook run `bin/any_command.sh delet
**Important**: Only https connections with a valid certificate chain are allowed as endpoint for webhook. **Important**: Only https connections with a valid certificate chain are allowed as endpoint for webhook.
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-28-g9958b5b

View File

@ -11,7 +11,7 @@
* @license http://www.wtfpl.net/txt/copying/ WTFPLv2 * @license http://www.wtfpl.net/txt/copying/ WTFPLv2
* @since 30.01.2021 20:24 * @since 30.01.2021 20:24
* *
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-28-g9958b5b
***********************************************************/ ***********************************************************/
// bashbot home dir // bashbot home dir
@ -26,10 +26,26 @@
} }
} }
// bashbot config file
$CONFIG=$BASHBOT_HOME.'/botconfig.jssh';
// set botname here or read botname from config file if unknown
$botname="unknown";
if ($botname == "unknown" && file_exists($CONFIG)) {
$prefix='["botname"] "';
$len=strlen($prefix);
$arr = file($CONFIG, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($arr as $line) {
if(substr($line, 0, $len) == $prefix) {
$botname=substr($line, $len, strlen($line)-$len-1);
}
}
}
// script endpoint // script endpoint
$cmd=$BASHBOT_HOME.'/bin/process_update.sh'; $cmd=$BASHBOT_HOME.'/bin/process_update.sh';
// fifo endpoint // default fifo endpoint
$fifo=$BASHBOT_HOME.'/data-bot-bash/webhook-fifo'; $fifo=$BASHBOT_HOME.'/data-bot-bash/webhook-fifo-'.$botname;
// prepeare read, e.g. run from CLI // prepeare read, e.g. run from CLI
$data=''; $data='';

View File

@ -5,7 +5,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-25-gb1f6a0b
# will be automatically sourced from bashbot # will be automatically sourced from bashbot
@ -20,6 +20,10 @@ new_chat_invite() {
[ "${BOTSENT[OK]}" = "true" ] && printf "%s\n" "${BOTSENT[RESULT]}" [ "${BOTSENT[OK]}" = "true" ] && printf "%s\n" "${BOTSENT[RESULT]}"
} }
# $1 chat, $2 user_id, $3 title
set_chatadmin_title() {
sendJson "$1" '"user_id":'"$2"',"custom_title": "'"$3"'"' "${URL}/setChatAdministratorCustomTitle"
}
# $1 chat, $2 title # $1 chat, $2 title
set_chat_title() { set_chat_title() {
sendJson "$1" '"title": "'"$2"'"' "${URL}/setChatTitle" sendJson "$1" '"title": "'"$2"'"' "${URL}/setChatTitle"
@ -30,6 +34,12 @@ set_chat_description() {
sendJson "$1" '"description": "'"$2"'"' "${URL}/setChatDescription" sendJson "$1" '"description": "'"$2"'"' "${URL}/setChatDescription"
} }
# $1 chat $2 file
set_chat_photo() {
local file; file="$(checkUploadFile "$1" "$2" "set_chat_photo")"
[ -z "${file}" ] && return 1
sendUpload "$1" "photo" "${file}" "${URL}/setChatPhoto"
}
# $1 chat # $1 chat
delete_chat_photo() { delete_chat_photo() {
sendJson "$1" "" "${URL}/deleteChatPhoto" sendJson "$1" "" "${URL}/deleteChatPhoto"
@ -93,7 +103,7 @@ promote_chat_member() {
*"invite"*) arg="can_invite_users";; *"invite"*) arg="can_invite_users";;
*"restrict"*) arg="can_restrict_members";; *"restrict"*) arg="can_restrict_members";;
*"promote"*) arg="can_promote_members";; *"promote"*) arg="can_promote_members";;
*) [ -n "${BASHBOTDEBUG}" ] && debug_log "${FUNCNAME[0]}: unknown promotion ${arg}" *) [ -n "${BASHBOTDEBUG}" ] && log_debug "promote_chat_member: unknown promotion CHAT=${chat} USER=${user} PROM=${arg}"
continue;; continue;;
esac esac
# compose json # compose json

View File

@ -5,7 +5,7 @@
# This file is public domain in the USA and all free countries. # This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-30-g8efbfca
# #
# source from commands.sh to use jsonDB functions # source from commands.sh to use jsonDB functions
# #
@ -353,9 +353,10 @@ function jssh_updateArray_async() {
# read JSON.sh style data and asssign to an ARRAY # read JSON.sh style data and asssign to an ARRAY
# $1 ARRAY name, must be declared with "declare -A ARRAY" before calling # $1 ARRAY name, must be declared with "declare -A ARRAY" before calling
Json2Array() { Json2Array() {
# match ["....."]\t and replace \t with = and print quote true false escape not escaped $ # match ["....."]\t and replace \t with = and print delete ` quote true false escape not escaped $
# shellcheck disable=SC1091,SC1090 # shellcheck disable=SC1091,SC1090
[ -z "$1" ] || source <( printf "$1"'=( %s )' "$(sed -E -n -e '/\["[-0-9a-zA-Z_,."]+"\]\+*\t/ s/\t/=/p' -e 's/`//g' -e 's/=(true|false)/="\1"/' -e 's/([^\]|^)\$/\1\\$/g')" ) [ -z "$1" ] || source <( printf "$1"'=( %s )'\
"$(sed -E -n -e '/\["[-0-9a-zA-Z_,."]+"\]\+*\t/ s/\t/=/p' -e 's/`//g' -e 's/=(true|false)/="\1"/' -e 's/([^\]|^)\$/\1\\$/g')" )
} }
# get Config Key from jssh file without jsshDB # get Config Key from jssh file without jsshDB
# output ARRAY as JSON.sh style data # output ARRAY as JSON.sh style data

View File

@ -4,7 +4,7 @@
# File: processUpdates.sh # File: processUpdates.sh
# Note: DO NOT EDIT! this file will be overwritten on update # Note: DO NOT EDIT! this file will be overwritten on update
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-30-g8efbfca
################################################################## ##################################################################
############## ##############
@ -47,6 +47,8 @@ delete_webhook() {
process_multi_updates() { process_multi_updates() {
local max num debug="$1" local max num debug="$1"
max="$(grep -F ',"update_id"]' <<< "${UPDATE}" | tail -1 | cut -d , -f 2 )" max="$(grep -F ',"update_id"]' <<< "${UPDATE}" | tail -1 | cut -d , -f 2 )"
# escape bash $ expansion bug
UPDATE="${UPDATE//$/\\$}"
Json2Array 'UPD' <<<"${UPDATE}" Json2Array 'UPD' <<<"${UPDATE}"
for ((num=0; num<=max; num++)); do for ((num=0; num<=max; num++)); do
process_update "${num}" "${debug}" process_update "${num}" "${debug}"
@ -82,7 +84,7 @@ process_update() {
process_message "${num}" "${debug}" process_message "${num}" "${debug}"
printf "%(%c)T: update received FROM=%s CHAT=%s CMD=%s\n" -1 "${USER[USERNAME]:0:20} (${USER[ID]})"\ printf "%(%c)T: update received FROM=%s CHAT=%s CMD=%s\n" -1 "${USER[USERNAME]:0:20} (${USER[ID]})"\
"${CHAT[USERNAME]:0:20}${CHAT[TITLE]:0:30} (${CHAT[ID]})"\ "${CHAT[USERNAME]:0:20}${CHAT[TITLE]:0:30} (${CHAT[ID]})"\
"${MESSAGE:0:30}${CAPTION:0:30}$(: "${URLS[*]//bot*:}"; printf "%s" "${_//[A-Z-]}")" >>"${UPDATELOG}" "${MESSAGE:0:30}${CAPTION:0:30}${URLS[*]}" >>"${UPDATELOG}"
fi fi
##### #####
# process inline and message events # process inline and message events
@ -128,7 +130,6 @@ process_inline_query() {
} }
process_inline_button() { process_inline_button() {
# debugging for impelemetation
local num="$1" local num="$1"
iBUTTON[DATA]="${UPD["result,${num},callback_query,data"]}" iBUTTON[DATA]="${UPD["result,${num},callback_query,data"]}"
iBUTTON[CHAT_ID]="${UPD["result,${num},callback_query,message,chat,id"]}" iBUTTON[CHAT_ID]="${UPD["result,${num},callback_query,message,chat,id"]}"
@ -148,7 +149,14 @@ process_message() {
# Message # Message
MESSAGE[0]+="$(JsonDecode "${UPD["result,${num},message,text"]}" | sed 's|\\/|/|g')" MESSAGE[0]+="$(JsonDecode "${UPD["result,${num},message,text"]}" | sed 's|\\/|/|g')"
MESSAGE[ID]="${UPD["result,${num},message,message_id"]}" MESSAGE[ID]="${UPD["result,${num},message,message_id"]}"
MESSAGE[CAPTION]="$(JsonDecode "${UPD["result,${num},message,caption"]}")"
CAPTION="${MESSAGE[CAPTION]}" # backward compatibility
# dice received
MESSAGE[DICE]="${UPD["result,${num},message,dice,emoji"]}"
if [ -n "${MESSAGE[DICE]}" ]; then
MESSAGE[RESULT]="${UPD["result,${num},message,dice,value"]}"
MESSAGE[0]="/_dice_received ${MESSAGE[DICE]} ${MESSAGE[RESULT]}"
fi
# Chat ID is now parsed when update is received # Chat ID is now parsed when update is received
CHAT[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,last_name"]}")" CHAT[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,last_name"]}")"
CHAT[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,first_name"]}")" CHAT[FIRST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,first_name"]}")"
@ -212,9 +220,6 @@ process_message() {
VENUE[FOURSQUARE]="${UPD["result,${num},message,venue,foursquare_id"]}" VENUE[FOURSQUARE]="${UPD["result,${num},message,venue,foursquare_id"]}"
fi fi
# Caption
CAPTION="$(JsonDecode "${UPD["result,${num},message,caption"]}")"
# Location # Location
LOCATION[LONGITUDE]="${UPD["result,${num},message,location,longitude"]}" LOCATION[LONGITUDE]="${UPD["result,${num},message,location,longitude"]}"
LOCATION[LATITUDE]="${UPD["result,${num},message,location,latitude"]}" LOCATION[LATITUDE]="${UPD["result,${num},message,location,latitude"]}"
@ -229,7 +234,6 @@ process_message() {
NEWMEMBER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,last_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[USERNAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,username"]}")"
NEWMEMBER[ISBOT]="${UPD["result,${num},message,new_chat_member,is_bot"]}" NEWMEMBER[ISBOT]="${UPD["result,${num},message,new_chat_member,is_bot"]}"
[ -z "${MESSAGE[0]}" ] &&\
MESSAGE[0]="/_new_chat_member ${NEWMEMBER[ID]} ${NEWMEMBER[USERNAME]:=${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]}}" MESSAGE[0]="/_new_chat_member ${NEWMEMBER[ID]} ${NEWMEMBER[USERNAME]:=${NEWMEMBER[FIRST_NAME]} ${NEWMEMBER[LAST_NAME]}}"
fi fi
# left chat member # left chat member
@ -240,16 +244,15 @@ process_message() {
LEFTMEMBER[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,last_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"]}")" LEFTMEBER[USERNAME]="$(JsonDecode "${UPD["result,${num},message,left_chat_member,username"]}")"
LEFTMEMBER[ISBOT]="${UPD["result,${num},message,left_chat_member,is_bot"]}" LEFTMEMBER[ISBOT]="${UPD["result,${num},message,left_chat_member,is_bot"]}"
[ -z "${MESSAGE[0]}" ] &&\
MESSAGE[0]="/_left_chat_member ${LEFTMEMBER[ID]} ${LEFTMEMBER[USERNAME]:=${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]}}" MESSAGE[0]="/_left_chat_member ${LEFTMEMBER[ID]} ${LEFTMEMBER[USERNAME]:=${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]}}"
fi fi
# chat title / photo, check for any of them! # chat title / photo, check for any of them!
if grep -qs -e '\["result",'"${num}"',"message","new_chat_[tp]' <<<"${UPDATE}"; then if grep -qs -e '\["result",'"${num}"',"message","new_chat_[tp]' <<<"${UPDATE}"; then
SERVICE[NEWTITLE]="$(JsonDecode "${UPD["result,${num},message,new_chat_title"]}")" SERVICE[NEWTITLE]="$(JsonDecode "${UPD["result,${num},message,new_chat_title"]}")"
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWTITLE]}" ] &&\ [ -n "${SERVICE[NEWTITLE]}" ] &&\
MESSAGE[0]="/_new_chat_title ${USER[ID]} ${SERVICE[NEWTITLE]}" MESSAGE[0]="/_new_chat_title ${USER[ID]} ${SERVICE[NEWTITLE]}"
SERVICE[NEWPHOTO]="$(get_file "${UPD["result,${num},message,new_chat_photo,0,file_id"]}")" SERVICE[NEWPHOTO]="$(get_file "${UPD["result,${num},message,new_chat_photo,0,file_id"]}")"
[ -z "${MESSAGE[0]}" ] && [ -n "${SERVICE[NEWPHOTO]}" ] &&\ [ -n "${SERVICE[NEWPHOTO]}" ] &&\
MESSAGE[0]="/_new_chat_photo ${USER[ID]} ${SERVICE[NEWPHOTO]}" MESSAGE[0]="/_new_chat_photo ${USER[ID]} ${SERVICE[NEWPHOTO]}"
fi fi
# pinned message # pinned message
@ -257,8 +260,7 @@ process_message() {
SERVICE[PINNED]="${UPD["result,${num},message,pinned_message,message_id"]}" SERVICE[PINNED]="${UPD["result,${num},message,pinned_message,message_id"]}"
PINNED[ID]="${SERVICE[PINNED]}" PINNED[ID]="${SERVICE[PINNED]}"
PINNED[MESSAGE]="$(JsonDecode "${UPD["result,${num},message,pinned_message,text"]}")" PINNED[MESSAGE]="$(JsonDecode "${UPD["result,${num},message,pinned_message,text"]}")"
[ -z "${MESSAGE[0]}" ] &&\ MESSAGE[0]="/_new_pinned_message ${USER[ID]} ${PINNED[ID]} ${PINNED[MESSAGE]}"
MESSAGE[0]="/_new_pinned_message ${USER[ID]} ${PINNED[ID]} ${PINNED[MESSAGE]}"
fi fi
# migrate to super group # migrate to super group
if [ -n "${UPD["result,${num},message,migrate_to_chat_id"]}" ]; then if [ -n "${UPD["result,${num},message,migrate_to_chat_id"]}" ]; then
@ -267,8 +269,7 @@ process_message() {
# CHAT is already migrated, so set new chat id # CHAT is already migrated, so set new chat id
[ "${CHAT[ID]}" = "${MIGRATE[FROM]}" ] && CHAT[ID]="${MIGRATE[FROM]}" [ "${CHAT[ID]}" = "${MIGRATE[FROM]}" ] && CHAT[ID]="${MIGRATE[FROM]}"
SERVICE[MIGRATE]="${MIGRATE[FROM]} ${MIGRATE[TO]}" SERVICE[MIGRATE]="${MIGRATE[FROM]} ${MIGRATE[TO]}"
[ -z "${MESSAGE[0]}" ] &&\ MESSAGE[0]="/_migrate_group ${SERVICE[MIGRATE]}"
MESSAGE[0]="/_migrate_group ${SERVICE[MIGRATE]}"
fi fi
# set SERVICE to yes if a service message was received # set SERVICE to yes if a service message was received
[[ "${SERVICE[*]}" =~ ^[[:blank:]]*$ ]] || SERVICE[0]="yes" [[ "${SERVICE[*]}" =~ ^[[:blank:]]*$ ]] || SERVICE[0]="yes"
@ -346,8 +347,6 @@ get_updates(){
log_error "Recovered from timeout/broken/no connection, continue with telegram updates" log_error "Recovered from timeout/broken/no connection, continue with telegram updates"
# calculate next sleep interval # calculate next sleep interval
((nextsleep+= stepsleep , nextsleep= nextsleep>maxsleep ?maxsleep:nextsleep)) ((nextsleep+= stepsleep , nextsleep= nextsleep>maxsleep ?maxsleep:nextsleep))
# escape bash $ expansion bug
UPDATE="${UPDATE//$/\\$}"
# warn if webhook is set # warn if webhook is set
if grep -q '^\["error_code"\] 409' <<<"${UPDATE}"; then if grep -q '^\["error_code"\] 409' <<<"${UPDATE}"; then
[ "${OFFSET}" != "-999" ] && nextsleep="${stepsleep}" [ "${OFFSET}" != "-999" ] && nextsleep="${stepsleep}"

View File

@ -6,7 +6,7 @@
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying) # Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
# #
# shellcheck disable=SC1117 # shellcheck disable=SC1117
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-24-g785e769
# will be automatically sourced from bashbot # will be automatically sourced from bashbot
@ -25,7 +25,6 @@ EDIT_URL=${URL}'/editMessageText'
# $1 CHAT $2 message # $1 CHAT $2 message
send_normal_message() { send_normal_message() {
local len text; text="$(JsonEscape "$2")" local len text; text="$(JsonEscape "$2")"
text="${text//$'\n'/\\n}"
until [ -z "${text}" ]; do until [ -z "${text}" ]; do
if [ "${#text}" -le 4096 ]; then if [ "${#text}" -le 4096 ]; then
sendJson "$1" '"text":"'"${text}"'"' "${MSG_URL}" sendJson "$1" '"text":"'"${text}"'"' "${MSG_URL}"
@ -38,46 +37,73 @@ send_normal_message() {
text="${text:$((len+2))}" text="${text:$((len+2))}"
fi fi
done done
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
} }
# $1 CHAT $2 message # $1 CHAT $2 message
send_markdown_message() { send_markdown_message() {
_format_message_url "$1" "$2" ',"parse_mode":"markdown"' "${MSG_URL}" _format_message_url "$1" "$2" ',"parse_mode":"markdown"' "${MSG_URL}"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
} }
# $1 CHAT $2 message # $1 CHAT $2 message
send_markdownv2_message() { send_markdownv2_message() {
_markdownv2_message_url "$1" "$2" ',"parse_mode":"markdownv2"' "${MSG_URL}" _markdownv2_message_url "$1" "$2" ',"parse_mode":"markdownv2"' "${MSG_URL}"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
} }
# $1 CHAT $2 message # $1 CHAT $2 message
send_html_message() { send_html_message() {
_format_message_url "$1" "$2" ',"parse_mode":"html"' "${MSG_URL}" _format_message_url "$1" "$2" ',"parse_mode":"html"' "${MSG_URL}"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
} }
# $1 CHAT $2 msg-id $3 message # $1 CHAT $2 msg-id $3 message
edit_normal_message() { edit_normal_message() {
_format_message_url "$1" "$3" ',"message_id":'"$2"'' "${EDIT_URL}" _format_message_url "$1" "$3" ',"message_id":'"$2"'' "${EDIT_URL}"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
} }
# $1 CHAT $2 msg-id $3 message # $1 CHAT $2 msg-id $3 message
edit_markdown_message() { edit_markdown_message() {
_format_message_url "$1" "$3" ',"message_id":'"$2"',"parse_mode":"markdown"' "${EDIT_URL}" _format_message_url "$1" "$3" ',"message_id":'"$2"',"parse_mode":"markdown"' "${EDIT_URL}"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
} }
# $1 CHAT $2 msg-id $3 message # $1 CHAT $2 msg-id $3 message
edit_markdownv2_message() { edit_markdownv2_message() {
_markdownv2_message_url "$1" "$3" ',"message_id":'"$2"',"parse_mode":"markdownv2"' "${EDIT_URL}" _markdownv2_message_url "$1" "$3" ',"message_id":'"$2"',"parse_mode":"markdownv2"' "${EDIT_URL}"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
} }
# $1 CHAT $2 msg-id $3 message # $1 CHAT $2 msg-id $3 message
edit_html_message() { edit_html_message() {
_format_message_url "$1" "$3" ',"message_id":'"$2"',"parse_mode":"html"' "${EDIT_URL}" _format_message_url "$1" "$3" ',"message_id":'"$2"',"parse_mode":"html"' "${EDIT_URL}"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
} }
# $1 chat $2 mesage_id, $3 caption # $1 chat $2 mesage_id, $3 caption
edit_message_caption() { edit_message_caption() {
sendJson "$1" '"message_id":'"$2"',"caption":"'"$3"'"' "${URL}/editMessageCaption" sendJson "$1" '"message_id":'"$2"',"caption":"'"$3"'"' "${URL}/editMessageCaption"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
}
# $ chat $2 msg_id $3 nolog
delete_message() {
[ -z "$3" ] && log_update "Delete Message CHAT=$1 MSG_ID=$2"
sendJson "$1" '"message_id": '"$2"'' "${URL}/deleteMessage"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
} }
@ -85,7 +111,6 @@ edit_message_caption() {
# $1 CHAT $2 message $3 action $4 URL # $1 CHAT $2 message $3 action $4 URL
_format_message_url(){ _format_message_url(){
local text; text="$(JsonEscape "$2")" local text; text="$(JsonEscape "$2")"
text="${text//$'\n'/\\n}"
[ "${#text}" -ge 4096 ] && log_error "Warning: html/markdown message longer than 4096 characters, message is rejected if formatting crosses 4096 border." [ "${#text}" -ge 4096 ] && log_error "Warning: html/markdown message longer than 4096 characters, message is rejected if formatting crosses 4096 border."
until [ -z "${text}" ]; do until [ -z "${text}" ]; do
sendJson "$1" '"text":"'"${text:0:4096}"'"'"$3"'' "$4" sendJson "$1" '"text":"'"${text:0:4096}"'"'"$3"'' "$4"
@ -97,7 +122,6 @@ _format_message_url(){
# $1 CHAT $2 message $3 action $4 URL # $1 CHAT $2 message $3 action $4 URL
_markdownv2_message_url() { _markdownv2_message_url() {
local text; text="$(JsonEscape "$2")" local text; text="$(JsonEscape "$2")"
text="${text//$'\n'/\\n}"
[ "${#text}" -ge 4096 ] && log_error "Warning: markdownv2 message longer than 4096 characters, message is rejected if formatting crosses 4096 border." [ "${#text}" -ge 4096 ] && log_error "Warning: markdownv2 message longer than 4096 characters, message is rejected if formatting crosses 4096 border."
# markdown v2 needs additional double escaping! # markdown v2 needs additional double escaping!
text="$(sed -E -e 's|([_|~`>+=#{}()!.-])|\\\1|g' <<< "${text}")" text="$(sed -E -e 's|([_|~`>+=#{}()!.-])|\\\1|g' <<< "${text}")"
@ -120,8 +144,10 @@ send_keyboard() {
text='"text":"'"${text//$'\n'/\\n}"'"' text='"text":"'"${text//$'\n'/\\n}"'"'
fi fi
local one_time=', "one_time_keyboard":true' && [ -n "$4" ] && one_time="" local one_time=', "one_time_keyboard":true' && [ -n "$4" ] && one_time=""
sendJson "$1" "${text}"', "reply_markup": {"keyboard": [ '"$3"' ] '"${one_time}"'}' "${MSG_URL}"
# '"text":"$2", "reply_markup": {"keyboard": [ $3 ], "one_time_keyboard": true}' # '"text":"$2", "reply_markup": {"keyboard": [ $3 ], "one_time_keyboard": true}'
sendJson "$1" "${text}"', "reply_markup": {"keyboard": [ '"$3"' ] '"${one_time}"'}' "${MSG_URL}"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
} }
# $1 CHAT $2 message $3 remove # $1 CHAT $2 message $3 remove
@ -133,8 +159,10 @@ remove_keyboard() {
fi fi
sendJson "$1" "${text}"', "reply_markup": {"remove_keyboard":true}' "${MSG_URL}" sendJson "$1" "${text}"', "reply_markup": {"remove_keyboard":true}' "${MSG_URL}"
# delete message if no message or $3 not empty # delete message if no message or $3 not empty
[[ -z "$2" || -n "$3" ]] && delete_message "$1" "${BOTSENT[ID]}" "nolog"
#JSON='"text":"$2", "reply_markup": {"remove_keyboard":true}' #JSON='"text":"$2", "reply_markup": {"remove_keyboard":true}'
[[ -z "$2" || -n "$3" ]] && delete_message "$1" "${BOTSENT[ID]}" "nolog"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
} }
# buttons will specified as "texts # buttons will specified as "texts
@ -177,8 +205,10 @@ _button_row() {
# raw inline functions, for special use # raw inline functions, for special use
# $1 CHAT $2 message-id $3 keyboard # $1 CHAT $2 message-id $3 keyboard
edit_inline_keyboard() { edit_inline_keyboard() {
sendJson "$1" '"message_id":'"$2"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${URL}/editMessageReplyMarkup"
# JSON='"message_id":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}' # JSON='"message_id":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}'
sendJson "$1" '"message_id":'"$2"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${URL}/editMessageReplyMarkup"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
} }
@ -186,7 +216,8 @@ edit_inline_keyboard() {
send_inline_keyboard() { send_inline_keyboard() {
local text; text='"text":"'$(JsonEscape "$2")'"'; [ -z "$2" ] && text='"text":"..."' local text; text='"text":"'$(JsonEscape "$2")'"'; [ -z "$2" ] && text='"text":"..."'
sendJson "$1" "${text}"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${MSG_URL}" sendJson "$1" "${text}"', "reply_markup": {"inline_keyboard": [ '"$3"' ]}' "${MSG_URL}"
# JSON='"text":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}' # func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
} }
# $1 callback id, $2 text to show, alert if not empty # $1 callback id, $2 text to show, alert if not empty
@ -199,6 +230,8 @@ answer_callback_query() {
# $1 chat, $2 file_id on telegram server # $1 chat, $2 file_id on telegram server
send_sticker() { send_sticker() {
sendJson "$1" '"sticker": "'"$2"'"' "${URL}/sendSticker" sendJson "$1" '"sticker": "'"$2"'"' "${URL}/sendSticker"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
} }
@ -229,12 +262,10 @@ else
} }
fi fi
UPLOADDIR="${BASHBOT_UPLOAD:-${DATADIR}/upload}"
# supports local file, URL and file_id # supports local file, URL and file_id
# $1 chat, $2 file https::// file_id:// , $3 caption, $4 extension (optional) # $1 chat, $2 file https::// file_id:// , $3 caption, $4 extension (optional)
send_file(){ send_file(){
local url what num stat err media capt file="$2" ext="$4" local url what num stat media capt file="$2" ext="$4"
capt="$(JsonEscape "$3")" capt="$(JsonEscape "$3")"
if [[ "${file}" =~ ^https*:// ]]; then if [[ "${file}" =~ ^https*:// ]]; then
media="URL" media="URL"
@ -244,28 +275,8 @@ send_file(){
else else
# we have a file, check file location ... # we have a file, check file location ...
media="FILE" media="FILE"
[[ "${file}" = *'..'* || "${file}" = '.'* ]] && err=1 # no directory traversal file="$(checkUploadFile "$1" "$2" "send_file")"
if [[ "${file}" = '/'* ]] ; then [ -z "${file}" ] && return 1
[[ ! "${file}" =~ ${FILE_REGEX} ]] && err=2 # absolute must match REGEX
else
file="${UPLOADDIR:-NOUPLOADDIR}/${file}" # others must be in UPLOADDIR
fi
[ ! -r "${file}" ] && err=3 # and file must exits of course
# file path error, generate error response
if [ -n "${err}" ]; then
BOTSENT=(); BOTSENT[OK]="false"
case "${err}" in
1) BOTSENT[ERROR]="Path to file $2 contains to much '../' or starts with '.'";;
2) BOTSENT[ERROR]="Path to file $2 does not match regex: ${FILE_REGEX} ";;
3) if [[ "$2" == "/"* ]];then
BOTSENT[ERROR]="File not found: $2"
else
BOTSENT[ERROR]="File not found: ${UPLOADDIR}/$2"
fi;;
esac
[ -n "${BASHBOTDEBUG}" ] && log_message "Error in upload_file: ${BOTSENT[ERROR]}"
return
fi
# file OK, let's continue # file OK, let's continue
fi fi
@ -313,24 +324,54 @@ send_file(){
return 0 return 0
} }
# $1 typing upload_photo record_video upload_video record_audio upload_audio upload_document find_location # $1 chat $2 typing upload_photo record_video upload_video record_audio upload_audio upload_document find_location
send_action() { send_action() {
[ -z "$2" ] && return [ -z "$2" ] && return
sendJson "$1" '"action": "'"$2"'"' "${URL}/sendChatAction" & sendJson "$1" '"action": "'"$2"'"' "${URL}/sendChatAction" &
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
}
# $1 chat $2 emoji “🎲”, “🎯”, “🏀”, “⚽”, “🎰"
# code: "\ud83c\udfb2" "\ud83c\udfaf" "\ud83c\udfc0" "\u26bd" "\ud83c\udfb0"
# text: ":game_die:" ":dart:" ":basketball:" ":soccer:" :slot_machine:"
# $3 reply_to_id
send_dice() {
local reply emoji='\ud83c\udfb2' # default "🎲"
[[ "$3" =~ ^[${o9o9o9}-]+$ ]] && reply=',"reply_to_message_id":'"$3"',"allow_sending_without_reply": true'
case "$2" in # convert input to single character emoji
*🎲*|*game*|*dice*|*'dfb2'*|*'DFB2'*) : ;;
*🎯*|*dart* |*'dfaf'*|*'DFAF'*) emoji='\ud83c\udfaf' ;;
*🏀*|*basket*|*'dfc0'*|*'DFC0'*) emoji='\ud83c\udfc0' ;;
*⚽*|*soccer*|*'26bd'*|*'26BD'*) emoji='\u26bd' ;;
*🎰*|*slot* |*'dfb0'*|*'DFB0'*) emoji='\ud83c\udfb0' ;;
esac
sendJson "$1" '"emoji": "'"${emoji}"'"'"${reply}" "${URL}/sendDice"
if [ "${BOTSENT[OK]}" = "true" ]; then
BOTSENT[DICE]="${UPD["result,dice,emoji"]}"
BOTSENT[RESULT]="${UPD["result,dice,value"]}"
else
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2"
fi
} }
# $1 CHAT $2 lat $3 long # $1 CHAT $2 lat $3 long
send_location() { send_location() {
[ -z "$3" ] && return [ -z "$3" ] && return
sendJson "$1" '"latitude": '"$2"', "longitude": '"$3"'' "${URL}/sendLocation" sendJson "$1" '"latitude": '"$2"', "longitude": '"$3"'' "${URL}/sendLocation"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
} }
# $1 CHAT $2 lat $3 long $4 title $5 address $6 foursquard id # $1 CHAT $2 lat $3 long $4 title $5 address $6 foursquare id
send_venue() { send_venue() {
local add="" local add=""
[ -z "$5" ] && return [ -z "$5" ] && return
[ -n "$6" ] && add=', "foursquare_id": '"$6"'' [ -n "$6" ] && add=', "foursquare_id": '"$6"''
sendJson "$1" '"latitude": '"$2"', "longitude": '"$3"', "address": "'"$5"'", "title": "'"$4"'"'"${add}" "${URL}/sendVenue" sendJson "$1" '"latitude": '"$2"', "longitude": '"$3"', "address": "'"$5"'", "title": "'"$4"'"'"${add}" "${URL}/sendVenue"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3" "$4" "$5" "$6"
} }
@ -342,9 +383,16 @@ send_venue() {
forward_message() { forward_message() {
[ -z "$3" ] && return [ -z "$3" ] && return
sendJson "$1" '"from_chat_id": '"$2"', "message_id": '"$3"'' "${URL}/forwardMessage" sendJson "$1" '"from_chat_id": '"$2"', "message_id": '"$3"'' "${URL}/forwardMessage"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
} }
forward() { # backward compatibility
forward_message "$@" || return # $1 CHAT $2 from chat $3 from msg id
copy_message() {
[ -z "$3" ] && return
sendJson "$1" '"from_chat_id": '"$2"', "message_id": '"$3"'' "${URL}/copyMessage"
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
[ -n "${BOTSENT[ERROR]}" ] && processError "${FUNCNAME[0]}" "${BOTSENT[ERROR]}" "$1" "" "${BOTSENT[DESCRIPTION]}" "$2" "$3"
} }
# $1 CHAT $2 bashbot formatted message, see manual advanced usage # $1 CHAT $2 bashbot formatted message, see manual advanced usage

View File

@ -13,7 +13,7 @@
# License: WTFPLv2 http://www.wtfpl.net/txt/copying/ # License: WTFPLv2 http://www.wtfpl.net/txt/copying/
# Author: KayM (gnadelwartz), kay@rrr.de # Author: KayM (gnadelwartz), kay@rrr.de
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-27-g77ffbab
####################################################### #######################################################
# shellcheck disable=SC1117 # shellcheck disable=SC1117
@ -123,7 +123,26 @@ else
case "${MESSAGE}" in case "${MESSAGE}" in
################## ##################
# example commands, replace thm by your own # example commands, replace them by your own
'/_dice_re'*) # dice from user received
sleep 5
local gameresult="*Congratulation ${USER[FIRST_NAME]} ${USER[LAST_NAME]}* you got *${MESSAGE[RESULT]} Points*."
[ -z "${FORWARD[UID]}" ] && send_markdownv2_message "${CHAT[ID]}" "${gameresult}"
;;
'/game'*) # send random dice, edit list to fit your needs
send_dice "${CHAT[ID]}" ":$(printf "slot_machine\ngame_die\ndart\nbasketball\nsoccer\nslot_machine"|sort -R|shuf -n 1shuf -n 1):"
if [ "${BOTSENT[OK]}" = "true" ]; then
local gameresult="*Congratulation ${USER[FIRST_NAME]}* ${USER[LAST_NAME]} you got *${BOTSENT[RESULT]} Points*."
sleep 5
case "${BOTSENT[RESULT]}" in
1) gameresult="*Sorry* only *one Point* ...";;
2) gameresult="*Hey*, 2 Points are *more then one!*";;
5|6) [[ "${BOTSENT[EMOJI]}" =~ fb0$ ]] || gameresult="*Super! ${BOTSENT[RESULT]} Points!*";;
6*) gameresult="*JACKPOT! ${BOTSENT[RESULT]} Points!*";;
esac
send_markdownv2_message "${CHAT[ID]}" "${gameresult}"
fi
;;
'/unpin'*) # unpin all messages if (bot)admin or allowed for user '/unpin'*) # unpin all messages if (bot)admin or allowed for user
user_is_allowed "${USER[ID]}" "unpin" "${CHAT[ID]}" &&\ user_is_allowed "${USER[ID]}" "unpin" "${CHAT[ID]}" &&\
unpinall_chat_messages "${CHAT[ID]}" unpinall_chat_messages "${CHAT[ID]}"
@ -281,6 +300,8 @@ else
[ -f ".jssh" ] && printf "%s: %s\n" "$1" "Ups, found file \"${PWD:-.}/.jssh\"! ==========" [ -f ".jssh" ] && printf "%s: %s\n" "$1" "Ups, found file \"${PWD:-.}/.jssh\"! =========="
} }
###########################
# example recover from telegram block function
# called when bashbot send_xxx command failed because we can not connect to telegram # called when bashbot send_xxx command failed because we can not connect to telegram
# return 0 to retry, return non 0 to give up # return 0 to retry, return non 0 to give up
bashbotBlockRecover() { bashbotBlockRecover() {
@ -291,7 +312,22 @@ else
return 1 return 1
} }
# place your processing functions here ###########################
# example error processing
# called when delete Message failed
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
bashbotError_delete_message() {
log_debug "errorProcessing for delete_message failed: ERR=$2 CHAT=$3 MSGID=$6 ERTXT=$5"
}
# called when error 403 is returned (and no func processing)
# func="$1" err="$2" chat="$3" user="$4" emsg="$5" remaining args
bashbotError_403() {
log_debug "errorProcessing for error 403 in FUNC=$1 CHAT=$3 USER=${4:-no-user} MSGID=$6 ERTXT=$5"
}
###########################
# place your processing functions here --------------
# $1 search parameter # $1 search parameter
my_image_search(){ my_image_search(){
@ -307,3 +343,4 @@ else
} }
fi fi

View File

@ -11,7 +11,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de # AUTHOR: KayM (gnadelwartz), kay@rrr.de
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-21-ge67e43d
#=============================================================================== #===============================================================================
# common variables # common variables
@ -39,12 +39,12 @@ export SUCCESS NOSUCCESS
NOSUCCESS=" FAILED!" NOSUCCESS=" FAILED!"
# default input, reference and output files # default input, reference and output files
export INPUTFILE REFFILE INPUTFILE2 REFFILE2 OUTPUTFILE export INPUTFILE REFFILE OUTPUTFILE INPUTFILELIST
# shellcheck disable=SC2125
INPUTFILELIST="${DIRME}/${REFDIR}/${REFDIR}-"*".input"
OUTPUTFILE="${TESTDIR}/${REFDIR}.out" OUTPUTFILE="${TESTDIR}/${REFDIR}.out"
INPUTFILE="${DIRME}/${REFDIR}/${REFDIR}.input" INPUTFILE="${DIRME}/${REFDIR}/${REFDIR}.input"
REFFILE="${DIRME}/${REFDIR}/${REFDIR}.result" REFFILE="${DIRME}/${REFDIR}/${REFDIR}.result"
INPUTFILE2="${DIRME}/${REFDIR}/${REFDIR}2.input"
REFFILE2="${DIRME}/${REFDIR}/${REFDIR}2.result"
# reset ENVIRONMENT # reset ENVIRONMENT
export BASHBOT_URL TESTTOKEN BOTTOKEN BASHBOT_HOME BASHBOT_VAR BASHBOT_ETC export BASHBOT_URL TESTTOKEN BOTTOKEN BASHBOT_HOME BASHBOT_VAR BASHBOT_ETC

View File

@ -10,7 +10,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/ # LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de # AUTHOR: KayM (gnadelwartz), kay@rrr.de
# #
#### $$VERSION$$ v1.40-0-gf9dab50 #### $$VERSION$$ v1.45-dev-22-g6b07242
#=============================================================================== #===============================================================================
# include common functions and definitions # include common functions and definitions
@ -38,34 +38,24 @@ declare -Ax UPD
# run process_message -------------- # run process_message --------------
ARRAYS="USER CHAT REPLYTO FORWARD URLS CONTACT CAPTION LOCATION MESSAGE VENUE SERVICE NEWMEMBER LEFTMEMBER PINNED" ARRAYS="USER CHAT REPLYTO FORWARD URLS CONTACT CAPTION LOCATION MESSAGE VENUE SERVICE NEWMEMBER LEFTMEMBER PINNED"
printf "Check process_message regular message...\n" printf "Check process_message ...\n"
UPDATE="$(< "${INPUTFILE}")" for testfile in ${INPUTFILELIST}
Json2Array 'UPD' <"${INPUTFILE}" do
set -x printf " ... %s\n" "${testfile##*/}"
{ pre_process_message "0"; process_message "0"; set +x; } >>"${LOGFILE}" 2>&1; testref="${testfile%.input}.result"
USER[ID]="123456789"; CHAT[ID]="123456789" UPDATE="$(< "${testfile}")"
Json2Array 'UPD' <"${testfile}"
set -x
{ pre_process_message "0"; process_message "0"; set +x; } >>"${LOGFILE}" 2>&1;
USER[ID]="123456789"; CHAT[ID]="123456789"
# output processed input # output processed input
# shellcheck disable=SC2086 # shellcheck disable=SC2086
print_array ${ARRAYS} >"${OUTPUTFILE}" print_array ${ARRAYS} >"${OUTPUTFILE}"
compare_sorted "${REFFILE}" "${OUTPUTFILE}" || exit 1 compare_sorted "${testref}" "${OUTPUTFILE}" || exit 1
printf "%s\n" "${SUCCESS}"
# run process_message ------------ done
printf "Check process_message service message...\n"
UPDATE="$(cat "${INPUTFILE2}")"
Json2Array 'UPD' <"${INPUTFILE2}"
set -x
{ pre_process_message "0"; process_message "0"; set +x; } >>"${LOGFILE}" 2>&1;
USER[ID]="123456789"; CHAT[ID]="123456789"
# output processed input
# shellcheck disable=SC2086
print_array ${ARRAYS} >"${OUTPUTFILE}"
compare_sorted "${REFFILE2}" "${OUTPUTFILE}" || exit 1
printf "%s\n" "${SUCCESS}"
cd "${DIRME}" || exit 1 cd "${DIRME}" || exit 1

View File

@ -0,0 +1,25 @@
["ok"] true
["result",0,"update_id"] 123456789
["result",0,"message","message_id"] 123456789
["result",0,"message","from","id"] 123456789
["result",0,"message","from","is_bot"] false
["result",0,"message","from","first_name"] "Kay"
["result",0,"message","from","last_name"] "M"
["result",0,"message","from","username"] "Gnadelwartz"
["result",0,"message","from","language_code"] "de"
["result",0,"message","chat","id"] -123456789
["result",0,"message","chat","title"] "Testgruppe bot only test"
["result",0,"message","chat","type"] "group"
["result",0,"message","chat","all_members_are_administrators"] true
["result",0,"message","date"] 1592372719
["result",0,"message","left_chat_participant","id"] 123456789
["result",0,"message","left_chat_participant","is_bot"] false
["result",0,"message","left_chat_participant","first_name"] "Kay"
["result",0,"message","left_chat_participant","last_name"] "M"
["result",0,"message","left_chat_participant","username"] "Gnadelwartz"
["result",0,"message","left_chat_member","id"] 123456789
["result",0,"message","left_chat_member","is_bot"] false
["result",0,"message","left_chat_member","first_name"] "Kay"
["result",0,"message","left_chat_member","last_name"] "M"
["result",0,"message","left_chat_member","username"] "Gnadelwartz"

View File

@ -0,0 +1,25 @@
USER: FIRST_NAME Kay
USER: ID 123456789
USER: LAST_NAME M
USER: USERNAME Gnadelwartz
CHAT: ALL_ADMIN true
CHAT: FIRST_NAME
CHAT: ID 123456789
CHAT: LAST_NAME
CHAT: TITLE Testgruppe bot only test
CHAT: TYPE group
CHAT: USERNAME
CAPTION: 0
LOCATION: LATITUDE
LOCATION: LONGITUDE
MESSAGE: 0 /_left_chat_member Kay M
MESSAGE: CAPTION
MESSAGE: DICE
MESSAGE: ID 123456789
SERVICE: 0 yes
SERVICE: LEFTMEMBER 123456789
LEFTMEMBER: FIRST_NAME Kay
LEFTMEMBER: ID
LEFTMEMBER: ISBOT false
LEFTMEMBER: LAST_NAME M
LEFTMEMBER: USERNAME Kay M

View File

@ -31,11 +31,13 @@ CONTACT: LAST_NAME Pannenhilfe
CONTACT: NUMBER 222222 CONTACT: NUMBER 222222
CONTACT: USER_ID CONTACT: USER_ID
CONTACT: VCARD BEGIN:VCARD\nVERSION:2.1\nN:Pannenhilfe;ADAC;;;\nFN:ADAC Pannenhilfe\nTEL;CELL;PREF:+49179222222\nTEL;X-Mobil:222222\nEND:VCARD CONTACT: VCARD BEGIN:VCARD\nVERSION:2.1\nN:Pannenhilfe;ADAC;;;\nFN:ADAC Pannenhilfe\nTEL;CELL;PREF:+49179222222\nTEL;X-Mobil:222222\nEND:VCARD
CAPTION: 0 CAPTION: 0 Myproteine kein spell check
LOCATION: LATITUDE 49.631824 LOCATION: LATITUDE 49.631824
LOCATION: LONGITUDE 8.377072 LOCATION: LONGITUDE 8.377072
MESSAGE: 0 😂😝👌☺❤😕😈#⃣🌏🎉🙊🙉☕🚀✈🚂💯✔〽🔚 MESSAGE: 0 😂😝👌☺❤😕😈#⃣🌏🎉🙊🙉☕🚀✈🚂💯✔〽🔚
MESSAGE: ID 6541 MESSAGE: ID 6541
MESSAGE: CAPTION Myproteine kein spell check
MESSAGE: DICE
VENUE: ADDRESS Am Rhein 1 VENUE: ADDRESS Am Rhein 1
VENUE: FOURSQUARE 4c4321afce54e21eee980d1a VENUE: FOURSQUARE 4c4321afce54e21eee980d1a
VENUE: LATITUDE 49.631824 VENUE: LATITUDE 49.631824

View File

@ -89,3 +89,7 @@
["result",0,"message","voice","duration"] 2 ["result",0,"message","voice","duration"] 2
["result",0,"message","voice","mime_type"] "audio/ogg" ["result",0,"message","voice","mime_type"] "audio/ogg"
["result",0,"message","voice","file_size"] 4262 ["result",0,"message","voice","file_size"] 4262
["result",0,"message","caption"] "Myproteine kein spell check"
["result","dice","emoji"] "\ud83c\udfb2"
["result","dice","value"] 5

View File

@ -0,0 +1,45 @@
USER: FIRST_NAME Kay
USER: ID 123456789
USER: LAST_NAME M
USER: USERNAME Gnadelwartz
CHAT: ALL_ADMIN
CHAT: FIRST_NAME Test
CHAT: ID 123456789
CHAT: LAST_NAME Bot
CHAT: TITLE BotTestTitle
CHAT: TYPE private
CHAT: USERNAME BotTest
REPLYTO: 0 Ich bin der Deal-O-Mat Bot. Für eine Liste der Befehle sende /help
REPLYTO: FIRST_NAME dealzbot
REPLYTO: ID 6542
REPLYTO: LAST_NAME
REPLYTO: UID 987654321
REPLYTO: USERNAME Deal_O_Mat_bot
FORWARD: FIRST_NAME Kay
FORWARD: ID 6541
FORWARD: LAST_NAME M
FORWARD: UID 123456789
FORWARD: USERNAME Gnadelwartz
URLS: AUDIO audio-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
URLS: DOCUMENT document-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
URLS: PHOTO photo-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
URLS: STICKER sticker-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
URLS: VIDEO video-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
URLS: VOICE voice-AgADAgADL6oxG-Gw4EndCWGl2WUfUo1pXw8ABOusSilDGzAYa
CONTACT: FIRST_NAME ADAC
CONTACT: LAST_NAME Pannenhilfe
CONTACT: NUMBER 222222
CONTACT: USER_ID
CONTACT: VCARD BEGIN:VCARD\nVERSION:2.1\nN:Pannenhilfe;ADAC;;;\nFN:ADAC Pannenhilfe\nTEL;CELL;PREF:+49179222222\nTEL;X-Mobil:222222\nEND:VCARD
CAPTION: 0 Myproteine kein spell check
LOCATION: LATITUDE 49.631824
LOCATION: LONGITUDE 8.377072
MESSAGE: 0 😂😝👌☺❤😕😈#⃣🌏🎉🙊🙉☕🚀✈🚂💯✔〽🔚
MESSAGE: CAPTION Myproteine kein spell check
MESSAGE: DICE
MESSAGE: ID 6541
VENUE: ADDRESS Am Rhein 1
VENUE: FOURSQUARE 4c4321afce54e21eee980d1a
VENUE: LATITUDE 49.631824
VENUE: LONGITUDE 8.377072
VENUE: TITLE Kolb's Biergarten

View File

@ -0,0 +1,25 @@
["ok"] true
["result",0,"update_id"] 123456789
["result",0,"message","message_id"] 123456789
["result",0,"message","from","id"] 123456789
["result",0,"message","from","is_bot"] false
["result",0,"message","from","first_name"] "Kay"
["result",0,"message","from","last_name"] "M"
["result",0,"message","from","username"] "Gnadelwartz"
["result",0,"message","from","language_code"] "de"
["result",0,"message","chat","id"] -123456789
["result",0,"message","chat","title"] "Testgruppe bot only test"
["result",0,"message","chat","type"] "group"
["result",0,"message","chat","all_members_are_administrators"] true
["result",0,"message","date"] 1592372719
["result",0,"message","new_chat_participant","id"] 123456789
["result",0,"message","new_chat_participant","is_bot"] false
["result",0,"message","new_chat_participant","first_name"] "Kay"
["result",0,"message","new_chat_participant","last_name"] "M"
["result",0,"message","new_chat_participant","username"] "Gnadelwartz"
["result",0,"message","new_chat_member","id"] 123456789
["result",0,"message","new_chat_member","is_bot"] false
["result",0,"message","new_chat_member","first_name"] "Kay"
["result",0,"message","new_chat_member","last_name"] "M"
["result",0,"message","new_chat_member","username"] "Gnadelwartz"

View File

@ -13,21 +13,15 @@ CAPTION: 0
LOCATION: LATITUDE LOCATION: LATITUDE
LOCATION: LONGITUDE LOCATION: LONGITUDE
MESSAGE: 0 /_new_chat_member 123456789 Gnadelwartz MESSAGE: 0 /_new_chat_member 123456789 Gnadelwartz
MESSAGE: CAPTION
MESSAGE: DICE
MESSAGE: ID 123456789 MESSAGE: ID 123456789
SERVICE: 0 yes SERVICE: 0 yes
SERVICE: LEFTMEMBER 123456789
SERVICE: NEWMEMBER 123456789 SERVICE: NEWMEMBER 123456789
SERVICE: NEWPHOTO AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE SERVICE: NEWPHOTO
SERVICE: NEWTITLE new Testgruppe bot only SERVICE: NEWTITLE
SERVICE: PINNED 3022
NEWMEMBER: FIRST_NAME Kay NEWMEMBER: FIRST_NAME Kay
NEWMEMBER: ID 123456789 NEWMEMBER: ID 123456789
NEWMEMBER: ISBOT false NEWMEMBER: ISBOT false
NEWMEMBER: LAST_NAME M NEWMEMBER: LAST_NAME M
NEWMEMBER: USERNAME Gnadelwartz NEWMEMBER: USERNAME Gnadelwartz
LEFTMEMBER: FIRST_NAME Kay
LEFTMEMBER: ID
LEFTMEMBER: ISBOT false
LEFTMEMBER: LAST_NAME M
PINNED: ID 3022
PINNED: MESSAGE new pinned Message

View File

@ -0,0 +1,30 @@
["ok"] true
["result",0,"update_id"] 123456789
["result",0,"message","message_id"] 123456789
["result",0,"message","from","id"] 123456789
["result",0,"message","from","is_bot"] false
["result",0,"message","from","first_name"] "Kay"
["result",0,"message","from","last_name"] "M"
["result",0,"message","from","username"] "Gnadelwartz"
["result",0,"message","from","language_code"] "de"
["result",0,"message","chat","id"] -123456789
["result",0,"message","chat","title"] "Testgruppe bot only test"
["result",0,"message","chat","type"] "group"
["result",0,"message","chat","all_members_are_administrators"] true
["result",0,"message","date"] 1592372719
["result",0,"message","new_chat_photo",0,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE"
["result",0,"message","new_chat_photo",0,"file_unique_id"] "AQADK6S6ki4AAzdIAwAB"
["result",0,"message","new_chat_photo",0,"file_size"] 5939
["result",0,"message","new_chat_photo",0,"width"] 160
["result",0,"message","new_chat_photo",0,"height"] 160
["result",0,"message","new_chat_photo",1,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANiAAM4SAMAARoE"
["result",0,"message","new_chat_photo",1,"file_unique_id"] "AQADK6S6ki4AAzhIAwAB"
["result",0,"message","new_chat_photo",1,"file_size"] 14124
["result",0,"message","new_chat_photo",1,"width"] 320
["result",0,"message","new_chat_photo",1,"height"] 320
["result",0,"message","new_chat_photo",2,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANjAAM5SAMAARoE"
["result",0,"message","new_chat_photo",2,"file_unique_id"] "AQADK6S6ki4AAzlIAwAB"
["result",0,"message","new_chat_photo",2,"file_size"] 34052
["result",0,"message","new_chat_photo",2,"width"] 640
["result",0,"message","new_chat_photo",2,"height"] 640

View File

@ -0,0 +1,21 @@
USER: FIRST_NAME Kay
USER: ID 123456789
USER: LAST_NAME M
USER: USERNAME Gnadelwartz
CHAT: ALL_ADMIN true
CHAT: FIRST_NAME
CHAT: ID 123456789
CHAT: LAST_NAME
CHAT: TITLE Testgruppe bot only test
CHAT: TYPE group
CHAT: USERNAME
CAPTION: 0
LOCATION: LATITUDE
LOCATION: LONGITUDE
MESSAGE: 0 /_new_chat_photo 123456789 AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE
MESSAGE: CAPTION
MESSAGE: DICE
MESSAGE: ID 123456789
SERVICE: 0 yes
SERVICE: NEWPHOTO AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE
SERVICE: NEWTITLE

View File

@ -0,0 +1,16 @@
["ok"] true
["result",0,"update_id"] 123456789
["result",0,"message","message_id"] 123456789
["result",0,"message","from","id"] 123456789
["result",0,"message","from","is_bot"] false
["result",0,"message","from","first_name"] "Kay"
["result",0,"message","from","last_name"] "M"
["result",0,"message","from","username"] "Gnadelwartz"
["result",0,"message","from","language_code"] "de"
["result",0,"message","chat","id"] -123456789
["result",0,"message","chat","title"] "Testgruppe bot only test"
["result",0,"message","chat","type"] "group"
["result",0,"message","chat","all_members_are_administrators"] true
["result",0,"message","date"] 1592372719
["result",0,"message","new_chat_title"] "new Testgruppe bot only"

View File

@ -0,0 +1,21 @@
USER: FIRST_NAME Kay
USER: ID 123456789
USER: LAST_NAME M
USER: USERNAME Gnadelwartz
CHAT: ALL_ADMIN true
CHAT: FIRST_NAME
CHAT: ID 123456789
CHAT: LAST_NAME
CHAT: TITLE Testgruppe bot only test
CHAT: TYPE group
CHAT: USERNAME
CAPTION: 0
LOCATION: LATITUDE
LOCATION: LONGITUDE
MESSAGE: 0 /_new_chat_title 123456789 new Testgruppe bot only
MESSAGE: CAPTION
MESSAGE: DICE
MESSAGE: ID 123456789
SERVICE: 0 yes
SERVICE: NEWPHOTO
SERVICE: NEWTITLE new Testgruppe bot only

View File

@ -0,0 +1,27 @@
["ok"] true
["result",0,"update_id"] 123456789
["result",0,"message","message_id"] 123456789
["result",0,"message","from","id"] 123456789
["result",0,"message","from","is_bot"] false
["result",0,"message","from","first_name"] "Kay"
["result",0,"message","from","last_name"] "M"
["result",0,"message","from","username"] "Gnadelwartz"
["result",0,"message","from","language_code"] "de"
["result",0,"message","chat","id"] -123456789
["result",0,"message","chat","title"] "Testgruppe bot only test"
["result",0,"message","chat","type"] "group"
["result",0,"message","chat","all_members_are_administrators"] true
["result",0,"message","date"] 1592372719
["result",0,"message","pinned_message","message_id"] 3022
["result",0,"message","pinned_message","from","id"] 796814662
["result",0,"message","pinned_message","from","is_bot"] true
["result",0,"message","pinned_message","from","first_name"] "DealOMat"
["result",0,"message","pinned_message","from","username"] "Deal_O_Mat_bot"
["result",0,"message","pinned_message","chat","id"] -1001220313778
["result",0,"message","pinned_message","chat","title"] "Testgruppe bot only test"
["result",0,"message","pinned_message","chat","type"] "supergroup"
["result",0,"message","pinned_message","date"] 1593121152
["result",0,"message","pinned_message","text"] "new pinned Message"
["result",0,"message","new_chat_title"] "new Testgruppe bot only"

View File

@ -0,0 +1,24 @@
USER: FIRST_NAME Kay
USER: ID 123456789
USER: LAST_NAME M
USER: USERNAME Gnadelwartz
CHAT: ALL_ADMIN true
CHAT: FIRST_NAME
CHAT: ID 123456789
CHAT: LAST_NAME
CHAT: TITLE Testgruppe bot only test
CHAT: TYPE group
CHAT: USERNAME
CAPTION: 0
LOCATION: LATITUDE
LOCATION: LONGITUDE
MESSAGE: 0 /_new_pinned_message 123456789 3022 new pinned Message
MESSAGE: CAPTION
MESSAGE: DICE
MESSAGE: ID 123456789
SERVICE: 0 yes
SERVICE: NEWPHOTO
SERVICE: NEWTITLE new Testgruppe bot only
SERVICE: PINNED 3022
PINNED: ID 3022
PINNED: MESSAGE new pinned Message

View File

@ -1,65 +0,0 @@
["ok"] true
["result",0,"update_id"] 123456789
["result",0,"message","message_id"] 123456789
["result",0,"message","from","id"] 123456789
["result",0,"message","from","is_bot"] false
["result",0,"message","from","first_name"] "Kay"
["result",0,"message","from","last_name"] "M"
["result",0,"message","from","username"] "Gnadelwartz"
["result",0,"message","from","language_code"] "de"
["result",0,"message","chat","id"] -123456789
["result",0,"message","chat","title"] "Testgruppe bot only test"
["result",0,"message","chat","type"] "group"
["result",0,"message","chat","all_members_are_administrators"] true
["result",0,"message","date"] 1592372719
["result",0,"message","left_chat_participant","id"] 123456789
["result",0,"message","left_chat_participant","is_bot"] false
["result",0,"message","left_chat_participant","first_name"] "Kay"
["result",0,"message","left_chat_participant","last_name"] "M"
["result",0,"message","left_chat_participant","username"] "Gnadelwartz"
["result",0,"message","left_chat_member","id"] 123456789
["result",0,"message","left_chat_member","is_bot"] false
["result",0,"message","left_chat_member","first_name"] "Kay"
["result",0,"message","left_chat_member","last_name"] "M"
["result",0,"message","left_chat_member","username"] "Gnadelwartz"
["result",0,"message","new_chat_participant","id"] 123456789
["result",0,"message","new_chat_participant","is_bot"] false
["result",0,"message","new_chat_participant","first_name"] "Kay"
["result",0,"message","new_chat_participant","last_name"] "M"
["result",0,"message","new_chat_participant","username"] "Gnadelwartz"
["result",0,"message","new_chat_member","id"] 123456789
["result",0,"message","new_chat_member","is_bot"] false
["result",0,"message","new_chat_member","first_name"] "Kay"
["result",0,"message","new_chat_member","last_name"] "M"
["result",0,"message","new_chat_member","username"] "Gnadelwartz"
["result",0,"message","new_chat_photo",0,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE"
["result",0,"message","new_chat_photo",0,"file_unique_id"] "AQADK6S6ki4AAzdIAwAB"
["result",0,"message","new_chat_photo",0,"file_size"] 5939
["result",0,"message","new_chat_photo",0,"width"] 160
["result",0,"message","new_chat_photo",0,"height"] 160
["result",0,"message","new_chat_photo",1,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANiAAM4SAMAARoE"
["result",0,"message","new_chat_photo",1,"file_unique_id"] "AQADK6S6ki4AAzhIAwAB"
["result",0,"message","new_chat_photo",1,"file_size"] 14124
["result",0,"message","new_chat_photo",1,"width"] 320
["result",0,"message","new_chat_photo",1,"height"] 320
["result",0,"message","new_chat_photo",2,"file_id"] "AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANjAAM5SAMAARoE"
["result",0,"message","new_chat_photo",2,"file_unique_id"] "AQADK6S6ki4AAzlIAwAB"
["result",0,"message","new_chat_photo",2,"file_size"] 34052
["result",0,"message","new_chat_photo",2,"width"] 640
["result",0,"message","new_chat_photo",2,"height"] 640
["result",0,"message","pinned_message","message_id"] 3022
["result",0,"message","pinned_message","from","id"] 796814662
["result",0,"message","pinned_message","from","is_bot"] true
["result",0,"message","pinned_message","from","first_name"] "DealOMat"
["result",0,"message","pinned_message","from","username"] "Deal_O_Mat_bot"
["result",0,"message","pinned_message","chat","id"] -1001220313778
["result",0,"message","pinned_message","chat","title"] "Testgruppe bot only test"
["result",0,"message","pinned_message","chat","type"] "supergroup"
["result",0,"message","pinned_message","date"] 1593121152
["result",0,"message","pinned_message","text"] "new pinned Message"
["result",0,"message","new_chat_title"] "new Testgruppe bot only"