เจจเฉเฉฑเจเจตเจฐเจ 'เจคเฉ IP-PBX Asterisk เจ
เจคเฉ CRM Bitrix24 เจจเฉเฉฐ เจเจเฉเจเฉเจฐเจฟเจค เจเจฐเจจ เจฒเจ เจตเฉฑเจ-เจตเฉฑเจ เจตเจฟเจเจฒเจช เจนเจจ, เจชเจฐ เจ
เจธเฉเจ เจซเจฟเจฐ เจตเฉ เจเจชเจฃเจพ เจฒเจฟเจเจฃ เจฆเจพ เจซเฉเจธเจฒเจพ เจเฉเจคเจพ เจนเฉเฅค
เจเจพเจฐเจเจธเจผเฉเจฒเจคเจพ เจฆเฉ เจฎเจพเจฎเจฒเฉ เจตเจฟเฉฑเจ, เจนเจฐ เจเฉเจเจผ เจฎเจฟเจเจฐเฉ เจนเฉ:
- Bitrix24 เจตเจฟเฉฑเจ เจเฉฑเจ เจเจฒเจพเจเฉฐเจ เจฆเฉ เจซเจผเฉเจจ เจจเฉฐเจฌเจฐ เจฆเฉ เจจเจพเจฒ เจเฉฑเจ เจฒเจฟเฉฐเจ 'เจคเฉ เจเจฒเจฟเฉฑเจ เจเจฐเจจ เจฆเฉเจเจฐเจพ, Asterisk เจเจชเจญเฉเจเจคเจพ เจฆเฉ เจ เฉฐเจฆเจฐเฉเจจเฉ เจจเฉฐเจฌเจฐ เจจเฉเฉฐ เจเฉเฉเจฆเจพ เจนเฉ เจเจฟเจธเจฆเฉ เจคเจฐเจซเจผเฉเจ เจเจฒเจพเจเฉฐเจ เจฆเฉ เจซเจผเฉเจจ เจจเฉฐเจฌเจฐ เจจเจพเจฒ เจเจฒเจฟเฉฑเจ เจเฉเจคเจพ เจเจฟเจ เจธเฉเฅค Bitrix24 เจตเจฟเฉฑเจ, เจเจพเจฒ เจฆเจพ เจเฉฑเจ เจฐเจฟเจเจพเจฐเจก เจฐเจฟเจเจพเจฐเจก เจเฉเจคเจพ เจเจพเจเจฆเจพ เจนเฉ เจ เจคเฉ เจเจพเจฒ เจฆเฉ เจ เฉฐเจค เจตเจฟเฉฑเจ, เจเฉฑเจฒเจฌเจพเจค เจฆเฉ เจเฉฑเจ เจฐเจฟเจเจพเจฐเจกเจฟเฉฐเจ เจเจฟเฉฑเจเฉ เจเจพเจเจฆเฉ เจนเฉเฅค
- Asterisk เจจเฉเฉฐ เจฌเจพเจนเจฐเฉเจ เจเฉฑเจ เจเจพเจฒ เจชเฉเจฐเจพเจชเจค เจนเฉเฉฐเจฆเฉ เจนเฉ - Bitrix24 เจเฉฐเจเจฐเจซเฉเจธ เจตเจฟเฉฑเจ เจ
เจธเฉเจ เจเจธ เจเจฐเจฎเจเจพเจฐเฉ เจจเฉเฉฐ เจเจฒเจพเจเฉฐเจ เจเจพเจฐเจก เจฆเจฟเจเจพเจเจเจฆเฉ เจนเจพเจ เจเจฟเจธ เจฆเฉ เจจเฉฐเจฌเจฐ 'เจคเฉ เจเจน เจเจพเจฒ เจเจ เจธเฉเฅค
เจเฉเจเจฐ เจ เจเจฟเจนเจพ เจเฉเจ เจเจพเจนเจ เจจเจนเฉเจ เจนเฉ, เจคเจพเจ เจ เจธเฉเจ เจจเจตเฉเจ เจฒเฉเจก เจฌเจฃเจพเจเจฃ เจฒเจ เจเจพเจฐเจก เจเฉเจฒเฉเจนเจพเจเจเฉเฅค
เจเจฟเจตเฉเจ เจนเฉ เจเจพเจฒ เจชเฉเจฐเฉ เจนเฉ เจเจพเจเจฆเฉ เจนเฉ, เจ เจธเฉเจ เจเจธเจจเฉเฉฐ เจเจพเจฐเจก 'เจคเฉ เจชเฉเจฐเจคเฉเจฌเจฟเฉฐเจฌเจค เจเจฐเจฆเฉ เจนเจพเจ เจ เจคเฉ เจเฉฑเจฒเจฌเจพเจค เจฆเฉ เจฐเจฟเจเจพเจฐเจกเจฟเฉฐเจ เจเจฟเฉฑเจ เจฒเฉเจเจฆเฉ เจนเจพเจเฅค
ะะพะด ะบะฐัะพะผ ัะฐััะบะฐะถั ะบะฐะบ ะฒัะต ะฝะฐัััะพะธัั ั ัะตะฑั ะธ ะดะฐะผ ะปะธะฝะบ ะฝะฐ github โ ะดะฐ-ะดะฐ, ะทะฐะฑะธัะฐะนัะต ะธ ะฟะพะปัะทัะนัะตัั!
เจเจฎ เจตเจฐเจฃเจจ
เจ เจธเฉเจ เจเจชเจฃเฉ เจเจเฉเจเจฐเจฃ เจจเฉเฉฐ CallMe เจเจนเจฟเฉฐเจฆเฉ เจนเจพเจเฅค CallMe PHP เจตเจฟเฉฑเจ เจฒเจฟเจเฉ เจเฉฑเจ เจเฉเจเฉ เจตเฉเฉฑเจฌ เจเจชเจฒเฉเจเฉเจธเจผเจจ เจนเฉเฅค
เจคเจเจจเจพเจฒเฉเจเฉเจเจ เจ เจคเฉ เจธเฉเจตเจพเจตเจพเจ เจตเจฐเจคเฉเจเจ เจเจพเจเจฆเฉเจเจ เจนเจจ
- PHP 5.6
PHP AMI เจฒเจพเจเจฌเฉเจฐเฉเจฐเฉ - เจเฉฐเจชเฉเจเจผเจฐ
- Nginx + php-fpm
- เจธเฉเจชเจฐเจตเจพเจเจเจผเจฐ
- AMI (Asterisk Manager Interface)
- เจฌเจฟเจเฉเจฐเจฟเจเจธ เจตเฉเจฌเจนเฉเฉฑเจ (เจธเจฐเจฒเฉเจเฉเจฐเจฟเจค REST API เจฒเจพเจเฉ เจเจฐเจจเจพ)
เจชเฉเจฐเฉ-เจธเฉเจเจฟเฉฐเจ
Asterisk เจตเจพเจฒเฉ เจธเจฐเจตเจฐ 'เจคเฉ, เจคเฉเจนเจพเจจเฉเฉฐ เจเฉฑเจ เจตเฉเฉฑเจฌ เจธเจฐเจตเจฐ (เจธเจพเจกเฉ เจฒเจ เจเจน nginx+php-fpm เจนเฉ), เจธเฉเจชเจฐเจตเจพเจเจเจผเจฐ เจ เจคเฉ git เจจเฉเฉฐ เจธเจฅเจพเจชเจค เจเจฐเจจ เจฆเฉ เจฒเฉเฉ เจนเฉเฅค
เจเฉฐเจธเจเจพเจฒเฉเจธเจผเจจ เจเจฎเจพเจเจก (CentOS):
yum install nginx php-fpm supervisor git
เจ เจธเฉเจ เจตเฉเจฌ เจธเจฐเจตเจฐ เจคเฉฑเจ เจชเจนเฉเฉฐเจเจฏเฉเจ เจกเจพเจเจฐเฉเจเจเจฐเฉ 'เจคเฉ เจเจพเจเจฆเฉ เจนเจพเจ, Git เจคเฉเจ เจเจชเจฒเฉเจเฉเจธเจผเจจ เจจเฉเฉฐ เจเจฟเฉฑเจเจฆเฉ เจนเจพเจ เจ เจคเฉ เจซเฉเจฒเจกเจฐ เจฒเจ เจฒเฉเฉเฉเจเจฆเฉ เจ เจงเจฟเจเจพเจฐ เจธเฉเจ เจเจฐเจฆเฉ เจนเจพเจ:
cd /var/www
git clone https://github.com/ViStepRU/callme.git
chown nginx. -R callme/
เจ เฉฑเจเฉ, เจเจ nginx เจฆเฉ เจธเฉฐเจฐเจเจจเจพ เจเจฐเฉเจ, เจธเจพเจกเฉ เจธเฉฐเจฐเจเจจเจพ เจตเจฟเฉฑเจ เจธเจฅเจฟเจค เจนเฉ
/etc/nginx/conf.d/pbx.vistep.ru.conf
server {
server_name www.pbx.vistep.ru pbx.vistep.ru;
listen *:80;
rewrite ^ https://pbx.vistep.ru$request_uri? permanent;
}
server {
# listen *:80;
# server_name pbx.vistep.ru;
access_log /var/log/nginx/pbx.vistep.ru.access.log main;
error_log /var/log/nginx/pbx.vistep.ru.error.log;
listen 443 ssl http2;
server_name pbx.vistep.ru;
resolver 8.8.8.8;
ssl_stapling on;
ssl on;
ssl_certificate /etc/letsencrypt/live/pbx.vistep.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pbx.vistep.ru/privkey.pem;
ssl_dhparam /etc/nginx/certs/dhparam.pem;
ssl_session_timeout 24h;
ssl_session_cache shared:SSL:2m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers kEECDH+AES128:kEECDH:kEDH:-3DES:kRSA+AES128:kEDH+3DES:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!MD5:!EXPORT:!LOW:!SEED:!CAMELLIA:!IDEA:!PSK:!SRP:!SSLv2;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000;";
add_header Content-Security-Policy-Report-Only "default-src https:; script-src https: 'unsafe-eval' 'unsafe-inline'; style-src https: 'unsafe-inline'; img-src https: data:; font-src https: data:; report-uri /csp-report";
root /var/www/callme;
index index.php;
location ~ /. {
deny all; # ะทะฐะฟัะตั ะดะปั ัะบััััั
ัะฐะนะปะพะฒ
}
location ~* /(?:uploads|files)/.*.php$ {
deny all; # ะทะฐะฟัะตั ะดะปั ะทะฐะณััะถะตะฝะฝัั
ัะบัะธะฟัะพะฒ
}
location ~* ^.+.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off;
log_not_found off;
expires max; # ะบะตัะธัะพะฒะฐะฝะธะต ััะฐัะธะบะธ
}
location ~ .php {
root /var/www/callme;
index index.php;
fastcgi_pass unix:/run/php/php5.6-fpm.sock;
# fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
}
เจฎเฉเจ เจธเฉฐเจฐเจเจจเจพ, เจธเฉเจฐเฉฑเจเจฟเจ เจฎเฉเฉฑเจฆเจฟเจเจ เจจเฉเฉฐ เจชเจพเจฐเจธ เจเจฐเจจ, เจเฉฑเจ เจธเจฐเจเฉเจซเจฟเจเฉเจ เจชเฉเจฐเจพเจชเจค เจเจฐเจจ เจ เจคเฉ เจฒเฉเจ เจฆเฉ เจฆเจพเจเจฐเฉ เจคเฉเจ เจฌเจพเจนเจฐ เจเฉฑเจ เจตเฉเจฌ เจธเจฐเจตเจฐ เจฆเฉ เจเฉเจฃ เจเจฐเจจ เจจเฉเฉฐ เจเฉฑเจก เจฆเจฟเจเจเจเจพ - เจเจธ เจฌเจพเจฐเฉ เจฌเจนเฉเจค เจเฉเจ เจฒเจฟเจเจฟเจ เจเจฟเจ เจนเฉ. เจเจชเจฒเฉเจเฉเจธเจผเจจ เจตเจฟเฉฑเจ เจเฉเจ เจชเจพเจฌเฉฐเจฆเฉเจเจ เจจเจนเฉเจ เจนเจจ, เจเจน http เจ เจคเฉ https เจฆเฉเจตเจพเจ 'เจคเฉ เจเฉฐเจฎ เจเจฐเจฆเจพ เจนเฉเฅค
เจ เจธเฉเจ https เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐเจฆเฉ เจนเจพเจ, เจเจ เจชเฉเจฐเจฎเจพเจฃ เจชเฉฑเจคเจฐ เจจเฉเฉฐ เจเจจเจเฉเจฐเจฟเจชเจ เจเจฐเจฆเฉ เจนเจพเจเฅค
เจเฉเจเจฐ เจคเฉเจธเฉเจ เจธเจญ เจเฉเจ เจธเจนเฉ เจขเฉฐเจ เจจเจพเจฒ เจเฉเจคเจพ เจนเฉ, เจคเจพเจ เจฒเจฟเฉฐเจ 'เจคเฉ เจเจฒเจฟเฉฑเจ เจเจฐเจเฉ เจคเฉเจนเจพเจจเฉเฉฐ เจ เจเจฟเจนเจพ เจเฉเจ เจฆเฉเจเจฃเจพ เจเจพเจนเฉเจฆเจพ เจนเฉ
Bitrix24 เจธเฉเจ เจ เจช เจเจฐ เจฐเจฟเจนเจพ เจนเฉ
เจเจ เจฆเฉ เจตเฉเจฌเจนเฉเฉฑเจ เจฌเจฃเจพเจเจเจฆเฉ เจนเจพเจเฅค
เจเจเจฃ เจตเจพเจฒเจพ เจตเฉเจฌเจนเฉเฉฑเจเฅค
เจชเฉเจฐเจธเจผเจพเจธเจ เจเจพเจคเฉ เจฆเฉ เจ เจงเฉเจจ (เจเจเจกเฉ 1 เจฆเฉ เจจเจพเจฒ), เจฎเจพเจฐเจ เจฆเฉ เจชเจพเจฒเจฃเจพ เจเจฐเฉ: เจเจชเจฒเฉเจเฉเจธเจผเจจ -> เจตเฉเจฌเจนเฉเฉฑเจ -> เจตเฉเจฌเจนเฉเฉฑเจ เจธเจผเจพเจฎเจฒ เจเจฐเฉ -> เจเจเจฃ เจตเจพเจฒเฉ เจตเฉเจฌเจนเฉเฉฑเจ
เจเจเจฃ เจตเจพเจฒเฉ เจตเฉเจฌเจนเฉเฉฑเจ เจฆเฉ เจชเฉเจฐเจพเจฎเฉเจเจฐเจพเจ เจจเฉเฉฐ เจญเจฐเฉ เจเจฟเจตเฉเจ เจเจฟ เจธเจเฉเจฐเฉเจจเจธเจผเฉเจเจธ เจตเจฟเฉฑเจ เจนเฉ:
เจ
เจคเฉ เจธเฉเจต 'เจคเฉ เจเจฒเจฟเฉฑเจ เจเจฐเฉเฅค
เจธเฉเจต เจเจฐเจจ เจคเฉเจ เจฌเจพเจ เจฆ, Bitrix24 เจเจเจฃ เจตเจพเจฒเฉ เจตเฉเจฌเจนเฉเฉฑเจ เจฆเจพ URL เจชเฉเจฐเจฆเจพเจจ เจเจฐเฉเจเจพ, เจเจฆเจพเจนเจฐเจจ เจฒเจ:
URL เจฆเฉ เจเจชเจฃเฉ เจธเฉฐเจธเจเจฐเจฃ เจจเฉเฉฐ เจ
เฉฐเจคเจฟเจฎ /profile/ เจคเฉเจ เจฌเจฟเจจเจพเจ เจธเฉเจฐเฉฑเจเจฟเจ
เจค เจเจฐเฉ - เจเจธเจฆเฉ เจตเจฐเจคเฉเจ เจเจเจฃ เจตเจพเจฒเฉเจเจ เจเจพเจฒเจพเจ เจจเจพเจฒ เจเฉฐเจฎ เจเจฐเจจ เจฒเจ เจเจชเจฒเฉเจเฉเจธเจผเจจ เจตเจฟเฉฑเจ เจเฉเจคเฉ เจเจพเจตเฉเจเฉเฅค
เจฎเฉเจฐเฉ เจเฉเจฒ เจเจน เจนเฉ https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/
ะัั ะพะดััะธะน ะฒะตะฑั ัะบ.
เจเจชเจฒเฉเจเฉเจธเจผเจจ -> เจตเฉเจฌเจนเฉเฉฑเจ -> เจตเฉเจฌเจนเฉเฉฑเจ เจธเจผเจพเจฎเจฒ เจเจฐเฉ -> เจเจเจเจเฉเจเฉฐเจ เจตเฉเจฌเจนเฉเฉฑเจ
เจตเฉเจฐเจตเฉ เจฆเฉเจฌเจพเจฐเจพ เจธเจเฉเจฐเฉเจจเจธเจผเจพเจ 'เจคเฉ เจนเจจ:
เจ
เจงเจฟเจเจพเจฐ เจเฉเจก เจจเฉเฉฐ เจธเฉเจฐเฉฑเจเจฟเจ
เจค เจเจฐเฉ เจ
เจคเฉ เจชเฉเจฐเจพเจชเจค เจเจฐเฉ
เจฎเฉเจฐเฉ เจเฉเจฒ เจเจน เจนเฉ xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6
. เจคเฉเจนเจพเจจเฉเฉฐ เจเจธเจจเฉเฉฐ เจเจชเจฃเฉ เจฒเจ เจเจพเจชเฉ เจเจฐเจจ เจฆเฉ เจตเฉ เจฒเฉเฉ เจนเฉ; เจคเฉเจนเจพเจจเฉเฉฐ เจเจเจเจเฉเจเฉฐเจ เจเจพเจฒเจพเจ เจเจฐเจจ เจฒเจ เจเจธเจฆเฉ เจฒเฉเฉ เจนเฉเฅค
เจฎเจนเฉฑเจคเจตเจชเฉเจฐเจจ!
เจเฉฑเจ SSL เจธเจฐเจเฉเจซเจฟเจเฉเจ เจจเฉเฉฐ Bitrix24 เจธเจฐเจตเจฐ เจเฉฑเจคเฉ เจเฉเจเจซเจฟเจเจฐ เจเฉเจคเจพ เจเจพเจฃเจพ เจเจพเจนเฉเจฆเจพ เจนเฉ (เจคเฉเจธเฉเจ letsencrypt เจฆเฉ เจตเจฐเจคเฉเจ เจเจฐ เจธเจเจฆเฉ เจนเฉ), เจจเจนเฉเจ เจคเจพเจ Bitrix api เจเฉฐเจฎ เจจเจนเฉเจ เจเจฐเฉเจเฉเฅค เจเฉ เจคเฉเจนเจพเจกเฉ เจเฉเจฒ เจเจฒเจพเจเจก เจธเฉฐเจธเจเจฐเจฃ เจนเฉ, เจคเจพเจ เจเจฟเฉฐเจคเจพ เจจเจพ เจเจฐเฉ - เจเจธ เจตเจฟเฉฑเจ เจชเจนเจฟเจฒเจพเจ เจนเฉ ssl เจนเฉ.
เจฎเจนเฉฑเจคเจตเจชเฉเจฐเจจ!
"เจชเฉเจฐเฉเจธเฉเจธเจฐ เจเจกเจฐเฉเฉฑเจธ" เจซเฉเจฒเจก เจตเจฟเฉฑเจ เจเฉฐเจเจฐเจจเฉเจ เจคเฉเจ เจชเจนเฉเฉฐเจเจฏเฉเจ เจชเจคเจพ เจนเฉเจฃเจพ เจเจพเจนเฉเจฆเจพ เจนเฉ!
เจ เจคเฉ เจเฉฑเจ เจ เฉฐเจคเจฎ เจเฉเจน เจฆเฉ เจคเฉเจฐ 'เจคเฉ, เจเจ เจเจพเจฒ เจเจฐเจจ เจฒเจ เจเฉฑเจ เจเจชเจฒเฉเจเฉเจธเจผเจจ เจฆเฉ เจคเฉเจฐ 'เจคเฉ เจธเจพเจกเฉ CallMeOut เจจเฉเฉฐ เจธเจฅเจพเจชเจฟเจค เจเจฐเฉเจ (เจคเจพเจ เจเจฟ เจเจฆเฉเจ เจคเฉเจธเฉเจ PBX 'เจคเฉ เจจเฉฐเจฌเจฐ 'เจคเฉ เจเจฒเจฟเฉฑเจ เจเจฐเฉเจเฉ, เจคเจพเจ เจเจพเจฒ เจธเจผเฉเจฐเฉ เจเจฐเจจ เจฆเฉ เจเจฎเจพเจเจก เจเฉฑเจก เจเจพเจตเฉเจเฉ)เฅค
เจฎเฉเจจเฉ เจตเจฟเฉฑเจ, เจเฉเจฃเฉ: เจนเฉเจฐ -> เจเฉเจฒเฉเจซเฉเจจเฉ -> เจนเฉเจฐ -> เจธเฉเจเจฟเฉฐเจเจพเจ, "เจกเจฟเจซเจพเจฒเจ เจเจเจเจเฉเจเฉฐเจ เจเจพเจฒ เจจเฉฐเจฌเจฐ" เจเจชเจฒเฉเจเฉเจธเจผเจจ เจตเจฟเฉฑเจ เจธเฉเฉฑเจ เจเจฐเฉ: CallMeOut เจ เจคเฉ "เจธเฉเจต" 'เจคเฉ เจเจฒเจฟเฉฑเจ เจเจฐเฉเฅค
เจคเจพเจฐเจพ เจฆเจพ เจธเฉเฉฑเจเจ เฉฑเจช เจเฉเจคเจพ เจเจพ เจฐเจฟเจนเจพ เจนเฉ
ะะปั ััะฟะตัะฝะพะณะพ ะฒะทะฐะธะผะพะดะตะนััะฒะธั Asterisk ะธ Bitrix24 ะฝะฐะผ ะฝัะถะฝะพ ะดะพะฑะฐะฒะธัั AMI-ะฟะพะปัะทะพะฒะฐัะตะปั callme ะฒ manager.conf:
[callme]
secret = JD3clEB8_f23r-3ry84gJ
deny = 0.0.0.0/0.0.0.0
permit = 127.0.0.1/255.255.255.0
permit= 10.100.111.249/255.255.255.255
permit = 192.168.254.0/255.255.255.0
read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan
write = system,call,agent,log,verbose,user,config,command,reporting,originate
เจ เฉฑเจเฉ, เจเฉฑเจฅเฉ เจฌเจนเฉเจค เจธเจพเจฐเฉเจเจ เจเจพเจฒเจพเจ เจนเจจ เจเจฟเจจเฉเจนเจพเจ เจจเฉเฉฐ เจกเจพเจเจฒเจชเจฒเจพเจจ เจฆเฉเจเจฐเจพ เจฒเจพเจเฉ เจเจฐเจจ เจฆเฉ เจฒเฉเฉ เจนเฉเจตเฉเจเฉ (เจธเจพเจกเฉ เจฒเจ เจเจน extensions.ael เจนเฉ)เฅค
เจฎเฉเจ เจชเฉเจฐเฉ เจซเจพเจเจฒ เจชเฉเจฐเจฆเจพเจจ เจเจฐเจพเจเจเจพ, เจ เจคเฉ เจซเจฟเจฐ เจฎเฉเจ เจเฉฑเจ เจธเจชเฉฑเจธเจผเจเฉเจเจฐเจจ เจฆเฉเจตเจพเจเจเจพ:
globals {
WAV=/var/www/pbx.vistep.ru/callme/records/wav; //ะัะตะผะตะฝะฝัะน ะบะฐัะฐะปะพะณ ั WAV
MP3=/var/www/pbx.vistep.ru/callme/records/mp3; //ะัะดะฐ ะฒัะณััะถะฐัั mp3 ัะฐะนะปั
URLRECORDS=https://pbx.vistep.ru/callme/records/mp3;
RECORDING=1; // ะะฐะฟะธัั, 1 - ะฒะบะปััะตะฝะฐ.
};
macro recording(calling,called) {
if ("${RECORDING}" = "1"){
Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${calling}-${called});
Set(datedir=${STRFTIME(${EPOCH},,%Y/%m/%d)});
System(mkdir -p ${MP3}/${datedir});
System(mkdir -p ${WAV}/${datedir});
Set(monopt=nice -n 19 /usr/bin/lame -b 32 --silent "${WAV}/${datedir}/${fname}.wav" "${MP3}/${datedir}/${fname}.mp3" && rm -f "${WAV}/${fname}.wav" && chmod o+r "${MP3}/${datedir}/${fname}.mp3");
Set(FullFname=${URLRECORDS}/${datedir}/${fname}.mp3);
Set(CDR(filename)=${fname}.mp3);
Set(CDR(recordingfile)=${fname}.wav);
Set(CDR(realdst)=${called});
MixMonitor(${WAV}/${datedir}/${fname}.wav,b,${monopt});
};
};
context incoming {
888999 => {
&recording(${CALLERID(number)},${EXTEN});
Answer();
ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp()); // ะฒัััะฐะฒะปัะตะผ CallerID ะตัะปะธ ัะทะฝะฐะปะธ ะตะณะพ ั ะะธััะธะบั24
Set(CallStart=${STRFTIME(epoch,,%s)});
Queue(Q1,tT);
Set(CallMeDISPOSITION=${CDR(disposition)});
Hangup();
}
h => {
Set(CDR_PROP(disable)=true);
Set(CallStop=${STRFTIME(epoch,,%s)});
Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)});
ExecIF(${ISNULL(${CallMeDISPOSITION})}?Set(CallMeDISPOSITION=${CDR(disposition)}):NoOP(=== CallMeDISPOSITION already was set ===));
}
}
context default {
_X. => {
Hangup();
}
};
context dial_out {
_[1237]XX => {
&recording(${CALLERID(number)},${EXTEN});
Set(__CallIntNum=${CALLERID(num)})
Set(CallStart=${STRFTIME(epoch,,%s)});
Dial(SIP/${EXTEN},,tTr);
Hangup();
}
_11XXX => {
&recording(${CALLERID(number)},${EXTEN});
Set(CallStart=${STRFTIME(epoch,,%s)});
Set(__CallIntNum=${CALLERID(num)});
Dial(SIP/${EXTEN:2}@toOurAster,,t);
Hangup();
}
_. => {
&recording(${CALLERID(number)},${EXTEN});
Set(__CallIntNum=${CALLERID(num)})
Set(CallStart=${STRFTIME(epoch,,%s)});
Dial(SIP/${EXTEN}@toOurAster,,t);
Hangup();
}
h => {
Set(CDR_PROP(disable)=true);
Set(CallStop=${STRFTIME(epoch,,%s)});
Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)});
if(${ISNULL(${CallMeDISPOSITION})}) {
Set(CallMeDISPOSITION=${CDR(disposition)});
}
System(curl -s http://pbx.vistep.ru/CallMeOut.php --data action=sendcall2b24 --data call_id=${CallMeCALL_ID} --data-urlencode FullFname=${FullFname} --data CallIntNum=${CallIntNum} --data CallDuration=${CallMeDURATION} --data-urlencode CallDisposition=${CallMeDISPOSITION});
}
};
เจเจ เจธเจผเฉเจฐเฉ เจคเฉเจ เจธเจผเฉเจฐเฉ เจเจฐเฉเจ: เจจเจฟเจฐเจฆเฉเจธเจผ เจเจฒเฉเจฌเจฒ.
เจชเจฐเจฟเจตเจฐเจคเจจเจธเจผเฉเจฒ URLRECORDS URL เจจเฉเฉฐ เจเฉฑเจฒเจฌเจพเจค เจฐเจฟเจเจพเจฐเจกเจฟเฉฐเจ เจซเจพเจเจฒเจพเจ เจตเจฟเฉฑเจ เจธเจเฉเจฐ เจเจฐเจฆเจพ เจนเฉ, เจเจฟเจธเจฆเฉ เจ เจจเฉเจธเจพเจฐ Bitrix24 เจเจนเจจเจพเจ เจจเฉเฉฐ เจธเฉฐเจชเจฐเจ เจเจพเจฐเจก เจตเจฟเฉฑเจ เจเจฟเฉฑเจเฉเจเจพเฅค
เจ เฉฑเจเฉ เจ เจธเฉเจ เจฎเฉเจเจฐเฉ เจฎเฉเจเจฐเฉ เจตเจฟเฉฑเจ เจฆเจฟเจฒเจเจธเจชเฉ เจฐเฉฑเจเจฆเฉ เจนเจพเจ เจฐเจฟเจเจพเจฐเจกเจฟเฉฐเจ.
เจเฉฑเจฅเฉ, เจเฉฑเจฒเจฌเจพเจค เจจเฉเฉฐ เจฐเจฟเจเจพเจฐเจก เจเจฐเจจ เจคเฉเจ เจเจฒเจพเจตเจพ, เจ เจธเฉเจ เจตเฉเจฐเฉเจเจฌเจฒ เจธเฉเฉฑเจ เจเจฐเจพเจเจเฉ เจชเฉเจฐเจพ เจจเจพเจฎ.
Set(FullFname=${URLRECORDS}/${datedir}/${fname}.mp3);
เจเจน เจชเฉเจฐเฉ URL เจจเฉเฉฐ เจเฉฑเจ เจเจพเจธ เจซเจพเจเจฒ เจตเจฟเฉฑเจ เจธเจเฉเจฐ เจเจฐเจฆเจพ เจนเฉ (เจฎเฉเจเจฐเฉ เจจเฉเฉฐ เจนเจฐ เจฅเจพเจ เจเจฟเจนเจพ เจเจพเจเจฆเจพ เจนเฉ)เฅค
เจเจ เจเจเจเจเฉเจเฉฐเจ เจเจพเจฒ เจฆเจพ เจตเจฟเจธเจผเจฒเฉเจธเจผเจฃ เจเจฐเฉเจ:
_. => {
&recording(${CALLERID(number)},${EXTEN});
Set(__CallIntNum=${CALLERID(num)})
Set(CallStart=${STRFTIME(epoch,,%s)});
Dial(SIP/${EXTEN}@toOurAster,,t);
Hangup();
}
h => {
Set(CDR_PROP(disable)=true);
Set(CallStop=${STRFTIME(epoch,,%s)});
Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)});
if(${ISNULL(${CallMeDISPOSITION})}) {
Set(CallMeDISPOSITION=${CDR(disposition)});
}
System(curl -s http://pbx.vistep.ru/CallMeOut.php --data action=sendcall2b24 --data call_id=${CallMeCALL_ID} --data-urlencode FullFname=${FullFname} --data CallIntNum=${CallIntNum} --data CallDuration=${CallMeDURATION} --data-urlencode CallDisposition=${CallMeDISPOSITION});
}
เจฎเฉฐเจจ เจฒเจ เจเจฟ เจ เจธเฉเจ 89991234567 'เจคเฉ เจเจพเจฒ เจเจฐเจฆเฉ เจนเจพเจ, เจธเจญ เจคเฉเจ เจชเจนเจฟเจฒเจพเจ เจ เจธเฉเจ เจเฉฑเจฅเฉ เจชเฉเจฐเจพเจชเจค เจเจฐเจฆเฉ เจนเจพเจ:
&recording(${CALLERID(number)},${EXTEN});
เจเจน. เจเฉฑเจฒเจฌเจพเจค เจฐเจฟเจเจพเจฐเจกเจฟเฉฐเจ เจฎเฉเจเจฐเฉ เจจเฉเฉฐ เจฌเฉเจฒเจพเจเจ เจเจพเจเจฆเจพ เจนเฉ เจ เจคเฉ เจฒเฉเฉเฉเจเจฆเฉ เจตเฉเจฐเฉเจเจฌเจฒ เจธเฉเฉฑเจ เจเฉเจคเฉ เจเจพเจเจฆเฉ เจนเจจเฅค
เจนเฉเจฐ เจ เฉฑเจเฉ
Set(__CallIntNum=${CALLERID(num)})
Set(CallStart=${STRFTIME(epoch,,%s)});
เจ เจธเฉเจ เจฐเจฟเจเจพเจฐเจก เจเจฐเจฆเฉ เจนเจพเจ เจเจฟ เจเจพเจฒ เจเจฟเจธ เจจเฉ เจธเจผเฉเจฐเฉ เจเฉเจคเฉ เจ เจคเฉ เจเจพเจฒ เจธเจผเฉเจฐเฉ เจนเฉเจฃ เจฆเจพ เจธเจฎเจพเจ เจฐเจฟเจเจพเจฐเจก เจเฉเจคเจพเฅค
เจ เจคเฉ เจเจธเจฆเฉ เจชเฉเจฐเจพ เจนเฉเจฃ 'เจคเฉ, เจเฉฑเจ เจตเจฟเจธเจผเฉเจธเจผ เจธเฉฐเจฆเจฐเจญ เจตเจฟเฉฑเจ h
h => {
Set(CDR_PROP(disable)=true);
Set(CallStop=${STRFTIME(epoch,,%s)});
Set(CallMeDURATION=${MATH(${CallStop}-${CallStart},int)});
if(${ISNULL(${CallMeDISPOSITION})}) {
Set(CallMeDISPOSITION=${CDR(disposition)});
}
System(curl -s http://pbx.vistep.ru/CallMeOut.php --data action=sendcall2b24 --data call_id=${CallMeCALL_ID} --data-urlencode FullFname=${FullFname} --data CallIntNum=${CallIntNum} --data CallDuration=${CallMeDURATION} --data-urlencode CallDisposition=${CallMeDISPOSITION});
}
เจเจธ เจเจเจธเจเฉเจเจธเจผเจจ เจฒเจ เจธเฉเจกเฉเจเจฐ เจเฉเจฌเจฒ เจตเจฟเฉฑเจ เจเจเจเจฐเฉ เจจเฉเฉฐ เจ เจธเจฎเจฐเฉฑเจฅ เจเจฐเฉ (เจเฉฑเจฅเฉ เจเจธเจฆเฉ เจฒเฉเฉ เจจเจนเฉเจ เจนเฉ), เจเจพเจฒ เจฆเจพ เจ เฉฐเจค เจธเจฎเจพเจ เจธเฉเฉฑเจ เจเจฐเฉ, เจฎเจฟเจเจฆ เจฆเฉ เจเจฃเจจเจพ เจเจฐเฉ, เจเฉเจเจฐ เจเจพเจฒ เจฆเจพ เจจเจคเฉเจเจพ เจชเจคเจพ เจจเจนเฉเจ เจนเฉ - เจธเฉเฉฑเจ (เจตเฉเจฐเฉเจเจฌเจฒ) CallMeDISPOSITION) เจ เจคเฉ, เจเจเจฐเฉ เจชเฉเจพเจ , เจธเจฟเจธเจเจฎ เจเจฐเจฒ เจฐเจพเจนเฉเจ เจฌเจฟเจเจฐเจฟเจเจธ เจจเฉเฉฐ เจธเจญ เจเฉเจ เจญเฉเจเฉเฅค
เจ เจคเฉ เจฅเฉเฉเจพ เจนเฉเจฐ เจเจพเจฆเฉ - เจเฉฑเจ เจเจเจฃ เจตเจพเจฒเฉ เจเจพเจฒ:
888999 => {
&recording(${CALLERID(number)},${EXTEN});
Answer();
ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp()); // ะฒัััะฐะฒะปัะตะผ CallerID ะตัะปะธ ัะทะฝะฐะปะธ ะตะณะพ ั ะะธััะธะบั24
Set(CallStart=${STRFTIME(epoch,,%s)}); // ะฝะฐัะธะฝะฐะตะผ ะพัััะตั ะฒัะตะผะตะฝะธ ะทะฒะพะฝะบะฐ
Queue(Q1,tT);
Set(CallMeDISPOSITION=${CDR(disposition)});
Hangup();
}
เจเฉฑเจฅเฉ เจ เจธเฉเจ เจธเจฟเจฐเจซ เจเฉฑเจ เจฒเจพเจเจจ เจตเจฟเฉฑเจ เจฆเจฟเจฒเจเจธเจชเฉ เจฐเฉฑเจเจฆเฉ เจนเจพเจ.
ExecIF(${CallMeCallerIDName}?Set(CALLERID(name)=${CallMeCallerIDName}):NoOp());
เจเจน PBX เจจเฉเฉฐ เจเฉฐเจธเจเจพเจฒ เจเจฐเจจ เจฒเจ เจเจนเจฟเฉฐเจฆเฉ เจนเฉ เจเจพเจฒเจฐเจเจเจกเฉ(เจจเจพเจฎ) เจตเฉเจฐเฉเจเจฌเจฒ เจฆเฉ เจฌเจฐเจพเจฌเจฐ CallMeCallerIDName.
CallMeCallerIDName เจตเฉเจฐเฉเจเจฌเจฒ, เจฌเจฆเจฒเฉ เจตเจฟเฉฑเจ, CallMe เจเจชเจฒเฉเจเฉเจธเจผเจจ เจฆเฉเจเจฐเจพ เจธเฉเฉฑเจ เจเฉเจคเจพ เจเจพเจเจฆเจพ เจนเฉ (เจเฉเจเจฐ Bitrix24 เจเฉเจฒ เจเจพเจฒเจฐ เจฆเฉ เจจเฉฐเจฌเจฐ เจฒเจ เจชเฉเจฐเจพ เจจเจพเจฎ เจนเฉ, เจคเจพเจ เจเจธเจจเฉเฉฐ เจเจธ เจคเจฐเฉเจนเจพเจ เจธเฉเฉฑเจ เจเจฐเฉ เจเจพเจฒเจฐเจเจเจกเฉ(เจจเจพเจฎ), ะฝะตั โ ะฝะธัะตะณะพ ะฝะต ะฑัะดะตะผ ะดะตะปะฐัั).
เจเจชเจฒเฉเจเฉเจธเจผเจจ เจฆเฉ เจธเจฅเจพเจชเจจเจพ เจเฉเจคเฉ เจเจพ เจฐเจนเฉ เจนเฉ
เจเจชเจฒเฉเจเฉเจธเจผเจจ เจธเฉเจเจฟเฉฐเจเจเจผ เจซเจพเจเจฒ - /var/www/pbx.vistep.ru/config.php
เจเจชเจฒเฉเจเฉเจธเจผเจจ เจชเฉเจฐเจพเจฎเฉเจเจฐเจพเจ เจฆเจพ เจตเฉเจฐเจตเจพ:
- เจเจพเจฒMeDEBUG โ เจเฉเจเจฐ 1, เจคเจพเจ เจเจชเจฒเฉเจเฉเจธเจผเจจ เจฆเฉเจเจฐเจพ เจธเฉฐเจธเจพเจงเจฟเจค เจธเจพเจฐเฉเจเจ เจเจเจจเจพเจตเจพเจ เจจเฉเฉฐ เจฒเฉเจ เจซเจพเจเจฒ เจตเจฟเฉฑเจ เจฒเจฟเจเจฟเจ เจเจพเจตเฉเจเจพ, 0 โ เจ เจธเฉเจ เจเฉเจ เจจเจนเฉเจ เจฒเจฟเจเจฆเฉ
- เจคเจเจจเฉเจเฉ โ SIP/PJSIP/IAX/etc
- authToken - Bitrix24 เจชเฉเจฐเจฎเจพเจฃเจฟเจเจคเจพ เจเฉเจเจจ, เจเจเจเจเฉเจเฉฐเจ เจตเฉเจฌเจนเฉเฉฑเจ เจชเฉเจฐเจฎเจพเจฃเฉเจเจฐเจจ เจเฉเจก
- bitrixApiUrl - เจเจเจฃ เจตเจพเจฒเฉ เจตเฉเจฌเจนเฉเฉฑเจ เจฆเจพ URL, เจฌเจฟเจจเจพเจ เจชเฉเจฐเฉเจซเจพเจเจฒ/
- เจเจเจธเจเฉเจเจธเจผเจจเจพเจ - เจฌเจพเจนเจฐเฉ เจธเฉฐเจเจฟเจเจตเจพเจ เจฆเฉ เจธเฉเจเฉ
- เจชเฉเจฐเจธเฉฐเจ - เจเฉฑเจ เจเจพเจฒ เจธเจผเฉเจฐเฉ เจเจฐเจจ เจฒเจ เจธเฉฐเจฆเจฐเจญ
- listener_timeout - เจคเจพเจฐเฉ เจคเฉเจ เจเจตเฉเจเจ เจชเฉเจฐเฉเจธเฉเจธเจฟเฉฐเจ เจฆเฉ เจเจคเฉ
- เจคเจพเจฐเฉ - เจคเจพเจฐเฉ เจจเจพเจฒ เจเฉเฉเจจ เจฒเจ เจธเฉเจเจฟเฉฐเจเจพเจ เจตเจพเจฒเฉ เจเฉฑเจ เจเจฐเฉ:
- เจนเฉเจธเจ - เจคเจพเจฐเจพ เจธเจฐเจตเจฐ เจฆเจพ ip เจเจพเจ เจฎเฉเจเจผเจฌเจพเจจ เจจเจพเจ
- เจธเจเฉเจฎ - เจเฉเจจเฉเจเจธเจผเจจ เจเจฟเฉฑเจคเจฐ (tcp://, tls://)
- เจชเฉเจฐเจ - เจชเฉเจฐเจ
- เจเจชเจญเฉเจเฉ - เจเจชเจญเฉเจเจคเจพ เจจเจพเจฎ
- เจเฉเจชเจค - เจชเจพเจธเจตเจฐเจก
- connect_timeout - เจเฉเจจเฉเจเจธเจผเจจ เจธเจฎเจพเจ เจธเจฎเจพเจชเจค
- read_timeout - เจธเจฎเจพเจ เจธเจฎเจพเจชเจค เจชเฉเฉเจนเฉ
เจเจฆเจพเจนเจฐเจจ เจธเฉเจเจฟเฉฐเจ เจซเจพเจเจฒ:
<?php
return array(
'CallMeDEBUG' => 1, // ะดะตะฑะฐะณ ัะพะพะฑัะตะฝะธั ะฒ ะปะพะณะต: 1 - ะฟะธัะตะผ, 0 - ะฝะต ะฟะธัะตะผ
'tech' => 'SIP',
'authToken' => 'xcrp2ylhzzd2v43cmfjqmkvrgrcbkni6', //ัะพะบะตะฝ ะฐะฒัะพัะธะทะฐัะธะธ ะฑะธััะธะบัะฐ
'bitrixApiUrl' => 'https://b24-xsynia.bitrix24.ru/rest/1/7eh61lh8pahw0fwt/', //url ะบ api ะฑะธััะธะบัะฐ (ะฒั
ะพะดััะธะน ะฒะตะฑั
ัะบ)
'extentions' => array('888999'), // ัะฟะธัะพะบ ะฒะฝะตัะฝะธั
ะฝะพะผะตัะพะฒ, ัะตัะตะท ะทะฐะฟัััั
'context' => 'dial_out', //ะธัั
ะพะดััะธะน ะบะพะฝัะตะบัั ะดะปั ะพัะธะณะธะฝะฐัะธะธ ะทะฒะพะฝะบะฐ
'asterisk' => array( // ะฝะฐัััะพะนะบะธ ะดะปั ะฟะพะดะบะปััะตะฝะธั ะบ ะฐััะตัะธัะบั
'host' => '10.100.111.249',
'scheme' => 'tcp://',
'port' => 5038,
'username' => 'callme',
'secret' => 'JD3clEB8_f23r-3ry84gJ',
'connect_timeout' => 10000,
'read_timeout' => 10000
),
'listener_timeout' => 300, //ัะบะพัะพััั ะพะฑัะฐะฑะพัะบะธ ัะพะฑััะธะน ะพั asterisk
);
เจธเฉเจชเจฐเจตเจพเจเจเจผเจฐ เจธเฉเฉฑเจเจ เฉฑเจช
เจธเฉเจชเจฐเจตเจพเจเจเจผเจฐ เจฆเฉ เจตเจฐเจคเฉเจ Asterisk CallMeIn.php เจคเฉเจ เจเจตเฉเจเจ เจนเฉเจเจกเจฒเจฐ เจชเฉเจฐเจเจฟเจฐเจฟเจ เจจเฉเฉฐ เจธเจผเฉเจฐเฉ เจเจฐเจจ เจฒเจ เจเฉเจคเฉ เจเจพเจเจฆเฉ เจนเฉ, เจเฉ เจเจเจฃ เจตเจพเจฒเฉเจเจ เจเจพเจฒเจพเจ เจฆเฉ เจจเจฟเจเจฐเจพเจจเฉ เจเจฐเจฆเฉ เจนเฉ เจ เจคเฉ Bitrix24 (เจธเจผเฉเจ เจเจพเจฐเจก, เจนเจพเจเจก เจเจพเจฐเจก, เจเจฆเจฟ) เจจเจพเจฒ เจเฉฐเจเจฐเฉเจเจ เจเจฐเจฆเฉ เจนเฉเฅค
เจฌเจฃเจพเจเจฃ เจฒเจ เจธเฉเจเจฟเฉฐเจเจพเจ เจซเจพเจเจฒ:
/etc/supervisord.d/callme.conf
[program:callme]
command=/usr/bin/php CallMeIn.php
directory=/var/www/pbx.vistep.ru
autostart=true
autorestart=true
startretries=5
stderr_logfile=/var/www/pbx.vistep.ru/logs/daemon.log
stdout_logfile=/var/www/pbx.vistep.ru/logs/daemon.log
ะะฐะฟััะบ ะธ ัะตััะฐัั ะฟัะธะปะพะถะตะฝะธั:
supervisorctl start callme
supervisorctl restart callme
เจเจชเจฒเฉเจเฉเจธเจผเจจ เจฆเฉ เจเจชเจฐเฉเจเจฟเฉฐเจ เจธเจฅเจฟเจคเฉ เจจเฉเฉฐ เจตเฉเจเจฃเจพ:
supervisorctl status callme
callme RUNNING pid 11729, uptime 17 days, 16:58:07
เจธเจฟเฉฑเจเจพ
เจเจน เจเจพเจซเจผเฉ เจเฉเฉฐเจเจฒเจฆเจพเจฐ เจธเจพเจฌเจค เจนเฉเจเจ, เจชเจฐ เจฎเฉเจจเฉเฉฐ เจฏเจเฉเจจ เจนเฉ เจเจฟ เจเฉฑเจ เจคเจเจฐเจฌเฉเจเจพเจฐ เจชเฉเจฐเจฌเฉฐเจงเจ เจเจธเจจเฉเฉฐ เจฒเจพเจเฉ เจเจฐเจจ เจ เจคเฉ เจเจธเจฆเฉ เจเจชเจญเฉเจเจคเจพเจตเจพเจ เจจเฉเฉฐ เจเฉเจธเจผ เจเจฐเจจ เจฆเฉ เจฏเฉเจ เจนเฉเจตเฉเจเจพ.
เจตเจพเจ
เจฆเฉ เจฎเฉเจคเจพเจฌเจ,
เจธเจตเจพเจฒ, เจธเฉเจเจพเจ
- เจเจฟเจฐเจชเจพ เจเจฐเจเฉ เจเจนเจจเจพเจ เจจเฉเฉฐ เจเจฟเฉฑเจชเจฃเฉเจเจ เจตเจฟเฉฑเจ เจเฉฑเจกเฉเฅค เจจเจพเจฒ เจนเฉ, เจเฉ เจคเฉเจธเฉเจ เจเจธ เจตเจฟเฉฑเจ เจฆเจฟเจฒเจเจธเจชเฉ เจฐเฉฑเจเจฆเฉ เจนเฉ เจเจฟ เจเจธ เจเจเฉเจเจฐเจฃ เจฆเจพ เจตเจฟเจเจพเจธ เจเจฟเจตเฉเจ เจนเฉเจเจ, เจคเจพเจ เจฒเจฟเจเฉ, เจ
เจคเฉ เจ
เจเจฒเฉ เจฒเฉเจ เจตเจฟเฉฑเจ เจฎเฉเจ เจนเจฐ เจเฉเจเจผ เจจเฉเฉฐ เจตเจงเฉเจฐเฉ เจตเจฟเจธเจฅเจพเจฐ เจตเจฟเฉฑเจ เจชเฉเจฐเจเจ เจเจฐเจจ เจฆเฉ เจเฉเจธเจผเจฟเจธเจผ เจเจฐเจพเจเจเจพ.
เจธเจฐเฉเจค: www.habr.com