开发者文档
简体中文

服务器运维

管理与设置

管理页面、注册验证码的发送(短信和电子邮件)、服务器设置值、备份与安全——面向运营方的参考。

服务器内置了一个用浏览器打开的管理页面。你可以在这里查看服务器状态,决定如何发送注册和登录验证码,并管理用户和机器人。本文档把管理页面和服务器设置值集中整理在一处,供查阅。如果需要先安装,请参阅服务器安装。

打开管理页面

管理页面位于管理 HTTP 端口(生产配置中为 8080)的 /admin/,只能在服务器本机(127.0.0.1)上打开。运营方通过 SSH 隧道进入。

# 在自己的电脑上执行(保持运行)
ssh -N -L 8080:127.0.0.1:8080 <用户>@<服务器>
# 浏览器:http://localhost:8080/admin/

# 令牌(在服务器上查看)
sudo cat /srv/pabal/pabal_server/data/admin-token

输入令牌后点打开(열기)。浏览器会记住令牌,可以用右上角的清除令牌(토큰 지우기)将其清除。如果要自行设定令牌,请设置 TELEGRAM_ADMIN_TOKEN(至少 16 个字符)——这样就不会写入文件。

各标签页显示的内容

标签页内容刷新
仪表盘(대시보드)当前在线的用户、会话和连接,用户、机器人、群组、消息、照片和文件的数量,运行时间、端口、数据库,JVM,状态检查。测试号码开启时会显示警告横幅5 秒
注册验证码(가입 코드)等待中的验证码(号码、发送方式、发送状态、验证码、剩余时间、输错次数)和最近记录。可以复制或取消验证码3 秒
用户(사용자)所有账号——手机号码、登录邮箱(可编辑)、是否在线、登录设备数、消息数。退出所有设备(모든 기기 로그아웃)、封禁号码(번호 차단)、删除账号(계정 삭제,需附上核实本人身份的备注——删除后只留下账号 id 和备注)10 秒
机器人(봇)用 BotFather 创建的机器人——创建者、命令菜单、连接方式(MTProto · HTTP 轮询 · Webhook 地址及失败原因)、等待中的更新数量10 秒
语音(음성)语音机器人——网关、中继和隐私政策的状态、紧急停止开关、正式开放、允许文字记录、正在进行的通话及挂断、允许和暂停机器人、测试者、限额(见下文)5 秒
举报(신고)通过应用中的“举报”提交的内容——举报时内容的副本(发送者删除后也能查看)。删除(对话双方;如果是群组,则从所有成员处删除)、停用账号(退出所有设备,无法再登录或注册)、已停用账号的列表。在停用状态下注销的账号,其号码在注销后 1 年内(默认)不能重新注册——可在停用时延长,或之后在列表的限制重新注册(재가입 막기)中延长到更晚的截止日期(以 1 年和所选日期中较晚者为准,不会缩短)或无限期(管理 API:POST /admin/api/reports/<id>/suspend {"userId": …, "blockSignupUntil": "2028-01-01"} 或 "blockSignupForever": true;之后修改用 POST /admin/api/suspensions/<id>/block-signup,请求体为空则恢复默认)。已处理的举报也能查看。已处理的举报自处理之日起满 3 年后连同副本一并删除(卡片上显示该日期);如出现纠纷、调查或诉讼,保留(보존)会一直保存到解除为止(管理 API:POST /admin/api/reports/<id>/hold,解除用 /release)10 秒
客服中心(고객센터)发给 @PabalSupport 的对话。选中对话回复后,会以客服机器人的名义发到该对话中10 秒
设置(설정)注册和登录规则、应用审核账号、短信、电子邮件(SMTP)、封禁手机号码、网站上显示的运营方信息手动保存
保留用户名(예약 아이디)预先封住、谁都不能占用的用户名——搜索、添加、下载列表(.txt)、服务器默认封住的用户名。已被别人使用的名称,保留后也不会被收回打开时一次
存储(저장소)数据目录和数据库地址(密码会被隐藏)、照片和文件的数量与容量、按类型统计的存储流数量10 秒

危险的操作(退出登录、封禁、取消验证码)需要点击两次才会执行。

注册和登录验证码

用户在应用中输入手机号码后,服务器会生成验证码,并通过在设置(설정)标签页中选定的方式发送出去。

发送方式验证码的去向应用界面
管理页面(관리 화면)注册验证码(가입 코드)标签页。由运营方复制后直接告知用户号码 → “验证码已发送” → 验证码(新号码还要输入名字)
SMS通过 Twilio · Solapi · Webhook 之一发送短信与管理页面方式相同
电子邮件(이메일)通过 SMTP 发送邮件号码 → 输入电子邮件 → “验证码已发送到电子邮件” → 验证码
  • 在电子邮件方式下,新注册可以使用任意地址,该地址会成为账号的登录邮箱(로그인 이메일)。已有账号只能通过已登记的登录邮箱接收——这是为了防止有人在别人的号码上填入自己的地址来登录。没有登录邮箱的已有账号,会改用短信(如已设置)或管理页面发送。可以在用户标签页中为其填入登录邮箱。
  • 发送在后台进行,应用会直接进入输入验证码的界面。发送结果(成功或失败及原因)会显示在注册验证码标签页中。
  • 注册(输入名字)只有在验证码输入正确之后才能进行。错误的验证码只接受允许的次数,超过之后,即使输入正确的验证码也会被拒绝。
  • 更换号码(应用的设置 → 电话号码)默认关闭,应用会显示错误。打开允许更换号码后,无论采用哪种发送方式,验证码都只通过短信发到新号码(即使打开了显示验证码,注册验证码标签页也不会显示它——在那里拿到验证码的人未必是该号码的主人),并使用短信设置中专门的更换号码文本(번호 바꾸기 문구,默认 [파발] 번호 바꾸기 확인 코드: {code})。重新发送间隔和每日上限同时适用于新号码和账号;被封禁或被停用的号码,以及其他账号正在使用的号码,在索取验证码时和更换时都会被拒绝。验证码只对该账号和该号码有效,且只能使用一次;正在等待该号码的他人的登录验证码保持不变。更换之后,旧号码不能再登录这个账号。

设置——注册和登录

项目含义默认值
允许新注册(새 가입 허용)关闭后只有已有账号可以登录。新号码会以“号码无效”被拒绝开启
验证码发送方式(코드 전달 방식)管理页面 / 短信 / 电子邮件管理页面
在管理页面显示验证码(관리 화면에 코드 표시)在短信和电子邮件方式下,也在注册验证码标签页中显示验证码(以防发送失败)开启
测试号码 +99966…(테스트 번호)按服务器设置 / 开启 / 关闭。生产环境中请关闭按服务器设置
验证码位数 · 有效时间(코드 자릿수 · 코드 유효 시간)5~6 位 · 1~60 分钟5 位 · 5 分钟
重新请求间隔 · 每日上限(재요청 간격 · 번호당 하루 최대 요청)同一号码再次获取验证码前需等待的秒数(0~3600)· 24 小时内的最多次数(1~1000)60 秒 · 10 次
允许输错次数(틀린 입력 허용 횟수)超过后该验证码会被锁定(1~20)5 次
允许更换号码(번호 바꾸기 허용)已登录的账号可以用应用的“更换号码”换到另一个号码。只有设置好短信之后才能打开关闭

设置——SMS

服务商要填写的值备注
Webhook(웹훅)接收地址(웹훅 주소,https://…)、Authorization 请求头(可选)服务器会发送 POST {"phone":"+8210…","code":"12345","text":"…"}。返回 2xx 即视为成功。适用于连接自建的短信服务器或其他服务
TwilioAccount SID、Auth Token、发送号码(발신 번호)或 Messaging Service SID包括海外号码在内,覆盖全球
Solapi(原 CoolSMS)API Key、API Secret、发送号码韩国国内短信。发送号码必须是在 Solapi 预先登记的号码。+82 号码会以 010… 的格式发送

文本(문구)中可以使用 {code}(验证码)和 {minutes}(有效时间)。默认值:[파발] 인증 코드: {code}(意为“[Pabal] 验证码:{code}”)。保存后,请用测试发送(테스트 발송)进行确认。

设置——电子邮件(SMTP)

服务服务器 · 端口 · 安全(SMTP 서버 · 포트 · 보안)用户名 · 密码(사용자명 · 비밀번호)
Gmailsmtp.gmail.com · 587 · STARTTLSGmail 地址 · 应用专用密码(Google 账号 → 安全性 → 两步验证 → 应用专用密码)
Naversmtp.naver.com · 587 · STARTTLS账号 ID · 密码(在邮件设置中开启 POP3/SMTP)
公司内部邮件中继中继地址 · 25 · 无(없음)留空

发件地址(보내는 주소)必须是该 SMTP 账号有权发送的地址。主题(제목)和正文(본문)中也可以使用 {code}、{minutes}。

用户管理

  • 退出所有设备(모든 기기 로그아웃):断开该账号的所有登录(授权密钥)。用于丢失了设备的用户。
  • 封禁号码(번호 차단):该号码将无法接收验证码,该号码的账号会立即在所有设备上退出登录。与设置标签页中的封禁手机号码(전화번호 차단)列表相同。
  • 登录邮箱(로그인 이메일):在电子邮件方式下,已有账号要通过电子邮件登录时需要它。
  • 删除账号(계정 삭제):用户请求删除账号时,在确认是本人之后使用。删除的内容与应用内的删除账号完全相同,且无法撤销。需要再次输入该账号的 ID 或手机号码,并写下请求从哪里来、如何确认本人的备注,才会执行。备注会与 ID、日期一起保留(其中的手机号码、邮箱地址以及该账号的名字和用户名会被去掉)。如果邮件请求不是从该账号登记的登录邮箱发来的,可在同一窗口向该账号的手机号码发送短信验证码,再填入请求人通过邮件回复的验证码进行确认。机器人和服务器自身的账号不能在这里删除。
  • @BotFather 是服务器内置的机器人,不能对它执行退出登录。

机器人管理

在机器人(봇)标签页中可以查看每个机器人的连接方式——是否通过 MTProto 连接,最近 1 分钟内是否通过 HTTP 调用过 getUpdates,Webhook 地址是什么以及当前是否正在失败(包括原因)。如果等待中的更新数持续增加,说明机器人程序已经停止,或者 Webhook 正在失败。删除机器人和重新签发令牌,由创建该机器人的人在 @BotFather 中操作。

语音标签页

这里用于运营语音机器人(有人打电话时由 AI 语音模型接听的机器人,语音机器人)。即使服务器上没有开启语音,这个标签页也会显示,状态栏会告诉你缺少什么。开启方法见服务器安装——语音机器人。每 5 秒刷新一次。

栏目显示的内容和可以进行的操作
最上方的数字正在进行的通话 · 今天已用的时长(服务器的每日限额,通话中预留的时长) · 已连接的网关 · 开启了语音的机器人(已允许的机器人) · 测试者(是否已正式开放)
状态网关链路(地址,或“关闭(没有链路机密值)”(꺼짐 (링크 비밀 없음)))、通话中继(TURN;没有时显示“所有机器人通话都是忙音”(모든 봇 통화가 통화 중))、隐私政策中是否有 bot-calls 一节(没有时显示“任何机器人都不接听”(어떤 봇도 받지 않음))、等待中的同意,以及以忙音结束的电话按原因统计的次数(例如 워치가 못 거는 모드(手表无法拨打的模式)——用 Apple Watch 给使用工具、MCP、自有密钥、音频流模式或所有者文字记录的机器人打电话的情况,WATCH_NOT_YET)
紧急停止开关停止所有语音通话(모든 음성 통화 멈추기):按下的那一刻就在这台服务器上生效,所有正在进行的机器人通话都会结束,不再接听新通话,任何机器人都不再显示通话按钮。随后会被保存,服务器重启后依然有效(保存失败时会有警告)。用重新开放语音通话(음성 통화 다시 열기)解除
正式开放正式开放前,只有下面的测试者可以给语音机器人打电话。要向所有人开放,请在输入框中原样输入 공개합니다(意为“我要公开”)并点向所有人开放(모두에게 공개)(如果服务器的接收方键 TELEGRAM_VOICE_RECIPIENTS 是尚未确定处理地区的 …@unset,则会被拒绝——必须先发布写入了地区的应用版本)。用恢复为仅限测试者(시험자만으로 되돌리기)撤回。正式开放前是否已完成法律审查并取得提供商(Google)的书面答复,由运营方判断——代码不会阻止
网关每个已连接网关的 id、承担的通话数/容量、声音发送的去向(google.vertex.gemini-live@us-central1 等)、功能(tools·byok·transcripts·stream …)、引擎、boot
文字记录 · 自有密钥允许文字记录:在输入框中输入 대화 기록을 허용합니다(意为“我允许文字记录”)并点允许文字记录(대화 기록 허용)。完成法律审查之前请不要允许。关闭后立即生效,并会丢弃正在进行的通话以及机器人尚未取走的对话文字。来电者选择的保存对话与这项允许无关,管理页面上也没有它的开关——由隐私政策中的 bot-calls-keep-text 一节开启(服务器安装——保存对话)。自有密钥:是否接受及不接受的原因、主密钥 id、有密钥的机器人数量(密钥本身不会出现在任何地方)
正在进行的通话通话 id、机器人、来电者(名字和 id)、状态、已用时长/最长时长、网关、未完成的工具查询数。挂断(끊기)(需点击两次才执行)
语音机器人可以使用语音的机器人:仅限已允许的机器人(허용한 봇만)(默认)或用 @BotFather 创建的所有机器人(@BotFather 로 만든 모든 봇)。按机器人 id 或 @用户名允许(허용)。表格:机器人、创建者、状态(开启/关闭、能否接听及原因、暂停、音频流模式下声音发送的地址、工具及回答/错误/超时次数)、音色和语言、限额、今天的通话。可以进行的操作:允许(허용)·取消允许(허용 취소)、检查后再次允许(확인하고 다시 허용)、暂停(멈추기)(必须填写原因,200 个字符,会显示给机器人所有者,正在进行的通话会结束)·恢复(다시 열기)、查看设置(설정 보기)
查看机器人的设置指令和问候语的原文(供审查)、工具定义以及各工具的响应时间(p50·p95)、工具查询的去向、同意的规则版本、冒充检查的适用和豁免、最近的变更,以及每月的通话、时长、未接和拒绝
测试者按人的 id 或 @用户名(@ 可有可无,不区分大小写)加为测试者(시험자로 넣기)·移除(빼기)(机器人和服务器自身的账号不行)。通过服务器设置 TELEGRAM_VOICE_TESTERS 加入的人显示为“服务器”(서버),不能在这里移除
限额下表 + 加入冒充检查的名字(사칭 검사에 더할 이름)(每行一个)。保存时会告诉你哪些机器人因此无法再接听电话
机器人打来的电话全局开关:在框中原样输入 봇이 거는 전화를 켭니다 后开启——只能在法律审查之后(许可窗口文字的 callme.legal_review 不是 done 时会被拒绝;开发和测试服务器的例外是 TELEGRAM_VOICE_CALLME_UNREVIEWED)。关闭后新请求立即返回 503。国家(默认 82,999 仅限测试服务器)、限额(生产服务器不会保存比下限更宽松的值)、所有者已开启的机器人列表(审核状态、令牌暂停、自动停止、今天的请求),以及在机器人详情(名称、@用户名、照片、指令、问候语、工具、音色、语言、模式、目的、所有者姓名及其 outboundReviewHash)中许可、撤回许可,自动停止的解除,各判定阶段的拒绝次数

允许就是审查。在“仅限已允许的机器人”模式下允许一个机器人,就等于允许了它当前的指令、问候语和工具(音频流模式下是音频流地址)。如果机器人所有者修改了其中任何一项,机器人表格中会显示“指令·问候语已更改——检查后再次允许才会接听电话”(지시문·인사말이 바뀜 — 확인하고 다시 허용해야 전화를 받습니다),在你点检查后再次允许(확인하고 다시 허용)之前,该机器人不会接听电话。机器人语言不是韩语或英语的机器人,即使在“用 @BotFather 创建的所有机器人”模式下也是如此——因为保存时的自动规则检查只能读懂韩语和英语。这类机器人的表格中会显示“韩语、英语以外的机器人(自动规则检查读不懂):请阅读指令和问候语——检查后再次允许才会接听电话”(한국어·영어가 아닌 봇 (자동 규칙 검사가 읽지 못함): 지시문·인사말을 읽어 주세요 — 확인하고 다시 허용해야 전화를 받습니다),请让能读懂该语言的人阅读指令和问候语后再允许。

限额默认范围
一通电话的最长时间(秒)60060~3600,不超过服务器设置 TELEGRAM_VOICE_MAX_SECONDS
单个机器人的同时通话数21~100,不超过服务器设置 TELEGRAM_VOICE_BOT_CONCURRENCY
每人每小时的通话次数201~200
每人每天的通话(分钟)601~600
单个机器人每天的通话(分钟)601~6000
单个机器人所有者每天的通话(分钟)1201~6000
整个服务器每天的通话(分钟)3001~100000
接听的最短通话(秒)6030~300——剩余时长少于这个值时不接听
新账号限制(天)70~90(0 = 关闭)——测试者,以及机器人一天以前给其发过消息的人除外
  • “一天”以服务器的时区为准(TELEGRAM_VOICE_TIME_ZONE,默认 Asia/Seoul)。接听通话时,在当天剩余时长内确定最长时间,并在所有限额中预留;结束后只按服务器时钟的实际秒数计费。用机器人所有者的自有密钥接听的通话,只占用来电者的限额。
  • 机器人所有者只能在这些限额以内设定自己机器人的通话时长(默认 300 秒)和同时通话数。
  • 所有操作(紧急停止开关、正式开放、允许、暂停、挂断、限额 …)都会以 음성: …(意为“语音:…”)记录在注册验证码标签页的活动记录中。
  • 语音通话的质量数据(到第一声的时间、插话时停下所需的时间、工具的响应时间等)不在这个标签页中,只在管理端口的 /metrics 中(JSON 中以 voice. 开头,Prometheus 格式 /metrics?format=prometheus 中以 voice_ 开头的名称)。其中不含人、机器人或话语,只有合计值。

同样的操作也可以通过管理 API 完成(均需 Authorization: Bearer <令牌>):GET /admin/api/voice、GET /admin/api/voice/bots/<id>,以及用 POST 调用 voice/kill {"on": true}、voice/launch {"launched": true, "confirm": "…"}、voice/transcripts {"allowed": true, "confirm": "…"}、voice/testers·voice/testers/remove {"userId": …}、voice/gate {"botGate": "ALLOWLIST"}、voice/bots/allow·voice/bots/disallow {"botId": …}、voice/bots/<id>/suspend {"reason": "…"}·…/lift·…/name-exempt、voice/calls/<id>/end,限额则用 /admin/api/settings/voice。机器人打电话:voice/outbound {"on": true, "confirm": "…"}、voice/outbound/settings {"countries": […], "limits": {…}}、GET /admin/api/voice/outbound/bots/<id>、voice/outbound/bots/allow {"botId": …, "expect": "<outboundReviewHash>"}·voice/outbound/bots/disallow、voice/outbound/bots/<id>/lift。

环境变量

服务器先读取配置文件(server-config.json),然后用环境变量覆盖。生产环境的 Compose 文件会设定下列值,因此通常只需修改 .env。

变量含义生产 Compose 中的值
TELEGRAM_PORTMTProto 端口MTPROTO_PORT(8443)
TELEGRAM_HOSTMTProto 监听的地址0.0.0.0
TELEGRAM_PUBLIC_HOST告知应用的服务器地址(help.getConfig)PUBLIC_IP
TELEGRAM_WEB_PORT网站、文档、Bot API、管理页面的端口8080
TELEGRAM_WEB_HOST该端口监听的地址。默认为 127.0.0.10.0.0.0(容器内。在主机上只以 127.0.0.1 公开)
TELEGRAM_PUBLIC_URL网站地址。用于链接(me_url_prefix)、邀请链接、文档示例、预览图片https://DOMAIN/
TELEGRAM_DATA_DIR照片、文件、admin-token、operations.json 的位置/app/data
TELEGRAM_RSA_KEY服务器 RSA 私钥的路径(不存在时首次启动会生成,公钥为 .pub)/app/keys/private.pem
TELEGRAM_DC_ID这台服务器的 DC 编号。必须与应用作为主 DC 使用的编号一致(所有 Telegram 应用都是 2)——否则照片和文件的下载不会开始DC_ID(2)
TELEGRAM_DB_TYPEmemory · h2 · postgresqlpostgresql
TELEGRAM_DB_URL, TELEGRAM_DB_USERNAME, TELEGRAM_DB_PASSWORDJDBC 连接jdbc:postgresql://pabal-postgres:5432/pabal, pabal, POSTGRES_PASSWORD
TELEGRAM_DB_MAX_POOL_SIZE数据库连接数20
TELEGRAM_ADMIN_TOKEN管理页面令牌(留空时在 data/admin-token 中生成)ADMIN_TOKEN
TELEGRAM_MAX_FILE_SIZE可以发送的最大文件(2GB·512MB·字节数)。分片会随到随写入磁盘,因此受到限制的是磁盘而不是内存MAX_FILE_SIZE(2GB)
TELEGRAM_TEST_NUMBERS+99966… 测试号码。仅限开发false
TELEGRAM_WEBHOOK_ALLOW_LOCAL允许机器人 Webhook 使用 http:// 和内部地址。仅限开发(未设置 = false)
TELEGRAM_FCM_CREDENTIALSAndroid 推送用的 Firebase 服务账号密钥文件路径。留空则关闭推送(服务器安装——第 10 步)FCM_CREDENTIALS(空)
TELEGRAM_FCM_PROJECT_ID仅当要发送到密钥文件中 project_id 以外的 Firebase 项目时FCM_PROJECT_ID(空)
TELEGRAM_PUSH_PREVIEWS设为 false 时,推送通知中不含消息内容,只显示发送者PUSH_PREVIEWS(true)
TELEGRAM_TURN_HOST、TELEGRAM_TURN_PORT、TELEGRAM_TURN_SECRET通话中继(TURN)——位于不同网络的两个应用会合的地方。机密值为空时只有直连(服务器安装——通话中继)TURN_HOST(为空则用 DOMAIN)、TURN_PORT(3478)、TURN_SECRET(为空)
TELEGRAM_APNS_KEY、TELEGRAM_APNS_KEY_ID、TELEGRAM_APNS_TEAM_ID、TELEGRAM_APNS_TOPIC、TELEGRAM_APNS_MIN_BUILD、TELEGRAM_APNS_VOIP_MIN_BUILDiPhone 推送(APNs)——密钥文件路径、密钥 ID(为空则从文件名读取)、为应用签名的团队、Bundle ID、推送的最低版本号、使用 CallKit 通话界面的第一个版本号。没有密钥时 iPhone 推送关闭(服务器安装——第 11 步)APNS_*(无密钥、为空——从文件名读取、4Z8R468M2D、me.pabal.ios、4、为空)
TELEGRAM_STATIC_MAPS_KEY、TELEGRAM_STATIC_MAPS_PER_DAY、TELEGRAM_STATIC_MAPS_PER_USER_HOUR位置消息中的地图图片——Google Maps Static API 密钥、每天新获取的图片数、一个人每小时能让服务器新获取的图片数。没有密钥时地图图片关闭(服务器安装——地图图片)STATIC_MAPS_*(无密钥、300、120)
JAVA_OPTSJVM 选项(内存).env 中的值

环境变量——语音机器人

在生产环境中,附加文件 deploy/docker-compose.voice.yml 会用 .env 中的值设置其中的链路、中继、时区、限额、测试者和最低版本,其余的按功能分别审查后再加(服务器安装——语音机器人)。网关(pabal-voice)的 VOICE_* 设置在代码仓库的 voice/README.md 中。

变量默认含义
TELEGRAM_VOICE_LINK_SECRET_FILE—与网关相同的 32 字节链路机密值(64 位 hex)。不存在或有误时语音关闭
TELEGRAM_VOICE_LINK_HOST, TELEGRAM_VOICE_LINK_PORT127.0.0.1, 8095链路监听的位置。不是回环地址时需要 TELEGRAM_VOICE_LINK_ANY_ADDRESS=true,公网地址总是被拒绝
TELEGRAM_VOICE_LINK_ANY_ADDRESS—声明“这个网络只有服务器和网关使用”
TELEGRAM_VOICE_TURN_HOST, TELEGRAM_VOICE_TURN_PORT—交给网关的中继地址(服务器的局域网地址)。是回环地址时忽略
TELEGRAM_VOICE_MAX_SECONDS600这台服务器允许的最长通话(60~3600)
TELEGRAM_VOICE_BOT_CONCURRENCY2单个机器人同时通话数的上限(运营方和机器人所有者只能调低)
TELEGRAM_VOICE_TIME_ZONEAsia/Seoul每日、每月限额的基准
TELEGRAM_VOICE_TESTERS—测试者用户 id 列表(与管理页面的列表合并)。* 只用于测试服务器
TELEGRAM_VOICE_RECIPIENTSgoogle.vertex.gemini-live@us-central1应用确认窗口所说的接收方。必须与网关的相同,通话才能接通
TELEGRAM_VOICE_MIN_BUILD_DESKTOP, _ANDROID, _IOS, _WATCHOS1, 62151, 5, 1真正包含确认窗口的第一个应用版本(桌面版是标记 pabal-bc 后面的数字)。接收方变化时,发布新版本并调高这些值。桌面版在首次批准韩语、英语以外的确认窗口时调高到 2
TELEGRAM_VOICE_MIN_SHEET_VERSION1接受的最低确认窗口版本
TELEGRAM_VOICE_TOOL_RESULT_BYTES16384工具回答的最大大小(1024~16384)
TELEGRAM_VOICE_KEYS_MASTER_FILE, TELEGRAM_VOICE_KEYS_PREVIOUS_MASTER_FILE—封装自有密钥和音频流机密值的主密钥,以及更换期间的旧密钥。放在备份之外权限为 700 的文件夹中
TELEGRAM_VOICE_OWN_KEYS_APPS_READY—只有在应用显示了自有密钥机器人的确认窗口(第 2 版)之后才设为 true。在此之前不接受自有密钥
TELEGRAM_VOICE_OWN_KEY_MIN_SHEET_VERSION, TELEGRAM_VOICE_TRANSCRIPT_MIN_SHEET_VERSION2, 1自有密钥通话和文字记录提示所需的确认窗口版本(生产服务器不会把自有密钥的版本降到 2 以下)
TELEGRAM_VOICE_STREAM_MIN_BUILD_DESKTOP, _ANDROID, _IOS0(无)包含音频流确认窗口的第一个应用版本。为 0 时谁都不能给音频流机器人打电话
TELEGRAM_VOICE_STREAM_MIN_SHEET_VERSION2音频流确认窗口的版本
TELEGRAM_VOICE_STREAM_DENY_ADDRESSES—音频流地址不得访问的本部署地址(公开主机和网站主机会自动包含)
TELEGRAM_WATCH_API_PORT, _HOST, _ANY_ADDRESS, TELEGRAM_WATCH_AUDIO_URL, TELEGRAM_WATCH_ALLOW_PLAIN, TELEGRAM_WATCH_SESSION_DAYS, TELEGRAM_WATCH_AUTH_PER_MINUTE—, 127.0.0.1, —, —, —, 7, 30Apple Watch API 和音频入口的地址(服务器安装——Apple Watch 入口)。ALLOW_PLAIN 仅限开发
TELEGRAM_VOICE_EVIDENCE_KEY_DIR—机器人打电话的许可记录(HMAC 证据)所用密钥的文件夹。700,放在会被备份的文件夹之外。用 scripts/voice-evidence-key.py 创建和更换。没有它,谁都不能开启许可。使用 Docker Compose 时,只写在 .env 里不会传到服务器——开启机器人打来的电话时,把它加到 deploy/docker-compose.voice.yml 中 pabal-server 的 environment(容器内的路径)和 volumes(主机上的那个文件夹)
TELEGRAM_VOICE_OUTBOUND_MIN_BUILD_DESKTOP、_ANDROID、_IOS、_WATCHOS0(无)带许可窗口的第一个应用版本。更旧的版本不能开启许可,机器人的来电也不会让它响铃。0 表示该平台没有
TELEGRAM_VOICE_CALLME_DEVICE_AGE_SECONDS86400设备登录后多久才能开启许可(秒)。只有测试服务器可以更改(生产服务器会警告并忽略)
TELEGRAM_VOICE_KEEP_TEXT_UNREVIEWED—在法律审查之前就把保存对话复选框的文案显示在手表上。仅限内部测试服务器
TELEGRAM_MCP_*, TELEGRAM_MCP_APPS_READY—MCP 组件(由 deploy/docker-compose.mcp.yml 填入)。即使不使用 MCP,TELEGRAM_MCP_EGRESS_OWN_ADDRESSES(Pabal 的公网地址)也会用来防止 Webhook 和工具请求发往 Pabal 自身
TELEGRAM_VOICE_BOTS, TELEGRAM_VOICE_NOTICE_CHECK=off, TELEGRAM_VOICE_STREAM_ALLOW_PRIVATE—仅限测试服务器(只在 TELEGRAM_TEST_NUMBERS=true 时):允许列出的机器人(id 或 @用户名,* 为所有机器人) · 跳过法律条款检查 · 音频流地址可以使用私有地址
TELEGRAM_VOICE_CALLME_UNREVIEWED, TELEGRAM_VOICE_DEV_ECHO_OUTBOUND, TELEGRAM_VOICE_TEST_DIAL, TELEGRAM_VOICE_TEST_DIAL_USERS—仅限测试和开发服务器:可以在法律审查前打开机器人打电话的开关(开发和测试服务器)· 由回声网关拨打机器人的电话(开发服务器,TELEGRAM_TEST_MODE)· 管理 API 的测试拨号及其可拨打的账号(+99966 测试号码之外最多 20 个,测试服务器)。生产服务器会警告并忽略

数据文件

文件内容权限
keys/private.pem服务器 RSA 私钥。绝不外传600
keys/private.pem.pub公钥。用于构建应用和 /docs/server-key.pem—
keys/firebase-service-account.json(可选)Android 推送用的 Firebase 私钥。泄露时在 Firebase 控制台中删除并重新获取600
data/admin-token管理页面令牌600
data/operations.json设置标签页中的值——注册规则、短信和 SMTP 的机密值、封禁的号码,以及语音标签页的设置(紧急停止开关、正式开放、测试者、已允许的机器人、限额)600
keys/voice-link.secret(语音机器人)与网关相同的链路机密值400
/etc/pabal/voice/voice-master.key(语音机器人)封装机器人所有者自有密钥和音频流机密值的主密钥。放在数据文件夹之外,不放进备份600(文件夹 700)
data/media/照片和文件的原始文件—
PostgreSQL events 表账号、对话、消息、登录、机器人、Webhook 设置——所有变更的记录—

安全须知

  • 不要把管理端口直接开放到互联网上。生产配置中的 Caddy 会以 404 拦截 /admin、/health、/metrics 等管理路径。
  • 所有管理数据请求都需要 Authorization: Bearer <令牌>,其他网站的页面无法读取这些数据。
  • 短信和 SMTP 的机密值只保存在 operations.json 中,界面和 API 只会告知“已保存”。机密值输入框留空保存时,会保留原来的值。
  • 令牌和机密值不会写入日志,日志中的手机号码会做遮盖处理。Bot API 地址(包含令牌)也不会写入日志。
  • 推送通知的设备令牌在日志中只以指纹形式记录,Firebase 密钥文件的内容和通知内容都不会写入日志。
  • 授权密钥保存在数据库中,因此能够访问数据库的人就能解密用户流量。请像保护 RSA 密钥一样保护数据库和备份。

已知限制

  • 等待中的验证码和最近记录保存在内存中,服务器重启后会丢失(在应用中重新请求即可)。
  • 短信服务商的实际发送效果,需要用各服务商的账号来确认。服务器按照各服务商的文档来构造请求。
  • 尚未提供的功能:强制删除机器人、查看消息、查看日志、图表、推送通知统计(推送情况请通过服务器日志确认)。