Fast, simple, async php telegram api server: MadelineProto and Amp Http Server
- Online demo (getHistory + Media Download): tg.i-c-a.su
- My content aggregator: i-c-a.su
- Get telegram channels in RSS: TelegramRSS
- Fast async Amp Http Server
- Full access to telegram api: bot and user
- Multiple sessions
- Stream media (view files in a browser)
- Upload media
- Websocket endpoints for events and logs
- MadelineProto optimized settings to reduce memory consumption
git clone https://github.com/xtrime-ru/TelegramApiServer.git TelegramApiServer
cd TelegramApiServer
- Start container:
docker-compose up
Folder will be linked inside container to store all necessary data: sessions, env, db.
-
Requirements:
- ssh / cli
- php 7.4 or php 8
- composer
- git
- Mysql/MariaDB (optional)
- MadelindeProto Requirements
- Amp Requirements
- XAMPP (for Windows)
-
git clone https://github.com/xtrime-ru/TelegramApiServer.git TelegramApiServer
-
cd TelegramApiServer
-
composer install -o --no-dev
-
php server.php
- Ctrl + C to stop TelegramApiServer if running.
- Get app_id and app_hash at my.telegram.org. Only one app_id needed for any amount of users and bots.
- Fill app_id and app_hash in
.env.docker
or.env
. - Start TelegramApiServer in cli:
- docker:
- Start:
docker-compose up
- Start new shell and connect to docker container:
bash bin/docker-exec.sh
- Start another instance with different port inside new shell:
php server.php -p=9500 -s=session --docker -e=.env.docker
- Start:
- manual:
php server.php --session=session
- docker:
- Authorize your session:
- Chose account type: user (
u
) or bot (b
) - Follow instructions
- Chose account type: user (
- Wait 10-30 seconds until authorization is end and exit with
Ctrl + C
. - Run TAS in screen, tmux, supervisor (see below) or docker.
-
Run server/parser
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 -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) -s --session Name for session file (optional) Multiple sessions can be specified: "--session=user --session=bot" Each session is stored in `sessions/{$session}.madeline`. Nested folders supported. See README for more examples. -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)
-
Access Telegram API with simple GET/POST requests.
Regular and application/json POST supported. Its recommended to use http_build_query, when using GET requests.
Rules:
-
All methods from MadelineProto supported: Methods List
-
Url:
http://%address%:%port%/api[/%session%]/%class%.%method%/?%param%=%val%
-
Important: api available only from ip in whitelist. By default it is:
127.0.0.1
You can add a client IP in .env file toIP_WHITELIST
(separate with a comma)In docker version by default api available only from localhost (127.0.0.1). To allow connections from the internet, need to change ports in docker-compose.yml to
9503:9503
and recreate the container:docker-compose up -d
. This is very insecure, because this will open TAS port to anyone from the internet. Only protection is theIP_WHITELIST
, and there are no warranties that it will secure your accounts. -
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:
http://127.0.0.1:9503/api/getInfo/?id=@xtrime
orhttp://127.0.0.1:9503/api/getInfo/?abcd=@xtrime
works the same
Examples:
- 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
- repost:
http://127.0.0.1:9503/api/messages.forwardMessages/?data[from_peer]=@xtrime&data[to_peer]=@xtrime&data[id]=1234
- get messages from channel/user:
http://127.0.0.1:9503/api/getHistory/?data[peer]=@breakingmash&data[limit]=10
- get messages with text in HTML:
http://127.0.0.1:9503/api/getHistoryHtml/?data[peer]=@breakingmash&data[limit]=10
- search:
http://127.0.0.1:9503/api/searchGlobal/?data[q]=Hello%20World&data[limit]=10
- sendMessage:
http://127.0.0.1:9503/api/sendMessage/?data[peer]=@xtrime&data[message]=Hello!
- 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
-
- Docker:
docker-compose up -d
Docker will monitor and restart containers. - Manual:
- Use supervisor to monitor and restart swoole/amphp servers.
apt-get install supervisor
- 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
- Load new config:
supervisorctl update
- View/control processes:
supervisorctl
git pull
orgit fetch && git reset --hard origin/master
composer install -o --no-dev
- Compare
.env.docker
or.env
with corresponding.env.example
. Update if needed. - Docker:
docker-compose pull
docker-compose down
docker-compose up
- Manual:
supervisorctl restart telegram_api_server
There are few options to upload and send media files:
- Custom method
sendMedia
supports upload from form: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 tomessages.sendMedia
:-
curl "http://127.0.0.1:9503/api/uploadMediaForm" -g -F "file=@/Users/xtrime/Downloads/test.txt"
Method supportsapplication/x-www-form-urlencoded
andmultipart/form-data
. -
Send result from
uploadMediaForm
tomessages.sendMedia
orsendMedia
:
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" } ] } } }'
-
- See other options: https://docs.madelineproto.xyz/docs/FILES.html#uploading-files
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",
"bytes": "AkKdqJkAACnyXshwzMhdzeC5RkdVZeh58sAB/UU="
},
"date": 1551713685,
"mime_type": "video/mp4",
"size": 400967,
"dc_id": 2,
"attributes": [
{
"_": "documentAttributeFilename",
"file_name": "одолдол.mp4"
}
]
}
}
}'
Also see: https://docs.madelineproto.xyz/docs/FILES.html#downloading-files
When running multiple sessions, need to define which session to use for request.
Each session stored in sessions/{$session}.madeline
. Nested folders supported.
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
andsessions/users/user1.madeline
- glob syntax for sessions:
--session=*
to use allsessions/*.madeline
files (in subfolders too).--session=users/* --session=bots/*
to use all session files fromsessions/bots
andsessions/users
folders.
-
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:{ "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.
Examples:
- Session list:
http://127.0.0.1:9503/system/getSessionList
- Adding session:
http://127.0.0.1:9503/system/addSession?session=users/xtrime
- Removing session (session file will remain):
http://127.0.0.1:9503/system/removeSession?session=users/xtrime
Due to madelineProto issue its instance still might be in memory and continue working even after the remove. - Remove session file:
http://127.0.0.1:9503/system/unlinkSessionFile?session=users/xtrime
Don`t forget to logout and call removeSession first! - Close TelegramApiServer (end process):
http://127.0.0.1:9503/system/exit
Full list of system methods available in SystemApiExtensions class
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=%2B7123...
, %2B - is urlencoded "+" signhttp://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
Save new session to file immediately: http://127.0.0.1:9503/api/bot/serialize
Also, session can be authorized in cli/shell on server start.
Connect to ws://127.0.0.1:9503/events
to get all events in json.
This is efficient alternative for webhooks.
Each event is json object in json-rpc 2.0 format. Example:
When using multiple sessions, name of session can be added to path of websocket endpoint:
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
php examples/websocket-events.php --url=ws://127.0.0.1:9503/events
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
php examples/websocket-events.php --url=ws://127.0.0.1:9503/log
TelegramApiServer extends madelineProto with some handful methods.
Full list of custom methods and their parameters available in ApiExtensions class
getHistory
- same as messages.getHistory, but all params exept peer is optional.getHistoryHtml
- message entities converted to htmlformatMessage
- converts entities to htmlcopyMessages
- copy message from one peer to onother. Like forwardMessages, but without the link to original.getMedia
- download media to stream/browsergetMediaPreview
- download media preview to stream/browseruploadMediaForm
- upload document from POST request.
- Telegram:
- Email: alexander(at)i-c-a.su