So in this quest to build a custom pseudo web chat service with Telegram, I’m trying to get the messages Telegram sends to the server and redirect them to frontend. SSE with HTML5 EventSource seems the best and easy solution to do that.
The thing is that EventSource needs 'Content-Type: text/event-stream'
and 'Cache-Control: no-cache'
headers set in server’s response.
If a WP_REST_REQUEST
is returned on the function that sets the response (“set_telegram_response”, below), nothing will arrive at EventSource. But if the response is echoed, EventSource will close the connection claiming that the server is sending a JSON response instead of a text/event-stream
one.
Following is the barebones of the class I wrote for this. If I pull a GET request on that endpoint, it will return the “Some text” string. But the EventSource script prints nothing, as if the response were empty.
class Chat
{
private static $token, $telegram, $chat_id;
public $telegram_message;
public function __construct()
{
self::$chat_id = "<TELEGRAM-CHAT-ID>";
self::$token = "<TELEGRAM-TOKEN>";
self::$telegram = "https://api.telegram.org:443/bot" . self::$token;
add_action('rest_api_init', array( $this, 'set_telegram_message_endpoint' ));
add_action('admin_post_chat_form', array( $this, 'chat_telegram' ));
add_action('admin_post_nopriv_chat_form', array( $this, 'chat_telegram' ));
}
public function set_telegram_message_endpoint()
{
register_rest_route('mybot/v2', 'bot', array(
array(
'methods' => WP_REST_SERVER::CREATABLE,
'callback' => array( $this, 'get_telegram_message' ),
),
array(
'methods' => WP_REST_SERVER::READABLE,
'callback' => array( $this, 'set_telegram_message' ),
),
));
}
public function set_telegram_message( WP_REST_REQUEST $request )
{
$new_response = new WP_REST_Response( "Some text" . PHP_EOL . PHP_EOL, 200 );
$new_response->header( 'Content-Type', 'text/event-stream' );
$new_response->header( 'Cache-Control', 'no-cache' );
ob_flush();
return $new_response;
}
public function get_telegram_message( WP_REST_REQUEST $request )
{
$this->telegram_message = $request;
//return rest_ensure_response( $request['message']['text'] );
}
public function chat_telegram( $input = null )
{
$mensaje = $input === '' ? $_POST['texto'] : $input;
echo $mensaje;
$query = http_build_query([
'chat_id' => self::$chat_id,
'text' => $mensaje,
'parse_mode' => "Markdown",
]);
$response = file_get_contents( self::$telegram . '/sendMessage?' . $query );
return $response;
}
}
I spent all the afternoon and part of this morning reading the documentation on REST API, but couldn’t find any clue on what could be wrong or how to do this.
BTW, the server I’m deploying this can handle EventSource requests – I just tried it on a test PHP script and it worked well. So I really don’t know what is going on here. Any help would be hugely appreciated.