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>
<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>
<h4>$$VERSION$$ v1.40-dev-34-g1440d56</h4>
<h4>$$VERSION$$ v1.41-0-gad1b91f</h4>
</body>
</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!
#### $$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
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
# 10 - not bash!
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.45-dev-26-g82a57a7
##################################################################
# are we running in a terminal?
@ -99,11 +99,15 @@ getConfigKey() {
[[ "$1" =~ ^[-${azAZo9},._]+$ ]] || return 3
[ -r "${BOTCONFIG}.jssh" ] && sed -n 's/\["'"$1"'"\]\t*"\(.*\)"/\1/p' "${BOTCONFIG}.jssh" | tail -n 1
}
# escape / remove text characters for json strings, eg. " -> \"
# $1 string
# output escaped string
# escape characters in json strings for telegram
# $1 string, output escaped string
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
# 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! =========="
# call user defined debug_checks if exists
_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
@ -174,10 +178,10 @@ RUNDIR="$(dirname "$0")"
MODULEDIR="${SCRIPTDIR}/modules"
# adjust stuff for source, use return from source without source
alias exit_source='exit'
exit_source() { exit "$1"; }
if [[ "${SCRIPT}" != "${REALME}" || "$1" == "source" ]]; then
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
# emmbeded system may claim bash but it is not
@ -271,6 +275,7 @@ if [ -z "${BOTTOKEN}" ]; then
[ -z "${admin}" ] && admin='?'
printf '["botadmin"]\t"%s"\n' "${admin}" >> "${BOTCONFIG}.jssh"
fi
# setup botacl file
if [ ! -f "${BOTACL}" ]; then
printf "${GREY}Create initial ${BOTACL} file.${NN}"
@ -279,15 +284,14 @@ if [ -z "${BOTTOKEN}" ]; then
# check data dir file
if [ ! -w "${DATADIR}" ]; then
printf "${RED}ERROR: ${DATADIR} does not exist or is not writeable!.${NN}"
exit_source 2
[ "$1" != "init" ] && exit_source 2 # skip on init
fi
# setup count file
if [ ! -f "${COUNTFILE}.jssh" ]; then
printf '["counted_user_chat_id"]\t"num_messages_seen"\n' >> "${COUNTFILE}.jssh"
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"
exit_source 2
fi
# setup blocked file
if [ ! -f "${BLOCKEDFILE}.jssh" ]; then
@ -342,6 +346,7 @@ fi
BASHBOT_RETRY="" # retry by default
URL="${BASHBOT_URL:-https://api.telegram.org/bot}${BOTTOKEN}"
FILEURL="${URL%%/bot*}/file/bot${BOTTOKEN}"
ME_URL=${URL}'/getMe'
#################
@ -388,16 +393,6 @@ if ! _is_function jssh_newDB; then
exit_source 6
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
# $2 prefix, back- or startbot-
procname(){
@ -425,19 +420,56 @@ killallproc() {
debug_checks "end killallproc" "$1"
}
# $ chat $2 msg_id $3 nolog
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
# URL path for file id, $1 file_id
# use download_file "path" to download file
get_file() {
[ -z "$1" ] && return
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
@ -461,7 +493,7 @@ sendJson(){
if [ -n "${BASHBOTDEBUG}" ] ; then
log_update "sendJson (${DETECTED_CURL}) CHAT=${chat#*:} JSON=${2:0:100} URL=${3##*/}"
# 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
# chat id not a number
if [[ "${chat}" == *"NAN\"," ]]; then
@ -477,6 +509,36 @@ sendJson(){
[ -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

View File

@ -21,7 +21,7 @@ USAGE='any_command.sh [-h|--help] [--force|--reference] bot_command args ...'
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# 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
#
# DESCRIPTION: extend / overwrite bashbot initialisation
# DESCRIPTION: extend / overwrite bashbot initialisation
#
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
# CREATED: 27.01.2021 13:42
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.45-dev-3-g429c230
#===============================================================================
# shellcheck disable=SC2059
@ -54,17 +54,23 @@ bot_init() {
[ -r "${addons}" ] && source "${addons}" "init" "${DEBUG}"
done
printf "Done.\n"
# ask for bashbot user
# shellcheck disable=SC2153
runuser="${RUNUSER}"; [ "${UID}" = "0" ] && runuser="nobody"
# guess bashbot from botconfig.jssh owner:group
[ -f "${BOTCONFIG}.jssh" ] && runuser="$(stat -c '%U' "${BOTCONFIG}.jssh"):$(stat -c '%G' "${BOTCONFIG}.jssh")"
# 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}]: "
read -r chown
[ -z "${chown}" ] && chown="${runuser}"; touser="${chown%:*}"
[ -z "${chown}" ] && chown="${runuser}"
touser="${chown%:*}"
# check user ...
if ! id "${touser}" &>/dev/null; then
printf "${RED}User \"${touser}\" does not exist!${NN}"
exit 3
elif [[ "${UID}" != "0" && "${touser}" != "${runuser}" ]]; then
elif [ "${UID}" != "0" ]; then
# 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
[ -n "${INTERACTIVE}" ] && read -r runuser
@ -98,13 +104,13 @@ bot_init() {
fi
# adjust permissions
printf "Adjusting files and permissions for user \"${touser}\" ...\n"
chown -Rf "${chown}" . ./*
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 \{\} +
chown -Rf "${chown}" . ./*
printf "Done.\n"
# adjust values in bashbot.rc
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
# 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.
# 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
@ -42,10 +42,12 @@ bashbot_help='
*• /start*: _Start bot and get this message_.
*• /help*: _Get this message_.
*• /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_.
*• /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).
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
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.45-dev-21-ge67e43d
#############################################################
#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:
* `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`: 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
@ -185,14 +187,15 @@ The following variables are set if the message contains optional parts:
* `${FORWARD[FIRST_NAME]}`: Original user's first name
* `${FORWARD[LAST_NAME]}`: Original user's' last name
* `${FORWARD[USERNAME]}`: Original user's username
* `$CAPTION`: Picture, Audio, Video, File Captions
* `$URLS`: This array contains documents, audio files, voice recordings and stickers as URL.
* `${URLS[AUDIO]}`: Audio files
* `${URLS[VIDEO]}`: Videos
* `${URLS[PHOTO]}`: Photos (maximum quality)
* `${URLS[VOICE]}`: Voice recordings
* `${URLS[STICKER]}`: Stickers
* `${URLS[DOCUMENT]}`: Any other file
* `$URLS`: This array contains the `path` on Telegram server for files send to chat, e.g. photo, video, audio file.
* `${URLS[AUDIO]}`: Path to audio file
* `${URLS[VIDEO]}`: Path to video
* `${URLS[PHOTO]}`: Path to photo (maximum quality)
* `${URLS[VOICE]}`: Path to voice recording
* `${URLS[STICKER]}`: Path to sticker
* `${URLS[DOCUMENT]}`: Path to 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[ID]}`: User id
* `${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
* `${SERVICE[NEWPHOTO]}`: New Chat Picture
* `${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
* `${MESSAGE}`: /_new_pinned_message SENDER ID
* `${PINNED[ID]}`: Id of pinned message
@ -372,5 +377,5 @@ send_action "${CHAT[ID]}" "action"
#### [Prev Create Bot](1_firstbot.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` 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"
----
### 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
@ -571,7 +664,6 @@ Returns the new invite link as String on success.
##### pin_chat_message
# $1 chat, $2 message_id
`pin_chat_message` add a message to the list of pinned messages in a chat.
*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
##### 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
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
Outputs decoded string to STDOUT
*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
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)
#### [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:
- 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_)
- 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
@ -24,16 +24,16 @@ Prepare Apache to forward webhook to Bashbot:
- execute `php index.php`
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"}`
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.
#### 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.
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.
#### $$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
* @since 30.01.2021 20:24
*
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.45-dev-28-g9958b5b
***********************************************************/
// 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
$cmd=$BASHBOT_HOME.'/bin/process_update.sh';
// fifo endpoint
$fifo=$BASHBOT_HOME.'/data-bot-bash/webhook-fifo';
// default fifo endpoint
$fifo=$BASHBOT_HOME.'/data-bot-bash/webhook-fifo-'.$botname;
// prepeare read, e.g. run from CLI
$data='';

View File

@ -5,7 +5,7 @@
# This file is public domain in the USA and all free countries.
# 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
@ -20,6 +20,10 @@ new_chat_invite() {
[ "${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
set_chat_title() {
sendJson "$1" '"title": "'"$2"'"' "${URL}/setChatTitle"
@ -30,6 +34,12 @@ set_chat_description() {
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
delete_chat_photo() {
sendJson "$1" "" "${URL}/deleteChatPhoto"
@ -93,7 +103,7 @@ promote_chat_member() {
*"invite"*) arg="can_invite_users";;
*"restrict"*) arg="can_restrict_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;;
esac
# compose json

View File

@ -5,7 +5,7 @@
# This file is public domain in the USA and all free countries.
# 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
#
@ -353,9 +353,10 @@ function jssh_updateArray_async() {
# read JSON.sh style data and asssign to an ARRAY
# $1 ARRAY name, must be declared with "declare -A ARRAY" before calling
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
[ -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
# output ARRAY as JSON.sh style data

View File

@ -4,7 +4,7 @@
# File: processUpdates.sh
# 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() {
local max num debug="$1"
max="$(grep -F ',"update_id"]' <<< "${UPDATE}" | tail -1 | cut -d , -f 2 )"
# escape bash $ expansion bug
UPDATE="${UPDATE//$/\\$}"
Json2Array 'UPD' <<<"${UPDATE}"
for ((num=0; num<=max; num++)); do
process_update "${num}" "${debug}"
@ -82,7 +84,7 @@ process_update() {
process_message "${num}" "${debug}"
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]})"\
"${MESSAGE:0:30}${CAPTION:0:30}$(: "${URLS[*]//bot*:}"; printf "%s" "${_//[A-Z-]}")" >>"${UPDATELOG}"
"${MESSAGE:0:30}${CAPTION:0:30}${URLS[*]}" >>"${UPDATELOG}"
fi
#####
# process inline and message events
@ -128,7 +130,6 @@ process_inline_query() {
}
process_inline_button() {
# debugging for impelemetation
local num="$1"
iBUTTON[DATA]="${UPD["result,${num},callback_query,data"]}"
iBUTTON[CHAT_ID]="${UPD["result,${num},callback_query,message,chat,id"]}"
@ -148,7 +149,14 @@ process_message() {
# Message
MESSAGE[0]+="$(JsonDecode "${UPD["result,${num},message,text"]}" | sed 's|\\/|/|g')"
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[LAST_NAME]="$(JsonDecode "${UPD["result,${num},message,chat,last_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"]}"
fi
# Caption
CAPTION="$(JsonDecode "${UPD["result,${num},message,caption"]}")"
# Location
LOCATION[LONGITUDE]="${UPD["result,${num},message,location,longitude"]}"
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[USERNAME]="$(JsonDecode "${UPD["result,${num},message,new_chat_member,username"]}")"
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]}}"
fi
# left chat member
@ -240,16 +244,15 @@ process_message() {
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"]}"
[ -z "${MESSAGE[0]}" ] &&\
MESSAGE[0]="/_left_chat_member ${LEFTMEMBER[ID]} ${LEFTMEMBER[USERNAME]:=${LEFTMEMBER[FIRST_NAME]} ${LEFTMEMBER[LAST_NAME]}}"
fi
# chat title / photo, check for any of them!
if grep -qs -e '\["result",'"${num}"',"message","new_chat_[tp]' <<<"${UPDATE}"; then
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]}"
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]}"
fi
# pinned message
@ -257,8 +260,7 @@ process_message() {
SERVICE[PINNED]="${UPD["result,${num},message,pinned_message,message_id"]}"
PINNED[ID]="${SERVICE[PINNED]}"
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
# migrate to super group
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[ID]}" = "${MIGRATE[FROM]}" ] && CHAT[ID]="${MIGRATE[FROM]}"
SERVICE[MIGRATE]="${MIGRATE[FROM]} ${MIGRATE[TO]}"
[ -z "${MESSAGE[0]}" ] &&\
MESSAGE[0]="/_migrate_group ${SERVICE[MIGRATE]}"
MESSAGE[0]="/_migrate_group ${SERVICE[MIGRATE]}"
fi
# set SERVICE to yes if a service message was received
[[ "${SERVICE[*]}" =~ ^[[:blank:]]*$ ]] || SERVICE[0]="yes"
@ -346,8 +347,6 @@ get_updates(){
log_error "Recovered from timeout/broken/no connection, continue with telegram updates"
# calculate next sleep interval
((nextsleep+= stepsleep , nextsleep= nextsleep>maxsleep ?maxsleep:nextsleep))
# escape bash $ expansion bug
UPDATE="${UPDATE//$/\\$}"
# warn if webhook is set
if grep -q '^\["error_code"\] 409' <<<"${UPDATE}"; then
[ "${OFFSET}" != "-999" ] && nextsleep="${stepsleep}"

View File

@ -6,7 +6,7 @@
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
# shellcheck disable=SC1117
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.45-dev-24-g785e769
# will be automatically sourced from bashbot
@ -25,7 +25,6 @@ EDIT_URL=${URL}'/editMessageText'
# $1 CHAT $2 message
send_normal_message() {
local len text; text="$(JsonEscape "$2")"
text="${text//$'\n'/\\n}"
until [ -z "${text}" ]; do
if [ "${#text}" -le 4096 ]; then
sendJson "$1" '"text":"'"${text}"'"' "${MSG_URL}"
@ -38,46 +37,73 @@ send_normal_message() {
text="${text:$((len+2))}"
fi
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
send_markdown_message() {
_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
send_markdownv2_message() {
_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
send_html_message() {
_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
edit_normal_message() {
_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
edit_markdown_message() {
_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
edit_markdownv2_message() {
_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
edit_html_message() {
_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
edit_message_caption() {
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
_format_message_url(){
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."
until [ -z "${text}" ]; do
sendJson "$1" '"text":"'"${text:0:4096}"'"'"$3"'' "$4"
@ -97,7 +122,6 @@ _format_message_url(){
# $1 CHAT $2 message $3 action $4 URL
_markdownv2_message_url() {
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."
# markdown v2 needs additional double escaping!
text="$(sed -E -e 's|([_|~`>+=#{}()!.-])|\\\1|g' <<< "${text}")"
@ -120,8 +144,10 @@ send_keyboard() {
text='"text":"'"${text//$'\n'/\\n}"'"'
fi
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}'
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
@ -133,8 +159,10 @@ remove_keyboard() {
fi
sendJson "$1" "${text}"', "reply_markup": {"remove_keyboard":true}' "${MSG_URL}"
# 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}'
[[ -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
@ -177,8 +205,10 @@ _button_row() {
# raw inline functions, for special use
# $1 CHAT $2 message-id $3 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"}]<- ]}'
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() {
local text; text='"text":"'$(JsonEscape "$2")'"'; [ -z "$2" ] && text='"text":"..."'
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
@ -199,6 +230,8 @@ answer_callback_query() {
# $1 chat, $2 file_id on telegram server
send_sticker() {
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
UPLOADDIR="${BASHBOT_UPLOAD:-${DATADIR}/upload}"
# supports local file, URL and file_id
# $1 chat, $2 file https::// file_id:// , $3 caption, $4 extension (optional)
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")"
if [[ "${file}" =~ ^https*:// ]]; then
media="URL"
@ -244,28 +275,8 @@ send_file(){
else
# we have a file, check file location ...
media="FILE"
[[ "${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_message "Error in upload_file: ${BOTSENT[ERROR]}"
return
fi
file="$(checkUploadFile "$1" "$2" "send_file")"
[ -z "${file}" ] && return 1
# file OK, let's continue
fi
@ -313,24 +324,54 @@ send_file(){
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() {
[ -z "$2" ] && return
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
send_location() {
[ -z "$3" ] && return
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() {
local add=""
[ -z "$5" ] && return
[ -n "$6" ] && add=', "foursquare_id": '"$6"''
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() {
[ -z "$3" ] && return
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

View File

@ -13,7 +13,7 @@
# License: WTFPLv2 http://www.wtfpl.net/txt/copying/
# Author: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.45-dev-27-g77ffbab
#######################################################
# shellcheck disable=SC1117
@ -123,7 +123,26 @@ else
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
user_is_allowed "${USER[ID]}" "unpin" "${CHAT[ID]}" &&\
unpinall_chat_messages "${CHAT[ID]}"
@ -281,6 +300,8 @@ else
[ -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
# return 0 to retry, return non 0 to give up
bashbotBlockRecover() {
@ -291,7 +312,22 @@ else
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
my_image_search(){
@ -307,3 +343,4 @@ else
}
fi

View File

@ -11,7 +11,7 @@
# LICENSE: WTFPLv2 http://www.wtfpl.net/txt/copying/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.45-dev-21-ge67e43d
#===============================================================================
# common variables
@ -39,12 +39,12 @@ export SUCCESS NOSUCCESS
NOSUCCESS=" FAILED!"
# 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"
INPUTFILE="${DIRME}/${REFDIR}/${REFDIR}.input"
REFFILE="${DIRME}/${REFDIR}/${REFDIR}.result"
INPUTFILE2="${DIRME}/${REFDIR}/${REFDIR}2.input"
REFFILE2="${DIRME}/${REFDIR}/${REFDIR}2.result"
# reset ENVIRONMENT
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/
# AUTHOR: KayM (gnadelwartz), kay@rrr.de
#
#### $$VERSION$$ v1.40-0-gf9dab50
#### $$VERSION$$ v1.45-dev-22-g6b07242
#===============================================================================
# include common functions and definitions
@ -38,34 +38,24 @@ declare -Ax UPD
# run process_message --------------
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}")"
Json2Array 'UPD' <"${INPUTFILE}"
set -x
{ pre_process_message "0"; process_message "0"; set +x; } >>"${LOGFILE}" 2>&1;
USER[ID]="123456789"; CHAT[ID]="123456789"
for testfile in ${INPUTFILELIST}
do
printf " ... %s\n" "${testfile##*/}"
testref="${testfile%.input}.result"
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
# shellcheck disable=SC2086
print_array ${ARRAYS} >"${OUTPUTFILE}"
compare_sorted "${REFFILE}" "${OUTPUTFILE}" || exit 1
# output processed input
# shellcheck disable=SC2086
print_array ${ARRAYS} >"${OUTPUTFILE}"
compare_sorted "${testref}" "${OUTPUTFILE}" || exit 1
printf "%s\n" "${SUCCESS}"
# run process_message ------------
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}"
done
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: 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
CAPTION: 0 Myproteine kein spell check
LOCATION: LATITUDE 49.631824
LOCATION: LONGITUDE 8.377072
MESSAGE: 0 😂😝👌☺❤😕😈#⃣🌏🎉🙊🙉☕🚀✈🚂💯✔〽🔚
MESSAGE: ID 6541
MESSAGE: CAPTION Myproteine kein spell check
MESSAGE: DICE
VENUE: ADDRESS Am Rhein 1
VENUE: FOURSQUARE 4c4321afce54e21eee980d1a
VENUE: LATITUDE 49.631824

View File

@ -89,3 +89,7 @@
["result",0,"message","voice","duration"] 2
["result",0,"message","voice","mime_type"] "audio/ogg"
["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: LONGITUDE
MESSAGE: 0 /_new_chat_member 123456789 Gnadelwartz
MESSAGE: CAPTION
MESSAGE: DICE
MESSAGE: ID 123456789
SERVICE: 0 yes
SERVICE: LEFTMEMBER 123456789
SERVICE: NEWMEMBER 123456789
SERVICE: NEWPHOTO AgACAgIAAxkBAAEBFute6a3vIpB99vim811hxeu2tyQWfwACrKwxG0TMUUtDBH10RqlzGCukupIuAAMBAAMCAANhAAM3SAMAARoE
SERVICE: NEWTITLE new Testgruppe bot only
SERVICE: PINNED 3022
SERVICE: NEWPHOTO
SERVICE: NEWTITLE
NEWMEMBER: FIRST_NAME Kay
NEWMEMBER: ID 123456789
NEWMEMBER: ISBOT false
NEWMEMBER: LAST_NAME M
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"