From 0970259080453f1c742e13faf627023412966aae Mon Sep 17 00:00:00 2001 From: Dominika Liberda Date: Thu, 2 Sep 2021 18:13:01 +0200 Subject: [PATCH] + README, minor fixes --- README.md | 22 ++++++ tg.sh | 222 ++++++++++++++++++++++++++++-------------------------- 2 files changed, 136 insertions(+), 108 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..69bf8d7 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# telegram.sh, a telegram bot api library in bash + +This library aims to make creating quick-and-dirty bots in Bash as easy as possible. + +``` +#!/bin/bash +source tg.sh +TELEGRAM_TOKEN="" + +function _on_msg() { + echo "${event[from_username]}: ${event[text]}" + + if [[ "${event[text]}" == "o/" ]]; then + tg_send ${event[chat_id]} "\o" + fi +} + +tg_start +``` + +The above example is all you need to create a basic telegram bot. +The library is currently very WiP. Please proceed with caution. diff --git a/tg.sh b/tg.sh index 01140e6..6fc304a 100755 --- a/tg.sh +++ b/tg.sh @@ -2,8 +2,13 @@ TELEGRAM_TOKEN="" PARSE_MODE="MarkdownV2" +function _escape_text() { + sed 's/[][`~!@#$%^&*():;<>.,?\|{}=+-]/\\&/g' <<< "$1" +} + # tg_send(chat, text, file, type) -function tg_send_message() { +function tg_send() { + text="$(_escape_text "$2")" if [[ $3 != '' ]]; then local type_snake=$4 [[ $4 == '' ]] && local type_snake='document' @@ -15,16 +20,16 @@ function tg_send_message() { [[ $4 == 'voice' ]] && local type="Voice" [[ $4 == 'video_note' ]] && local type="VideoNote" - curl -s + curl -s \ -F chat_id=$1 \ - -F caption="$2" \ + -F caption="$text" \ -F parse_mode=$PARSE_MODE \ -F $type_snake=@$3 \ "https://api.telegram.org/bot${TELEGRAM_TOKEN}/send${type}" else - curl -s + curl -s \ -F chat_id=$1 \ - -F text="$2" \ + -F text="$text" \ -F parse_mode=$PARSE_MODE \ "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" fi @@ -82,110 +87,111 @@ function _on_voice() { #jq_to_array(jq_expression) function _jq_to_array() { - declare -ga "_tmp=($(jq -r "$1" | sed 's/[][`~!@#$%^&*():;<>.,?/\|{}=+-]/\\&/g' ))" + declare -ga "_tmp=($(jq -r "$1" | sed 's/[][`~!@#$%^&*():;<>.,?\|{}=+-]/\\&/g;'"s@\\\'@\\'@g" ))" } - -_offset=0 -while true; do - IFS=$'\n' - _events=($(_tg_get_updates $_offset 10)) - unset IFS - - for (( i=0; i<${#_events[@]}; i++ )); do - declare -A event - _msg_type="$(jq -r '(select(.message) | "message"), (select(.edited_message) | "edited_message")' <<< "${_events[$i]}")" - _event_type="$(jq -r '(select(.message) | .message), (select(.edited_message) | .edited_message) | ( - (select(.animation) | "animation"), - (select(.audio) | "audio"), - (select(.document) | "document"), - (select(.photo) | "photo"), - (select(.sticker) | "sticker"), - (select(.video) | "video"), - (select(.video_note) | "video_note"), - (select(.voice) | "voice"))' <<< "${_events[$i]}")" - - _jq_to_array '(select(.message) | .message), (select(.edited_message) | .edited_message) | - [.message_id, - .from.id, - .from.is_bot, - .from.first_name, - .from.last_name, - .from.username, - .chat.id, - (if .chat.type == "private" then .chat.username else .chat.title end), - .chat.type, - .date, - .text, - (if .reply_to_message then - .reply_to_message | ( - "true", - .message_id, - .from.id, - .from.is_bot, - .from.first_name, - .from.last_name, - .from.username, - .date, - .text - ) - else - "false" - end)] - | @sh' <<< "${_events[$i]}" - - event[message_id]="${_tmp[0]}" - event[from_id]="${_tmp[1]}" - event[from_is_bot]="${_tmp[2]}" - event[from_first_name]="${_tmp[3]}" - event[from_last_name]="${_tmp[4]}" - event[from_username]="${_tmp[5]}" - event[chat_id]="${_tmp[6]}" - event[chat_title]="${_tmp[7]}" - event[chat_type]="${_tmp[8]}" - event[date]="${_tmp[9]}" - event[text]="${_tmp[10]}" - - if [[ "${_tmp[11]}" == "true" ]]; then - event[reply]=true - event[reply_message_id]="${_tmp[12]}" - event[reply_from_id]="${_tmp[13]}" - event[reply_from_is_bot]="${_tmp[14]}" - event[reply_from_first_name]="${_tmp[15]}" - event[reply_from_last_name]="${_tmp[16]}" - event[reply_from_username]="${_tmp[17]}" - event[reply_date]="${_tmp[18]}" - event[reply_text]="${_tmp[19]}" - else - event[reply]=false - fi +function tg_start() { + _offset=0 + while true; do + IFS=$'\n' + _events=($(_tg_get_updates $_offset 10)) + unset IFS - event[type]="$_msg_type" - event[json]="${_events[$i]}" - if [[ "$_msg_type" == edited_message ]]; then - _on_edit - elif [[ "$_event_type" == animation ]]; then - _on_animation - elif [[ "$_event_type" == audio ]]; then - _on_audio - elif [[ "$_event_type" == document ]]; then - _on_document - elif [[ "$_event_type" == photo ]]; then - _on_photo - elif [[ "$_event_type" == sticker ]]; then - _on_sticker - elif [[ "$_event_type" == video ]]; then - _on_video - elif [[ "$_event_type" == video_note ]]; then - _on_video_note - elif [[ "$_event_type" == voice ]]; then - _on_voice - else - _on_msg - fi - unset event + for (( i=0; i<${#_events[@]}; i++ )); do + declare -A event + _msg_type="$(jq -r '(select(.message) | "message"), (select(.edited_message) | "edited_message")' <<< "${_events[$i]}")" + _event_type="$(jq -r '(select(.message) | .message), (select(.edited_message) | .edited_message) | ( + (select(.animation) | "animation"), + (select(.audio) | "audio"), + (select(.document) | "document"), + (select(.photo) | "photo"), + (select(.sticker) | "sticker"), + (select(.video) | "video"), + (select(.video_note) | "video_note"), + (select(.voice) | "voice"))' <<< "${_events[$i]}")" + + _jq_to_array '(select(.message) | .message), (select(.edited_message) | .edited_message) | + [.message_id, + .from.id, + .from.is_bot, + .from.first_name, + .from.last_name, + .from.username, + .chat.id, + (if .chat.type == "private" then .chat.username else .chat.title end), + .chat.type, + .date, + .text, + (if .reply_to_message then + .reply_to_message | ( + "true", + .message_id, + .from.id, + .from.is_bot, + .from.first_name, + .from.last_name, + .from.username, + .date, + .text + ) + else + "false" + end)] + | @sh' <<< "${_events[$i]}" + + event[message_id]="${_tmp[0]}" + event[from_id]="${_tmp[1]}" + event[from_is_bot]="${_tmp[2]}" + event[from_first_name]="${_tmp[3]}" + event[from_last_name]="${_tmp[4]}" + event[from_username]="${_tmp[5]}" + event[chat_id]="${_tmp[6]}" + event[chat_title]="${_tmp[7]}" + event[chat_type]="${_tmp[8]}" + event[date]="${_tmp[9]}" + event[text]="${_tmp[10]}" + + if [[ "${_tmp[11]}" == "true" ]]; then + event[reply]=true + event[reply_message_id]="${_tmp[12]}" + event[reply_from_id]="${_tmp[13]}" + event[reply_from_is_bot]="${_tmp[14]}" + event[reply_from_first_name]="${_tmp[15]}" + event[reply_from_last_name]="${_tmp[16]}" + event[reply_from_username]="${_tmp[17]}" + event[reply_date]="${_tmp[18]}" + event[reply_text]="${_tmp[19]}" + else + event[reply]=false + fi + + event[type]="$_msg_type" + event[json]="${_events[$i]}" + if [[ "$_msg_type" == edited_message ]]; then + _on_edit + elif [[ "$_event_type" == animation ]]; then + _on_animation + elif [[ "$_event_type" == audio ]]; then + _on_audio + elif [[ "$_event_type" == document ]]; then + _on_document + elif [[ "$_event_type" == photo ]]; then + _on_photo + elif [[ "$_event_type" == sticker ]]; then + _on_sticker + elif [[ "$_event_type" == video ]]; then + _on_video + elif [[ "$_event_type" == video_note ]]; then + _on_video_note + elif [[ "$_event_type" == voice ]]; then + _on_voice + else + _on_msg + fi + unset event + done + [[ ${#_events[@]} -gt 0 ]] && _update_id=$(jq 'select(.update_id != null) | .update_id' <<< "${_events[-1]}") + [[ $_update_id != '' ]] && _offset=$((_update_id+1)) + echo $_offset done - [[ ${#_events[@]} -gt 0 ]] && _update_id=$(jq 'select(.update_id != null) | .update_id' <<< "${_events[-1]}") - [[ $_update_id != '' ]] && _offset=$((_update_id+1)) - echo $_offset -done +}