ឯកសារអ្នកអភិវឌ្ឍន៍
ភាសាខ្មែរ

ការដំណើរការម៉ាស៊ីនមេ

ការដំឡើងម៉ាស៊ីនមេ

របៀបដំឡើង និងដំណើរការម៉ាស៊ីនមេ Pabal លើម៉ាស៊ីនមេមួយគ្រឿងដែលបើកចំហលើអ៊ីនធឺណិត ដោយប្រើ Docker Compose។

នេះជារបៀបដំឡើងម៉ាស៊ីនមេ Pabal លើម៉ាស៊ីនមេមួយគ្រឿងដែលបើកចំហលើអ៊ីនធឺណិត។ យើងដំណើរការ container បី — ម៉ាស៊ីនមេ Pabal · PostgreSQL · Caddy (HTTPS) — ដោយ Docker Compose ហើយទិន្នន័យទាំងអស់ដែលមិនត្រូវបាត់ ត្រូវបានbind ទៅថតនៅលើម៉ាស៊ីន (host)។ គ្រាន់តែធ្វើតាមលំដាប់ពីលើចុះក្រោម។

តម្លៃឧទាហរណ៍ក្នុងឯកសារនេះ

domain pabal.me, IP សាធារណៈរបស់ម៉ាស៊ីនមេ 203.0.113.10 (អាសយដ្ឋានសម្រាប់ពន្យល់ — សូមអានជំនួសដោយ IP ពិតរបស់អ្នក), ទីតាំងកូដប្រភព /opt/pabal, ទីតាំងទិន្នន័យ /srv/pabal, ប្រព័ន្ធប្រតិបត្តិការ Ubuntu 24.04 LTS។ ឯកសារដែលត្រូវការ មាននៅក្នុងថត deploy/ នៃឃ្លាំងកូដ។

ទិដ្ឋភាពរួម

អ៊ីនធឺណិត docker compose · ssemiya-net /srv/pabal (bind mount) កម្មវិធី PabalPabal.app កម្មវិធីរុករក · បូតគេហទំព័រ · Bot API ប្រតិបត្តិករSSH pabal-server MTProto :8443 វេប·Bot API·គ្រប់គ្រង :8080 uid 1000 · JRE 21 webhook → បូត (HTTPS) pabal-caddy:80 · :443 TLS ស្វ័យប្រវត្តិ pabal-postgres 16បណ្តាញខាងក្នុង · គ្មានច្រក pabal_server/keys · សោ RSA pabal_server/data · រូបថត pabal_server/logs postgres_data/ · ការសន្ទនា caddy/ · វិញ្ញាបនបត្រ backups/ · backup.sh MTProto :8443 (អ៊ិនគ្រីបខ្លួនឯង) HTTPS :443 SSH tunnel → 127.0.0.1:8080/admin/
ម៉ាស៊ីនមេមួយ container បី ហើយអ្វីដែលត្រូវរក្សាទុក ស្ថិតនៅក្នុង /srv/pabal ទាំងអស់

ការពន្យល់ដ្យាក្រាម

  • តំបន់បី៖ អ្នកប្រើនៅលើអ៊ីនធឺណិត → container បីនៅលើម៉ាស៊ីនមេផលិតកម្ម → ថត bind នៅលើថាសរបស់ម៉ាស៊ីន (host)។ container អាចលុប និងបង្កើតឡើងវិញនៅពេលណាក៏បាន ហើយអ្វីដែលត្រូវរក្សាទុក ស្ថិតនៅក្នុង /srv/pabal ទាំងអស់។
  • មានច្រកចូលតែពីរប៉ុណ្ណោះ៖ កម្មវិធីភ្ជាប់ទៅម៉ាស៊ីនមេដោយផ្ទាល់តាមច្រក MTProto (មិនត្រូវការ HTTPS ព្រោះវាអ៊ិនគ្រីបដោយខ្លួនឯង) ហើយគេហទំព័រ ឯកសារ និង Bot API ឆ្លងកាត់ច្រក 443 របស់ Caddy។ Caddy រារាំងផ្លូវសម្រាប់ការគ្រប់គ្រង (/admin, /health …) ហើយបញ្ជូនបន្តតែផ្លូវផ្សេងទៀត។
  • បន្ទាត់ដាច់ៗពណ៌ក្រហម ជាផ្លូវសម្រាប់តែប្រតិបត្តិករ។ ទំព័រគ្រប់គ្រងបើកតែនៅ 127.0.0.1:8080 របស់ម៉ាស៊ីនមេ ដូច្នេះអាចចូលបានតែតាម SSH tunnel។ PostgreSQL គ្មានច្រកបើកទៅខាងក្រៅតែម្តង។
  • ប្រអប់ក្រហមពីរ គឺជាទិន្នន័យសំខាន់បំផុត។ សោ RSA ក្នុង pabal_server/keys ត្រូវបានបង្កប់ក្នុងកម្មវិធីពេល build ដូច្នេះបើបាត់ ត្រូវចែកចាយកម្មវិធីទាំងអស់ឡើងវិញ ហើយ postgres_data/ មានគណនី និងការសន្ទនាទាំងអស់។ ទាំងពីរនេះជាអាទិភាពទីមួយនៃការបម្រុងទុក។
  • ព្រួញពណ៌ប្រផេះ គឺជាការរក្សាទុក៖ ម៉ាស៊ីនមេសរសេរសោ រូបថត ការកំណត់ និង log, PostgreSQL សរសេរព្រឹត្តិការណ៍ (event) ហើយ Caddy សរសេរវិញ្ញាបនបត្រ ទៅក្នុងថតរៀងៗខ្លួន។

អ្វីដែលត្រូវរៀបចំ

ធាតុខ្លឹមសារ
ម៉ាស៊ីនមេUbuntu 24.04 LTS · សម្រាប់ចាប់ផ្តើម 2 vCPU · 4 GB RAM · 40 GB SSD។ ពេលអ្នកប្រើ និងសារកើនឡើង សូមបង្កើនអង្គចងចាំជាមុនសិន
IPv4 សាធារណៈIP ថេរ។ កម្មវិធីត្រូវបាន build ដោយបង្កប់អាសយដ្ឋានម៉ាស៊ីនមេជា IP ហើយម៉ាស៊ីនមេក៏ប្រាប់កម្មវិធីជា IP ដែរ
Domaindomain មួយដែលអ្នកអាចកែ DNS បាន (A record)
មធ្យោបាយបញ្ជូនលេខកូដចុះឈ្មោះគណនី SMS (Twilio · Solapi · webhook) ឬអ៊ីមែល (SMTP) មួយ
MacMac មួយសម្រាប់ build កម្មវិធីសម្រាប់ម៉ាស៊ីនមេនេះ (បើចង់បង្កើតកម្មវិធី Windows ផង ត្រូវមានកុំព្យូទ័រ Windows មួយទៀតដែរ)
គម្រោង Firebase (ជាជម្រើស)សម្រាប់ផ្ញើការជូនដំណឹង push ទៅកម្មវិធី Android។ បង្កើតដោយឥតគិតថ្លៃ ជាមួយគណនី Google (ជំហានទី 10)

ច្រក (port)

ច្រកអ្នកណាបើកការពិពណ៌នា
22/tcpប្រតិបត្តិករណែនាំឲ្យបើកតែ IP ប្រតិបត្តិករSSH
80/tcpCaddyទាំងអស់ចេញវិញ្ញាបនបត្រ · បង្វែរទៅ HTTPS
443/tcp, 443/udpCaddyទាំងអស់គេហទំព័រ · ឯកសារ · Bot API (udp សម្រាប់ HTTP/3)
8443/tcpម៉ាស៊ីនមេទាំងអស់ការតភ្ជាប់របស់កម្មវិធី (MTProto)
8080/tcpម៉ាស៊ីនមេមិនបើកទំព័រគ្រប់គ្រង · health check — តែនៅ 127.0.0.1 របស់ម៉ាស៊ីនមេ
5432/tcpPostgreSQLមិនបើកតែក្នុងបណ្តាញខាងក្នុងរបស់ container
ហេតុអ្វីច្រករបស់កម្មវិធីមិនមែន 443

ច្រក 443 ត្រូវបានប្រើដោយគេហទំព័រ (HTTPS)។ MTProto មិនមែនជា HTTP ឬ TLS ទេ ដូច្នេះមិនអាចចែកទទួលលើច្រកតែមួយបានទេ។ បើអ្នកចង់ឲ្យកម្មវិធីក៏ទទួលតាម 443 ដែរ ដោយសារបណ្តាញក្រុមហ៊ុន ឬសាលារៀនដែលរារាំងច្រកមិនសូវប្រើ សូមទទួលIP មួយទៀត ហើយផ្តល់ច្រក 443 នៃ IP នោះឲ្យម៉ាស៊ីនមេ (ក្នុង .env កំណត់ PUBLIC_IP ជា IP ទីពីរ · MTPROTO_PORT=443 · ហើយបែងចែកដោយភ្ជាប់ IP ទៅនឹងច្រកក្នុងឯកសារ compose)។ ដោយសារម៉ាស៊ីនមេប្រាប់កម្មវិធីថា «សូមភ្ជាប់តាមច្រកនេះនៃ IP នេះ» សូមរក្សាច្រកកម្មវិធីខាងក្នុង និងខាងក្រៅ container ឲ្យដូចគ្នា។

1. រៀបចំម៉ាស៊ីនមេ

sudo apt update && sudo apt -y upgrade
timedatectl                      # ពិនិត្យថាបង្ហាញ "System clock synchronized: yes"

ការធ្វើសមកាលកម្មពេលវេលាគឺចាំបាច់។ ដោយសារលេខសារ MTProto បង្កើតចេញពីពេលវេលា បើនាឡិការបស់ម៉ាស៊ីនមេខុស កម្មវិធីនឹងភ្ជាប់ម្តងហើយម្តងទៀត។ បើជា no សូមដំណើរការ sudo timedatectl set-ntp true។

# ជញ្ជាំងភ្លើង
sudo ufw allow OpenSSH           # បើអាច៖ sudo ufw allow from <IP ប្រតិបត្តិករ> to any port 22
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp
sudo ufw allow 8443/tcp
sudo ufw enable

# Docker (script ដំឡើងផ្លូវការ)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER     # ចូលម្តងទៀត ដើម្បីប្រើ docker ដោយគ្មាន sudo
docker compose version            # v2 ឡើងទៅ
Docker និង ufw

ច្រកដែល Docker បើក (ports:) ត្រូវបានបើកដោយមិនគិតពីច្បាប់ ufw ទេ។ ដូច្នេះឯកសារ compose បើកតែច្រកដែលត្រូវបើកចំហ (80 · 443 · 8443) បើកច្រកគ្រប់គ្រងតែនៅ 127.0.0.1:8080 ហើយមិនបើក PostgreSQL ទេ។ សូមចងចាំចំណុចនេះ ពេលកែ ports:។

2. ទាញយកកូដប្រភព

sudo mkdir -p /opt/pabal && sudo chown $USER: /opt/pabal
git clone <អាសយដ្ឋានឃ្លាំងកូដ> /opt/pabal

បើចម្លងពីកុំព្យូទ័រអភិវឌ្ឍ កុំផ្ញើសោ ទិន្នន័យ និង log (rsync --exclude 'keys/' --exclude 'data/' --exclude 'logs/' --exclude '**/target/')។ សោ RSA របស់ម៉ាស៊ីនមេផលិតកម្ម ត្រូវបានបង្កើតថ្មី ពេលម៉ាស៊ីនមេផលិតកម្មបើកជាលើកដំបូង — បើប្រើសោអភិវឌ្ឍក្នុងផលិតកម្ម កុំព្យូទ័រអភិវឌ្ឍនោះនឹងក្លាយជាកន្លែងដែលអាចឌិគ្រីបចរាចរណ៍ផលិតកម្មបាន។

3. ថតទិន្នន័យ (bind mount)

sudo mkdir -p /srv/pabal/{postgres_data,pabal_server/keys,pabal_server/data,pabal_server/logs,caddy/data,caddy/config,backups}
sudo chown -R 1000:1000 /srv/pabal/pabal_server        # container ម៉ាស៊ីនមេដំណើរការជា uid 1000
sudo chown -R $USER: /srv/pabal/backups
sudo chmod 700 /srv/pabal/pabal_server/keys /srv/pabal/backups
ថតក្នុង containerអ្វីដែលមានបើបាត់
pabal_server/keys/app/keysprivate.pem (សោឯកជន RSA របស់ម៉ាស៊ីនមេ), private.pem.pub, (ជាជម្រើស) firebase-service-account.json (សោសម្ងាត់ Firebase សម្រាប់ push Android)ត្រូវ build និងចែកចាយកម្មវិធីទាំងអស់ឡើងវិញ (សោ Firebase គ្រាន់តែទាញយកថ្មីពី console)
pabal_server/data/app/dataរូបថត (media/), admin-token, operations.json (ការកំណត់លេខកូដចុះឈ្មោះ SMS និង SMTP រួមទាំងតម្លៃសម្ងាត់)រូបថត និងការកំណត់ប្រតិបត្តិការ
pabal_server/logs/app/logslog របស់ម៉ាស៊ីនមេ (បង្ហាប់រៀងរាល់ថ្ងៃ)តែកំណត់ត្រា
postgres_data/var/lib/postgresql/dataគណនី ការសន្ទនា សារ ការចូលគណនី បូត និងការកំណត់ webhook ទាំងអស់សេវាទាំងមូល
caddy/data, caddy/config/data, /configវិញ្ញាបនបត្រ HTTPSនឹងត្រូវចេញឡើងវិញ
backups(សម្រាប់តែ host)លទ្ធផលនៃ backup.sh—

4. ឯកសារកំណត់ .env

cd /opt/pabal/deploy
cp .env.example .env
chmod 600 .env
openssl rand -base64 30 | tr -d '/+=' | cut -c1-32     # ដាក់តម្លៃដែលចេញមក ក្នុង POSTGRES_PASSWORD
nano .env
DOMAIN=pabal.me
PUBLIC_IP=203.0.113.10
POSTGRES_PASSWORD=(តម្លៃដែលបានបង្កើតខាងលើ)
PABAL_HOME=/srv/pabal
PABAL_SOURCE=..
PABAL_NETWORK=ssemiya-net
MTPROTO_PORT=8443
HTTP_PORT=80
HTTPS_PORT=443
ADMIN_PORT=8080
ADMIN_TOKEN=
JAVA_OPTS="-Xms512m -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=100"
FCM_CREDENTIALS=
FCM_PROJECT_ID=
PUSH_PREVIEWS=true
តម្លៃអ្វីដែលត្រូវដាក់កំណត់ចំណាំ
DOMAINdomain របស់គេហទំព័រតំណដែលកម្មវិធីបង្កើត (pabal.me/ឈ្មោះអ្នកប្រើ) · អាសយដ្ឋានឯកសារ · និងការមើលតំណជាមុន ក៏ប្រើអាសយដ្ឋាននេះដែរ
PUBLIC_IPIPv4 សាធារណៈរបស់ម៉ាស៊ីនមេបើជា cloud គឺ IP សាធារណៈដែលបង្ហាញក្នុង console (មិនមែន IP ឯកជនក្នុងម៉ាស៊ីនមេទេ)
POSTGRES_PASSWORDតម្លៃចៃដន្យសូមកំណត់មុនពេលបើកជាលើកដំបូង។ PostgreSQL ប្រើតម្លៃនេះតែពេលបង្កើតថតទិន្នន័យជាលើកដំបូងប៉ុណ្ណោះ
PABAL_HOME/srv/pabalថតនៅជំហានទី 3
PABAL_SOURCE..ឃ្លាំងកូដដែលប្រើសម្រាប់ build image ម៉ាស៊ីនមេ៖ .. បើឯកសារ compose នៅក្នុង deploy/ នៃឃ្លាំង បើមិនដូច្នោះទេ គឺផ្លូវទៅកាន់កូដប្រភព
PABAL_NETWORKssemiya-netបណ្តាញ Docker ដែល container ទាំងបីចូលរួម។ ត្រូវបង្កើតជាមុន (ជំហានទី 6)
MTPROTO_PORT8443បើប្តូរ ត្រូវប្តូរជញ្ជាំងភ្លើង និងការ build កម្មវិធីជាមួយផង
ADMIN_TOKENទុកទទេបើទុកទទេ វានឹងត្រូវបង្កើតក្នុង pabal_server/data/admin-token ពេលបើកជាលើកដំបូង។ បើចង់កំណត់ដោយខ្លួនឯង ត្រូវមាន 16 តួឡើងទៅ
JAVA_OPTSតម្លៃលំនាំដើមបើអង្គចងចាំមិនគ្រប់ សូមបង្កើន -Xmx (រហូតដល់ប្រហែលពាក់កណ្តាលនៃអង្គចងចាំម៉ាស៊ីនមេ)
FCM_CREDENTIALSទុកទទេការជូនដំណឹង push របស់ Android។ ពេលបើក ដាក់ /app/keys/firebase-service-account.json (ជំហានទី 10)។ បើទុកទទេ ម៉ាស៊ីនមេដំណើរការដោយគ្មាន push
FCM_PROJECT_IDទុកទទេសម្រាប់តែពេលផ្ញើទៅគម្រោង Firebase ផ្សេងពី project_id ក្នុងឯកសារសោ
PUSH_PREVIEWStrueបើ false ការជូនដំណឹងបង្ហាញតែអ្នកផ្ញើ ដោយគ្មានខ្លឹមសារសារ

ឯកសារ compose សម្រាប់ផលិតកម្ម បើកម៉ាស៊ីនមេដោយបិទលេខសាកល្បង (TELEGRAM_TEST_NUMBERS=false)។ តម្លៃកំណត់ទាំងអស់ដែលម៉ាស៊ីនមេអាន មាននៅក្នុង ការគ្រប់គ្រង និងការកំណត់ — អថេរបរិស្ថាន។

5. DNS

ឈ្មោះប្រភេទតម្លៃ
pabal.meA203.0.113.10
www.pabal.meA203.0.113.10
dig +short pabal.me        # ត្រូវតែបង្ហាញ 203.0.113.10 (ការអនុវត្តចំណាយពេលពីប៉ុន្មាននាទី ដល់ប៉ុន្មានម៉ោង)

អ្នកអាចបើកម៉ាស៊ីនមេមុនពេល DNS ចង្អុលមកម៉ាស៊ីនមេក៏បាន។ Caddy នឹងព្យាយាមម្តងទៀតដោយខ្លួនឯង រហូតដល់ទទួលបានវិញ្ញាបនបត្រ។

6. build ហើយបើក

cd /opt/pabal/deploy
docker network inspect ssemiya-net >/dev/null 2>&1 || docker network create ssemiya-net   # តែម្តងប៉ុណ្ណោះ
docker compose up -d --build       # លើកដំបូងចំណាយពេលប៉ុន្មាននាទី (Maven ទាញយកបណ្ណាល័យ)
docker compose ps                  # pabal-server, pabal-postgres, pabal-caddy គឺ running (healthy)
docker compose logs -f pabal-server      # ចុច Ctrl+C ដើម្បីចេញ

ពេលបើកជាលើកដំបូង បន្ទាត់ទាំងនេះនឹងបង្ហាញក្នុង log។

WARN  ServerKeys - Generated a new RSA key at /app/keys/private.pem (fingerprint -3898654385185406269). Clients must embed /app/keys/private.pem.pub
INFO  TelegramServer - JDBC persistence active (jdbc:postgresql://pabal-postgres:5432/pabal)
INFO  BotFather - BotFather is user 100000
INFO  AdminToken - Created the admin token in /app/data/admin-token
INFO  TelegramServer - Website: http://0.0.0.0:8080/ (published at https://pabal.me/)
  • បន្ទាត់ទីមួយជា WARN ប៉ុន្តែវាធម្មតាទេ (ជាការជូនដំណឹងថាសោត្រូវបានបង្កើតតែម្តងលើកដំបូង)។ ចាប់ពីលើកក្រោយ នឹងបង្ហាញ Loaded RSA key … (fingerprint …)។ fingerprint ខុសគ្នាតាមម៉ាស៊ីនមេនីមួយៗ។
  • តារាងត្រូវបានបង្កើតដោយម៉ាស៊ីនមេខ្លួនឯង ពេលវាបើក។

7. ការពិនិត្យ

# ពីខាងក្រៅ (កុំព្យូទ័ររបស់ខ្ញុំ)
curl -sI https://pabal.me/ | head -1                              # HTTP/2 200
curl -s -o /dev/null -w '%{http_code}\n' https://pabal.me/docs/    # 200 — ឯកសារនេះ
curl -s -o /dev/null -w '%{http_code}\n' https://pabal.me/admin/   # 404 — ទំព័រគ្រប់គ្រងមិនបើកចំហ
curl -s https://pabal.me/docs/server-key.pem | head -1             # -----BEGIN RSA PUBLIC KEY-----
nc -vz 203.0.113.10 8443                                          # succeeded — ច្រករបស់កម្មវិធី

# នៅលើម៉ាស៊ីនមេ
curl -s http://127.0.0.1:8080/health          # {"status":"UP",…}
ls -l /srv/pabal/pabal_server/keys                  # private.pem(600), private.pem.pub

8. ទំព័រគ្រប់គ្រង និងការកំណត់ដំបូង

# នៅលើកុំព្យូទ័ររបស់ខ្ញុំ (ទុកឲ្យដំណើរការ)
ssh -N -L 8080:127.0.0.1:8080 <អ្នកប្រើ>@203.0.113.10

# តូខឹន (នៅលើម៉ាស៊ីនមេ)
sudo cat /srv/pabal/pabal_server/data/admin-token

បើក http://localhost:8080/admin/ ក្នុងកម្មវិធីរុករក ហើយបញ្ចូលតូខឹន។ ការកំណត់ដែលត្រូវតែធ្វើមុនដំណើរការពិត (លម្អិតនៅក្នុង ការគ្រប់គ្រង និងការកំណត់)៖

  1. កំណត់វិធីបញ្ជូនលេខកូដ (코드 전달 방식) ជា SMS ឬអ៊ីមែល។ វិធី «ទំព័រគ្រប់គ្រង» (관리 화면) តម្រូវឲ្យប្រតិបត្តិករប្រាប់លេខកូដម្តងមួយៗ។
  2. បញ្ចូលតម្លៃ SMS ឬអ៊ីមែល (SMTP) (이메일) ហើយរក្សាទុក → ពិនិត្យថាវាមកដល់ពិតប្រាកដ ដោយការផ្ញើសាកល្បង (테스트 발송)។
  3. ពិនិត្យថាលេខសាកល្បង (테스트 번호) ត្រូវបានបិទ។ បើបើក អ្នកណាក៏អាចចូលគណនីដោយលេខ +99966… បាន។
  4. បើចាំបាច់ ចាប់ផ្តើមដោយបិទអនុញ្ញាតការចុះឈ្មោះថ្មី (새 가입 허용) ហើយទទួលតែមនុស្សដែលអ្នកអញ្ជើញជាមុនសិន។

9. ភ្ជាប់កម្មវិធីទៅម៉ាស៊ីនមេនេះ

កម្មវិធីត្រូវបាន build ដោយបង្កប់IP · ច្រក · សោសាធារណៈរបស់ម៉ាស៊ីនមេក្នុងខ្លួន។ ត្រូវ build ម្តងទៀតជាមួយសោសាធារណៈរបស់ម៉ាស៊ីនមេនេះ ទើបវាភ្ជាប់ទៅម៉ាស៊ីនមេនេះបាន។ នៅលើ Mac៖

# 1. សោសាធារណៈរបស់ម៉ាស៊ីនមេនេះ (សោសាធារណៈ មិនមែនសោឯកជនទេ — អាចទាញយកពីគេហទំព័រឯកសារក៏បាន)
curl -s -o keys/production.pem.pub https://pabal.me/docs/server-key.pem

# 2. ឲ្យកូដប្រភពកម្មវិធីចង្អុលទៅម៉ាស៊ីនមេនេះ + អនុវត្តម៉ាក
python3 scripts/tdesktop/point_to_server.py ~/Developer/tdesktop \
    --host 203.0.113.10 --port 8443 --key keys/production.pem.pub
python3 scripts/tdesktop/apply_branding.py ~/Developer/tdesktop

បន្ទាប់មក ធ្វើជំហានទី 5 (configure) និងជំហានទី 6 (build) នៃ docs/tdesktop-build-guide.md ក្នុងឃ្លាំងកូដ។ សូមចម្លងលទ្ធផល out/Debug/Pabal.app ទុកក្រោមឈ្មោះផ្សេង — បើ build កូដប្រភពដដែលម្តងទៀតសម្រាប់ម៉ាស៊ីនមេផ្សេង វានឹងត្រូវសរសេរជាន់ពីលើ។

មុនពេលចែកកម្មវិធីទៅអ្នកដទៃ

build បច្ចុប្បន្នជាdebug build ដែលគ្មានហត្ថលេខា និងការបញ្ជាក់ (notarization) ដូច្នេះអ្នកទទួលត្រូវចុចកណ្តុរស្តាំ → បើក ពេលបើកជាលើកដំបូង។ debug build ទុកទិន្នន័យក្នុងថតក្បែរកម្មវិធី (tdata/) ហើយបើមិនអាចសរសេរទៅទីនោះបាន វានឹងប្រើថតទិន្នន័យដូចគ្នានឹង Telegram Desktop ពិតប្រាកដ។ សូមណែនាំឲ្យទុកកម្មវិធីក្នុងថតអ្នកប្រើ (ឧ. ~/Applications/Pabal/)។ release build សម្រាប់ការចែកចាយទូទៅ (ថតទិន្នន័យដាច់ដោយឡែក ហត្ថលេខា និងការបញ្ជាក់របស់ Apple) គឺជាការងារដាច់ដោយឡែក។

សម្រាប់កម្មវិធី Android, iPhone និង Windows វិធីដូចគ្នា (script ដែលបញ្ចូលអាសយដ្ឋាន និងសោសាធារណៈរបស់ម៉ាស៊ីនមេ → build) មាននៅក្នុង docs/mobile-apps-guide.md នៃឃ្លាំងកូដ។ ដើម្បីឲ្យកម្មវិធី Android មានការជូនដំណឹង push ត្រូវមានការកំណត់កម្មវិធី Firebase នៃជំហានទី 10 មុនពេល build។

10. ការជូនដំណឹង push របស់ Android (ជាជម្រើស)

Android ឆាប់ធ្វើឲ្យកម្មវិធីដែលចេញពីអេក្រង់ចូលគេង។ បើមិនបើក push ទេ សារនឹងបង្ហាញ និងការហៅនឹងរោទ៍ តែពេលកម្មវិធីកំពុងបើកប៉ុណ្ណោះ។ push ត្រូវបានផ្ញើតាម Firebase Cloud Messaging (FCM) របស់ Google (ឥតគិតថ្លៃ) ហើយខ្លឹមសារការជូនដំណឹង (ឈ្មោះអ្នកផ្ញើ ការមើលសារជាមុន) ត្រូវបានម៉ាស៊ីនមេអ៊ិនគ្រីបដោយសោដែលមានតែទូរស័ព្ទនោះ ដូច្នេះ Google មិនអាចអានបានទេ។

គម្រោង Firebase (របស់ប្រតិបត្តិករ) ការ build · ការដំឡើង ទូរស័ព្ទ · Google google-services.json ការកំណត់ដែលដាក់ក្នុងកម្មវិធី នៅក្នុង APK · មិនមែនសម្ងាត់ សោគណនីសេវា firebase-service-account.json សម្ងាត់ · នៅតែលើម៉ាស៊ីនមេ build កម្មវិធី Android apply_branding.py → APK pabal-server keys/ · chmod 600 FCM_CREDENTIALS អ៊ិនគ្រីបដោយសោរបស់ទូរស័ព្ទ កម្មវិធី Pabal លើទូរស័ព្ទ ចុះឈ្មោះទូរស័ព្ទ ពេលបើកលើកដំបូង Google FCM បញ្ជូនតែទិន្នន័យអ៊ិនគ្រីប · អានមិនបាន ① ចុះឈ្មោះទូរស័ព្ទ ② អ៊ិនគ្រីបរួច ③ ដាស់ → ជូនដំណឹង
ឯកសារពីរទៅកន្លែងខុសគ្នា ការជូនដំណឹងធ្វើដំណើរជាទម្រង់អ៊ិនគ្រីប

ការពន្យល់ដ្យាក្រាម

  • តំបន់បី៖ គម្រោង Firebase ដែលប្រតិបត្តិករបង្កើត → កន្លែង build កម្មវិធី និងបើកម៉ាស៊ីនមេ → ទូរស័ព្ទ និង Google។ ឯកសារពីរត្រូវបានទទួលពីគម្រោង Firebase តែមួយ។
  • ព្រួញពណ៌ប្រផេះ គឺជាការរៀបចំដែលធ្វើតែម្តង។ ប្រអប់ពណ៌បៃតង google-services.json ចូលទៅក្នុងកម្មវិធី ហើយមាននៅក្នុងគ្រប់ APK ដូច្នេះមិនមែនជាការសម្ងាត់ទេ ចំណែកប្រអប់ពណ៌ក្រហម សោគណនីសេវា គឺជាការសម្ងាត់ដែលទុកតែនៅក្នុង keys/ របស់ម៉ាស៊ីនមេ។ ឯកសារទាំងពីរត្រូវតែទទួលពីគម្រោងតែមួយ។
  • ព្រួញពណ៌ខៀវ គឺជាផ្លូវដែលការជូនដំណឹងធ្វើដំណើរ៖ ① ពេលបើកកម្មវិធីលើកដំបូង ទូរស័ព្ទចុះឈ្មោះតូខឹន FCM និងសោដែលមានតែទូរស័ព្ទនោះ ទៅម៉ាស៊ីនមេ ② ពេលមានសារ ឬការហៅថ្មី ម៉ាស៊ីនមេអ៊ិនគ្រីបការជូនដំណឹងដោយសោនោះ ហើយប្រគល់ឲ្យ FCM ③ ពេល FCM ដាស់ទូរស័ព្ទ កម្មវិធីដោះការអ៊ិនគ្រីប បង្ហាញការជូនដំណឹង ហើយភ្ជាប់ទៅម៉ាស៊ីនមេម្តងទៀត ដើម្បីទទួលអ្វីដែលខកខាន។
  • អ្វីដែល Google ឃើញ មានតែព័ត៌មានបញ្ជូន ដូចជាតូខឹនឧបករណ៍ ពេលវេលាផ្ញើ និងអាទិភាពប៉ុណ្ណោះ។ ឈ្មោះអ្នកផ្ញើ និងសារត្រូវបានអ៊ិនគ្រីប ដូច្នេះ Google អានមិនបានទេ។
  • ទូរស័ព្ទដែលកំពុងមើលកម្មវិធី មិនត្រូវបានផ្ញើ push ទេ — ព្រោះវាកំពុងទទួលតាមការតភ្ជាប់រួចហើយ។ push នៃការសន្ទនាដែលបានបិទការជូនដំណឹង ត្រូវបានផ្ញើដោយអាទិភាពមិនបន្ទាន់ ហើយកម្មវិធីច្រោះវាចោលដោយខ្លួនឯង។
គម្រោង Firebase ជាគូជាមួយកម្មវិធី

ដោយសោរបស់ម៉ាស៊ីនមេ អាចផ្ញើ push បានតែទៅកម្មវិធីដែល build ដោយគម្រោង Firebase តែមួយប៉ុណ្ណោះ។ កម្មវិធីដែលអ្នកដទៃ build (ឧ. កម្មវិធីដែលទាញយកពី Pabal.me) ត្រូវបានចងភ្ជាប់ទៅគម្រោង Firebase របស់អ្នកនោះ ហើយតាំងពីដំបូងមក ត្រូវបាន build ជាមួយអាសយដ្ឋាន និងសោសាធារណៈនៃម៉ាស៊ីនមេរបស់អ្នកនោះ។ កម្មវិធីសម្រាប់ម៉ាស៊ីនមេរបស់អ្នក គឺអ្នក build ដោយខ្លួនឯង ហើយគម្រោង Firebase ក៏អ្នកបង្កើតដោយខ្លួនឯងដែរ។

ការបង្កើតគម្រោង Firebase

  1. នៅក្នុង Firebase console ចុច Add project។ ដាក់ឈ្មោះអ្វីក៏បាន ហើយមិនត្រូវការ Google Analytics ទេ។
  2. Project settings → General → Your apps → Add app (Android)។ បញ្ចូល me.pabal.android (ឈ្មោះដែល script build ដាក់ឲ្យកម្មវិធី) ក្នុងឈ្មោះកញ្ចប់ (package name)។ ស្នាមម្រាមដៃវិញ្ញាបនបត្រ (SHA-1) មិនចាំបាច់សម្រាប់ push ទេ។
  3. ទាញយក google-services.json របស់កម្មវិធីនោះ។ វាជាការកំណត់ដែលដាក់ក្នុងកម្មវិធី ហើយមិនមែនជាការសម្ងាត់ទេ។
  4. តាម Project settings → Service accounts → Generate new private key ទាញយកឯកសារ JSON ហើយប្តូរឈ្មោះទៅជា firebase-service-account.json។ ឯកសារនេះជាការសម្ងាត់ — កុំដាក់ខ្លឹមសាររបស់វាក្នុងឃ្លាំងកូដ ការជជែក ឬ .env។
  5. នៅក្នុង Project settings → Cloud Messaging សូមពិនិត្យថា Firebase Cloud Messaging API (V1) ត្រូវបានបើក (គម្រោងថ្មីជាធម្មតាបើករួចហើយ)។

ដាក់ការកំណត់ចូលក្នុងកម្មវិធី

មុនពេល build កម្មវិធី Android សូមដាក់ google-services.json នៅកន្លែងដែល script build ស្វែងរក។ script ពិនិត្យឯកសារ (ថាជាគម្រោងដែលបានចុះឈ្មោះ me.pabal.android ឬទេ និងថាមិនបានផ្តល់សោសម្ងាត់ដោយច្រឡំ) រួចដាក់វាចូលក្នុងកូដប្រភពកម្មវិធី។

mkdir -p ~/.pabal/android
cp ~/Downloads/google-services.json ~/.pabal/android/     # បើចង់ទុកកន្លែងផ្សេង៖ --google-services <ផ្លូវ> ក្នុង apply_branding.py
python3 scripts/android/point_to_server.py <កូដប្រភព Android> \
    --host 203.0.113.10 --port 8443 --key keys/production.pem.pub
python3 scripts/android/apply_branding.py <កូដប្រភព Android>
# នៅចុងក្រោយ ត្រូវតែឃើញ "Firebase: project <ID គម្រោង>"។ បើឃើញ pabal-placeholder កម្មវិធីនឹងគ្មាន push

បន្ទាប់មក build តាមផ្នែក Android (Android 앱) នៃ docs/mobile-apps-guide.md ក្នុងឃ្លាំងកូដ។ ទូរស័ព្ទដែលកំពុងប្រើកម្មវិធីចាស់ មុនពេលមាន push ក៏ត្រូវធ្វើបច្ចុប្បន្នភាពទៅកម្មវិធីដែលទើប build ដែរ ទើបទទួលបានការជូនដំណឹង។

ដាក់សោសម្ងាត់នៅលើម៉ាស៊ីនមេ

sudo cp firebase-service-account.json /srv/pabal/pabal_server/keys/
sudo chown 1000:1000 /srv/pabal/pabal_server/keys/firebase-service-account.json    # អ្នកប្រើរបស់ container ម៉ាស៊ីនមេ
sudo chmod 600 /srv/pabal/pabal_server/keys/firebase-service-account.json

បន្ថែមមួយបន្ទាត់ទៅក្នុង .env។ នៅក្នុង container pabal_server/keys គឺ /app/keys។

FCM_CREDENTIALS=/app/keys/firebase-service-account.json
docker compose up -d pabal-server
docker compose logs pabal-server | grep -i push
INFO  TelegramServer - Push notifications on: Firebase project <ID គម្រោង>, 0 device registrations, message text included (encrypted per device)
  • បើឃើញបន្ទាត់នេះ មានន័យថាបានបើកហើយ។ បើអានឯកសារមិនបាន ឬទម្រង់ខុស មូលហេតុនឹងបង្ហាញនៅ Push notifications are off: … (ខ្លឹមសារឯកសារមិនបង្ហាញក្នុង log ទេ)។
  • បើ PUSH_PREVIEWS=false ចុងបន្ទាត់នឹងក្លាយជា message text left out ហើយការជូនដំណឹងបង្ហាញតែអ្នកផ្ញើ ដោយគ្មានខ្លឹមសារសារ។
  • container ត្រូវតែអាចបើកការតភ្ជាប់ចេញទៅ oauth2.googleapis.com និង fcm.googleapis.com (443) បាន។

ការពិនិត្យ

  1. ដំឡើង (ឬធ្វើបច្ចុប្បន្នភាព) កម្មវិធីដែលទើប build លើទូរស័ព្ទ ហើយបើកវាម្តង។ log របស់ម៉ាស៊ីនមេនឹងបង្ហាញ Push device registered: user … type 2 token … (push key 256 bytes)។ តូខឹនត្រូវបានកត់ទុកត្រឹមជា fingerprint ប៉ុណ្ណោះ។
  2. អូសបិទកម្មវិធីពីបញ្ជីកម្មវិធីថ្មីៗ។ កុំប្រើ «បង្ខំឲ្យបញ្ឈប់» (Force stop) ក្នុងការកំណត់ — Android នឹងមិនបញ្ជូន push ទេ រហូតដល់អ្នកបើកកម្មវិធីដោយផ្ទាល់ម្តងទៀត។
  3. ផ្ញើសារពីគណនីផ្សេង នោះ log នឹងបង្ហាញ Push MESSAGE_TEXT to user …: sent ហើយការជូនដំណឹងលេចឡើងលើទូរស័ព្ទ។
  • គោលការណ៍ឯកជនភាព៖ នៅក្នុងទំព័រគ្រប់គ្រង → ការកំណត់ (설정) → ព័ត៌មានប្រតិបត្តិករ (운영자 정보) សូមសរសេរ Google LLC (Firebase Cloud Messaging, សហរដ្ឋអាមេរិក) ក្នុងការប្រគល់ការដំណើរការទិន្នន័យ (처리 위탁) និងការផ្ទេរទៅបរទេស (국외 이전)។ អត្ថបទគោលការណ៍មានប្រយោគថាការជូនដំណឹងឆ្លងកាត់ FCM រួចហើយ។ សូមសរសេរខ្លឹមសារដូចគ្នាក្នុងទម្រង់ «Data safety» របស់ Google Play ផងដែរ។
  • បើសោលេចធ្លាយ សូមលុបសោនោះក្នុង Firebase console ទាញយកសោថ្មី ប្តូរឯកសារ ហើយបើកម៉ាស៊ីនមេឡើងវិញ។ មិនចាំបាច់ build កម្មវិធីឡើងវិញទេ។
iPhone និងកុំព្យូទ័រ

iPhone ត្រូវបើកដាច់ដោយឡែក មិនមែនដោយ Firebase ទេ គឺដោយសោ APNs (.p8) ពីគណនីអ្នកអភិវឌ្ឍន៍ Apple — មើលជំហានទី 11 ខាងក្រោមនេះ។ កម្មវិធី Mac និង Windows មិនប្រើ push ទេ ហើយទទួលសារពេលកំពុងបើក។

11. ការជូនដំណឹង push របស់ iPhone (ជាជម្រើស)

iPhone ក៏ឆាប់បញ្ឈប់កម្មវិធីដែលចេញពីអេក្រង់ដែរ។ បើមិនបើក push ទេ សារ និងការហៅនឹងមកដល់តែពេលកម្មវិធីកំពុងបើកប៉ុណ្ណោះ។ push ត្រូវបានផ្ញើតាមសេវាការជូនដំណឹង push របស់ Apple (APNs) ហើយដូចគ្នានឹង Android ដែរ ខ្លឹមសារការជូនដំណឹងត្រូវបានអ៊ិនគ្រីបដោយសោដែលមានតែ iPhone នោះ។ អត្ថបទការជូនដំណឹងដែល Apple អាចមើលឃើញ មានត្រឹមឈ្មោះកម្មវិធី និងឃ្លាគ្មានខ្លឹមសារ ដូចជា «អ្នកមានការជូនដំណឹងថ្មី» ប៉ុណ្ណោះ ហើយផ្នែកបន្ថែមការជូនដំណឹង (Notification Service Extension) ក្នុងកម្មវិធី iPhone ដោះគ្រីបអត្ថបទដែលបានអ៊ិនគ្រីប ហើយបង្ហាញជាអ្នកផ្ញើ និងសារ។

  • ការចុះឈ្មោះ៖ រាល់ពេលបើក កម្មវិធីចុះឈ្មោះពីរយ៉ាងសម្រាប់គណនីនីមួយៗ — សម្រាប់ការជូនដំណឹង (type 1) និងសម្រាប់ការហៅ (VoIP, type 9)។ រួមជាមួយការចុះឈ្មោះ ម៉ាស៊ីនមេចងចាំភាសារបស់កម្មវិធី (ភាសាសម្រាប់អត្ថបទខាងក្រៅ) និងលេខ build។
  • សារត្រូវបានផ្ញើជាការជូនដំណឹង។ ការសន្ទនាដែលបានបិទការជូនដំណឹង នឹងមិនត្រូវបានផ្ញើអ្វីទេ។ អ្វីដែលបានអាន ឬលុបនៅលើឧបករណ៍ផ្សេង ត្រូវបានជូនដំណឹងតាម push ផ្ទៃខាងក្រោយដែលគ្មានសំឡេង ដើម្បីឲ្យកម្មវិធីសម្អាតការជូនដំណឹងដែលកំពុងបង្ហាញ។
  • ការហៅ បើផ្ញើតាម VoIP នឹងបង្ហាញអេក្រង់ការហៅរបស់ CallKit សូម្បីតែពេលអេក្រង់ចាក់សោ។ ប៉ុន្តែកម្មវិធីដែលទទួល VoIP ត្រូវតែប្រាប់ CallKit អំពីការហៅភ្លាមៗ បើធ្វើមិនបាន iOS នឹងបិទកម្មវិធី ហើយបើកើតឡើងដដែលៗ iOS នឹងឈប់ផ្ញើ VoIP ទៀត។ ដូច្នេះត្រូវបើក VoIP ដោយ APNS_VOIP_MIN_BUILD តែចាប់ពី build ដែលបានធ្វើបែបនោះប៉ុណ្ណោះ ហើយមុននោះ ការហៅក៏ត្រូវបានផ្ញើជាការជូនដំណឹងដែរ។
សោ APNs ជារបស់ក្រុមដែលបានចុះហត្ថលេខាលើកម្មវិធី

ខុសពី Firebase មិនមានឯកសារការកំណត់ណាដែលត្រូវដាក់ក្នុងកម្មវិធីទេ — កម្មវិធីត្រូវបាន build រួចហើយឲ្យអាចប្រើ APNs (សិទ្ធិជូនដំណឹង App Group ផ្នែកបន្ថែមការជូនដំណឹង) គ្រាន់តែដាក់សោនៅលើម៉ាស៊ីនមេប៉ុណ្ណោះ។ ប៉ុន្តែដោយសោរបស់ម៉ាស៊ីនមេ អាចផ្ញើ push បានតែទៅកម្មវិធីដែលចុះហត្ថលេខាដោយក្រុមដែលបានបង្កើតសោនោះ ហើយមាន bundle ID ដូចគ្នានឹង APNS_TOPIC ប៉ុណ្ណោះ។ បើអ្នកបានចុះហត្ថលេខាលើកម្មវិធី iPhone សម្រាប់ម៉ាស៊ីនមេរបស់អ្នក ដោយគណនីអ្នកអភិវឌ្ឍន៍ Apple របស់អ្នក សូមបង្កើតសោ APNs នៅក្នុងគណនីនោះដែរ។

ការបង្កើតសោ APNs

  1. Apple Developer → Certificates, IDs & Profiles → Keys → +។ ត្រូវតែជាគណនីរបស់ក្រុមដែលបានចុះហត្ថលេខាលើកម្មវិធី។
  2. សរសេរឈ្មោះ ហើយធីក Apple Push Notifications service (APNs)។ ទុកបរិស្ថានជា Sandbox & Production និងវិសាលភាពជាក្រុមទាំងមូល (Team Scoped) — ព្រោះត្រូវផ្ញើទៅកន្លែងពីរ គឺការជូនដំណឹង និង VoIP។
  3. Register → Download។ AuthKey_<ID សោ>.p8 អាចទាញយកបានតែម្តងប៉ុណ្ណោះ។ ឯកសារនេះជាការសម្ងាត់ — កុំដាក់ខ្លឹមសាររបស់វាក្នុងឃ្លាំងកូដ ការជជែក ឬ .env។

ដាក់សោនៅលើម៉ាស៊ីនមេ

sudo cp AuthKey_<ID សោ>.p8 /srv/pabal/pabal_server/keys/
sudo chown 1000:1000 /srv/pabal/pabal_server/keys/AuthKey_<ID សោ>.p8    # អ្នកប្រើរបស់ container ម៉ាស៊ីនមេ
sudo chmod 600 /srv/pabal/pabal_server/keys/AuthKey_<ID សោ>.p8

ដាក់ក្នុង .env។ នៅក្នុង container pabal_server/keys គឺ /app/keys។

APNS_KEY=/app/keys/AuthKey_<ID សោ>.p8
APNS_TEAM_ID=4Z8R468M2D
APNS_TOPIC=me.pabal.ios
APNS_MIN_BUILD=4
APNS_VOIP_MIN_BUILD=
តម្លៃអ្វីដែលត្រូវដាក់កំណត់ចំណាំ
APNS_KEYផ្លូវឯកសារសោID សោត្រូវបានអានពីឈ្មោះឯកសារ។ បើអ្នកដាក់ដោយឈ្មោះផ្សេង សូមដាក់ ID សោក្នុង APNS_KEY_ID
APNS_TEAM_IDID ក្រុមដែលបានចុះហត្ថលេខាលើកម្មវិធីសម្រាប់កម្មវិធីរបស់ Pabal គឺ 4Z8R468M2D។ បើជាកម្មវិធីដែលអ្នក build និងចុះហត្ថលេខាដោយខ្លួនឯង គឺក្រុមរបស់អ្នក
APNS_TOPICbundle ID របស់កម្មវិធីសម្រាប់កម្មវិធីរបស់ Pabal គឺ me.pabal.ios។ ការហៅ (VoIP) ត្រូវបានផ្ញើទៅតម្លៃនេះដែលបន្ថែម .voip ពីក្រោយ
APNS_MIN_BUILD4មិនផ្ញើអ្វីទៅ build ដែលទាបជាងនេះទេ (បើ 0 ផ្ញើទៅទាំងអស់)។ 4 ជាតម្លៃដែលដក Pabal 1.0 (3) ដែលបានធ្វើមុនការសាកល្បង push ចេញ
APNS_VOIP_MIN_BUILDទុកទទេបើទុកទទេ ការហៅក៏ត្រូវបានផ្ញើជាការជូនដំណឹងដែរ។ បើដាក់លេខ build ដំបូងដែលប្រាប់ CallKit អំពីការហៅភ្លាមៗ អេក្រង់ការហៅរបស់ CallKit នឹងបង្ហាញចាប់ពី build នោះ
docker compose up -d pabal-server
docker compose logs pabal-server | grep -i push
INFO  TelegramServer - iPhone push notifications on: APNs key <ID សោ> of team 4Z8R468M2D, topic me.pabal.ios, builds from 4, calls as alerts (TELEGRAM_APNS_VOIP_MIN_BUILD not set)
  • បើឃើញបន្ទាត់នេះ មានន័យថាបានបើកហើយ។ បើអានឯកសារសោមិនបាន ឬទម្រង់ខុស មូលហេតុនឹងបង្ហាញនៅ iPhone push notifications are off: … (ខ្លឹមសារឯកសារមិនបង្ហាញក្នុង log ទេ)។ វាបើក និងបិទដាច់ដោយឡែកពី Android (FCM) — បើកតែម្ខាងក៏បាន។
  • container ត្រូវតែអាចបើកការតភ្ជាប់ចេញទៅ api.push.apple.com (443, HTTP/2) បាន។ build បំបាត់កំហុស (debug) ដែលដំឡើងលើឧបករណ៍ដោយផ្ទាល់ដោយ Xcode នឹងទៅ api.sandbox.push.apple.com (កម្មវិធីប្រាប់ពេលចុះឈ្មោះ)។

ការពិនិត្យ

  1. នៅលើ iPhone ពិតប្រាកដ បើកកម្មវិធីម្តង ហើយអនុញ្ញាតការជូនដំណឹង។ log របស់ម៉ាស៊ីនមេនឹងបង្ហាញ Push device registered: user … type 1 token … (push key 256 bytes, build …) និងបន្ទាត់ type 9។ មិនអាចពិនិត្យដោយ simulator បានទេ — គ្មានទាំងតូខឹន APNs និង CallKit។
  2. អូសកម្មវិធីឡើងលើដើម្បីបិទ។
  3. ផ្ញើសារពីគណនីផ្សេង នោះ log នឹងបង្ហាញ Push MESSAGE_TEXT to user …: sent ហើយអ្នកផ្ញើ និងខ្លឹមសារលេចឡើងលើអេក្រង់ចាក់សោ។
  • គោលការណ៍ឯកជនភាព៖ នៅក្នុងទំព័រគ្រប់គ្រង → ការកំណត់ (설정) → ព័ត៌មានប្រតិបត្តិករ (운영자 정보) សូមសរសេរ Apple Inc. (សេវាការជូនដំណឹង push របស់ Apple, សហរដ្ឋអាមេរិក) ក្នុងការប្រគល់ការដំណើរការទិន្នន័យ (처리 위탁) និងការផ្ទេរទៅបរទេស (국외 이전)។ អត្ថបទគោលការណ៍មានប្រយោគថាការជូនដំណឹងឆ្លងកាត់ APNs រួចហើយ។ សូមពិនិត្យធាតុ ID ឧបករណ៍ (តូខឹន push) ក្នុងកម្រងសំណួរឯកជនភាពកម្មវិធីរបស់ App Store Connect ផងដែរ។
  • បើសោលេចធ្លាយ សូម Revoke សោនោះក្នុងគណនីអ្នកអភិវឌ្ឍន៍ បង្កើតសោថ្មី ប្តូរឯកសារ ហើយបើកម៉ាស៊ីនមេឡើងវិញ។ មិនចាំបាច់ build កម្មវិធីឡើងវិញទេ។

12. បូតសំឡេង (ជាជម្រើស)

បូតសំឡេង គឺជាមុខងារដែលពេលមនុស្សហៅទៅបូតពីកម្មវិធី ម៉ូដែលសំឡេង AI ជាអ្នកឆ្លើយ (ការពន្យល់សម្រាប់ម្ចាស់បូតនៅ បូតសំឡេង)។ ម៉ាស៊ីនមេត្រូវភ្ជាប់សមាសភាគពីរបន្ថែម ហើយត្រូវមានឯកសារច្បាប់ និង build កម្មវិធីគ្រប់គ្រាន់ ទើបវាបើកបាន។ លំនាំដើមគឺបិទ។

សំឡេងត្រូវបានបើកដោយឯកសារ compose បន្ថែម

សមាសភាគសំឡេងមិននៅក្នុង deploy/docker-compose.yml ទេ គឺនៅក្នុងឯកសារបន្ថែម deploy/docker-compose.voice.yml — ការកំណត់សំឡេងរបស់ម៉ាស៊ីនមេ និងបណ្តាញសម្រាប់តែតំណ · gateway pabal-voice (profile voice) · ច្រកចូលសំឡេងរបស់នាឡិកា pabal-voice-edge (profile voice-watch)។ បើ .env មិនហៅឯកសារនេះទេ គឺគ្មានការកំណត់សំឡេងសោះ។ ការរៀបចំនេះបានសាកដំណើរការជាមួយ engine echo ប៉ុន្តែមិនទាន់ធ្លាប់បើកសំឡេងលើម៉ាស៊ីនមេផលិតកម្មនៅឡើយ ហើយក៏មិនទាន់ធ្លាប់មានការហៅបូតសំឡេងណាមួយឆ្លងកាត់ការបញ្ជូនបន្ត (TURN) ផលិតកម្មពីដើមដល់ចប់ដែរ — ការសាកល្បងពេញខ្សែត្រូវបានធ្វើជាមួយការបញ្ជូនបន្តសាកល្បងនៅក្នុងបណ្តាញ Docker (scripts/voice-e2e/run.sh)។ មុនពេលបើក deploy/voice_readiness.py ក្នុងឃ្លាំងកូដពិនិត្យរកអ្វីដែលនៅខ្វះ។ លក្ខខណ្ឌមុនពេលបើកជាសាធារណៈ (ការពិនិត្យផ្នែកច្បាប់ ចម្លើយជាលាយលក្ខណ៍អក្សររបស់អ្នកផ្តល់សេវា និងការចេញផ្សាយកម្មវិធី) ជាការសម្រេចរបស់ប្រតិបត្តិករ ហើយកូដរារាំងបានតែមួយផ្នែកប៉ុណ្ណោះ។

សមាសភាគអ្វីដែលវាធ្វើបើគ្មាន
pabal-voice (gateway, image 0.11.0)ធ្វើជាចុងម្ខាងនៃការហៅជំនួសបូត ធ្វើការផ្លាស់ប្តូរសោ ហើយបញ្ជូនសំឡេងទៅមកជាមួយម៉ូដែល AI។ Python 3.12 + ntgcalls។ វានិយាយជាមួយម៉ាស៊ីនមេតាមតំណ (WebSocket មានការផ្ទៀងផ្ទាត់ ប៉ុន្តែមិនអ៊ិនគ្រីប)ការហៅបូតទាំងអស់រវល់ (no_gateway)
coturn (ការបញ្ជូនបន្តការហៅ)ការហៅបូតប្រើតែការបញ្ជូនបន្តប៉ុណ្ណោះ៖ ទាំងកម្មវិធី និង gateway បិទការតភ្ជាប់ផ្ទាល់ ហើយផ្ញើសំឡេងតែតាមការបញ្ជូនបន្ត។ ជាការបញ្ជូនបន្តដដែលនឹងការហៅរវាងមនុស្ស (TURN_SECRET)ការហៅបូតទាំងអស់រវល់ (no_relay) ហើយ gateway ក៏បដិសេធការតភ្ជាប់ដែរ (4008)
សោ Vertex AIសោ JSON របស់គណនីសេវា Google Cloud។ មានតែដំណើរការ engine របស់ gateway ប៉ុណ្ណោះដែលបើកវាគ្មានម៉ូដែល មានតែ echo (VOICE_ENGINE=echo · សំឡេងមិនចេញពីម៉ាស៊ីនទេ)
(ជាជម្រើស) សោមេសោដែលរុំសោផ្ទាល់ខ្លួនរបស់ម្ចាស់បូត និងសម្ងាត់នៃរបៀបសំឡេងដើមសោផ្ទាល់ខ្លួន និងរបៀបសំឡេងដើមបិទ
(ជាជម្រើស) សមាសភាគ MCPpabal-mcp · កម្មវិធីចុះហត្ថលេខា · proxy ចេញក្រៅ (ខាងក្រោម)ម៉ាស៊ីនមេ MCP បិទ

លក្ខខណ្ឌដើម្បីបើក

អ្វីដែលម៉ាស៊ីនមេពិនិត្យបើគ្មាន
ឯកសារសម្ងាត់តំណ (TELEGRAM_VOICE_LINK_SECRET_FILE, 32 បៃ)សំឡេងបិទ — ច្រកតំណក៏មិនបើកដែរ
ការបញ្ជូនបន្តការហៅ (TELEGRAM_TURN_HOST·TELEGRAM_TURN_SECRET)ការហៅបូតទាំងអស់រវល់
ផ្នែក id="bot-calls" នៃគោលការណ៍ឯកជនភាពរបស់គេហទំព័រ (ទាំង ko និង en) — ផ្ទាំងបញ្ជាក់របស់កម្មវិធីចង្អុលមកទីនេះគ្មានបូតណាទទួលការហៅទេ (log ERROR)។ សេចក្តីព្រាងនៅ docs/voice-bots/p0/privacy-*.draft.html
ផ្នែក id="voice-bot-owners" នៃលក្ខខណ្ឌនៃសេវាកម្មគ្មាននរណាអាចយល់ព្រមលក្ខខណ្ឌម្ចាស់បូតបានទេ → កំណត់ត្រាសន្ទនា សោផ្ទាល់ខ្លួន របៀបសំឡេងដើម និង MCP ប្រើមិនបានទាំងអស់
ផ្នែក id="bot-calls-stream" · id="bot-calls-mcp" នៃគោលការណ៍របៀបសំឡេងដើម · MCP បិទ
ការអនុញ្ញាតបូតនៅក្នុងទំព័រគ្រប់គ្រង (លំនាំដើម តែបូតដែលបានអនុញ្ញាត) និងការបើកជាសាធារណៈ (លំនាំដើម តែអ្នកសាកល្បង ហើយដើម្បីបើកត្រូវវាយឃ្លាបញ្ជាក់)បូតដែលមិនបានអនុញ្ញាតមិនទទួលការហៅទេ ហើយមុនបើកជាសាធារណៈ មានតែអ្នកសាកល្បងទេដែលអាចហៅបាន
build កម្មវិធីរបស់អ្នកហៅ៖ កុំព្យូទ័រ pabal-bc2 (ខណៈដែលផ្ទាំងបញ្ជាក់មានតែភាសាកូរ៉េ និងអង់គ្លេស pabal-bc1 ក៏បាន) · Android 62151 · iPhone 5 ឡើងទៅ · Apple Watch 1 ឡើងទៅ (TELEGRAM_VOICE_MIN_BUILD_*)មនុស្សនោះមិនឃើញប៊ូតុងហៅទេ ហើយទោះហៅក៏រវល់ដែរ
(ជាជម្រើស) Apple Watch៖ API នាឡិការបស់ម៉ាស៊ីនមេ (TELEGRAM_WATCH_API_PORT) និងអាសយដ្ឋានសំឡេង (TELEGRAM_WATCH_AUDIO_URL) ច្រកចូលសំឡេង pabal-voice-edge និង gateway ដែលប្រកាស direct (ខាងក្រោម)មិនអាចហៅពីនាឡិកាបានទេ (កម្មវិធីទូរស័ព្ទ និងកុំព្យូទ័រនៅដដែល)
(ជាជម្រើស) រក្សាទុកការសន្ទនា៖ ផ្នែក id="bot-calls-keep-text" ក្នុងគោលការណ៍ និង gateway ដែលប្រកាស keep_text (VOICE_KEEP_TEXT, ខាងក្រោម)ទោះធីកប្រអប់ក៏ដោយ ការសន្ទនាក៏មិនត្រូវបានរក្សាទុកដែរ
(ជាជម្រើស) ការហៅពីបូត៖ ផ្នែក id="bot-calls-outbound" ក្នុងគោលការណ៍ និងផ្នែក id="voice-bot-owners-outbound" ក្នុងលក្ខខណ្ឌ ថតសោភស្តុតាង កំណែអប្បបរមាសម្រាប់ការហៅចេញ gateway ដែលប្រកាស outbound និងកុងតាក់រួមនៅលើទំព័រគ្រប់គ្រង (ខាងក្រោម)គ្មានបូតណាអាចហៅទៅនរណាម្នាក់បានទេ

មានតែនៅលើម៉ាស៊ីនមេសាកល្បង (TELEGRAM_TEST_NUMBERS=true) ប៉ុណ្ណោះ ដែលអាចរំលងការពិនិត្យផ្នែកច្បាប់ដោយ TELEGRAM_VOICE_NOTICE_CHECK=off ហើយឲ្យនរណាក៏បានសាកល្បងដោយ TELEGRAM_VOICE_BOTS (បូតទាំងអស់ *) · TELEGRAM_VOICE_TESTERS=*។ កុំប្រើវានៅក្នុងផលិតកម្ម — ម៉ាស៊ីនមេផលិតកម្មមិនអើពើ TELEGRAM_VOICE_BOTS ព្រមទាំងចេញការព្រមាន។

ការបញ្ជូនបន្តការហៅ (coturn)

  • បើជាម៉ាស៊ីនមេ Linux សូមប្រើ pabal-turn ក្នុង compose (COMPOSE_PROFILES=turn)។ កំណត់ TURN_SECRET ក្នុង .env (openssl rand -hex 32) ហើយបើកនៅលើរ៉ោតទ័រ និងជញ្ជាំងភ្លើងនូវ TURN_PORT (3478, udp·tcp) និង TURN_MIN_PORT ដល់ TURN_MAX_PORT (49160 ដល់ 49200, udp)។ បើពង្រីកចន្លោះច្រក សូមកែទាំងរ៉ោតទ័រ និង .env ជាមួយគ្នា។
  • នៅលើ Docker Desktop របស់ macOS កុំដំណើរការ coturn ជា container។ អ្នកហៅទាំងអស់បង្ហាញជា 192.168.65.1 ដូច្នេះការអនុញ្ញាតបញ្ជូនបន្តមិនត្រូវគ្នា ហើយទោះមើលទៅដូចជាដំណើរការធម្មតា ក៏សំឡេងទាំងអស់ត្រូវបោះចោល។ នៅលើម៉ាស៊ីនមេ Mac សូមដំឡើង coturn ដោយផ្ទាល់ (deploy/turnserver.conf.example, docs/turn-relay-guide.md)។
  • អាសយដ្ឋានបញ្ជូនបន្តដែលផ្តល់ឲ្យ gateway គឺអាសយដ្ឋាន LAN របស់ម៉ាស៊ីនមេ៖ ដាក់តម្លៃដូចគ្នាក្នុង TELEGRAM_VOICE_TURN_HOST របស់ម៉ាស៊ីនមេ និង VOICE_TURN_HOST របស់ gateway។ ជាមួយ host.docker.internal វាមិនទៅដល់ទេ ហើយជាមួយ 127.0.0.1 ការបែងចែក (allocation) មិនបញ្ចប់ទេ។ កម្មវិធីនៅតែទទួលអាសយដ្ឋានសាធារណៈ (TURN_HOST) ដដែល។
  • ពីបណ្តាញខាងក្រៅ សូមប្រើ deploy/check_relay.py --data ដើម្បីពិនិត្យថាសំឡេងពិតជាឆ្លងកាត់ឬអត់។ មានករណីដែល STUN ឆ្លើយ និងការបែងចែក (allocation) ជោគជ័យ ប៉ុន្តែសំឡេងនៅតែមិនទៅ។

សោ Vertex AI

  1. នៅក្នុងគម្រោង Google Cloud សូមបើក Agent Platform API (ឈ្មោះចាស់ Vertex AI API, aiplatform.googleapis.com)។ គម្រោងត្រូវតែភ្ជាប់ជាមួយគណនីចេញវិក្កយបត្រ។ មិនប្រើ Gemini Developer API (សោ AI Studio) ទេ។
  2. បង្កើតគណនីសេវាមួយ ហើយផ្តល់តួនាទីតែមួយគត់ roles/aiplatform.user (បើចង់តូចជាងនេះ ប្រើតួនាទីផ្ទាល់ខ្លួនដែលមានតែសិទ្ធិ aiplatform.endpoints.predict)។ បង្កើតសោសម្រាប់ផលិតកម្មដាច់ដោយឡែកពីសោសម្រាប់ការអភិវឌ្ឍ។
  3. ទាញយកសោ JSON ហើយដាក់វានៅក្រៅឃ្លាំងកូដ និងក្រៅ .env ឧទាហរណ៍ /srv/pabal/pabal_voice/secrets/vertex-sa.json ដោយឲ្យតែអ្នកប្រើរបស់ gateway អានបាន (Linux៖ chown 10001:10001, chmod 400)។ បើនរណាក៏អានបាន gateway នឹងបដិសេធមិនចាប់ផ្តើមទេ។
  4. ម៉ូដែលពេលវេលាពិត មានតែនៅ us-central1 (Iowa សហរដ្ឋអាមេរិក) ប៉ុណ្ណោះ (បញ្ជាក់នៅ 2026-09-26)។ គោលការណ៍ឯកជនភាព និងផ្ទាំងបញ្ជាក់ត្រូវនិយាយថាសំឡេងនៃការហៅទៅសហរដ្ឋអាមេរិក ហើយតំបន់ដែលសរសេរលើផ្ទាំងបញ្ជាក់របស់កម្មវិធីត្រូវតែដូចគ្នានឹងតំបន់របស់ gateway (VOICE_VERTEX_REGION) ទើបម៉ាស៊ីនមេប្រគល់ការហៅទៅ gateway នោះ។
  5. កិច្ចការត្រូវធ្វើ៖ ការជូនដំណឹងថវិកា កូតាវគ្គក្នុងពេលតែមួយ (ពីរដងនៃសមត្ថភាព gateway) និងឃ្លាំងសម្ងាត់ទិន្នន័យរបស់ Vertex (បើបើក វារក្សាទិន្នន័យចូល និងចេញក្នុងអង្គចងចាំរហូតដល់ 24 ម៉ោង) — ផ្ទាំងបញ្ជាក់និយាយថា «Google មិនរក្សាទុកសំឡេង និងអត្ថបទក្រោយពេលបង្កើតចម្លើយទេ» ដូច្នេះមុនពេលបិទឃ្លាំងសម្ងាត់ ពាក្យនោះមិនទាន់ត្រឹមត្រូវទេ។ ការណែនាំ៖ បិទឃ្លាំងសម្ងាត់ទិន្នន័យមុនពេលបើកជាសាធារណៈ (ផ្នែកទី 9 នៃ docs/voice-bots/vertex-setup.md ក្នុងឃ្លាំងកូដ) ហើយបង្រួមតួនាទីរបស់សោឲ្យនៅសល់តែសិទ្ធិព្យាករណ៍មួយ (ផ្នែកទី 10 នៃឯកសារដដែល)។

ម៉ាស៊ីនមេ និង gateway អានសម្ងាត់តំណដូចគ្នាពីឯកសារ។ ដោយសារតំណមិនត្រូវបានអ៊ិនគ្រីប សូមដាក់វាតែនៅក្នុងបណ្តាញផ្តាច់មុខដែលមានតែ container ទាំងពីរនេះភ្ជាប់ — កុំដាក់វានៅលើ ssemiya-net ដែលប្រើរួមជាមួយ stack ផ្សេង ឬនៅលើ LAN។ កុំបើកចំហច្រកនោះទៅខាងក្រៅ។

(umask 077; openssl rand -hex 32 > /tmp/voice-link.secret)
sudo install -m 400 -o 1000 /tmp/voice-link.secret /srv/pabal/pabal_server/keys/voice-link.secret   # របស់ម៉ាស៊ីនមេ (uid 1000)
sudo install -d -m 700 -o 10001 /srv/pabal/pabal_voice/secrets
sudo install -m 400 -o 10001 /tmp/voice-link.secret /srv/pabal/pabal_voice/secrets/voice-link.secret # របស់ gateway (uid 10001)
shred -u /tmp/voice-link.secret

តម្លៃទាំងនេះដាក់ក្នុង .env។ ជាមួយតម្លៃទាំងនេះ ឯកសារបន្ថែមបន្ថែមការកំណត់សំឡេង (TELEGRAM_VOICE_*) និងបណ្តាញតំណ ឲ្យ pabal-server។

COMPOSE_FILE=docker-compose.yml:docker-compose.voice.yml
COMPOSE_PROFILES=voice                              # ជាមួយ profile ផ្សេងទៀត (turn ។ល។) ដោយបំបែកដោយក្បៀស
VOICE_LINK_SECRET_FILE=/app/keys/voice-link.secret  # ផ្លូវក្នុង container · ទទេ៖ សំឡេងបិទ
VOICE_TURN_HOST=192.168.1.64                        # អាសយដ្ឋាន LAN របស់ម៉ាស៊ីនមេ (កន្លែងដែល coturn ស្តាប់)
VOICE_TESTERS=100001                                # id របស់អ្នកដែលអាចហៅមុនពេលបើកជាសាធារណៈ (ទំព័រគ្រប់គ្រងអាចបន្ថែមទៀត)
  • ឯកសារបន្ថែមភ្ជាប់ម៉ាស៊ីនមេទៅបណ្តាញខាងក្នុងសុទ្ធ pabal-voice-link (10.231.53.0/29 — ម៉ាស៊ីនមេ .2 · gateway .3) ហើយម៉ាស៊ីនមេស្តាប់តែលើអាសយដ្ឋានរបស់ខ្លួននៅលើបណ្តាញនោះប៉ុណ្ណោះ (បើ 0.0.0.0 វានឹងបើកនៅលើបណ្តាញរួមដែលវាភ្ជាប់ជាមួយផងដែរ)។ បើជួរនេះជាន់នឹង LAN · VPN ឬបណ្តាញ Docker ផ្សេង សូមប្តូរ VOICE_LINK_SUBNET · VOICE_LINK_SERVER_IP · VOICE_LINK_GATEWAY_IP ទាំងបីជាមួយគ្នា។
  • ដើម្បីភ្ជាប់ទៅអាសយដ្ឋានដែលមិនមែន loopback ត្រូវមាន TELEGRAM_VOICE_LINK_ANY_ADDRESS=true ហើយតំណមិនដែលភ្ជាប់ទៅអាសយដ្ឋានសាធារណៈទេ។ log របស់ម៉ាស៊ីនមេប្រាប់ថាតំណកំពុងមើលឃើញបណ្តាញណា។
  • ចំពោះការតភ្ជាប់ដែលមិនទាន់ផ្ទៀងផ្ទាត់ ម៉ាស៊ីនមេរង់ចាំ upgrade 3 វិនាទី · hello 3 វិនាទី ហើយទទួលតែ 2 ការតភ្ជាប់ពីអាសយដ្ឋានមួយ និងសរុប 16 ការតភ្ជាប់ប៉ុណ្ណោះ។
  • ការកំណត់ម៉ាស៊ីនមេទាំងអស់ពាក់ព័ន្ធនឹងសំឡេង មាននៅ ការគ្រប់គ្រង និងការកំណត់ — អថេរបរិស្ថានបូតសំឡេង។

Gateway (pabal-voice)

cd /opt/pabal
docker build -t pabal-voice:latest voice/                                       # សម្រាប់ CPU របស់កុំព្យូទ័រនេះ
docker buildx build --platform linux/amd64 -t pabal-voice:latest --load voice/  # សម្រាប់ម៉ាស៊ីនមេ Intel
cd deploy && docker compose up -d                                         # តាម COMPOSE_FILE និង COMPOSE_PROFILES ក្នុង .env

image ដំណើរការដោយ Python 3.12 ដែលត្រូវបានចាក់សោដោយ hash គ្មាន compiler ឬ pip ហើយដំណើរការជា uid 10001។ ntgcalls មានតែសម្រាប់ Linux x86_64/aarch64 និង macOS arm64 ដូច្នេះនៅលើ Mac Intel ដំណើរការបានតែតាម Docker ប៉ុណ្ណោះ។ សេវា pabal-voice ក្នុងឯកសារបន្ថែមប្រើ image នេះដោយមិនបង្កើតវាទេ (image: pabal-voice:latest)។ ដើម្បីបង្កើតវាសម្រាប់ CPU របស់ម៉ាស៊ីនមេនៅលើកុំព្យូទ័រផ្សេង ហើយផ្ញើទៅ សូមប្រើ deploy/ship.sh <user@host> <ថត> --voice (image ដែលត្រូវបានជំនួសនៅសល់ជា pabal-voice:previous)។ ខាងក្រោមជាសេវា gateway ក្នុងឯកសារនោះ ដែលបានសង្ខេប។

  pabal-voice:                             # ពី deploy/docker-compose.voice.yml (សង្ខេប)
    image: pabal-voice:latest
    profiles: [voice]
    init: true
    stop_grace_period: 40s                 # វែងជាង VOICE_DRAIN_SECONDS (20)
    security_opt: ["no-new-privileges:true"]
    cap_drop: [ALL]
    mem_limit: ${VOICE_MEMORY:-1g}
    ulimits:
      core: 0
    environment:
      VOICE_LINK_URL: ws://${VOICE_LINK_SERVER_IP:-10.231.53.2}:8095/voice/link
      VOICE_LINK_SECRET_FILE: /run/secrets/voice-link.secret
      VOICE_ENGINE: gemini
      VOICE_VERTEX_KEY_FILE: /run/secrets/vertex-sa.json
      VOICE_VERTEX_REGION: us-central1
      VOICE_TURN_HOST: ${VOICE_TURN_HOST:-}  # តម្លៃដូចគ្នានឹង TELEGRAM_VOICE_TURN_HOST របស់ម៉ាស៊ីនមេ
      VOICE_CAPACITY: ${VOICE_CAPACITY:-2}
      VOICE_DAILY_MODEL_MINUTES: ${VOICE_DAILY_MODEL_MINUTES:-60}
      VOICE_SAFETY_THRESHOLD: ${VOICE_SAFETY_THRESHOLD:-MEDIUM}   # ការហៅរបស់អ្នកសាកល្បង៖ ការសន្មតដែលប្រតិបត្តិករត្រូវបញ្ជាក់ (ខាងក្រោម)
      VOICE_BYOK: "false"
      VOICE_STREAM: "false"
    volumes:
      - ${PABAL_HOME:-/srv/pabal}/pabal_voice/secrets:/run/secrets:ro   # សម្ងាត់តំណ និងសោ Vertex — មិននៅក្នុង backup.sh ទេ
      - pabal_voice_state:/var/lib/pabal-voice
    networks:
      pabal-voice-link:                    # បណ្តាញតំណដែលប្រើតែជាមួយម៉ាស៊ីនមេ (internal)
        ipv4_address: ${VOICE_LINK_GATEWAY_IP:-10.231.53.3}
      pabal-voice-out: {}                  # បណ្តាញចេញក្រៅរបស់ខ្លួន (Google · ការបញ្ជូនបន្ត)
  • ក្រៅពីតំណ gateway ក៏ត្រូវការផ្លូវចេញក្រៅដែរ៖ ទៅ Google (us-central1-aiplatform.googleapis.com:443) និងទៅការបញ្ជូនបន្តការហៅ (UDP)។ ដោយសារបណ្តាញតំណជា internal: true វាមិនអាចចេញក្រៅបានទេ ដូច្នេះសូមភ្ជាប់បណ្តាញ pabal-voice-out មួយទៀតដូចខាងលើ។
  • Landlock៖ gateway ដែលប្រើម៉ូដែល ឬរបៀបសំឡេងដើម បដិសេធមិនចាប់ផ្តើម (កូដចាកចេញ 2) បើខឺណែល Linux គ្មាន Landlock (5.13 ឡើងទៅ ដំណើរការជាមួយ seccomp លំនាំដើមរបស់ Docker)។ មូលហេតុគឺដំណើរការមេឌៀ ដែលកូដ native ដោះស្រាយអ្វីដែលអ្នកហៅផ្ញើមក ចាក់សោខ្លួនឯងកុំឲ្យអានឯកសារសោបាន។ នៅក្នុង container កុំ mount ឯកសារសម្ងាត់ក្រោម /app·/opt·/usr·/lib·/etc (/run/secrets មិនអីទេ — ដូចឧទាហរណ៍ខាងលើ)។ VOICE_ALLOW_NO_LANDLOCK=true សម្រាប់តែ Mac អភិវឌ្ឍប៉ុណ្ណោះ។ មិនទាន់បានពិនិត្យថា Landlock ដំណើរការលើ Docker Desktop របស់ macOS ឬអត់ទេ។
  • អង្គចងចាំ៖ ការហៅមួយត្រូវការមេឌៀ 60 ដល់ 100 MB + engine 30 ដល់ 40 MB។ ជាមួយសមត្ថភាព 8 (VOICE_CAPACITY) និងគូបម្រុងមួយ គឺប្រហែល 1.3 GB។ លំនាំដើមរបស់ឯកសារបន្ថែមគឺសមត្ថភាព 2 និងអង្គចងចាំ 1 GB (VOICE_MEMORY)។
  • លំនាំដើមរបស់ gateway សម្រាប់តម្រងសុវត្ថិភាព VOICE_SAFETY_THRESHOLD គឺ LOW (តឹងរ៉ឹងបំផុត) ប៉ុន្តែក្នុងការវាស់ វាបានប្តូរពាក្យកូរ៉េធម្មតា 13 ក្នុងចំណោម 172 ទៅជាការបដិសេធជាភាសាអង់គ្លេស (MEDIUM គឺ 0 ក្នុងចំណោម 69)។ ឃ្លាំងកូដសន្មតថាការហៅរបស់អ្នកសាកល្បងកំណត់ MEDIUM ឲ្យច្បាស់ ហើយមុនប្តូរលំនាំដើម ត្រូវការការសាកល្បង red team។
  • ដែនកំណត់៖ លំនាំដើមរបស់ gateway គឺការហៅមួយ 600 វិនាទី · 400,000 token · 30 វេនក្នុងមួយនាទី និងប្រចាំថ្ងៃ (UTC) ម៉ូដែល 300 នាទី · 8 លាន token ហើយឯកសារបន្ថែមកំណត់ប្រចាំថ្ងៃត្រឹម 60 នាទី · 1.6 លាន token (VOICE_DAILY_MODEL_* · បើលើស ការហៅថ្មីនឹងរវល់)។ engine OpenAI បានសាកល្បងតែជាមួយម៉ាស៊ីនមេក្លែងក្លាយប៉ុណ្ណោះ និងកំពុងបិទ ហើយក៏គ្មានការប្តូរដោយស្វ័យប្រវត្តិរវាង engine ដែរ។
  • ភាសា៖ ពេល gateway ភ្ជាប់ទៅម៉ាស៊ីនមេ វាប្រកាសភាសាបូតដែលខ្លួនអាចធ្វើការហៅបាន (ចាប់ពី 0.7.0 ប្រកាសទាំង 9) ហើយម៉ាស៊ីនមេប្រគល់ការហៅរបស់បូតមួយ តែទៅ gateway ដែលធ្វើការហៅជាភាសារបស់បូតនោះប៉ុណ្ណោះ — gateway ចាស់ (0.6.0) ដែលមិនប្រកាសភាសា ទទួលបានតែបូតភាសាកូរ៉េ និងអង់គ្លេស។ ការថតសំឡេងជូនដំណឹងស្ថិតនៅក្នុង assets/ នៃ image ហើយ assets/assets.json កំណត់ថាការថតណាខ្លះបានពិនិត្យរួច។ បើគ្មានឯកសារនេះទេ gateway មិនអាចផ្ទុកសេចក្តីជូនដំណឹង AI បាន ដូច្នេះមិនអាចទទួលការហៅបានទេ (log ERROR ពេលចាប់ផ្តើម)។ ការថតដែលមិនទាន់ពិនិត្យរួច (បច្ចុប្បន្ន គឺគ្រប់ភាសាក្រៅពីកូរ៉េ និងអង់គ្លេស) មិនត្រូវចាក់ទេ ហើយអ្នកហៅនៃភាសានោះឮសេចក្តីជូនដំណឹងជាភាសាអង់គ្លេស។ VOICE_DRAFT_NOTICES=true ជាកុងតាក់សម្រាប់តែម៉ាស៊ីនមេសាកល្បង ដែលចាក់សូម្បីតែការថតដែលនៅជាសេចក្តីព្រាង ហើយបើគ្មាន VOICE_ALLOW_TEST_URLS=true ជាមួយផងទេ gateway មិនចាប់ផ្តើមទេ។ VOICE_NOTICE_LANG (ភាសានៃសេចក្តីជូនដំណឹង ពេលម៉ាស៊ីនមេមិនប្រាប់ភាសារបស់អ្នកហៅ · លំនាំដើម ko) ត្រូវតែជាភាសាមួយក្នុងចំណោមភាសាថតទាំង 10 (ko en ja zh fr es id vi km ar) ហើយ VOICE_LANGUAGE (ភាសាបូតនៃការហៅដែលគ្មានការកំណត់របស់ម្ចាស់បូត · លំនាំដើម ko-KR) ត្រូវតែជា id មួយក្នុងបញ្ជីភាសាបូត (បូតសំឡេង — សំឡេង និងភាសា)។
  • log មិនកត់ត្រាសម្ងាត់តំណ សោ សំឡេង អត្ថបទសន្ទនា ឬសេចក្តីណែនាំទេ។ ពេលទទួល SIGTERM វាមិនទទួលការហៅថ្មី ផ្តល់ពេល VOICE_DRAIN_SECONDS (លំនាំដើម 20 វិនាទី) ដល់ការហៅដែលកំពុងដំណើរការ រួចបញ្ចប់។

ការពិនិត្យ

docker compose logs pabal-server | grep -E "Voice|voice"
docker compose logs pabal-voice | head -20
INFO  TelegramServer - Voice bots on: gateways connect to ws://10.231.53.2:8095/voice/link; bots 0 listed, 2 calls each at most
INFO  VoiceGatewayLink - Voice gateway link listening on ws://10.231.53.2:8095/voice/link (បណ្តាញ)
INFO  TelegramServer - Voice bot callers: patched apps only (desktop pabal-bc1+, Android 62151+, iOS 5+), recipients google.vertex.gemini-live@us-central1, testers 0 listed + the admin page's
INFO  VoiceGatewayLink - Voice gateway pabal-voice-1 (boot 823c9600d05e811847ce95a8f1ba9efa) connected: new session, capacity 2, features […], audio to google.vertex.gemini-live@us-central1
  • Voice bots are off: … បង្ហាញពេលគ្មានសម្ងាត់តំណ អានមិនបាន ឬវាមិនមែន 32 បៃ ហើយផ្នែកចុងបន្ទាត់ — but without a TURN relay every bot call is busy បង្ហាញពេលគ្មានការបញ្ជូនបន្ត។
  • បើឃើញ ERROR Voice bots are on, but no bot is callable: the privacy policy … has no id="bot-calls" section ត្រូវផ្សាយផ្នែកការហៅបូតនៅក្នុងគោលការណ៍របស់គេហទំព័រជាមុនសិន។
  • ពេល gateway ភ្ជាប់ features ក្នុង log ម៉ាស៊ីនមេមាន bot_settings·end_call·context·tools ហើយមាន byok បើ gateway អាចប្រើសោរបស់ម្ចាស់បូត និង transcripts បើមានសំឡេងជូនដំណឹងអំពីកំណត់ត្រាសន្ទនា (លំដាប់ខុសគ្នារាល់ដង)។ audio to ត្រូវតែដូចគ្នានឹងកន្លែងទទួលដែលផ្ទាំងបញ្ជាក់របស់កម្មវិធីនិយាយ។
  • នៅខាង gateway បន្ទាត់ដំបូងត្រូវតែជា starting as pabal-voice-1 (capacity 2, … engine gemini, audio to google.vertex.gemini-live@us-central1) បន្ទាត់ម៉ូដែលត្រូវមាន session resumption off; no failover ហើយត្រូវមាន media workers sandbox themselves with Landlock (ABI N)។ recordings for the callers' notices in: Korean, English គឺជាភាសាដែលអាចចាក់សេចក្តីជូនដំណឹងដល់អ្នកហៅបាន (បើជាម៉ាស៊ីនមេសាកល្បងដែលចាក់សូម្បីតែសេចក្តីព្រាង នឹងមាន (drafts included: …) បន្ថែម)។
  • បន្ទាប់មក នៅក្នុងផ្ទាំង សំឡេង (음성) នៃទំព័រគ្រប់គ្រង (ការគ្រប់គ្រង និងការកំណត់ — ផ្ទាំងសំឡេង) សូមមើលថា gateway បានភ្ជាប់ឬនៅ ដាក់អ្នកសាកល្បង ហើយអនុញ្ញាតបូត។

សោមេ (សោផ្ទាល់ខ្លួន · របៀបសំឡេងដើម)

សោម៉ូដែលរបស់ម្ចាស់បូត និងសម្ងាត់នៃរបៀបសំឡេងដើម ត្រូវបានរុំដោយសោនេះមុនរក្សាទុក។ ត្រូវដាក់វានៅកន្លែងដែលមិនត្រូវបានចម្លងជាមួយការបម្រុងទុក។

sudo install -d -m 700 -o 1000 -g 1000 /etc/pabal/voice                 # ក្រៅ /srv/pabal, 700
sudo sh -c 'umask 077; openssl rand -hex 32 > /etc/pabal/voice/voice-master.key'
sudo chown 1000:1000 /etc/pabal/voice/voice-master.key
      TELEGRAM_VOICE_KEYS_MASTER_FILE: /app/secrets/voice-master.key
    volumes:
      - /etc/pabal/voice:/app/secrets:ro
  • បើវានៅក្នុង ឬក្បែរថតទិន្នន័យ ឬថតសោ RSA ឬបើថតបើកឲ្យអ្នកប្រើផ្សេងទៀតសូម្បីតែបន្តិច (មិនមែន 700) ម៉ាស៊ីនមេនឹងមិនប្រើវាទេ (Voice keys off: …)។ បើឯកសារមិនទាន់មាន ម៉ាស៊ីនមេនឹងបង្កើតវាពេលទទួលសោដំបូង (បើ mount ជាបានតែអាន សូមបង្កើតវាដោយខ្លួនឯងដូចខាងលើ)។
  • កុំដាក់វាក្នុងការបម្រុងទុក សូមរក្សាច្បាប់ចម្លងក្រៅបណ្តាញមួយដាច់ដោយឡែក។ បើបាត់ ម្ចាស់បូតទាំងអស់ត្រូវកំណត់សោម្តងទៀត។ ពេលប្តូរ សូមផ្តល់សោចាស់ក្នុង TELEGRAM_VOICE_KEYS_PREVIOUS_MASTER_FILE បើក ពិនិត្យ log រួចលុបឯកសារចាស់។
  • ទោះមានសោមេ ម៉ាស៊ីនមេនៅតែមិនទទួលសោផ្ទាល់ខ្លួនទេ រហូតដល់កម្មវិធីបង្ហាញផ្ទាំងបញ្ជាក់ (កំណែ 2) សម្រាប់បូតសោផ្ទាល់ខ្លួន ហើយអ្នកផ្តល់ TELEGRAM_VOICE_OWN_KEYS_APPS_READY=true។ ចំពោះរបៀបសំឡេងដើម ត្រូវប្រាប់ build កម្មវិធីដែលមានផ្ទាំងបញ្ជាក់សំឡេងដើមតាម TELEGRAM_VOICE_STREAM_MIN_BUILD_DESKTOP·_ANDROID·_IOS ទើបអាចហៅបាន (លំនាំដើម 0 = គ្មាននរណាអាចហៅបាន) ហើយ gateway ត្រូវមាន VOICE_STREAM=true និង IP សាធារណៈនៃការដាក់ឲ្យដំណើរការនេះ (VOICE_STREAM_DENY_ADDRESSES)។

សមាសភាគ MCP (ជាជម្រើស)

នេះជាសមាសភាគដែលហៅម៉ាស៊ីនមេ MCP ដែលម្ចាស់បូតបានចុះឈ្មោះ ក្នុងពេលការហៅ។ លំនាំដើមគឺបិទ ហើយ deploy/docker-compose.mcp.yml (profile mcp) បន្ថែម container បី។

Containerអ្វីដែលវាធ្វើ
pabal-mcp (uid 1101)client MCP។ ភ្ជាប់ជាមួយម៉ាស៊ីនមេតែតាមឯកសារ socket ហើយដោយសារមានតែបណ្តាញខាងក្នុងមួយ វាចេញក្រៅបានតែតាម proxy ចេញក្រៅប៉ុណ្ណោះ។ បានតែអាន · គ្មានសិទ្ធិពិសេស · 512 MB
pabal-mcp-signer (uid 1102)កម្មវិធីចុះហត្ថលេខា។ គ្មានបណ្តាញសោះ ឆ្លើយតែតាម socket ហើយសរសេរឯកសារសាធារណៈរបស់អ្នកចេញ (issuer)
pabal-mcp-egress (uid 1103)proxy ចេញក្រៅ។ ចេញតែតាម 443 ហើយមិនទៅអាសយដ្ឋានរបស់ Pabal ខ្លួនឯងទេ
docker compose -f docker-compose.yml -f docker-compose.mcp.yml --profile mcp up -d
  • ដើម្បីបើក ត្រូវមាន TELEGRAM_MCP_EGRESS_OWN_ADDRESSES (អាសយដ្ឋានសាធារណៈរបស់ Pabal, ចាំបាច់) និងឯកសារសោ (សម្ងាត់តំណ · K_grant · សោដំឡើង — ទាំងអស់នៅក្នុងថត 700 ក្រៅ /srv/pabal) ហើយគេហទំព័រត្រូវមានផ្នែក bot-calls-mcp នៃគោលការណ៍ និងផ្នែកម្ចាស់បូតនៃលក្ខខណ្ឌ។ ការកំណត់ដែលធ្វើតែម្តង មានតាមលំដាប់ក្នុងមតិយោបល់នៅដើម docker-compose.mcp.yml។ កុំដាក់ vault និងសោចុះហត្ថលេខាក្នុងការបម្រុងទុក។
  • ផ្តល់ TELEGRAM_MCP_APPS_READY=true តែក្រោយពេលកម្មវិធីបង្ហាញកន្លែងទទួល MCP របស់បូតលើផ្ទាំងបញ្ជាក់ប៉ុណ្ណោះ។ មុននោះ អាចចុះឈ្មោះបានតែប៉ុណ្ណោះ ហើយគ្មានការហៅណាផ្ទុកឧបករណ៍ MCP ទេ។
  • ការរៀបចំអាសយដ្ឋានចេញក្រៅផ្តាច់មុខសម្រាប់សំណើ MCP មិនមែនជាលក្ខខណ្ឌក្នុងកូដទេ តែជាការសម្រេចចិត្តប្រតិបត្តិការ (ព្រោះវាជាច្រកចេញដែលសម្តីរបស់អ្នកហៅទៅកាន់ម៉ាស៊ីនមេភាគីទីបី)។
  • ពេលបើក log មាន MCP tools on: pabal-mcp dials …; issuer …; ports …; own addresses N; clock by NTP …។ deploy/ship.sh <ម៉ាស៊ីនមេ> <ថត> --mcp គ្រាន់តែបង្កើត និងផ្ទុក image បី រួចចម្លងឯកសារ override ប៉ុណ្ណោះ មិនបើកអ្វីទេ (មិនទាន់ធ្លាប់ដំណើរការលើ Docker Linux ទេ)។

ច្រកចូលរបស់ Apple Watch (ជាជម្រើស កំពុងរៀបចំ)

ជំនួសឲ្យ MTProto កម្មវិធី Apple Watch ចូលគណនី និងហៅ តាម API នាឡិកា (HTTPS JSON, /api/watch/v1/) របស់ម៉ាស៊ីនមេ ហើយសំឡេងនៃការហៅឆ្លងកាត់ច្រកចូលសំឡេង (pabal-voice-edge, WSS) ទៅដល់ gateway។ មិនប្រើការបញ្ជូនបន្តការហៅ (coturn) ទេ។ លំនាំដើមបិទ។

ច្រកចូលសំឡេងរបស់នាឡិកា មិនទាន់អាចចូលដល់ពីខាងក្រៅបាននៅឡើយទេ

deploy/docker-compose.voice.yml មានច្រកចូលសំឡេង pabal-voice-edge (profile voice-watch · គ្មានសម្ងាត់ · នៅលើបណ្តាញខាងក្នុងសុទ្ធ) ប៉ុន្តែមិនទាន់មានការកំណត់ API នាឡិការបស់ម៉ាស៊ីនមេ (TELEGRAM_WATCH_*) ឬផ្លូវនាឡិកានៅលើ reverse proxy ទេ ដូច្នេះនាឡិកាពីខាងក្រៅមិនអាចចូលដល់បានទេ។ ខាងក្រោមនេះជាការណែនាំអំពីតម្លៃការកំណត់ ហើយមិនធ្លាប់ដំណើរការជាការរៀបចំផលិតកម្មទេ (សាកល្បងតែលើម៉ាស៊ីនមេអភិវឌ្ឍន៍)។

ការកំណត់លំនាំដើមអត្ថន័យ
TELEGRAM_WATCH_API_PORT—ច្រកនៃ API នាឡិកា។ បើគ្មាន API នាឡិកាបិទ
TELEGRAM_WATCH_API_HOST, TELEGRAM_WATCH_API_ANY_ADDRESS127.0.0.1, —អាសយដ្ឋានដែលស្តាប់។ បើមិនមែន loopback ត្រូវមាន ANY_ADDRESS=true ហើយដាក់ proxy TLS នៅខាងមុខ
TELEGRAM_WATCH_AUDIO_URL—អាសយដ្ឋានច្រកចូលសំឡេងដែលប្រាប់នាឡិកា។ ផ្លូវត្រូវតែជា wss://<host>/api/watch/v1/audio ពិតប្រាកដ។ បើគ្មាន ឬខុស ការហៅពីនាឡិកាបិទ
TELEGRAM_WATCH_ALLOW_PLAIN—អនុញ្ញាតអាសយដ្ឋាន ws://។ សម្រាប់តែការអភិវឌ្ឍ (សាកល្បងក្នុងផ្ទះ)
TELEGRAM_WATCH_SESSION_DAYS7ចំនួនថ្ងៃដែលការចូលគណនីលើនាឡិកានៅបន្ត (1–365)
TELEGRAM_WATCH_AUTH_PER_MINUTE30ដែនកំណត់សំណើលេខកូដចូលគណនីរបស់ម៉ាស៊ីនមេទាំងមូល (ក្នុងមួយនាទី)។ ដែនកំណត់តាមអាសយដ្ឋាននីមួយៗមានដាច់ដោយឡែក
TELEGRAM_VOICE_MIN_BUILD_WATCHOS1build កម្មវិធីនាឡិកាដំបូងដែលបង្ហាញផ្ទាំងបញ្ជាក់ទាំងមូល
  • gateway៖ VOICE_DIRECT=true និង VOICE_EDGE_DIR (ថត socket ដែលប្រើរួមជាមួយច្រកចូល លំនាំដើម /run/pabal-voice-edge)។ ការហៅពីនាឡិកាដំណើរការតែជាមួយម៉ាស៊ីន 16 kHz (Gemini) ឬ echo ប៉ុណ្ណោះ។
  • ច្រកចូលសំឡេង៖ ដំណើរការ python -m pabal_voice.edge ជាសេវាទីពីរនៃ image ដដែល (VOICE_EDGE_HOST · VOICE_EDGE_PORT លំនាំដើម 127.0.0.1 · 8096, VOICE_EDGE_DIR)។ ច្រកចូលជាកន្លែងដំបូងដែលដោះអ្វីដែលមកពីអ៊ីនធឺណិត ដូច្នេះកុំភ្ជាប់សម្ងាត់ណាមួយឡើយ ហើយដាក់វាក្នុងបណ្តាញខាងក្នុងដែលគ្មានអ្វីក្រៅពី proxy និង gateway អាចទៅដល់។
  • reverse proxy បញ្ជូនតែផ្លូវនាឡិកាពីរប៉ុណ្ណោះ — /api/watch/v1/audio (WebSocket ទៅច្រកចូល) និង /api/watch/v1/ (ទៅ API នាឡិកា)។ ខាង API នាឡិកា ទុកឲ្យ proxy បន្ថែមអាសយដ្ឋានអ្នកភ្ជាប់នៅចុងក្រោយនៃ X-Forwarded-For (ម៉ាស៊ីនមេប្រើតម្លៃនោះរាប់ដែនកំណត់ចូលគណនីតាមអាសយដ្ឋាន)។ ខាងច្រកចូល សូមលុប X-Forwarded-For · X-Real-IP។
  • មិនអាចចុះឈ្មោះនៅលើនាឡិកាបានទេ ហើយមិនអាចហៅទៅបូតដែលប្រើឧបករណ៍ · MCP · សោផ្ទាល់ខ្លួន · របៀបសំឡេងដើម · កំណត់ត្រាសន្ទនារបស់ម្ចាស់បូតបានទេ (WATCH_NOT_YET)។

រក្សាទុកការសន្ទនា (ជាជម្រើស កំពុងរៀបចំ)

ជាមុខងារដែលរក្សាទុកការសន្ទនានៃការហៅជាអត្ថបទ តែក្នុងការសន្ទនារបស់អ្នកហៅប៉ុណ្ណោះ បើអ្នកនោះជ្រើសនៅលើផ្ទាំងបញ្ជាក់ (ការប្រើកម្មវិធី — បូតសំឡេង)។ គ្មានកុងតាក់អនុញ្ញាតរបស់ប្រតិបត្តិករទេ វាបើកពេលមានលក្ខខណ្ឌខាងក្រោមគ្រប់យ៉ាង។

  • ផ្នែក id="bot-calls-keep-text" ក្នុងគោលការណ៍ឯកជនភាព (សេចក្តីព្រាង៖ docs/voice-bots/p0/privacy-*.draft.html ក្នុងឃ្លាំងកូដ)។ ផ្នែកនេះហើយជាកុងតាក់បើក។ កម្មវិធីដឹងថាត្រូវបង្ហាញប្រអប់ធីកឬអត់ តាម pabal_voice_keep_text នៃ help.getAppConfig។
  • VOICE_KEEP_TEXT របស់ gateway 0.9.0៖ បើជាម៉ាស៊ីនម៉ូដែល លំនាំដើមគឺ true។ បើជាម៉ាស៊ីន echo (រួមទាំង gateway សម្រាប់តែសំឡេងដើម) ហើយវាជា true វាត្រូវចាត់ទុកជាកំហុសការកំណត់ ហើយមិនចាប់ផ្តើមទេ។
  • build កម្មវិធីដែលមានប្រអប់ធីក។ ពាក្យពេចន៍នៃប្រអប់ធីកត្រូវឆ្លងកាត់ការពិនិត្យផ្នែកច្បាប់ ទើបអាចដាក់ក្នុង build ចេញផ្សាយ។ នាឡិកាមិនបង្ហាញពាក្យពេចន៍ដែលមិនទាន់ពិនិត្យទេ ហើយ TELEGRAM_VOICE_KEEP_TEXT_UNREVIEWED=true គឺជាកុងតាក់សម្រាប់តែម៉ាស៊ីនមេសាកល្បងផ្ទៃក្នុង ដើម្បីបង្ហាញពាក្យពេចន៍មុនការពិនិត្យ។
  • នៅលើម៉ាស៊ីនមេដែលបានបើក voice_call ended នៃការហៅបូតទាំងអស់ដែលមិនមែនរបៀបសំឡេងដើម យឺតរហូតដល់ 10 វិនាទី ហើយលេខសារ 30 នៅក្រោយកំណត់ត្រាការហៅត្រូវបានបម្រុងទុកជាមុន (ដើម្បីកុំឲ្យម្ចាស់បូតដឹងជម្រើសរបស់អ្នកហៅ)។
  • អត្ថបទសន្ទនាដែលរង់ចាំការសរសេរបន្ទាប់ពីការហៅចប់ ស្ថិតនៅតែក្នុងអង្គចងចាំ ដូច្នេះបើចាប់ផ្តើមម៉ាស៊ីនមេឡើងវិញក្នុងចន្លោះនោះ អត្ថបទនៃការហៅនោះមិនត្រូវបានរក្សាទុកទេ។

ការហៅពីបូត (ជាជម្រើស កំពុងរង់ចាំការពិនិត្យផ្នែកច្បាប់)

បូតសំឡេងហៅទៅមុន ទៅមនុស្សដែលបានអនុញ្ញាតឲ្យបូតនោះហៅខ្លួន (បូតសំឡេង — ការហៅពីបូត)។ វាមានលក្ខខណ្ឌច្រើនជាងការហៅទៅបូត ហើយកុំបើកវាមុនពេលការពិនិត្យផ្នែកច្បាប់រួចរាល់។ លំដាប់៖

  1. ម៉ាស៊ីនមេ៖ បង្កើតថតសោភស្តុតាង (TELEGRAM_VOICE_EVIDENCE_KEY_DIR — 700 នៅក្រៅថតដែលត្រូវបម្រុងទុក ដូចជាថតទិន្នន័យ និងសោ) ដោយ new របស់ scripts/voice-evidence-key.py (rotate ដើម្បីប្តូរសោ check ដើម្បីពិនិត្យ) ហើយកំណត់កំណែកម្មវិធីដំបូងដែលមានផ្ទាំងអនុញ្ញាត ជាកំណែអប្បបរមាសម្រាប់ការហៅចេញ ដូចជា TELEGRAM_VOICE_OUTBOUND_MIN_BUILD_ANDROID (អថេរបរិស្ថាន)។ TELEGRAM_VOICE_EVIDENCE_KEY_DIR ដែលសរសេរតែក្នុង .env មិនទៅដល់ម៉ាស៊ីនមេទេ — សូមបន្ថែមវាទៅ pabal-server ក្នុង deploy/docker-compose.voice.yml នៅ environment (ផ្លូវក្នុង container) និង volumes (ថតនោះនៅលើម៉ាស៊ីន host)។
  2. កម្មវិធី៖ ចេញកំណែកម្មវិធីដែលមានផ្ទាំងអនុញ្ញាត។ ច្បាប់តំណអនុញ្ញាតរបស់កម្មវិធីស្គាល់តែ pabal.me ដូច្នេះសម្រាប់ម៉ាស៊ីនមេផ្សេង ត្រូវបន្ថែម host របស់វាទៅក្នុងច្បាប់តំណនៃកំណែកម្មវិធី ទើបតំណដែលបូតផ្ញើអាចបើកផ្ទាំងបាន (ម៉ឺនុយ និងបញ្ជីក្នុងការកំណត់ នៅតែដំណើរការធម្មតា)។
  3. ផ្នែកច្បាប់៖ ផ្សាយផ្នែក id="bot-calls-outbound" ក្នុងគោលការណ៍ឯកជនភាព និងផ្នែក id="voice-bot-owners-outbound" ក្នុងលក្ខខណ្ឌនៃសេវាកម្ម (ព្រមទាំងផ្នែក voice-bot-owners ដើម្បីឲ្យម្ចាស់បូតយល់ព្រមលក្ខខណ្ឌ)។ សេចក្តីព្រាងមាននៅ docs/voice-bots/p0/ ក្នុងឃ្លាំង។ ពាក្យពេចន៍នៃផ្ទាំងអនុញ្ញាត និងការថតសេចក្តីជូនដំណឹងការហៅចេញ (notice-out·apology-rule) ក៏ត្រូវពិនិត្យ និងអនុម័តនៅជំហាននេះដែរ។
  4. កុងតាក់៖ នៅ ការហៅពីបូត ក្នុងផ្ទាំងសំឡេងនៃទំព័រគ្រប់គ្រង កំណត់ប្រទេស និងដែនកំណត់ ហើយបើកដោយឃ្លាបញ្ជាក់ (ទំព័រគ្រប់គ្រង — ផ្ទាំងសំឡេង)។ បូតនីមួយៗក៏ត្រូវឆ្លងការពិនិត្យការហៅចេញរបស់ប្រតិបត្តិករដាច់ដោយឡែកដែរ។
  • Gateway៖ មានតែ gateway ដែលមាន VOICE_OUTBOUND=true ទេដែលធ្វើការហៅរបស់បូត។ ជាមួយម៉ាស៊ីនម៉ូដែល វាចាប់ផ្តើមបានតែពេលការថតសេចក្តីជូនដំណឹងការហៅចេញទាំងបួនត្រូវបានអនុម័ត ហើយការថតព្រាង (VOICE_OUTBOUND_DRAFT_NOTICES) សម្រាប់តែម៉ាស៊ីនមេសាកល្បង។
  • កុំដាក់ឈ្មោះសម្រាប់តែការសាកល្បង និងអភិវឌ្ឍន៍ ដូចជា TELEGRAM_VOICE_CALLME_UNREVIEWED និង TELEGRAM_VOICE_TEST_DIAL ក្នុង .env ផលិតកម្ម។
  • ការហៅពីបូតក៏មិនត្រូវបានអ៊ិនគ្រីបពីចុងម្ខាងទៅចុងម្ខាងដែរ — សំឡេងឆ្លងកាត់ gateway របស់ម៉ាស៊ីនមេនេះ និងអ្នកផ្តល់ AI។

13. រូបផែនទីក្នុងសារទីតាំង (ជាជម្រើស)

ពេលផ្ញើទីតាំង កម្មវិធី Android និងកម្មវិធីកុំព្យូទ័រ (Mac · Windows) មិនគូរផែនទីក្នុងពពុះសារដោយខ្លួនឯងទេ គឺសុំរូបផែនទីនៃចំណុចនោះពីម៉ាស៊ីនមេ (upload.getWebFile)។ ម៉ាស៊ីនមេយករូបនោះពី Maps Static API របស់ Google ហើយបញ្ជូនបន្ត។ បើមិនបើក Android បង្ហាញរូបជំនួស ហើយកុំព្យូទ័របង្ហាញតែប្រអប់ទទេជាមួយម្ជុលមួយ។ iPhone គូរផែនទីលើទូរស័ព្ទផ្ទាល់ ដូច្នេះការកំណត់នេះមិនពាក់ព័ន្ធទេ ហើយការផ្ញើទីតាំង និងផែនទីធំដែលបើកពេលចុច នៅតែដំណើរការធម្មតា។

  1. នៅក្នុងផ្ទាំងគ្រប់គ្រង Google Cloud ជ្រើសគម្រោងដែលភ្ជាប់គណនីបង់ប្រាក់ ហើយបើក Maps Static API។
  2. បង្កើត សោ API ៖ កំណត់កម្មវិធីត្រឹម អាសយដ្ឋាន IP (IP សាធារណៈដែលម៉ាស៊ីនមេប្រើចេញទៅអ៊ីនធឺណិត) ហើយកំណត់ API ត្រឹម Maps Static API តែមួយ។ សោនេះនៅតែលើម៉ាស៊ីនមេ ហើយមិនដែលចូលក្នុងកម្មវិធីទេ។
  3. ដាក់វាក្នុង .env ហើយចាប់ផ្តើមម៉ាស៊ីនមេឡើងវិញដោយ docker compose up -d pabal-server។
  4. ពិនិត្យក្នុងកំណត់ហេតុ។ បើផែនទីបិទ Maps in location messages are off: … នឹងប្រាប់មូលហេតុ (តម្លៃសោមិនដែលបង្ហាញក្នុងកំណត់ហេតុទេ)។
STATIC_MAPS_KEY=AIza…               # កុំទុកតម្លៃសោក្នុងការជជែក កំណត់ហេតុ ឬឃ្លាំងកូដ
STATIC_MAPS_PER_DAY=300             # ចំនួនរូបថ្មីដែលយកក្នុងមួយថ្ងៃ (0 = គ្មានកំណត់)
STATIC_MAPS_PER_USER_HOUR=120       # ចំនួនរូបថ្មីដែលមនុស្សម្នាក់អាចបង្កឲ្យយកក្នុងមួយម៉ោង
INFO  TelegramServer - Maps in location messages from Google Static Maps (120 new per person an hour, 300 a day)
  • តម្លៃ៖ Maps Static API ឥតគិតថ្លៃរហូតដល់ 10,000 សំណើក្នុងមួយខែ។ ម៉ាស៊ីនមេចងចាំរូបនីមួយៗរយៈពេលមួយថ្ងៃ ហើយផ្តល់ឲ្យម្តងទៀតទៅឧបករណ៍ណាដែលសុំផែនទីដដែល ហើយរូបដែលផ្តល់ម្តងទៀតមិនរាប់ក្នុងដែនកំណត់ទេ។ ដែនកំណត់លំនាំដើម (300 ក្នុងមួយថ្ងៃ) ស្មើប្រហែល 9,000 ក្នុងមួយខែ ដែលនៅក្នុងកម្រិតឥតគិតថ្លៃ។ សំណើដែលលើសដែនកំណត់ត្រូវបានបដិសេធដោយ FLOOD_WAIT ហើយក្នុងពេលនោះកម្មវិធីបង្ហាញរូបជំនួស។
  • គោលការណ៍ឯកជនភាព៖ កូអរដោនេ (រយៈទទឹង និងរយៈបណ្តោយ) នៃទីតាំងដែលបានចែករំលែកត្រូវផ្ញើទៅ Google — ប៉ុន្តែមិនផ្ញើថាអ្នកណាជាអ្នកផ្ញើទេ។ នៅទំព័រគ្រប់គ្រង → ការកំណត់ → ព័ត៌មានប្រតិបត្តិករ សូមបន្ថែម Google LLC (Maps Static API សហរដ្ឋអាមេរិក) ទៅក្នុងអ្នកដំណើរការដែលបានប្រគល់ និងការផ្ទេរទៅក្រៅប្រទេស។
  • បើកំណត់ហេតុបង្ហាញ Map picture not made: Google Static Maps answered 403: … សូមពិនិត្យការកំណត់របស់សោ (IP · API) ឬគណនីបង់ប្រាក់។

ប្រតិបត្តិការ

ស្ថានភាព និង log

cd /opt/pabal/deploy
docker compose ps
docker compose logs --since 1h pabal-server
tail -f /srv/pabal/pabal_server/logs/telegram-server.log

ការធ្វើបច្ចុប្បន្នភាព

cd /opt/pabal && git pull
cd deploy
./backup.sh                                     # បម្រុងទុកជាមុនសិន
docker compose up -d --build pabal-server             # ប្តូរតែម៉ាស៊ីនមេជាមួយ image ថ្មី
docker compose logs --since 5m pabal-server | grep -E "Website|ERROR"

ក្នុងរយៈពេលប៉ុន្មានដប់វិនាទី ដែលម៉ាស៊ីនមេកំពុងបើកឡើងវិញ កម្មវិធីនឹងដាច់ ហើយភ្ជាប់ឡើងវិញដោយខ្លួនឯងដោយមិនចាំបាច់ចូលគណនីម្តងទៀត។ ការផ្លាស់ប្តូរតារាងត្រូវបានអនុវត្តដោយស្វ័យប្រវត្តិ ពេលម៉ាស៊ីនមេបើក។ ថត bind មិនពាក់ព័ន្ធនឹង image ទេ ដូច្នេះ docker compose down ឬការលុប image មិនលុបទិន្នន័យទេ — គ្រាន់តែកុំលុប /srv/pabal។

ការត្រឡប់ទៅកំណែមុន៖ ការត្រឡប់ទៅ image មុន មិនលុបអ្វីដែលកំណែថ្មីបានសរសេរក្នុងមូលដ្ឋានទិន្នន័យរួចទេ ហើយកំណែចាស់ប្រហែលមិនអាចអានវាបាន (ឧទាហរណ៍ កំណែដែលមានកូដបូតសំឡេង សរសេរព្រឹត្តិការណ៍ថ្មីដូចជាកំណត់ត្រាការហៅក្នុងការសន្ទនា ទោះបីសំឡេងបិទក៏ដោយ)។ ដូច្នេះពេលត្រឡប់ សូមស្តារមូលដ្ឋានទិន្នន័យពីការបម្រុងទុកដែលធ្វើមុនការធ្វើបច្ចុប្បន្នភាពភ្លាមផងដែរ (ការស្តារ)។

ការបម្រុងទុក

./backup.sh            # → /srv/pabal/backups/<កាលបរិច្ឆេទ-ម៉ោង>/{pabal.dump, server-keys-data.tar.gz}
crontab -e             # រៀងរាល់ថ្ងៃម៉ោង 03:00៖
# 0 3 * * * /opt/pabal/deploy/backup.sh >> /srv/pabal/backups/backup.log 2>&1
  • ការបម្រុងទុកដែលលើស 14 ថ្ងៃ ត្រូវបានលុបដោយស្វ័យប្រវត្តិ (អាចប្តូរបាន ដូចជា KEEP_DAYS=30 ./backup.sh)។
  • សូមចម្លងទៅកន្លែងផ្សេងផងដែរ។ ការបម្រុងទុកនៅលើថាសដដែល មិនអាចទប់ទល់នឹងការខូចថាសបានទេ។
  • ការបម្រុងទុកមានសោឯកជន RSA និងតម្លៃសម្ងាត់ SMS និង SMTP។ សូមការពារកន្លែងរក្សាទុក ឲ្យបានដូចម៉ាស៊ីនមេដែរ។

ការស្តារ

cd /opt/pabal/deploy
B=/srv/pabal/backups/20260920-030000            # ការបម្រុងទុកដែលត្រូវស្តារ
docker compose stop pabal-server pabal-caddy
docker compose exec -T pabal-postgres dropdb -U pabal pabal
docker compose exec -T pabal-postgres createdb -U pabal pabal
docker compose exec -T pabal-postgres pg_restore -U pabal -d pabal --no-owner < $B/pabal.dump
docker compose exec -T pabal-postgres psql -U pabal -d pabal -c "ALTER DATABASE pabal SET search_path = public"   # ផ្លូវលំនាំដើមរបស់មូលដ្ឋានទិន្នន័យ — ការស្ដារមិននាំវាមកវិញទេ
sudo tar -C /srv/pabal/pabal_server -xzf $B/server-keys-data.tar.gz
sudo chown -R 1000:1000 /srv/pabal/pabal_server
docker compose up -d

ពេលផ្លាស់ទៅម៉ាស៊ីនមេថ្មី ក៏ដូចគ្នាដែរ៖ ធ្វើជំហាន 1 ដល់ 5 រួច ធ្វើការស្តារខាងលើជំនួសឲ្យជំហានទី 6 ហើយបើក។ បើស្តារសោដដែល មិនចាំបាច់ build កម្មវិធីម្តងទៀតទេ (បើ IP ម៉ាស៊ីនមេប្តូរ ត្រូវ build ម្តងទៀត)។

ការបើក និងបិទ

docker compose restart pabal-server       # ចាប់ផ្តើមតែម៉ាស៊ីនមេឡើងវិញ
docker compose stop                 # បញ្ឈប់ទាំងអស់ (ទិន្នន័យនៅដដែល)
docker compose up -d                # បើកម្តងទៀត

ទោះបីចាប់ផ្តើមម៉ាស៊ីនមេឡើងវិញ (reboot) ក៏ container បើកឡើងវិញដោយខ្លួនឯង ព្រោះមាន restart: unless-stopped។

បញ្ជីត្រួតពិនិត្យសុវត្ថិភាព

  • សិទ្ធិ .env គឺ 600 ហើយ POSTGRES_PASSWORD ជាតម្លៃចៃដន្យ
  • សិទ្ធិ /srv/pabal/pabal_server/keys គឺ 700 ហើយសោឯកជនមិនមាននៅកន្លែងផ្សេង ក្រៅពីការបម្រុងទុក
  • (បើបានបើក push) សិទ្ធិ firebase-service-account.json គឺ 600 ហើយខ្លឹមសាររបស់វាមិនមាននៅក្នុងឃ្លាំងកូដ ឬ .env
  • (បើបានបើក push របស់ iPhone) សិទ្ធិ AuthKey_<ID សោ>.p8 គឺ 600 ហើយខ្លឹមសាររបស់វាមិនមាននៅក្នុងឃ្លាំងកូដ ឬ .env
  • ជញ្ជាំងភ្លើង៖ តែ 22 (បើអាច តែ IP ប្រតិបត្តិករ) · 80 · 443 · 8443
  • ពីខាងក្រៅ https://domain/admin/ ឆ្លើយ 404
  • ទំព័រគ្រប់គ្រង៖ លេខសាកល្បង (테스트 번호) បិទ · វិធីបញ្ជូនលេខកូដ (코드 전달 방식) ជា SMS ឬអ៊ីមែល · ការផ្ញើសាកល្បង (테스트 발송) ជោគជ័យ
  • មិនបើក TELEGRAM_WEBHOOK_ALLOW_LOCAL (ដើម្បីកុំឲ្យ webhook របស់បូតទៅបណ្តាញខាងក្នុង)
  • (បើបានបើកបូតសំឡេង) សម្ងាត់តំណ សោ Vertex និងសោមេ អានបានតែដោយអ្នកប្រើដែលត្រូវអានឯកសារនីមួយៗប៉ុណ្ណោះ (400/600) ហើយសោមេនៅក្រៅ /srv/pabal ដូច្នេះមិនចូលក្នុងការបម្រុងទុក។ មិនបានបើកចំហច្រកតំណ ហើយបណ្តាញតំណប្រើតែដោយម៉ាស៊ីនមេ និង gateway។ ម៉ាស៊ីនមេផលិតកម្មគ្មាន TELEGRAM_VOICE_NOTICE_CHECK ឬ TELEGRAM_VOICE_TESTERS=*
  • SSH៖ បិទការចូលដោយពាក្យសម្ងាត់ ប្រើតែសោ
  • ពិនិត្យ cron បម្រុងទុក និងការចម្លងទៅខាងក្រៅ ហើយហាត់ការស្តារម្តង
  • ការធ្វើបច្ចុប្បន្នភាពសុវត្ថិភាពស្វ័យប្រវត្តិរបស់ OS ម៉ាស៊ីនមេ (unattended-upgrades)

ការដោះស្រាយបញ្ហា

រោគសញ្ញាមូលហេតុ → ដំណោះស្រាយ
កម្មវិធីជាប់នៅ «កំពុងភ្ជាប់…»① ច្រក 8443 ត្រូវបានរារាំង → nc -vz IP 8443 ពិនិត្យ ufw និង security group របស់ cloud ② កម្មវិធីត្រូវបាន build ជាមួយសោសាធារណៈផ្សេង → ធ្វើជំហានទី 9 ម្តងទៀតជាមួយសោរបស់ម៉ាស៊ីនមេនេះ ③ PUBLIC_IP ខុស → កែ .env ហើយ docker compose up -d pabal-server
ភ្ជាប់បានដំបូង តែដាច់ភ្លាមៗកម្មវិធីផ្លាស់ទៅអាសយដ្ឋានដែលម៉ាស៊ីនមេប្រាប់ (PUBLIC_IP:MTPROTO_PORT) ប៉ុន្តែអាសយដ្ឋាននោះខុស → ពិនិត្យ PUBLIC_IP
កំហុសវិញ្ញាបនបត្រ HTTPSDNS មិនទាន់ចង្អុលមកម៉ាស៊ីនមេនេះ ឬច្រក 80 ត្រូវបានរារាំង → dig +short domain, docker compose logs pabal-caddy
server ចាប់ផ្តើមឡើងវិញជាបន្តបន្ទាប់ · password authentication failedបានប្តូរ POSTGRES_PASSWORD ក្រោយពេលទិន្នន័យត្រូវបានបង្កើត → ប្តូរត្រឡប់ទៅតម្លៃដើម ឬដំណើរការ ALTER USER pabal PASSWORD '…' ក្នុង DB
AccessDeniedException: /app/keys/…ម្ចាស់ថត bind → sudo chown -R 1000:1000 /srv/pabal/pabal_server
OutOfMemoryError, យឺតបង្កើន -Xmx ក្នុង JAVA_OPTS ហើយ docker compose up -d pabal-server
លេខកូដចុះឈ្មោះមិនមកដល់ស្ថានភាពផ្ញើ និងមូលហេតុបរាជ័យ ក្នុងផ្ទាំង លេខកូដចុះឈ្មោះ (가입 코드) នៃទំព័រគ្រប់គ្រង → តម្លៃ SMS និង SMTP ក្នុងការកំណត់ (설정) និងការផ្ញើសាកល្បង (테스트 발송)
Android មិនទទួលបានការជូនដំណឹង① log មាន Push notifications are off → ផ្លូវ FCM_CREDENTIALS និងសិទ្ធិឯកសារ ② គ្មាន Push device registered → កម្មវិធីត្រូវបាន build ដោយគ្មានការកំណត់ Firebase (pabal-placeholder) ឬមិនទាន់បានបើកកម្មវិធីថ្មី ③ មាន sent ប៉ុន្តែមិនលេចឡើង → សិទ្ធិជូនដំណឹង និងការកំណត់ថ្មរបស់ទូរស័ព្ទ ហើយថាតើកម្មវិធីត្រូវបាន «បង្ខំឲ្យបញ្ឈប់» ឬទេ ④ SENDER_ID_MISMATCH … Registrations are kept → សោរបស់ម៉ាស៊ីនមេ និង google-services.json របស់កម្មវិធី មកពីគម្រោងខុសគ្នា ⑤ answered 404 without naming the token → FCM_PROJECT_ID ខុស ⑥ refused an access token → សោត្រូវបានដកហូត ឬជាសោរបស់គម្រោងផ្សេង (មិនសួរម្តងទៀតក្នុងរយៈពេល 5 នាទី)
iPhone មិនទទួលបានការជូនដំណឹង① log មាន iPhone push notifications are off → ផ្លូវ APNS_KEY សិទ្ធិឯកសារ និងឈ្មោះ (AuthKey_<ID សោ>.p8) ② គ្មានការចុះឈ្មោះ type 1 → មិនបានអនុញ្ញាតការជូនដំណឹងក្នុងកម្មវិធី ឬជា simulator ③ មានការចុះឈ្មោះ ប៉ុន្តែគ្មានអ្វីផ្ញើចេញ → build នោះទាបជាង APNS_MIN_BUILD (build ក្នុងបន្ទាត់ចុះឈ្មោះ) ឬជាការសន្ទនាដែលបានបិទការជូនដំណឹង ④ APNs refused the provider token → សោត្រូវបានដកហូត ឬ APNS_TEAM_ID ខុសពីក្រុមរបស់សោ (មិនផ្ញើម្តងទៀតក្នុងរយៈពេល 5 នាទី) ⑤ DeviceTokenNotForTopic … Registrations are kept → APNS_TOPIC ខុសពី bundle ID របស់កម្មវិធី ⑥ មាន sent ប៉ុន្តែឃើញតែ «អ្នកមានការជូនដំណឹងថ្មី» → ផ្នែកបន្ថែមការជូនដំណឹងដោះគ្រីបមិនបាន (បើបានដំឡើងកម្មវិធីឡើងវិញ សូមបើកម្តងដើម្បីចុះឈ្មោះឡើងវិញ) ⑦ ការហៅមកតែជាការជូនដំណឹង → APNS_VOIP_MIN_BUILD ទទេ ឬខ្ពស់ជាង build នោះ (ជាឥរិយាបថដែលបានគ្រោងទុក)
ចូលទំព័រគ្រប់គ្រងមិនបានពិនិត្យថា SSH tunnel កំពុងដំណើរការ ឬកម្មវិធីផ្សេងកំពុងប្រើច្រក 8080 នៃកុំព្យូទ័ររបស់អ្នក (ប្តូរជា -L 18080:127.0.0.1:8080 ហើយប្រើ localhost:18080)
network ssemiya-net declared as external, but could not be foundបណ្តាញមិនទាន់បានបង្កើត → docker network create ssemiya-net (ឬឈ្មោះផ្សេងតាម PABAL_NETWORK ក្នុង .env)

ដែនកំណត់ដែលដឹងរួច

  • នេះជារចនាសម្ព័ន្ធម៉ាស៊ីនមេមួយគ្រឿង។ ពេលបើក វាផ្ទុកគណនី ការសន្ទនា និងសារទាំងអស់ទៅក្នុងអង្គចងចាំ។ ការពង្រីកផ្តេក (បែងចែកទៅម៉ាស៊ីនច្រើន) មិនទាន់អាចធ្វើបានទេ ហើយពេលទិន្នន័យកើនឡើង ត្រូវបង្កើនអង្គចងចាំ។
  • លេខកូដចុះឈ្មោះដែលកំពុងរង់ចាំ update របស់បូតដែលមិនទាន់ទាញយក និងអត្ថបទរក្សាទុកការសន្ទនាដែលរង់ចាំការសរសេរ ស្ថិតនៅក្នុងអង្គចងចាំ ដូច្នេះវានឹងបាត់ពេលម៉ាស៊ីនមេចាប់ផ្តើមឡើងវិញ។
  • សំណើលេខកូដចុះឈ្មោះមានចន្លោះពេល និងដែនកំណត់ក្នុងមួយថ្ងៃ ប៉ុន្តែមិនទាន់មានការកំណត់ល្បឿនសម្រាប់សំណើផ្សេងៗទាំងអស់ទេ។ ក្រោយបើកចំហភ្លាម សូមពិនិត្យ log និងផ្ទាំង Dashboard (대시보드) ឲ្យបានញឹកញាប់។
  • ការជូនដំណឹង push ទៅដល់តែកម្មវិធីទូរស័ព្ទប៉ុណ្ណោះ — Android (ជំហានទី 10) និង iPhone (ជំហានទី 11)។ សម្រាប់ iPhone វាទៅដល់តែ build ចាប់ពី APNS_MIN_BUILD ឡើងទៅ (មិនរាប់បញ្ចូល Pabal 1.0 (3)) ហើយអេក្រង់ការហៅរបស់ CallKit បើកតែក្រោយពីកំណត់ APNS_VOIP_MIN_BUILD ប៉ុណ្ណោះ។ កម្មវិធី Mac និង Windows ទទួលពេលកំពុងបើក។
  • «បិទការជូនដំណឹង» តាមការសន្ទនានីមួយៗ មាននៅតែក្នុងអង្គចងចាំម៉ាស៊ីនមេប៉ុណ្ណោះ។ push នៃការសន្ទនាដែលបានបិទការជូនដំណឹង ត្រូវបានផ្ញើទៅ Android ដោយអាទិភាពមិនបន្ទាន់ (ទូរស័ព្ទច្រោះដោយខ្លួនឯង) ហើយមិនត្រូវបានផ្ញើទៅ iPhone ទេ ប៉ុន្តែក្រោយបើកម៉ាស៊ីនមេឡើងវិញ ទាំងពីរត្រូវបានផ្ញើដូចធម្មតា (កម្មវិធីប្រាប់ម៉ាស៊ីនមេម្តងទៀត តែពេលអ្នកប្តូរការកំណត់ប៉ុណ្ណោះ)។ បើកម្មវិធីដែលបិទ ត្រូវការពេលលើសពី 20 វិនាទី ដើម្បីភ្ញាក់ និងភ្ជាប់ទៅម៉ាស៊ីនមេ ការហៅអាចបញ្ចប់ជាការហៅដែលមិនបានលើក នៅខាងអ្នកហៅ។
  • ការភ្ជាប់ក្នុងសារ អាចជារូបថត និងឯកសារ ប៉ុន្តែសារវីដេអូ និងសារសំឡេងដែលចាក់ផ្ទាល់ក្នុងកម្មវិធី មិនទាន់មាននៅឡើយទេ។ ឆានែល · supergroup · ការហៅជាក្រុម និងការផ្ទៀងផ្ទាត់ 2 ជំហាន ក៏មិនទាន់មានដែរ។
  • auth key ត្រូវបានរក្សាទុកក្នុង DB ជាអត្ថបទធម្មតា (មិនអ៊ិនគ្រីប) (ចាំបាច់សម្រាប់ឲ្យម៉ាស៊ីនមេឌិគ្រីប)។ សូមការពារ DB និងការបម្រុងទុក ឲ្យបានដូចសោ RSA ដែរ។

ឯកសារ

ឯកសារតួនាទី
deploy/docker-compose.ymlរចនាសម្ព័ន្ធផលិតកម្ម (pabal-server · pabal-postgres · pabal-caddy, bind mount)
deploy/CaddyfileHTTPS · ការរារាំងផ្លូវគ្រប់គ្រង · ការបញ្ជូនបន្តគេហទំព័រ ឯកសារ និង Bot API
deploy/.env.exampleគំរូការកំណត់ → deploy/.env
deploy/backup.shdump DB + រក្សាទុកសោ និងទិន្នន័យ សម្អាតការបម្រុងទុកចាស់ៗ
Dockerfileimage ម៉ាស៊ីនមេ (build → JRE 21, uid 1000)
voice/gateway សំឡេង pabal-voice (កូដប្រភព · Dockerfile · README.md · លក្ខណៈបច្ចេកទេសតំណ PROTOCOL.md)
deploy/docker-compose.mcp.ymlcontainer បីនៃសមាសភាគ MCP សម្រាប់បូតសំឡេង (profile mcp)
deploy/docker-compose.voice.ymlបន្ថែមសមាសភាគបូតសំឡេង — ការកំណត់សំឡេងរបស់ម៉ាស៊ីនមេ និងបណ្តាញតំណ · gateway pabal-voice (profile voice) · ច្រកចូលសំឡេងរបស់នាឡិកា pabal-voice-edge (profile voice-watch)
deploy/ship.shបង្កើត image ម៉ាស៊ីនមេ (ជាមួយ --voice ក៏ image gateway ដែរ) សម្រាប់ CPU របស់ម៉ាស៊ីនមេនៅលើកុំព្យូទ័រផ្សេង ផ្ទុកតាម SSH ហើយចម្លងឯកសារដាក់ឲ្យដំណើរការ
deploy/voice_readiness.pyការពិនិត្យមុនពេលបើកសំឡេង (សោ Vertex · ផ្នែកច្បាប់ · build កម្មវិធី · ការបញ្ជូនបន្ត …) — មិនបង្ហាញសម្ងាត់ណាមួយទេ
deploy/turnserver.conf.example, deploy/check_relay.pyគំរូការកំណត់ coturn ដែលដំឡើងផ្ទាល់លើម៉ាស៊ីនមេ Mac និងឧបករណ៍ពិនិត្យការបញ្ជូនបន្ត