TelegramApiServer
Fast, simple, async php telegram api server: MadelineProto + Amp HTTP Server
Install / Use
/learn @xtrime-ru/TelegramApiServerREADME
TelegramApiServer
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
Features
- 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
Architecture Example

Installation
git clone https://github.com/xtrime-ru/TelegramApiServer.git TelegramApiServer
cd TelegramApiServer
cp .env.docker.example .env.docker
docker compose pull
Authorization
[!CAUTION] Please only use old and valid accounts. All new accounts will be banned by telegram. If your account was banned read this: https://docs.madelineproto.xyz/docs/LOGIN.html#getting-permission-to-use-the-telegram-api
- 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. - Start TelegramApiServer in cli:
- Start container interactively:
docker compose run --rm api - If you need to start multiple sessions, create docker-compose.override.yml. Add additional containers there. Use unique ports and session names in
command.
- Start container interactively:
- Authorize your session:
- After promt, fill your phone number, or bot hash.
- You will receive telegram code. Type it in. If you're not receiving code - your server IP or hosting may be blocked by telegram. Try another server or change server IP.
- If you have 2fa enabled - enter 2fa passord.
- Wait 10-30 seconds until session is started.
You will see logs:
TelegramApiServer ready. Number of sessions: 1. - Exit with
Ctrl + C - Run container in background
docker compose up -d.
Change existing account/session
- Stop container
docker compose stop api - Remove session folder:
rm -rf /sessions/session.madeline/ - Remove
session_MTProto_sessionfrom mysql database. - Log out session from app.
- Authorize as usual.
Update
git pullorgit fetch && git reset --hard origin/masterrm -rf vendor/- Compare
.env.dockeror.envwith corresponding.env.example. Update if needed. - Recreate containers:
docker compose pull docker compose down docker compose up -d
Security
Please be careful with settings, otherwise you can expose your telegram session and lose control. Default settings allow to access API only from localhost/127.0.0.1.
.env settings:
IP_WHITELIST- allow specific IP's to make requests without password.PASSWORDS- protect your api with basic auth.
Request with correct username and password overrides IP_WHITELIST. If you specify password, thenIP_WHITELISTis ignored How to make requests with basic auth:curl --user username:password "http://127.0.0.1:9503/api/getSelf" curl "http://username:password@127.0.0.1:9503/api/getSelf"
docker-compose.yml:
port- port forwarding rules from host to docker container. Remove 127.0.0.1 to listen all interfaces and forward all requests to container. Make sure to use IP_WHITELIST and/or PASSWORDS settings to protect your account.
Usage
Access Telegram API with simple GET/POST requests. Regular and application/json POST supported. It's recommended to use http_build_query, when using GET requests.
Rules:
-
All methods from MadelineProto supported: Method List
-
Url:
http://%address%:%port%/api[/%session%]/%class%.%method%/?%param%=%val% -
<b>Important: api available only from ip in whitelist.</b> By default it is:
127.0.0.1You 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:9503and 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 -
When passing files in POST forms, if the name of the field is
file, it must always come last in the field list, and all fields afterfilewill be ignored (this limit is not present for file fields named in another way, such as thumbnail fields).
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/?from_peer=@xtrime&to_peer=@xtrime&id=1234 - get messages from channel/user:
http://127.0.0.1:9503/api/messages.getHistory/?peer=@breakingmash&limit=10 - get messages with text in HTML:
http://127.0.0.1:9503/api/getHistoryHtml/?peer=@breakingmash&limit=10 - search:
http://127.0.0.1:9503/api/searchGlobal/?q=Hello%20World&limit=10 - sendMessage:
http://127.0.0.1:9503/api/messages.sendMessage/?peer=@xtrime&message=Hello! - copy message from one channel to another (not repost):
http://127.0.0.1:9503/api/copyMessages/?from_peer=@xtrime&to_peer=@xtrime&id[0]=1
Advanced features
Get events/updates
Telegram is event driven platform. For example: every time your account receives a message you immediately get an update. There are multiple ways of getting updates in TelegramApiServer / MadelineProto:
- Websocket
- Long Polling:
send request to getUpdates endpoint
curl "127.0.0.1:9503/api/getUpdates?limit=3&offset=0&timeout=10.0" -g - Webhook:
Redirect all updates to your endpoint, just like bot api!
curl "127.0.0.1:9503/api/setWebhook?url=http%3A%2F%2Fexample.com%2Fsome_webhook" -g
Example uses urlencoded url in query.
Uploading files.
There are few options to upload and send media files:
- Custom method
sendDocument/sendVideo/etc (full list here) to send document/video/audio/voice/etc by url or local path, remote url, or stream. Stream upload from client:
RemoteUrl:curl --location --request POST 'http://127.0.0.1:9503/api/sendDocument' -g \ -F peer=me \ -F caption=key \ -F file=@screenshot.png
Local file on server:curl --location --request POST 'http://127.0.0.1:9503/api/sendVideo' \ --header 'Content-Type: application/json' \ --data-raw '{ "peer": "me", "file": { "_": "RemoteUrl", "url": "https://domain.site/storage/video.mp4" }, "parseMode": "HTML", "caption": "<b>caption text</b>" }'curl --location --request POST 'http://127.0.0.1:9503/api/sendDocument' \ --header 'Content-Type: application/json' \ --data-raw '{ "peer": "me", "file": { "_": "LocalUrl", "file": "faust.txt" }, "parseMode": "HTML", "caption": "<b>caption text</b>" }' - See other options: https://docs.madelineproto.xyz/docs/FILES.html#uploading-files
Downloading 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
Multiple sessions support
Its recommended to run every session in separate container.
To add more containers create docker-compose.override.yml file.
Docker will automatically merge it with default docker-compose file.
Example of docker-compose.override.yml with two additional containers/sessions (3 in total):
services:
api-2:
extends:
file: docker-compose.base.yml
service: base-api
ports:
- "127.0.0.1:9512:9503"
command:
- "-s=session-2"
api-3:
extends:
file: docker-compose.base.yml
service: base-api
ports:
- "127.0.0.1:9513:9503"
command:
- "-s=session-3"
Multiple sessions in one container (deprecated)
WARNING: running multiple sessions in one instance/container is unstable. Crash/error in one session will crash all of them.
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/xtrim
