xtrime-ru/telegramapiserver

快速、简单、异步的 PHP Telegram 客户端和解析器:MadelineProto + Amphp HTTP Server

v2.3.1 2024-08-18 15:30 UTC

README

快速、简单、异步的 PHP Telegram API 服务器:MadelineProtoAmp Http Server

特性

  • 快速异步 Amp Http 服务器
  • 完全访问 Telegram API:bot 和用户
  • 多会话
  • 流式媒体(在浏览器中查看文件)
  • 上传媒体
  • 事件和日志的 WebSocket 端点
  • MadelineProto 优化设置以减少内存消耗

架构示例 Architecture Example

安装

git clone https://github.com/xtrime-ru/TelegramApiServer.git TelegramApiServer
cd TelegramApiServer
cp .env.docker.example .env.docker
docker compose pull

授权

  1. my.telegram.org 获取 app_id 和 app_hash。任何数量的用户和机器人只需要一个 app_id。
  2. .env.docker 中填写 app_id 和 app_hash。
  3. 在命令行中启动 TelegramApiServer:1. 交互式启动容器:docker compose run --rm api 2. 如果需要启动多个会话,创建 docker-compose.override.yml。在那里添加额外的容器。在 command 中使用唯一的端口和会话名称。
  4. 授权您的会话
    1. 根据提示填写您的电话号码或机器人哈希。
    2. 遵循指示
  5. 等待 10-30 秒,直到会话启动。您将看到日志
    TelegramApiServer ready. 
    Number of sessions: 1.
    
  6. 使用 Ctrl + C 退出
  7. 在后台运行容器:docker compose up -d.

更新

  • 使用 git pullgit fetch && git reset --hard origin/master
  • rm -rf vendor/
  • .env.docker.env 与相应的 .env.example 进行比较。如有必要,进行更新。
  • 重新创建容器
    docker compose pull
    docker compose down
    docker compose up -d

安全

请小心设置,否则您可能会暴露您的 Telegram 会话并失去控制。默认设置仅允许从 localhost/127.0.0.1 访问 API。

.env 设置

  • IP_WHITELIST - 允许特定 IP 的请求不使用密码。
  • PASSWORDS - 使用基本认证保护您的 API。
    使用正确的用户名和密码进行请求将覆盖 IP_WHITELIST。如果您指定了密码,则忽略 IP_WHITELIST。如何使用基本认证进行请求
    curl --user 'username:password' "http://127.0.0.1:9503/getSelf"
    curl "http://username:password@127.0.0.1:9503/getSelf"

docker-compose.yml

  • port - 从主机到 Docker 容器的端口转发规则。删除 127.0.0.1 以监听所有接口并将所有请求转发到容器。请确保使用 IP_WHITELIST 和/或 PASSWORDS 设置来保护您的帐户。

用法

通过简单的 GET/POST 请求访问 Telegram API。支持常规和 application/json POST。

规则

  • 支持所有 MadelineProto 方法:方法列表

  • URL: http://%address%:%port%/api[/%session%]/%class%.%method%/?%param%=%val%

  • 重要:API 仅限白名单中的 IP 地址访问。 默认为: 127.0.0.1 您可以在 .env 文件中将客户端 IP 添加到 IP_WHITELIST 中(用逗号分隔)

    在 Docker 版本中,默认情况下 API 仅从本地主机(127.0.0.1)访问。要允许从互联网连接,需要将 docker-compose.yml 中的端口更改为 9503:9503 并重新创建容器: docker compose up -d。这非常不安全,因为这会将 TAS 端口向互联网上的任何人开放。唯一的保护措施是 IP_WHITELIST,并且无法保证它将保护您的账户。

  • 如果方法在类内部(消息、联系人等)中,使用 '.' 分隔类和方法: http://127.0.0.1:9503/api/contacts.getContacts

  • 如果方法需要值数组,可以使用任意名称的数组,例如 'data': ?data[peer]=@xtrime&data[message]=Hello! 在这种情况下,参数的顺序无关紧要。

  • 如果方法需要一个或多个单独的参数(不在数组内)则按任何名称传递参数,但 必须严格按顺序http://127.0.0.1:9503/api/getInfo/?id=@xtrimehttp://127.0.0.1:9503/api/getInfo/?abcd=@xtrime 效果相同

示例

  • 获取频道/用户的 get_info: http://127.0.0.1:9503/api/getInfo/?id=@xtrime
  • 获取当前账户的 get_info: http://127.0.0.1:9503/api/getSelf
  • 转发: http://127.0.0.1:9503/api/messages.forwardMessages/?data[from_peer]=@xtrime&data[to_peer]=@xtrime&data[id]=1234
  • 从频道/用户获取消息: http://127.0.0.1:9503/api/messages.getHistory/?data[peer]=@breakingmash&data[limit]=10
  • 获取带有 HTML 文本的消息: http://127.0.0.1:9503/api/getHistoryHtml/?data[peer]=@breakingmash&data[limit]=10
  • 搜索: http://127.0.0.1:9503/api/searchGlobal/?data[q]=Hello%20World&data[limit]=10
  • sendMessage: http://127.0.0.1:9503/api/messages.sendMessage/?data[peer]=@xtrime&data[message]=Hello!
  • 从一个频道复制消息到另一个频道(非转发): http://127.0.0.1:9503/api/copyMessages/?data[from_peer]=@xtrime&data[to_peer]=@xtrime&data[id][0]=1

高级功能

获取事件/更新

Telegram 是事件驱动平台。例如:每当您的账户收到消息,您会立即收到更新。在 TelegramApiServer / MadelineProto 中有多种 获取更新 的方法。

  1. WebSocket
  2. 长轮询
    向 getUpdates 端点发送请求
    curl "127.0.0.1:9503/api/getUpdates?data[limit]=3&data[offset]=0&data[timeout]=10.0" -g
  3. Webhook:将所有更新重定向到您的端点,就像 bot api!
    curl "127.0.0.1:9503/api/setWebhook?url=http%3A%2F%2Fexample.com%2Fsome_webhook" -g
    示例使用 URL 编码的查询。

上传文件。

有几种上传和发送媒体文件的方法。

  • 自定义方法 sendMedia 支持从表单上传。
    curl "http://127.0.0.1:9503/api/messages.sendMedia?data[peer]=xtrime&data[message]=Hello" -g \
    -F "file=@/Users/xtrime/Downloads/test.txt"
  • 使用自定义 uploadMediaForm 方法,然后将结果传递给 messages.sendMedia
    1. curl "http://127.0.0.1:9503/api/uploadMediaForm" -g -F "file=@/Users/xtrime/Downloads/test.txt" 方法支持 application/x-www-form-urlencodedmultipart/form-data

    2. uploadMediaForm 发送结果到 messages.sendMediasendMedia

    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"
                    }
                ]
            }
        }
    }'
  • 查看其他选项: 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"
                }
            ]
        }
    }
}'

也请参阅: https://docs.madelineproto.xyz/docs/FILES.html#downloading-files

多会话支持

建议为每个会话运行一个独立的容器。

要添加更多容器,创建 docker-compose.override.yml 文件。Docker 将 自动合并 它与默认的 docker-compose 文件。

带有两个附加容器/会话的 docker-compose.override.yml 示例(总共 3 个)

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"

一个容器中的多会话(已弃用)

警告:在一个实例/容器中运行多个会话是不稳定的。 一个会话中的崩溃/错误将导致所有会话崩溃。

当运行多个会话时,需要定义用于请求的会话。每个会话存储在 sessions/{$session}.madeline 中。支持嵌套文件夹。 示例:

  • 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/bot.madelinesessions/users/xtrime.madelinesessions/users/user1.madeline
  • 会话的 glob 语法
    • --session=* 使用所有 sessions/*.madeline 文件(包括子文件夹中的文件)。
    • --session=users/* --session=bots/* 使用来自 sessions/botssessions/users 文件夹的所有会话文件。

会话的不同设置

  • 使用 --env 参数定义到 env 文件的相对路径。示例: php server.php --env=.envphp server.php --env=sessions/.env.session
    这有助于为不同的 TelegramApiServer 实例定义唯一的设置。
    您可以在不同的端口上使用不同的会话启动多个 TelegramApiServer 实例,并具有它们自己的设置。

  • 另一种管理设置的方法是将 %sessionName%.settings.json 放入会话文件夹。示例 session.settings.json 为一个会话添加代理

    {
        "connection": {
            "proxies": {
                "\\danog\\MadelineProto\\Stream\\Proxy\\SocksProxy": [
                    {
                      "address": "127.0.0.1",
                      "port": 1234,
                      "username": "user",
                      "password": "pass"
                    }
                ],
                "\\danog\\MadelineProto\\Stream\\Proxy\\HttpProxy": [
                    {
                      "address": "127.0.0.1",
                      "port": 1234,
                      "username": "user",
                      "password": "pass"
                    }
                ]
            }
        }
    }

    处理设置文件的方法

    • 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
  • 在添加会话时作为第二个参数提供设置:http://127.0.0.1:9503/system/addSession?session=users/xtrime&settings[app_info][app_id]=xxx&&settings[app_info][app_hash]=xxx 这些设置将被保存到 json 文件中,并在重启后生效。

会话管理

示例

  • 会话列表:http://127.0.0.1:9503/system/getSessionList
  • 添加会话:http://127.0.0.1:9503/system/addSession?session=users/xtrime
  • 删除会话(会话文件将保留):http://127.0.0.1:9503/system/removeSession?session=users/xtrime 由于 madelineProto 问题,其实例可能仍在内存中,并在删除后继续工作。
  • 删除会话文件:http://127.0.0.1:9503/system/unlinkSessionFile?session=users/xtrime 不要忘记登出并先调用 removeSession!
  • 关闭 TelegramApiServer(结束进程):http://127.0.0.1:9503/system/exit

SystemApiExtensions 类中可用的系统方法完整列表请参阅 SystemApiExtensions 类

远程授权会话

警告:建议使用交互式模式来授权会话!如果没有在会话中进行授权,或会话文件为空,则需要授权

用户

  • http://127.0.0.1:9503/api/users/xtrime/phoneLogin?phone=%2B7123..., %2B - 是 urlencoded "+" 符号
  • http://127.0.0.1:9503/api/users/xtrime/completePhoneLogin?code=123456
  • (可选) http://127.0.0.1:9503/api/users/xtrime/complete2falogin?password=123456
  • (可选) http://127.0.0.1:9503/api/users/xtrime/completeSignup?firstName=MyExampleName

机器人

  • http://127.0.0.1:9503/api/bot/botLogin?token=34298141894:aflknsaflknLKNFS

立即将新会话保存到文件:http://127.0.0.1:9503/api/bot/serialize

此外,会话也可以在服务器启动时在 cli/shell 中进行授权。

WebSocket

EventHandler 更新(webhooks)。

连接到 ws://127.0.0.1:9503/events 以获取所有事件的 json 格式。这是 webhooks 的有效替代方案。每个事件都是 json-rpc 2.0 格式 的 json 对象。示例

当使用多个会话时,会话名称可以添加到 websocket 端点路径中:此端点将只发送来自 users/xtrime 会话的事件:ws://127.0.0.1:9503/events/users/xtrime

PHP websocket 客户端示例:websocket-events.php

php examples/websocket-events.php --url=ws://127.0.0.1:9503/events

日志。

连接到 ws://127.0.0.1:9503/log[/%level%] 以实时获取日志。

%level% 是可选参数,用于过滤日志。如果指定了过滤器,则只会发送具有相等或更高级别的消息。此端点将只发送警报和紧急日志:ws://127.0.0.1:9503/log/alert

可用级别:debug、info、notice、warning、error、critical、alert、emergency。

PHP websocket 客户端示例:websocket-events.php

php examples/websocket-events.php --url=ws://127.0.0.1:9503/log

自定义方法

TelegramApiServer 扩展了 madelineProto 并增加了一些实用方法。
自定义方法和它们的参数的完整列表可以在 ApiExtensions 类 中找到

  • getHistoryHtml - 将消息实体转换为 html
  • formatMessage - 将实体转换为 html
  • copyMessages - 将消息从一个联系人复制到另一个联系人。类似于 forwardMessages,但不包含原始消息的链接。
  • getMedia - 将媒体下载到流/浏览器
  • getMediaPreview - 将媒体预览下载到流/浏览器
  • uploadMediaForm - 从 POST 请求中上传文档。

联系人