A funcionalidade deste guia foi transferida para a API do messengers Business, com o qual você também pode fazer mailings, criar chat bots e muito mais, mas sem correr o risco de ser bloqueado.
Devido a mudanças nas condições de trabalho da API, este guia pode utilizar parcialmente informações desatualizadas. Consulte a documentação antes de começar.
Agora, o Chat API oferece a messengers Business API mais acessível e automatizada do mercado, com Chat Multiusuário, Construtor de chatbot sem código, aplicação Web e integrador de API com o messengers e outros recursos.
Vamos contar como escrever um bot simples em PHP, usando a API do messengers.
O bot de demonstração responderá aos comandos que entram como mensagens regulares no messengers e respondem a eles. Agora, no nosso bot de bate-papo de demonstração, tem a seguinte funcionalidade:
- Exibição da lista de comandos
- Exibição do ID de bate-papo atual
- Exibição da hora actual do servidor que está a executar o bot.
- Exibição do seu nome
- Envio de arquivos de diferentes formatos (pdf, jpg, doc, mp3, etc.)
- Envio de mensagens de voz pré-gravadas
- Envio de coordenadas geográficas (locais)
- Criação da conferência (grupos)
Atenção: para que o bot funcione, o telefone deve estar sempre conectado à Internet e não deve ser usado para o messengers Web. Para esses fins, é mais prático ter um dispositivo separado.
Trabalho preparatório
No início, associamos imediatamente o messengers ao nosso script(roteiro), de modo que, à medida que escrevemos o código, verificamos sua operação. Para fazer isso, vá para sua conta pessoal e obtenha um código QR lá. Em seguida, abra o messengers no seu celular, vá para Configurações -> messengers Web -> Digitalize um código QR.
Agora, para que o servidor execute o nosso script(roteiro) com novas mensagens, você precisa especificar o URL do WebHook. Coloque lá um link direto para o seu script(roteiro), por exemplo, https://domain.com/PHP/messengersbot.php. Você não pode apenas especificar o endereço IP do servidor. Você pode especificar a porta.
Obtenha acesso de demonstração gratuito à API do messengersAgora vamos criar o arquivo messengersbot.php e criar nele a class: class messengersBot { }
Vamos criar as variáveis que são colocados na API Url e token. Eles podem ser encontrados em sua conta.
{var $APIurl = 'https://api.chat-api.com/instanceYYYYY/';
var $token = 'abcdefgh12345678';}
Agora iniciamos a escrever a função __construct() função que será executado automaticamente cada vez que você executar o script(roteiro). O servidor ChatAPI acessará o bot quando novas mensagens chegarem (mais sobre isso abaixo), enviando informações sobre a nova mensagem no formato JSON. Nós imediatamente pegamos esses dados no início da função e os colocamos em variáveis.
{public function __construct(){ $json = file_get_contents('php://input');
$decoded = json_decode($json,true);}}
Continuamos a escrever o código de função. Opcionalmente, podemos salvar os dados recebidos em um arquivo para análise adicional e depuração, se necessário. Para isso, usamos o buffer de saída.
{ ob_start();
var_dump($decoded);
$input = ob_get_contents();
ob_end_clean();
file_put_contents('input_requests.log',$input.PHP_EOL,FILE_APPEND);}
Agora escrevemos o processamento de mensagens recebidas e execução das funções correspondentes. Haverá muitos códigos aninhados, mas vamos classificá-lo linha por linha.
{ if(isset($decoded['messages'])){
foreach($decoded['messages'] as $message){
$text = explode(' ',trim($message['body']));
if(!$message['fromMe']){
switch(mb_strtolower($text[0],'UTF-8')){
case 'hi': {$this->welcome($message['chatId'],false); break;}
case 'chatId': {$this->showchatId($message['chatId']); break;}
case 'time': {$this->time($message['chatId']); break;}
case 'me': {$this->me($message['chatId'],$message['senderName']); break;}
case 'file': {$this->file($message['chatId'],$text[1]); break;}
case 'ptt': {$this->ptt($message['chatId']); break;}
case 'geo': {$this->geo($message['chatId']); break;}
case 'group': {$this->group($message['author']); break;}
default: {$this->welcome($message['chatId'],true); break;}
}}}}}
Explicação:
-
if(isset($decoded['messages']))
Notificações do tipo "o usuário deixou o bate-papo" também são enviados pelo servidor, mas eles não terão uma matriz(arranjo) de mensagens. Esta verificação previne o erro "Undefined index". -
foreach($decoded['messages'] as $message)
As mensagens estão em uma matriz(arranjo) e várias mensagens podem chegar ao mesmo tempo. O bot deve reagir a cada um deles. -
$text = explode(' ',trim($message['body']));
Dividimos o corpo da mensagem em palavras separadas. A primeira palavra é o comando, os outros serão os parâmetros do comando. -
if(!$message['fromMe'])
Essa verificação é necessária para que o bot não entre em recursão. Marca "fromMe" significa que a mensagem foi enviada pelo próprio bot. Portanto, continuamos a execução apenas para mensagens recebidas. -
switch(mb_strtolower($text[0],'UTF-8'))
Um bloco switch que determina qual comando está contido na primeira palavra. O comando é dado em letras minúsculas, para que o bot responda, independentemente de estar escrito em letras maiúsculas ou maiúscula. Ex: aBcDe -
case 'hi': {$this->welcome($message['chatId'],false)}
A implementação de um comando apropriado com base na primeira palavra. Transferimos o chatId da mensagem para a função chamada, para que o envio ocorra no chat correspondente. Em princípio, todas as linhas seguintes são as mesmas, mas preste atenção em:case 'file': {$this->file($message['chatId'],$text[1])}
Aqui nós passamos outro parâmetro, ou seja a segunda palavra da mensagem, assim como é um parâmetro de comando. Sobre isso mais abaixo. Também preste atenção em:case 'me': {$this->me($message['chatId'],$message['senderName'])}
Aqui como o segundo parâmetro é o nome do interlocutor, também retirado dos dados da mensagem. E no default executamos uma função que exibe uma lista de comandos, mas com o parâmetro true, o que significa obter o comando errado.
Terminamos de escrever a função __construct(). Agora nós passamos para as funções executadas pelos comandos do bloco de switch acima mencionado. Na parte das funções é executada a função sendMessage(), na outra parte - a função sendRequest(). No script(roteiro), essas funções são colocadas abaixo, mas falaremos sobre elas imediatamente:
A função sendRequest() realiza diretamente a solicitação para o servidor ChatAPI para o envio de mensagens e de mídia diferente. Ela aceita 2 parâmetro - $method e $data.
- $method determina qual método chatAPI deve ser executado.
- $data contém os dados necessários para a transferência.
{ public function sendRequest($method,$data){
$url = $this->APIurl.$method.'?token='.$this->token;
if(is_array($data)){ $data = json_encode($data);}
$options = stream_context_create(['http' => [
'method' => 'POST',
'header' => 'Content-type: application/json',
'content' => $data
]]);
$response = file_get_contents($url,false,$options);
file_put_contents('requests.log',$response.PHP_EOL,FILE_APPEND);}
Vamos explicar com mais detalhes: Em $ url, formamos um URL válido contendo o APIUrl, o método e o token. Em seguida, verificamos os dados recebidos. Se for uma matriz(arranjo), convertê-lo em JSON. Caso contrário, a conversão para JSON já foi implementada na função executada. $options - define cabeçalhos HTTP. Então, através de file_get_contents, executamos a solicitação para o URL gerado, transmitindo os dados.A última linha não é necessária, ela simplesmente grava a resposta do servidor ChatAPI para um arquivo para depuração e registro.
A função sendMessage() na realidade é apenas um simples invólucro de mensagens de texto. Ele forma a matriz(arranjo) de dados correto e a transmite para a função sendRequest() acima mencionado com o método "message".
{ public function sendMessage($chatId, $text){
$data = array('chatId'=>$chatId,'body'=>$text);
$this->sendRequest('message',$data);}}
Agora vamos criar uma função de controle a partir de um bloco switch. As funções que enviam uma mensagem de texto simples, na maioria das vezes, apenas executam o sendMessage() com um determinado texto. Funções que enviam mídias diferentes formam suas matrizes(arranjo) de dados, e executam sendRequest() com outros métodos.
A função welcome() - exibe a lista de comandos disponíveis.
{ public function welcome($chatId, $noWelcome = false){
$welcomeString = ($noWelcome) ? "Incorrect command\n" : "messengers Demo Bot PHP\n";
$this->sendMessage($chatId,
$welcomeString.
"Commands:\n".
"1. chatId - show ID of the current chat\n".
"2. time - show server time\n".
"3. me - show your nickname\n".
"4. file [format] - get a file. Available formats: doc/gif/jpg/png/pdf/mp3/mp4\n".
"5. ptt - get a voice message\n".
"6. geo - get a location\n".
"7. group - create a group with the bot");}}
Se o parâmetro $noWelcome for igual false, a primeira linha da mensagem será a saudação exibida pelo comando "hi". Se true - saudação será substituído por uma mensagem de comando inválido.
A função showchatId () exibe o ID de bate-papo atual usando o comando "chatId".
{ public function showchatId($chatId){
$this->sendMessage($chatId,'chatId: '.$chatId);}}
A função time () - exibe a hora atual do servidor usando o comando "time".
{ public function time($chatId){
$this->sendMessage($chatId,date('d.m.Y H:i:s'));}}
A função me() - exibe o nome do interlocutor usando o comando "me".
{
public function me($chatId,$name){
$this->sendMessage($chatId,$name);
}}
A função file() - envia um arquivo usando o comando "file". Essa função é mais interessante, já que funciona com o parâmetro. Como o parâmetro é transferido o formato de arquivo que você deseja enviar.
{ public function file($chatId,$format){
$availableFiles = array(
'doc' => 'document.doc',
'gif' => 'gifka.gif',
'jpg' => 'jpgfile.jpg',
'png' => 'pngfile.png',
'pdf' => 'presentation.pdf',
'mp4' => 'video.mp4',
'mp3' => 'mp3file.mp3'
);
if(isset($availableFiles[$format])){
$data = array(
'chatId'=>$chatId,
'body'=>'https://domain.com/PHP/'.$availableFiles[$format],
'filename'=>$availableFiles[$format],
'caption'=>'Get your file '.$availableFiles[$format]
);
$this->sendRequest('sendFile',$data);}}}
Vamos explicar com mais detalhes:
- $availableFiles é uma matriz na qual as chaves são os parâmetros da função e os valores são os nomes dos arquivos. Naturalmente, os arquivos com nomes da matriz devem estar presentes no servidor. Neste exemplo, eles estão no mesmo lugar que o script(roteiro) bot de bate-papo, mas você pode colocá-los em outra pasta.
- if(isset($availableFiles[$format])) - verifica a existência de uma chave de matriz(arranjo) com o parâmetro recebido. Se existir, então formamos uma matriz(arranjo) de dados e a transferimos para sendRequest() com o método "sendFile". Os dados a seguir devem estar na matriz(arranjo) de dados:
- chatId - como de costume, o ID de bate-papo para o qual a resposta é enviada.
- body - um link direto para o arquivo no seu servidor. Por favor, note que o SSL deve estar conectado no servidor!
- filename - nome do arquivo, você pode especificar qualquer
- caption - a mensagem que acompanha este arquivo.
A função ptt() - enviando uma mensagem de voz usando o comando "ptt". A mensagem de voz deve ser um arquivo .OGG no seu servidor.
{ public function ptt($chatId){
$data = array(
'audio'=>'https://domain.com/PHP/ptt.ogg',
'chatId'=>$chatId
);
$this->sendRequest('sendAudio',$data);}}
Aqui, como na função anterior, formamos uma matriz(arranjo) de dados: chatId - ID bate-papo audio - um link direto para o arquivo .ogg, novamente, o SSL é necessário. E passá-lo para a função sendRequest com o método "sendAudio".
Função geo() - envio de coordenadas geográficas usando o comando "geo"
{ public function geo($chatId){
$data = array(
'lat'=>51.51916,
'lng'=>-0.139214,
'address'=>'Your address',
'chatId'=>$chatId
);
$this->sendRequest('sendLocation',$data);
}}
A mesma coisa que nas duas funções anteriores. A matriz(arranjo) deve conter os seguintes dados: lat e lng - coordenadas; address é um endereço, mas você pode escrever qualquer string; chatld – é evidente.
A função group() cria uma conferência na qual você e o bot estarão, usando o comando "group".
{ public function group($author){
$phone = str_replace('@c.us','',$author);
$data = array(
'groupName'=>'Group with the bot PHP',
'phones'=>array($phone),
'messageText'=>'It is your group. Enjoy'
);
$this->sendRequest('group',$data);}}
Aqui, precisamos especificar os números de telefone dos usuários que serão adicionados à conferência. Na primeira linha, extraímos o número de telefone do usuário da sua ID pessoal, que se parece com [email protected] Então, formamos uma matriz(arranjo):
- groupName - o nome da conferência;
- phones - um conjunto de números de telefone;
- messageText - o texto da primeira mensagem no grupo;
Por favor, note que esta é a única função onde NÃO se transfere o chatId. E nós transferimos a matriz(arranjo) para sendRequest().
Agora que terminamos de trabalhar com funções, depois de parênteses que fecha o class escreva uma linha: new messengersBot();
Para que o class execute automaticamente ao acessar o script(roteiro).
O código final irá aparecer da seguinte forma
{
class messengersBot{
//specify instance URL and token
var $APIurl = 'https://api.chat-api.com/instanceYYYYY/';
var $token = '**************************';
public function __construct(){
//get the JSON body from the instance
$json = file_get_contents('php://input');
$decoded = json_decode($json,true);
//write parsed JSON-body to the file for debugging
ob_start();
var_dump($decoded);
$input = ob_get_contents();
ob_end_clean();
file_put_contents('input_requests.log',$input.PHP_EOL,FILE_APPEND);
if(isset($decoded['messages'])){
//check every new message
foreach($decoded['messages'] as $message){
//delete excess spaces and split the message on spaces. The first word in the message is a command, other words are parameters
$text = explode(' ',trim($message['body']));
//current message shouldn't be send from your bot, because it calls recursion
if(!$message['fromMe']){
//check what command contains the first word and call the function
switch(mb_strtolower($text[0],'UTF-8')){
case 'hi': {$this->welcome($message['chatId'],false); break;}
case 'chatId': {$this->showchatId($message['chatId']); break;}
case 'time': {$this->time($message['chatId']); break;}
case 'me': {$this->me($message['chatId'],$message['senderName']); break;}
case 'file': {$this->file($message['chatId'],$text[1]); break;}
case 'ptt': {$this->ptt($message['chatId']); break;}
case 'geo': {$this->geo($message['chatId']); break;}
case 'group': {$this->group($message['author']); break;}
default: {$this->welcome($message['chatId'],true); break;}
}}}}}
//this function calls function sendRequest to send a simple message
//@param $chatId [string] [required] - the ID of chat where we send a message
//@param $text [string] [required] - text of the message
public function welcome($chatId, $noWelcome = false){
$welcomeString = ($noWelcome) ? "Incorrect command\n" : "messengers Demo Bot PHP\n";
$this->sendMessage($chatId,
$welcomeString.
"Commands:\n".
"1. chatId - show ID of the current chat\n".
"2. time - show server time\n".
"3. me - show your nickname\n".
"4. file [format] - get a file. Available formats: doc/gif/jpg/png/pdf/mp3/mp4\n".
"5. ptt - get a voice message\n".
"6. geo - get a location\n".
"7. group - create a group with the bot"
);
}
//sends Id of the current chat. it is called when the bot gets the command "chatId"
//@param $chatId [string] [required] - the ID of chat where we send a message
public function showchatId($chatId){
$this->sendMessage($chatId,'chatId: '.$chatId);
}
//sends current server time. it is called when the bot gets the command "time"
//@param $chatId [string] [required] - the ID of chat where we send a message
public function time($chatId){
$this->sendMessage($chatId,date('d.m.Y H:i:s'));
}
//sends your nickname. it is called when the bot gets the command "me"
//@param $chatId [string] [required] - the ID of chat where we send a message
//@param $name [string] [required] - the "senderName" property of the message
public function me($chatId,$name){
$this->sendMessage($chatId,$name);
}
//sends a file. it is called when the bot gets the command "file"
//@param $chatId [string] [required] - the ID of chat where we send a message
//@param $format [string] [required] - file format, from the params in the message body (text[1], etc)
public function file($chatId,$format){
$availableFiles = array(
'doc' => 'document.doc',
'gif' => 'gifka.gif',
'jpg' => 'jpgfile.jpg',
'png' => 'pngfile.png',
'pdf' => 'presentation.pdf',
'mp4' => 'video.mp4',
'mp3' => 'mp3file.mp3'
);
if(isset($availableFiles[$format])){
$data = array(
'chatId'=>$chatId,
'body'=>'https://domain.com/PHP/'.$availableFiles[$format],
'filename'=>$availableFiles[$format],
'caption'=>'Get your file '.$availableFiles[$format]
);
$this->sendRequest('sendFile',$data);}}
//sends a voice message. it is called when the bot gets the command "ptt"
//@param $chatId [string] [required] - the ID of chat where we send a message
public function ptt($chatId){
$data = array(
'audio'=>'https://domain.com/PHP/ptt.ogg',
'chatId'=>$chatId
);
$this->sendRequest('sendAudio',$data);}
//sends a location. it is called when the bot gets the command "geo"
//@param $chatId [string] [required] - the ID of chat where we send a message
public function geo($chatId){
$data = array(
'lat'=>51.51916,
'lng'=>-0.139214,
'address'=>'Your address',
'chatId'=>$chatId
);
$this->sendRequest('sendLocation',$data);}
//creates a group. it is called when the bot gets the command "group"
//@param chatId [string] [required] - the ID of chat where we send a message
//@param author [string] [required] - "author" property of the message
public function group($author){
$phone = str_replace('@c.us','',$author);
$data = array(
'groupName'=>'Group with the bot PHP',
'phones'=>array($phone),
'messageText'=>'It is your group. Enjoy'
);
$this->sendRequest('group',$data);}
public function sendMessage($chatId, $text){
$data = array('chatId'=>$chatId,'body'=>$text);
$this->sendRequest('message',$data);}
public function sendRequest($method,$data){
$url = $this->APIurl.$method.'?token='.$this->token;
if(is_array($data)){ $data = json_encode($data);}
$options = stream_context_create(['http' => [
'method' => 'POST',
'header' => 'Content-type: application/json',
'content' => $data]]);
$response = file_get_contents($url,false,$options);
file_put_contents('requests.log',$response.PHP_EOL,FILE_APPEND);}}
//execute the class when this file is requested by the instance
new messengersBot();}
Você só precisará substituir seu token de sua conta pessoal pela variável $token e número da instância.
Obter chave de API