2019-05-12 15:51:52 +00:00
#!/bin/bash
# file: modules/message.sh
# do not edit, this file will be overwritten on update
# This file is public domain in the USA and all free countries.
# Elsewhere, consider it to be WTFPLv2. (wtfpl.net/txt/copying)
#
2020-11-29 14:34:00 +00:00
# shellcheck disable=SC1117
2020-12-13 17:25:46 +00:00
#### $$VERSION$$ v1.2-dev2-12-gda7b1bc
2020-06-14 18:56:46 +00:00
# will be automatically sourced from bashbot
2020-05-14 17:47:37 +00:00
# source once magic, function named like file
eval " $( basename " ${ BASH_SOURCE [0] } " ) (){ :; } "
2019-05-12 15:51:52 +00:00
# source from commands.sh to use the sendMessage functions
MSG_URL = $URL '/sendMessage'
2020-12-13 16:19:52 +00:00
EDIT_URL = $URL '/editMessageText'
2019-05-12 15:51:52 +00:00
PHO_URL = $URL '/sendPhoto'
AUDIO_URL = $URL '/sendAudio'
DOCUMENT_URL = $URL '/sendDocument'
STICKER_URL = $URL '/sendSticker'
VIDEO_URL = $URL '/sendVideo'
VOICE_URL = $URL '/sendVoice'
LOCATION_URL = $URL '/sendLocation'
VENUE_URL = $URL '/sendVenue'
ACTION_URL = $URL '/sendChatAction'
FORWARD_URL = $URL '/forwardMessage'
2020-06-26 06:26:52 +00:00
ALBUM_URL = $URL '/sendMediaGroup'
2019-05-12 15:51:52 +00:00
2020-12-13 15:23:03 +00:00
#
# send/edit message variants ------------------
#
2020-08-15 07:47:16 +00:00
# $1 CHAT $2 message
2019-05-12 15:51:52 +00:00
send_normal_message( ) {
2020-12-13 16:19:52 +00:00
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 } "
break
else
len = 4095
[ " ${ text : 4095 : 2 } " != "\n" ] && \
len = " ${ text : 0 : 4096 } " && len = " ${ len % \\ n * } " && len = " ${# len } "
sendJson " ${ 1 } " '"text":"' " ${ text : 0 : ${ len } } " '"' " ${ MSG_URL } "
text = " ${ text : $(( len+2)) } "
fi
done
2020-12-13 15:23:03 +00:00
}
# $1 CHAT $2 message
send_markdown_message( ) {
2020-12-13 17:25:46 +00:00
_format_message_url " ${ 1 } " " ${ 2 } " ',"parse_mode":"markdown"' " ${ MSG_URL } "
2020-12-13 15:23:03 +00:00
}
# $1 CHAT $2 message
send_markdownv2_message( ) {
2020-12-13 16:19:52 +00:00
_markdownv2_message_url " ${ 1 } " " ${ 2 } " ',"parse_mode":"markdownv2"' " ${ MSG_URL } "
2020-12-13 15:23:03 +00:00
}
# $1 CHAT $2 message
send_html_message( ) {
2020-12-13 17:25:46 +00:00
_format_message_url " ${ 1 } " " ${ 2 } " ',"parse_mode":"html"' " ${ MSG_URL } "
2020-12-13 15:23:03 +00:00
}
2020-12-13 16:19:52 +00:00
# $1 CHAT $2 msg-id $3 message
edit_normal_message( ) {
2020-12-13 17:25:46 +00:00
_format_message_url " ${ 1 } " " ${ 3 } " ',"message_id":' " ${ 2 } " '' " ${ EDIT_URL } "
2020-12-13 16:19:52 +00:00
}
2020-12-13 15:23:03 +00:00
2020-12-13 16:25:44 +00:00
# $1 CHAT $2 msg-id $3 message
2020-12-13 16:19:52 +00:00
edit_markdown_message( ) {
2020-12-13 17:25:46 +00:00
_format_message_url " ${ 1 } " " ${ 3 } " ',"message_id":' " ${ 2 } " ',"parse_mode":"markdown"' " ${ EDIT_URL } "
2020-12-13 16:19:52 +00:00
}
2020-12-13 16:25:44 +00:00
# $1 CHAT $2 msg-id $3 message
2020-12-13 16:19:52 +00:00
edit_markdownv2_message( ) {
_markdownv2_message_url " ${ 1 } " " ${ 3 } " ',"message_id":' " ${ 2 } " ',"parse_mode":"markdownv2"' " ${ EDIT_URL } "
2019-05-12 15:51:52 +00:00
}
2020-12-13 16:25:44 +00:00
# $1 CHAT $2 msg-id $3 message
2020-12-13 16:19:52 +00:00
edit_html_message( ) {
2020-12-13 17:25:46 +00:00
_format_message_url " ${ 1 } " " ${ 3 } " ',"message_id":' " ${ 2 } " ',"parse_mode":"html"' " ${ EDIT_URL } "
2020-12-13 16:19:52 +00:00
}
2020-12-13 15:23:03 +00:00
# internal function, send/edit formatted message with parse_mode and URL
2020-12-13 16:19:52 +00:00
# $1 CHAT $2 message $3 action $4 URL
2020-12-13 17:25:46 +00:00
_format_message_url( ) {
2020-05-14 11:04:57 +00:00
local text; text = " $( JsonEscape " ${ 2 } " ) "
2020-08-15 07:47:16 +00:00
text = " ${ text // $'\n' / \\ n } "
2020-12-13 15:23:03 +00:00
[ " ${# text } " -ge 4096 ] && log_error "Warning: html/markdown message longer than 4096 characters, message is rejected if formatting crosses 4096 border."
2020-05-20 13:18:23 +00:00
until [ -z " ${ text } " ] ; do
2020-12-13 17:07:27 +00:00
sendJson " ${ 1 } " '"text":"' " ${ text : 0 : 4096 } " '"' " ${ 3 } " '' " ${ 4 } "
2020-05-20 13:18:23 +00:00
text = " ${ text : 4096 } "
done
}
2020-12-13 15:23:03 +00:00
# internal function, send/edit markdownv2 message with URL
2020-12-13 16:19:52 +00:00
# $1 CHAT $2 message $3 action $4 URL
2020-12-13 15:23:03 +00:00
_markdownv2_message_url( ) {
2020-05-20 13:18:23 +00:00
local text; text = " $( JsonEscape " ${ 2 } " ) "
2020-08-15 07:47:16 +00:00
text = " ${ text // $'\n' / \\ n } "
2020-12-13 15:23:03 +00:00
[ " ${# text } " -ge 4096 ] && log_error "Warning: markdownv2 message longer than 4096 characters, message is rejected if formatting crosses 4096 border."
2020-05-20 13:18:23 +00:00
# markdown v2 needs additional double escaping!
text = " $( sed -E -e 's|([#{}()!.-])|\\\1|g' <<< " $text " ) "
2019-05-12 15:51:52 +00:00
until [ -z " ${ text } " ] ; do
2020-12-13 17:07:27 +00:00
sendJson " ${ 1 } " '"text":"' " ${ text : 0 : 4096 } " '"' " ${ 3 } " '' " ${ 4 } "
2019-05-12 15:51:52 +00:00
text = " ${ text : 4096 } "
done
}
2020-12-13 15:23:03 +00:00
#
# send keyboard, buttons, files ---------------
#
2019-05-12 15:51:52 +00:00
2020-08-15 07:47:16 +00:00
# $1 CHAT $2 message $3 keyboard
2019-05-12 15:51:52 +00:00
send_keyboard( ) {
if [ [ " $3 " != *'[' * ] ] ; then old_send_keyboard " ${ @ } " ; return ; fi
2020-08-15 07:47:16 +00:00
local text = '"text":"' "Keyboard:" '"'
if [ -n " ${ 2 } " ] ; then
text = " $( JsonEscape " ${ 2 } " ) "
text = '"text":"' " ${ text // $'\n' / \\ n } " '"'
fi
2020-05-14 18:33:30 +00:00
local one_time = ', "one_time_keyboard":true' && [ -n " $4 " ] && one_time = ""
2020-06-22 21:51:07 +00:00
sendJson " ${ 1 } " " ${ text } " ', "reply_markup": {"keyboard": [ ' " ${ 3 } " ' ] ' " ${ one_time } " '}' " $MSG_URL "
2019-05-12 15:51:52 +00:00
# '"text":"$2", "reply_markup": {"keyboard": [ ${3} ], "one_time_keyboard": true}'
}
2020-08-15 07:47:16 +00:00
# $1 CHAT $2 message $3 remove
2019-05-12 15:51:52 +00:00
remove_keyboard( ) {
2020-08-15 07:47:16 +00:00
local text = '"text":"' "remove custom keyboard ..." '"'
if [ -n " ${ 2 } " ] ; then
text = " $( JsonEscape " ${ 2 } " ) "
text = '"text":"' " ${ text // $'\n' / \\ n } " '"'
fi
2020-06-27 13:37:09 +00:00
sendJson " ${ 1 } " " ${ text } " ', "reply_markup": {"remove_keyboard":true}' " $MSG_URL "
2020-08-15 07:47:16 +00:00
# delete message if no message or $3 not empty
[ [ -z " ${ 2 } " || -n " ${ 3 } " ] ] && delete_message " ${ 1 } " " ${ BOTSENT [ID] } " "nolog"
2019-05-12 15:51:52 +00:00
#JSON='"text":"$2", "reply_markup": {"remove_keyboard":true}'
}
2020-08-15 07:47:16 +00:00
# $1 CHAT $2 message $3 keyboard
2019-05-12 15:51:52 +00:00
send_inline_keyboard( ) {
2020-06-22 21:51:07 +00:00
local text; text = '"text":"' $( JsonEscape " ${ 2 } " ) '"' ; [ -z " ${ 2 } " ] && text = '"text":"' "Keyboard:" '"'
sendJson " ${ 1 } " " ${ text } " ', "reply_markup": {"inline_keyboard": [ ' " ${ 3 } " ' ]}' " $MSG_URL "
2019-05-12 15:51:52 +00:00
# JSON='"text":"$2", "reply_markup": {"inline_keyboard": [ $3->[{"text":"text", "url":"url"}]<- ]}'
}
2020-08-15 07:47:16 +00:00
# $1 CHAT $2 message $3 button text $4 URL
2019-05-12 15:51:52 +00:00
send_button( ) {
2020-05-14 11:04:57 +00:00
send_inline_keyboard " ${ 1 } " " ${ 2 } " '[ {"text":"' " $( JsonEscape " ${ 3 } " ) " '", "url":"' " ${ 4 } " '"}]'
2019-05-12 15:51:52 +00:00
}
2019-05-28 18:44:40 +00:00
UPLOADDIR = " ${ BASHBOT_UPLOAD :- ${ DATADIR } /upload } "
2019-05-13 10:47:03 +00:00
2019-05-20 15:26:21 +00:00
# for now this can only send local files with curl!
# extend to allow send files by URL or telegram ID
2019-05-12 15:51:52 +00:00
send_file( ) {
2019-05-20 15:26:21 +00:00
upload_file " ${ @ } "
}
2020-06-26 06:26:52 +00:00
if [ -z " ${ BASHBOT_WGET } " ] && _exists curl ; then
# there are no checks if URL or ID exists
# $1 chat $3 ... $n URL or ID
send_album( ) {
[ -z " ${ 1 } " ] && return 1
[ -z " ${ 3 } " ] && return 2 # minimum 2 files
local CHAT JSON IMAGE; CHAT = " ${ 1 } " ; shift
for IMAGE in " $@ "
do
[ -n " ${ JSON } " ] && JSON += ","
JSON += '{"type":"photo","media":"' ${ IMAGE } '"}'
done
# shellcheck disable=SC2086
res = " $( " ${ BASHBOT_CURL } " -s -k ${ BASHBOT_CURL_ARGS } " ${ ALBUM_URL } " -F " chat_id= ${ CHAT } " \
-F " media=[ ${ JSON } ] " | " ${ JSONSHFILE } " -s -b -n 2>/dev/null ) "
sendJsonResult " ${ res } " "send_album (curl)" " ${ CHAT } " " $@ "
[ [ -z " ${ SOURCE } " && -n " ${ BASHBOT_EVENT_SEND [*] } " ] ] && event_send "album" " $@ " &
}
else
send_album( ) {
2020-06-27 10:49:20 +00:00
log_error "Sorry, wget Album upload not yet implemented"
2020-06-26 06:26:52 +00:00
BOTSENT[ OK] = "false"
[ [ -z " ${ SOURCE } " && -n " ${ BASHBOT_EVENT_SEND [*] } " ] ] && event_send "album" " $@ " &
}
fi
2019-05-20 15:26:21 +00:00
upload_file( ) {
2019-05-20 13:43:37 +00:00
local CUR_URL WHAT STATUS file = " $2 "
2019-05-13 10:47:03 +00:00
# file access checks ...
2019-05-20 13:43:37 +00:00
[ [ " $file " = *'..' * ] ] && return # no directory traversal
[ [ " $file " = '.' * ] ] && return # no hidden or relative files
2019-05-13 10:47:03 +00:00
if [ [ " $file " = '/' * ] ] ; then
2020-06-23 14:35:50 +00:00
[ [ ! " $file " = ~ $FILE_REGEX ] ] && return # absolute must match REGEX
2019-05-13 10:47:03 +00:00
else
file = " ${ UPLOADDIR :- NOUPLOADDIR } / ${ file } " # othiers must be in UPLOADDIR
fi
2019-05-20 13:43:37 +00:00
[ ! -r " $file " ] && return # and file must exits of course
2019-05-13 10:47:03 +00:00
2019-05-12 15:51:52 +00:00
local ext = " ${ file ##*. } "
case $ext in
mp3| flac)
2019-05-14 13:25:15 +00:00
CUR_URL = " $AUDIO_URL "
WHAT = "audio"
STATUS = "upload_audio"
2019-05-12 15:51:52 +00:00
; ;
2020-05-14 11:04:57 +00:00
png| jpg| jpeg| gif| pic)
2019-05-14 13:25:15 +00:00
CUR_URL = " $PHO_URL "
WHAT = "photo"
STATUS = "upload_photo"
2019-05-12 15:51:52 +00:00
; ;
webp)
2019-05-14 13:25:15 +00:00
CUR_URL = " $STICKER_URL "
WHAT = "sticker"
STATUS = "upload_photo"
2019-05-12 15:51:52 +00:00
; ;
mp4)
2019-05-14 13:25:15 +00:00
CUR_URL = " $VIDEO_URL "
WHAT = "video"
STATUS = "upload_video"
2019-05-12 15:51:52 +00:00
; ;
ogg)
2019-05-14 13:25:15 +00:00
CUR_URL = " $VOICE_URL "
WHAT = "voice"
STATUS = "upload_audio"
2019-05-12 15:51:52 +00:00
; ;
*)
2019-05-14 13:25:15 +00:00
CUR_URL = " $DOCUMENT_URL "
WHAT = "document"
STATUS = "upload_document"
2019-05-12 15:51:52 +00:00
; ;
esac
2019-05-14 13:25:15 +00:00
send_action " ${ 1 } " " $STATUS "
2019-05-20 15:26:21 +00:00
sendUpload " $1 " " ${ WHAT } " " ${ file } " " ${ CUR_URL } " " $3 "
2019-05-12 15:51:52 +00:00
}
# typing for text messages, upload_photo for photos, record_video or upload_video for videos, record_audio or upload_audio for audio files, upload_document for general files, find_location for location
send_action( ) {
2020-05-14 18:33:30 +00:00
[ -z " $2 " ] && return
2020-05-14 21:04:08 +00:00
sendJson " ${ 1 } " '"action": "' " ${ 2 } " '"' " $ACTION_URL " &
2019-05-12 15:51:52 +00:00
}
2020-08-15 07:47:16 +00:00
# $1 CHAT $2 lat $3 long
2019-05-12 15:51:52 +00:00
send_location( ) {
2020-05-14 18:33:30 +00:00
[ -z " $3 " ] && return
2019-05-12 15:51:52 +00:00
sendJson " ${ 1 } " '"latitude": ' " ${ 2 } " ', "longitude": ' " ${ 3 } " '' " $LOCATION_URL "
}
2020-08-15 07:47:16 +00:00
# $1 CHAT $2 lat $3 long $4 title $5 address $6 foursquard id
2019-05-12 15:51:52 +00:00
send_venue( ) {
local add = ""
2020-05-14 18:33:30 +00:00
[ -z " $5 " ] && return
[ -n " $6 " ] && add = ', "foursquare_id": ' " $6 " ''
2019-05-12 15:51:52 +00:00
sendJson " ${ 1 } " '"latitude": ' " ${ 2 } " ', "longitude": ' " ${ 3 } " ', "address": "' " ${ 5 } " '", "title": "' " ${ 4 } " '"' " ${ add } " " $VENUE_URL "
}
2020-12-13 15:23:03 +00:00
#
# other send message variants ---------------------------------
#
2020-08-15 07:47:16 +00:00
# $1 CHAT $2 from chat $3 from msg id
2019-05-12 15:51:52 +00:00
forward_message( ) {
2020-05-14 18:33:30 +00:00
[ -z " $3 " ] && return
2019-05-12 15:51:52 +00:00
sendJson " ${ 1 } " '"from_chat_id": ' " ${ 2 } " ', "message_id": ' " ${ 3 } " '' " $FORWARD_URL "
}
forward( ) { # backward compatibility
forward_message " $@ " || return
}
2020-08-15 07:47:16 +00:00
# $1 CHAT $2 bashbot formatted message, see manual advanced usage
2019-05-12 15:51:52 +00:00
send_message( ) {
2020-05-14 18:33:30 +00:00
[ -z " $2 " ] && return
2019-05-12 15:51:52 +00:00
local text keyboard btext burl no_keyboard file lat long title address sent
text = " $( sed <<< " ${ 2 } " 's/ mykeyboardend.*//;s/ *my[kfltab][a-z]\{2,13\}startshere.*//' ) $( sed <<< " ${ 2 } " -n '/mytextstartshere/ s/.*mytextstartshere//p' ) "
2020-06-20 11:19:45 +00:00
#shellcheck disable=SC2001
text = " $( sed <<< " ${ text } " 's/ *mynewlinestartshere */\\n/g' ) "
2020-06-19 16:50:55 +00:00
text = " ${ text // $'\n' / \\ n } "
2019-05-12 15:51:52 +00:00
[ " $3 " != "safe" ] && {
no_keyboard = " $( sed <<< " ${ 2 } " '/mykeyboardendshere/!d;s/.*mykeyboardendshere.*/mykeyboardendshere/' ) "
keyboard = " $( sed <<< " ${ 2 } " '/mykeyboardstartshere /!d;s/.*mykeyboardstartshere *//;s/ *my[nkfltab][a-z]\{2,13\}startshere.*//;s/ *mykeyboardendshere.*//' ) "
btext = " $( sed <<< " ${ 2 } " '/mybtextstartshere /!d;s/.*mybtextstartshere //;s/ *my[nkfltab][a-z]\{2,13\}startshere.*//;s/ *mykeyboardendshere.*//' ) "
burl = " $( sed <<< " ${ 2 } " '/myburlstartshere /!d;s/.*myburlstartshere //;s/ *my[nkfltab][a-z]\{2,13\}startshere.*//g;s/ *mykeyboardendshere.*//g' ) "
file = " $( sed <<< " ${ 2 } " '/myfilelocationstartshere /!d;s/.*myfilelocationstartshere //;s/ *my[nkfltab][a-z]\{2,13\}startshere.*//;s/ *mykeyboardendshere.*//' ) "
lat = " $( sed <<< " ${ 2 } " '/mylatstartshere /!d;s/.*mylatstartshere //;s/ *my[nkfltab][a-z]\{2,13\}startshere.*//;s/ *mykeyboardendshere.*//' ) "
long = " $( sed <<< " ${ 2 } " '/mylongstartshere /!d;s/.*mylongstartshere //;s/ *my[nkfltab][a-z]\{2,13\}startshere.*//;s/ *mykeyboardendshere.*//' ) "
title = " $( sed <<< " ${ 2 } " '/mytitlestartshere /!d;s/.*mytitlestartshere //;s/ *my[kfltab][a-z]\{2,13\}startshere.*//;s/ *mykeyboardendshere.*//' ) "
address = " $( sed <<< " ${ 2 } " '/myaddressstartshere /!d;s/.*myaddressstartshere //;s/ *my[nkfltab][a-z]\{2,13\}startshere.*//;s/ *mykeyboardendshere.*//' ) "
}
2020-05-14 18:33:30 +00:00
if [ -n " $no_keyboard " ] ; then
2019-05-12 15:51:52 +00:00
remove_keyboard " $1 " " $text "
sent = y
fi
2020-05-14 18:33:30 +00:00
if [ -n " $keyboard " ] ; then
2019-05-12 15:51:52 +00:00
if [ [ " $keyboard " != *"[" * ] ] ; then # pre 0.60 style
keyboard = " [ ${ keyboard // \" \" / \" \] , \[ \" } ] "
fi
send_keyboard " $1 " " $text " " $keyboard "
sent = y
fi
2020-05-14 18:33:30 +00:00
if [ -n " $btext " ] && [ -n " $burl " ] ; then
2019-05-12 15:51:52 +00:00
send_button " $1 " " $text " " $btext " " $burl "
sent = y
fi
2020-05-14 18:33:30 +00:00
if [ -n " $file " ] ; then
2019-05-12 15:51:52 +00:00
send_file " $1 " " $file " " $text "
sent = y
fi
2020-05-14 18:33:30 +00:00
if [ -n " $lat " ] && [ -n " $long " ] ; then
if [ -n " $address " ] && [ -n " $title " ] ; then
2019-05-12 15:51:52 +00:00
send_venue " $1 " " $lat " " $long " " $title " " $address "
else
send_location " $1 " " $lat " " $long "
fi
sent = y
fi
if [ " $sent " != "y" ] ; then
send_text " $1 " " $text "
fi
}
2020-08-15 07:47:16 +00:00
# $1 CHAT $2 message starting possibly with html_parse_mode or markdown_parse_mode
# not working, fix or remove after 1.0!!
2019-05-12 15:51:52 +00:00
send_text( ) {
case " $2 " in
2020-06-19 16:50:55 +00:00
'html_parse_mode' *)
2019-05-12 15:51:52 +00:00
send_html_message " $1 " " ${ 2 //html_parse_mode } "
; ;
2020-06-19 16:50:55 +00:00
'markdown_parse_mode' *)
2019-05-12 15:51:52 +00:00
send_markdown_message " $1 " " ${ 2 //markdown_parse_mode } "
; ;
*)
send_normal_message " $1 " " $2 "
; ;
esac
}