TelegramApiServer/README.md

327 lines
14 KiB
Markdown
Raw Normal View History

# TelegramApiServer
2019-06-09 19:18:49 +02:00
Fast, simple, async php telegram api server:
2020-06-08 23:45:22 +02:00
[MadelineProto](https://github.com/danog/MadelineProto) and [Amp](https://github.com/amphp/amp) Http Server
2020-06-08 23:45:22 +02:00
* Online demo (getHistory + Media Download): [tg.i-c-a.su](https://tg.i-c-a.su)
2019-06-02 18:22:03 +02:00
* My content aggregator: [i-c-a.su](https://i-c-a.su)
2020-06-08 23:45:22 +02:00
* Get telegram channels in RSS: [TelegramRSS](https://github.com/xtrime-ru/TelegramRSS)
2020-01-18 15:38:26 +01:00
## Features
2020-06-08 23:45:22 +02:00
* Fast async Amp Http Server
* Full access to telegram api: bot and user
2020-01-18 15:38:26 +01:00
* Multiple sessions
2020-06-08 23:45:22 +02:00
* Stream media (view files in a browser)
2020-02-08 01:53:17 +01:00
* Upload media
2020-06-08 23:45:22 +02:00
* Websocket endpoints for events and logs
* MadelineProto optimized settings to reduce memory consumption
2019-06-02 18:22:03 +02:00
2020-01-13 22:01:48 +01:00
**Architecture Example**
![Architecture Example](https://hsto.org/webt/j-/ob/ky/j-obkye1dv68ngsrgi12qevutra.png)
2019-06-02 18:22:03 +02:00
2020-01-18 15:38:26 +01:00
## Installation
2020-06-08 23:45:22 +02:00
### Docker:
2020-07-01 21:28:54 +02:00
1. `git clone https://github.com/xtrime-ru/TelegramApiServer.git TelegramApiServer`
1. `cd TelegramApiServer`
1. Start container: `docker-compose up`
2020-06-08 23:45:22 +02:00
Folder will be linked inside container to store all necessary data: sessions, env, db.
### Manual:
2020-07-01 21:28:54 +02:00
1. Requirements:
* ssh / cli
* php 7.4
* composer
* git
* Mysql/MariaDB (optional)
* [MadelindeProto Requirements](https://docs.madelineproto.xyz/docs/REQUIREMENTS.html)
* [Amp Requirements](https://github.com/amphp/amp#requirements)
* XAMPP (for Windows)
2020-06-08 23:45:22 +02:00
1. `git clone https://github.com/xtrime-ru/TelegramApiServer.git TelegramApiServer`
2020-06-13 21:26:44 +02:00
1. `cd TelegramApiServer`
2020-06-08 23:45:22 +02:00
1. `composer install -o --no-dev`
1. `php server.php`
## First start
1. Ctrl + C to stop TelegramApiServer if running.
2020-05-12 13:49:45 +02:00
1. Get app_id and app_hash at [my.telegram.org](https://my.telegram.org/).
Only one app_id needed for any amount of users and bots.
2020-06-08 23:45:22 +02:00
1. Fill app_id and app_hash in `.env.docker` or `.env`.
1. Start TelegramApiServer in cli:
* docker:
1. Start: `docker-compose up`
1. Connect to docker container: `bash bin/docker-exec.sh`
2020-06-08 23:55:14 +02:00
1. Start another instance with different port: `php server.php --docker --port=9500 --session=session`
2020-06-08 23:45:22 +02:00
* manual:
1. `php server.php --session=session`
1. Authorize your session:
1. chose manual mode (`m`)
1. Chose account type: user (`u`) or bot (`b`)
1. Follow instructions
1. Wait 10-30 seconds until authorization is end and exit with `Ctrl + C`.
2020-05-12 13:49:45 +02:00
1. Run TAS in screen, tmux, supervisor (see below) or docker.
2020-01-18 15:38:26 +01:00
## Usage
1. Run server/parser
```
2020-06-25 00:33:18 +02:00
usage: php server.php [--help] [-a=|--address=127.0.0.1] [-p=|--port=9503] [-s=|--session=] [-e=|--env=.env] [--docker]
Options:
--help Show this message
2020-01-15 00:00:58 +01:00
-a --address Server ip (optional) (default: 127.0.0.1)
To listen external connections use 0.0.0.0 and fill IP_WHITELIST in .env
-p --port Server port (optional) (default: 9503)
2020-01-19 04:17:14 +01:00
-s --session Name for session file (optional)
2020-01-15 00:00:58 +01:00
Multiple sessions can be specified: "--session=user --session=bot"
2020-06-25 00:33:18 +02:00
Each session is stored in `sessions/{$session}.madeline`.
2020-01-15 00:00:58 +01:00
Nested folders supported.
See README for more examples.
2020-06-25 00:33:18 +02:00
-e --env .env file name. (default: .env).
Helpful when need multiple instances with different settings
--docker Apply some settings for docker: add docker network to whitelist.
Also some options can be set in .env file (see .env.example)
```
2020-02-08 01:53:17 +01:00
1. Access Telegram API with simple GET/POST requests.
2020-02-06 00:52:47 +01:00
Regular and application/json POST supported.
2020-02-08 01:53:17 +01:00
Its recommended to use http_build_query, when using GET requests.
2020-01-18 15:38:26 +01:00
**Rules:**
2019-02-03 19:17:38 +01:00
* All methods from MadelineProto supported: [Methods List](https://docs.madelineproto.xyz/API_docs/methods/)
2020-01-15 00:00:58 +01:00
* Url: `http://%address%:%port%/api[/%session%]/%class%.%method%/?%param%=%val%`
2019-01-20 18:20:41 +01:00
* <b>Important: api available only from ip in whitelist.</b>
By default it is: `127.0.0.1`
You can add client ip in .env file to `API_CLIENT_WHITELIST` (use json format)
2019-02-03 19:17:38 +01:00
* If method is inside class (messages, contacts and etc.) use '.' to separate class from method:
`http://127.0.0.1:9503/api/contacts.getContacts`
* If method requires array of values, use any name of array, for example 'data':
`?data[peer]=@xtrime&data[message]=Hello!`. Order of parameters does't matter in this case.
* If method requires one or multiple separate parameters (not inside array) then pass parameters with any names but **in strict order**:
2019-06-21 20:44:20 +02:00
`http://127.0.0.1:9503/api/getInfo/?id=@xtrime` or `http://127.0.0.1:9503/api/getInfo/?abcd=@xtrime` works the same
2020-01-12 00:11:18 +01:00
2020-01-18 15:38:26 +01:00
**Examples:**
2019-06-21 20:44:20 +02:00
* get_info about channel/user: `http://127.0.0.1:9503/api/getInfo/?id=@xtrime`
* get_info about currect account: `http://127.0.0.1:9503/api/getSelf`
2019-02-03 19:17:38 +01:00
* repost: `http://127.0.0.1:9503/api/messages.forwardMessages/?data[from_peer]=@xtrime&data[to_peer]=@xtrime&data[id]=1234`
2019-01-20 18:20:41 +01:00
* get messages from channel/user: `http://127.0.0.1:9503/api/getHistory/?data[peer]=@breakingmash&data[limit]=10`
2019-11-22 23:58:52 +01:00
* get messages with text in HTML: `http://127.0.0.1:9503/api/getHistoryHtml/?data[peer]=@breakingmash&data[limit]=10`
2019-01-22 23:03:36 +01:00
* search: `http://127.0.0.1:9503/api/searchGlobal/?data[q]=Hello%20World&data[limit]=10`
2019-01-20 18:20:41 +01:00
* sendMessage: `http://127.0.0.1:9503/api/sendMessage/?data[peer]=@xtrime&data[message]=Hello!`
2020-01-15 00:00:58 +01:00
* copy message from one channel to another (not repost): `http://127.0.0.1:9503/api/copyMessages/?data[from_peer]=@xtrime&data[to_peer]=@xtrime&data[id][0]=1`
2020-01-13 00:02:29 +01:00
2020-06-08 23:45:22 +02:00
## Run in background
* Docker: `docker compose up -d`
Docker will monitor and restart containers.
* Manual:
1. Use [http://supervisord.org](supervisor) to monitor and restart swoole/amphp servers.
1. `apt-get install supervisor`
1. Put config file in `/etc/supervisor/conf.d/telegram_api_server.conf`. Example:
```
[program:telegram_api_server]
command=/usr/bin/php /home/admin/web/tg.i-c-a.su/TelegramApiServer/server.php --session=*
numprocs=1
directory=/home/admin/web/tg.i-c-a.su/TelegramApiServer/
autostart=true
autorestart=true
startretries=10
stdout_logfile=/var/log/telegram/stdout.log
redirect_stderr=true
```
1. Load new config: `supervisorctl update`
1. View/control processes: `supervisorctl`
## Update
* `git fetch && git reset --hard origin/master`
* `composer install -o --no-dev`
* Compare `.env.docker` or `.env` with corresponding `.env.example`. Update if needed.
* `docker-compose restart` or `supervisorctl restart telegram_api_server`
2020-01-18 15:38:26 +01:00
## Advanced features
2020-02-08 01:54:32 +01:00
### Uploading files.
2020-01-13 00:02:29 +01:00
2020-05-11 00:50:29 +02:00
There are few options to upload and send media files:
- Custom method `sendMedia` supports upload from form:
2020-07-01 21:28:54 +02:00
```shell script
2020-05-11 00:50:29 +02:00
curl "http://127.0.0.1:9503/api/sendMedia?data[peer]=xtrime&data[message]=Hello" -g \
-F "file=@/Users/xtrime/Downloads/test.txt"
```
- use custom `uploadMediaForm` method and then pass result to `messages.sendMedia`:
1. `curl "http://127.0.0.1:9503/api/uploadMediaForm" -g -F "file=@/Users/xtrime/Downloads/test.txt"`
Method supports `application/x-www-form-urlencoded` and `multipart/form-data`.
2. Send result from `uploadMediaForm` to `messages.sendMedia` or `sendMedia`:
2020-07-01 21:28:54 +02:00
```shell script
2020-05-11 00:50:29 +02:00
curl --location --request POST 'http://127.0.0.1:9503/api/sendMedia' \
--header 'Content-Type: application/json' \
--data-raw '{
"data":{
"peer": "@xtrime",
"media": {
"_": "inputMediaUploadedDocument",
"file": {
"_": "inputFile",
"id": 1164670976363200575,
"parts": 1,
"name": "test.txt",
"mime_type": "text/plain",
"md5_checksum": ""
},
"attributes": [
{
"_": "documentAttributeFilename",
"file_name": "test.txt"
}
]
}
2020-02-08 01:53:17 +01:00
}
2020-05-11 00:50:29 +02:00
}'
```
- See other options: https://docs.madelineproto.xyz/docs/FILES.html#uploading-files
2020-02-08 01:53:17 +01:00
2020-02-08 01:54:32 +01:00
### Downloading files
2020-02-08 01:53:17 +01:00
2020-07-01 21:28:54 +02:00
```shell script
2020-02-08 01:53:17 +01:00
curl --location --request POST '127.0.0.1:9503/api/downloadToResponse' \
--header 'Content-Type: application/json' \
--data-raw '{
"media": {
"_": "messageMediaDocument",
"document": {
"_": "document",
"id": 5470079466401169993,
"access_hash": -6754208767885394084,
"file_reference": {
"_": "bytes",
2020-05-23 02:48:11 +02:00
"bytes": "AkKdqJkAACnyXshwzMhdzeC5RkdVZeh58sAB/UU="
2020-02-08 01:53:17 +01:00
},
"date": 1551713685,
"mime_type": "video/mp4",
"size": 400967,
2020-05-23 02:48:11 +02:00
"dc_id": 2,
"attributes": [
{
"_": "documentAttributeFilename",
"file_name": "одолдол.mp4"
}
]
2020-02-08 01:53:17 +01:00
}
}
}'
```
Also see: https://docs.madelineproto.xyz/docs/FILES.html#downloading-files
2020-06-25 00:33:18 +02:00
### Multiple sessions support
2020-02-08 01:53:17 +01:00
When running multiple sessions, need to define which session to use for request.
2020-05-11 00:50:29 +02:00
Each session stored in `sessions/{$session}.madeline`. Nested folders supported.
2020-02-08 01:53:17 +01:00
**Examples:**
* `php server.php --session=bot --session=users/xtrime --session=users/user1`
* `http://127.0.0.1:9503/api/bot/getSelf`
* `http://127.0.0.1:9503/api/users/xtrime/getSelf`
* `http://127.0.0.1:9503/api/users/user1/getSelf`
* sessions file paths are: `sessions/bot.madeline`, `sessions/users/xtrime.madeline` and `sessions/users/user1.madeline`
* glob syntax for sessions:
2020-05-11 00:50:29 +02:00
* `--session=*` to use all `sessions/*.madeline` files (in subfolders too).
2020-02-08 01:53:17 +01:00
* `--session=users/* --session=bots/*` to use all session files from `sessions/bots` and `sessions/users` folders.
2020-06-25 00:33:18 +02:00
### Different settings for sessions
2020-07-01 21:28:54 +02:00
* Use `--env` argument to define the relative path to env file.
Example: ```php server.php --env=.env```, ```php server.php --env=sessions/.env.session```
This is helpful to define unique settings for different instances of TelegramApiServer.
You can start multiple instances of TelegramApiServer with different sessions on different ports with their own settings.
* Another way to manage settings - put %sessionName%.settings.json in sessions folder.
Example of `session.settings.json` to add proxy for the one session:
```json
{
"connection_settings": {
"all": {
"proxy": "\\SocksProxy",
"proxy_extra": {
"address": "127.0.0.1",
"port": 1234,
"username": "user",
"password": "pass"
}
}
}
}
```
Methods to work with settings files:
* `http://127.0.0.1:9503/system/saveSessionSettings?session=session&settings[app_info][app_id]=xxx&settings[app_info][app_hash]=xxx`
* `http://127.0.0.1:9503/system/unlinkSessionSettings?session=session`
* Provide settings as second argument when adding session: `http://127.0.0.1:9503/system/addSession?session=users/xtrime&settings[app_info][app_id]=xxx&&settings[app_info][app_hash]=xxx`
These settings will be saved into json file and will apply after the restart.
2020-06-25 00:33:18 +02:00
2020-02-08 01:54:32 +01:00
### Session management
2020-01-18 15:38:26 +01:00
2020-02-08 01:53:17 +01:00
**Examples:**
* Session list: `http://127.0.0.1:9503/system/getSessionList`
* Adding session: `http://127.0.0.1:9503/system/addSession?session=users/xtrime`
2020-05-11 00:50:29 +02:00
* Removing session (session file will remain): `http://127.0.0.1:9503/system/removeSession?session=users/xtrime`
2020-06-25 00:33:18 +02:00
* Remove session file: `http://127.0.0.1:9503/system/unlinkSessionFile?session=users/xtrime`
Don`t forget to logout and call removeSession first!
2020-02-08 01:53:17 +01:00
If there is no authorization in session, or session file is blank, authorization required:
User:
* `http://127.0.0.1:9503/api/users/xtrime/phoneLogin?phone=+7123...`
* `http://127.0.0.1:9503/api/users/xtrime/completePhoneLogin?code=123456`
* (optional) `http://127.0.0.1:9503/api/users/xtrime/complete2falogin?password=123456`
* (optional) `http://127.0.0.1:9503/api/users/xtrime/completeSignup?firstName=MyExampleName`
Bot:
* `http://127.0.0.1:9503/api/bot/botLogin?token=34298141894:aflknsaflknLKNFS`
2020-03-11 00:20:14 +01:00
Save new session to file immediately: `http://127.0.0.1:9503/api/bot/serialize`
2020-02-10 02:50:17 +01:00
### Websocket
#### EventHandler updates (webhooks).
2020-02-08 01:53:17 +01:00
2020-02-10 02:50:17 +01:00
Connect to `ws://127.0.0.1:9503/events` to get all events in json.
This is efficient alternative for webhooks.
2020-02-08 01:53:17 +01:00
Each event is json object in [json-rpc 2.0 format](https://www.jsonrpc.org/specification#response_object). Example:
2020-02-10 02:50:17 +01:00
When using multiple sessions, name of session can be added to path of websocket endpoint:
2020-02-08 01:53:17 +01:00
This endpoint will send events only from `users/xtrime` session: `ws://127.0.0.1:9503/events/users/xtrime`
PHP websocket client example: [websocket-events.php](https://github.com/xtrime-ru/TelegramApiServer/blob/master/examples/websocket-events.php)
2019-06-02 18:22:03 +02:00
2020-02-10 02:50:17 +01:00
`php examples/websocket-events.php --url=ws://127.0.0.1:9503/events`
#### Logs.
Connect to `ws://127.0.0.1:9503/log[/%level%]` to get logs in real time.
`%level%` is optional parameter to filter logs.
If filter is specified, then only messages with equal or greater level will be send.
This endpoint will send only alert and emergency logs: `ws://127.0.0.1:9503/log/alert`
Available levels: debug, info, notice, warning, error, critical, alert, emergency.
PHP websocket client example: [websocket-events.php](https://github.com/xtrime-ru/TelegramApiServer/blob/master/examples/websocket-events.php)
`php examples/websocket-events.php --url=ws://127.0.0.1:9503/log`
2020-01-18 15:38:26 +01:00
## Contacts
2019-06-02 18:22:03 +02:00
2020-07-01 21:28:54 +02:00
* Telegram:
* Author: [@xtrime](tg://resolve?domain=xtrime)
* [MadelineProto and Amp Support Groups](tg://resolve?domain=pwrtelegramgroup)
2020-01-18 15:38:26 +01:00
* Email: alexander(at)i-c-a.su
* Donations:
* BTC: `1BE1nitXgEAxg7A5tgec67ucNryQwusoiP`
* ETH: `0x0e2d369E28DCA2336803b9dE696eCDa50ff61e27`