forked from antoninguyot/telegram-sh
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
anto2oo
committed
May 29, 2018
0 parents
commit e4405c0
Showing
3 changed files
with
157 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# telegram-sh | ||
telegram-sh is a lightweight and fast telegram bot that you can fully customize to your needs. It is written in such a way that it almost doesn't interact with your request so that it doesn't need to be updated everytime telegram adds something to their API. | ||
|
||
## Setting it up | ||
|
||
**Dependencies** : | ||
- jq | ||
- bash >= 4 | ||
|
||
To start your bot (and thus update polling), just start the script with bash : `bash telegram.sh`. You should get a message like `"Started long polling..."`. | ||
|
||
It is recommanded to use `tmux` or `screen` to keep the script running in the background. | ||
|
||
## Getting data | ||
|
||
You can see at the top of `telegram.sh` the following line : `path="commands.sh"`. This represent the script files that will be executed everytime someone sends a message to the bot. | ||
It supports wildcards, for example you could set it to `functions/*.func.sh` to execute every script ending with `.func.sh` in `functions`. | ||
|
||
The script files executed will be allowed to access variables related to the message sent to the bot. The variable structure uses an associative array (that requires bash 4) and is formatted in the following way : | ||
|
||
`${UPDATE_OBJECT[FIELD_NAME.OBJECT.VALUE]}` | ||
|
||
For instance, if you want to get the chat id of a message, the variable storing it will be `${message[chat.id]}`. If you need the message_id attribute of an edited message, then the variable will be `${edited_message[message_id]}`. | ||
|
||
This can be a little tricky to use at first, but it's very logic when you get used to it. You can get the full Telegram API data structure by looking at [Bot API types](https://core.telegram.org/bots/api#available-types) on the bot API docs. | ||
|
||
## Sending data | ||
|
||
To send data to Telegram (messages to users for instance), you'll need to use the `post` function in your scripts. `post` accepts the following syntax : | ||
|
||
`post METHOD param1="some data" param2="some data"` | ||
|
||
For example, here's a line that answer a message containing `Hello world` to anyone who sent a message to the bot : | ||
`post sendMessage chat_id="${message[from.id]}" text="Hello world"` | ||
|
||
You can get the full list of available methods on telegram [bots methods doc page](https://core.telegram.org/bots/api#available-methods). You must use the exact same name as described on the documentation with the post function (case-insensitive). You must also use the same arguments as described in the doc, passing them to `post` in the order that you want. | ||
Example : | ||
`post deleteMessage chat_id="xxx" message_id="xxx"` is the same as `post deleteMessage message_id="xxx" chat_id="xxx" ` | ||
|
||
## Example | ||
|
||
You can find the default `commands.sh` that contains a sample program that sends an `Hello world` message to everyone that sends `/start`. You can take a look at it : | ||
``` | ||
case "${message[text]}" in | ||
'/start') | ||
post sendMessage chat_id="${message[chat.id]}" text="Your bot is working ! This a just a sample message that you can modify in the commands.sh file. | ||
It allows multiline messages too (and is full UTF-8 compatible 😊)." | ||
;; | ||
esac | ||
``` | ||
You can of course do much more advanced message proccessing after this. | ||
|
||
Enjoy ! 😊 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
case "${message[text]}" in | ||
'/start') | ||
post sendMessage chat_id="${message[chat.id]}" text="Your bot is working ! This a just a sample message that you can modify in the commands.sh file. | ||
It allows multiline messages too (and is full UTF-8 compatible 😊)." | ||
;; | ||
esac |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#!/bin/bash | ||
|
||
### Config ### | ||
|
||
# This should be your telegram bot token | ||
token="you should write your token here" | ||
|
||
# This is the address where request will be made | ||
base_url="https://api.telegram.org/bot" | ||
|
||
# This defines what command files will be executed | ||
path="commands.sh" | ||
# Note : can be set to mutliple files with * | ||
# path="commands/*.sh" | ||
|
||
# Please don't change this | ||
offset=0 | ||
|
||
function post() { | ||
|
||
get_method="$1" | ||
target="$base_url$token/$get_method" | ||
|
||
declare -A request | ||
|
||
# Catching every argument with = and adding to to an associative aray | ||
while :; do | ||
case $2 in | ||
?*=?*) | ||
request[${2%=*}]="${2%=*}=${2#*=}" | ||
;; | ||
|
||
*) | ||
break | ||
;; | ||
esac | ||
shift | ||
done | ||
|
||
# Sending the request by listing the array | ||
QUERY=$(curl -s "$target" "${request[@]/#/-d}") | ||
|
||
# Basic response parsing | ||
if [ $(echo "$QUERY" | jq -cr '.ok') == "true" ]; then | ||
echo "[SENT] method : $get_method" | ||
else | ||
echo "[ERROR] $(echo "$QUERY" | jq -cr '.')" | ||
fi | ||
|
||
} | ||
|
||
function parse() { | ||
|
||
# Declare an associative array for the type of request | ||
declare -A $(echo "$REQUEST" | jq -cr '.result[0] | del(.update_id) | keys | .[]') | ||
|
||
# Parsing and saving every var | ||
eval "$(echo "$REQUEST" | jq -cr '.result[0] | del(.update_id) | tostream | select(length==2) | .[0] |= map(strings) | flatten | "\(.[:1] |.[])[\(.[1:-1] | join("."))]=\"\(.[-1])\""')" | ||
|
||
# Source every file ending with .func.sh | ||
for file in "$path" ; do | ||
if [ -f "$file" ] ; then | ||
. "$file" | ||
fi | ||
done | ||
} | ||
|
||
# If not sourced, start long polling | ||
if [ "$0" = "$BASH_SOURCE" ]; then | ||
|
||
echo "Started long polling..." | ||
while : | ||
do | ||
|
||
REQUEST=$(curl -s "$base_url$token/getUpdates?offset=$offset&timeout=60&limit=1") | ||
|
||
OFFSET_DATA=$(echo "$REQUEST" | jq -cr '.result|.[0].update_id') | ||
|
||
# Check if new update is detected | ||
if [ ! "$OFFSET_DATA" == "null" ]; then | ||
|
||
# Check if jq failed to parse offset | ||
if [ ! -z "$OFFSET_DATA" ]; then | ||
|
||
# If jq was okay, continue parsing | ||
offset=$((OFFSET_DATA+1)) | ||
echo "[RECEIVED] update $offset" | ||
parse | ||
else | ||
|
||
# Handles exception by skipping the request | ||
offset=$((offset+1)) | ||
echo "[ERROR] couldn't parse $offset, skipping..." | ||
fi | ||
|
||
fi | ||
done | ||
fi |