1- <?php
1+ <?php
22/**
3- * Script retranslates queries to telegram bot API
3+ * Telegram API Proxy
4+ * -------------------
5+ * Acts as a middle layer between the client and Telegram Bot API.
6+ * Intercepts incoming HTTP requests and forwards them to the Telegram servers,
7+ * optionally logging request/response details for debugging or analytics.
48 */
9+
510class TelegramApiProxy {
6- private $ url ;
7- private $ ch ;
8- private $ log = false ;
9-
10- public function __construct (){
11- $ this ->getUrl ();
12- $ this ->initCurl ();
13- }
14-
15- public function setLog (bool $ log ){
16- $ this ->log = $ log ;
17- }
18-
19- private function log (string $ m ){
20- if (!$ this ->log ) return ;
21- file_put_contents ('proxy.log ' , $ m . PHP_EOL , FILE_APPEND );
22- }
23-
24- public function start (){
25- $ this ->log ('[ ' . date ('Y-m-d H:i:s ' ) . '] Query init. URL: ' . $ this ->url );
26- $ this ->sendRequest ();
27-
28- $ response = curl_exec ($ this ->ch );
29- $ debug = curl_getinfo ($ this ->ch );
30- $ this ->log ('Response headers: code= ' . $ debug ['http_code ' ] . '; content_type= ' . $ debug ['content_type ' ] . '; size_upload= ' . $ debug ['size_upload ' ] . '; size_download= ' . $ debug ['size_upload ' ] . '; ' );
31- $ this ->log ('Response body: ' . $ response );
32- $ this ->log (' ' );
33-
34- $ this ->sendResponse ($ response , $ debug ['content_type ' ], $ debug ['http_code ' ]);
35- }
36-
37- private function sendResponse (string $ response , string $ type , int $ code ){
38- header ('Content-type: ' . $ type , $ code );
39- die ($ response );
40- }
41-
42- public function getUrl (){
43- $ dir = dirname ($ _SERVER ['SCRIPT_NAME ' ]); // detect path to dir
44- if (strpos ($ _SERVER ['REQUEST_URI ' ], $ dir ) === 0 ){
45- $ uri = substr ($ _SERVER ['REQUEST_URI ' ], strlen ($ dir ));
46- } else {
47- $ uri = $ _SERVER ['REQUEST_URI ' ];
48- }
49-
50- if (substr ($ uri , 0 , 1 ) != '/ ' ){
51- $ uri = '/ ' . $ uri ;
52- }
53-
54- return $ this ->url = "https://api.telegram.org " . $ uri ;
55- }
56-
57- private function initCurl (){
58- $ this ->ch = curl_init ($ this ->url );
59- curl_setopt ($ this ->ch , CURLOPT_RETURNTRANSFER , true );
60- return $ this ->ch ;
61- }
62-
63- private function sendRequest (){
64- $ method = $ _SERVER ['REQUEST_METHOD ' ] ?? 'GET ' ;
65- $ method = 'GET ' ;
66-
67- $ this ->log ('HTTP Request: ' . $ method );
68-
69- $ this ->log ('HTTP Request2: ' . file_get_contents ('php://input ' ));
70-
71- if ($ method == 'POST ' || file_get_contents ('php://input ' )!='' || sizeof ($ _POST )>0 ){
72- curl_setopt ($ this ->ch , CURLOPT_POST , true );
73-
74- if (sizeof ($ _FILES ) > 0 ){
75- $ post = [];
76- foreach ($ _FILES as $ name => $ file ) {
77- $ post [$ name ] = new CURLFile ($ file ['tmp_name ' ], $ file ['type ' ], $ file ['name ' ]);
78- }
79-
80- foreach ($ _POST as $ name => $ value ) {
81- $ post [$ name ] = $ value ;
82- }
83-
84- } else {
85- $ post = file_get_contents ('php://input ' );
86- $ ct = $ _SERVER ['HTTP_CONTENT_TYPE ' ] ?? $ _SERVER ['CONTENT_TYPE ' ];
87- curl_setopt ($ this ->ch , CURLOPT_HTTPHEADER , ['Content-type: ' . $ ct ]);
88- }
89-
90- $ this ->log ('Send To Telegram HTTP Request body: ' . json_encode ($ post ,JSON_UNESCAPED_UNICODE ));
91- curl_setopt ($ this ->ch , CURLOPT_POSTFIELDS , $ post );
92- $ this ->log ('Send data: ' . var_export ($ post , true ));
93-
94- } else {
95- curl_setopt ($ this ->ch , CURLOPT_CUSTOMREQUEST , $ method );
96- }
97- }
11+ /** @var string Fully qualified API request URL */
12+ private $ url ;
13+
14+ /** @var resource cURL handler */
15+ private $ ch ;
16+
17+ /** @var bool Enable/disable request logging */
18+ private $ log = false ;
19+
20+ /**
21+ * Constructor:
22+ * - Detects target URL
23+ * - Initializes cURL session
24+ */
25+ public function __construct () {
26+ $ this ->getUrl ();
27+ $ this ->initCurl ();
28+ }
29+
30+ /**
31+ * Enable or disable logging.
32+ * @param bool $log
33+ */
34+ public function setLog (bool $ log ) {
35+ $ this ->log = $ log ;
36+ }
37+
38+ /**
39+ * Append message to log file if logging is enabled.
40+ * @param string $m
41+ */
42+ private function log (string $ m ) {
43+ if (!$ this ->log ) return ;
44+ file_put_contents ('proxy.log ' , $ m . PHP_EOL , FILE_APPEND );
45+ }
46+
47+ /**
48+ * Main request handler:
49+ * - Logs initialization
50+ * - Prepares and sends the request
51+ * - Handles the response
52+ */
53+ public function start () {
54+ $ this ->log ('[ ' . date ('Y-m-d H:i:s ' ) . '] Query init. URL: ' . $ this ->url );
55+ $ this ->sendRequest ();
56+
57+ $ response = curl_exec ($ this ->ch );
58+ $ debug = curl_getinfo ($ this ->ch );
59+
60+ $ this ->log (sprintf (
61+ 'Response headers: code=%d; content_type=%s; size_upload=%d; size_download=%d; ' ,
62+ $ debug ['http_code ' ] ?? 0 ,
63+ $ debug ['content_type ' ] ?? '' ,
64+ $ debug ['size_upload ' ] ?? 0 ,
65+ $ debug ['size_download ' ] ?? 0
66+ ));
67+
68+ $ this ->log ('Response body: ' . $ response );
69+ $ this ->log (str_repeat ('- ' , 50 ));
70+
71+ $ this ->sendResponse ($ response , $ debug ['content_type ' ] ?? 'application/json ' , $ debug ['http_code ' ] ?? 200 );
72+ }
73+
74+ /**
75+ * Send the HTTP response back to client with correct headers.
76+ * @param string $response
77+ * @param string $type
78+ * @param int $code
79+ */
80+ private function sendResponse (string $ response , string $ type , int $ code ) {
81+ http_response_code ($ code );
82+ header ('Content-Type: ' . $ type );
83+ echo $ response ;
84+ exit ;
85+ }
86+
87+ /**
88+ * Construct full Telegram API URL based on incoming request URI.
89+ * @return string
90+ */
91+ public function getUrl () {
92+ $ dir = dirname ($ _SERVER ['SCRIPT_NAME ' ]); // Detect script directory
93+ if (strpos ($ _SERVER ['REQUEST_URI ' ], $ dir ) === 0 ) {
94+ $ uri = substr ($ _SERVER ['REQUEST_URI ' ], strlen ($ dir ));
95+ } else {
96+ $ uri = $ _SERVER ['REQUEST_URI ' ];
97+ }
98+
99+ if (substr ($ uri , 0 , 1 ) !== '/ ' ) {
100+ $ uri = '/ ' . $ uri ;
101+ }
102+
103+ return $ this ->url = "https://api.telegram.org " . $ uri ;
104+ }
105+
106+ /**
107+ * Initialize cURL session for the prepared URL.
108+ * @return resource
109+ */
110+ private function initCurl () {
111+ $ this ->ch = curl_init ($ this ->url );
112+ curl_setopt ($ this ->ch , CURLOPT_RETURNTRANSFER , true );
113+ return $ this ->ch ;
114+ }
115+
116+ /**
117+ * Prepare and send the HTTP request to Telegram API.
118+ */
119+ private function sendRequest () {
120+ $ method = $ _SERVER ['REQUEST_METHOD ' ] ?? 'GET ' ;
121+ $ this ->log ('HTTP Request: ' . $ method );
122+ $ rawInput = file_get_contents ('php://input ' );
123+ $ this ->log ('HTTP Raw Input: ' . $ rawInput );
124+
125+ if ($ method === 'POST ' || $ rawInput !== '' || !empty ($ _POST )) {
126+ curl_setopt ($ this ->ch , CURLOPT_POST , true );
127+
128+ if (!empty ($ _FILES )) {
129+ // Prepare file uploads
130+ $ post = [];
131+ foreach ($ _FILES as $ name => $ file ) {
132+ $ post [$ name ] = new CURLFile ($ file ['tmp_name ' ], $ file ['type ' ], $ file ['name ' ]);
133+ }
134+ foreach ($ _POST as $ name => $ value ) {
135+ $ post [$ name ] = $ value ;
136+ }
137+ } else {
138+ // Forward raw POST body (e.g., JSON payload)
139+ $ post = $ rawInput ;
140+ $ ct = $ _SERVER ['HTTP_CONTENT_TYPE ' ] ?? $ _SERVER ['CONTENT_TYPE ' ] ?? 'application/json ' ;
141+ curl_setopt ($ this ->ch , CURLOPT_HTTPHEADER , ['Content-Type: ' . $ ct ]);
142+ }
143+
144+ $ this ->log ('Send To Telegram HTTP Request body: ' . json_encode ($ post , JSON_UNESCAPED_UNICODE ));
145+ curl_setopt ($ this ->ch , CURLOPT_POSTFIELDS , $ post );
146+ } else {
147+ curl_setopt ($ this ->ch , CURLOPT_CUSTOMREQUEST , $ method );
148+ }
149+ }
98150}
99151
100- $ proxy = new TelegramApiProxy ;
101- $ proxy ->setLog (false ); // use logs only for debug
102- $ proxy ->start ();
103- ?>
152+ // -------------------------------------------------------------
153+ // Bootstrap
154+ // -------------------------------------------------------------
155+ $ proxy = new TelegramApiProxy ();
156+ $ proxy ->setLog (false ); // Enable (true) only for debugging
157+ $ proxy ->start ();
0 commit comments