Introdução
Sabe aquela rotina crítica rodando via Schedule no Protheus que não pode parar? aquele velho processo de importar os pedidos de vendas para o Protheus que quando algum execauto da erro ninguém fica sabendo e acaba tendo vendas perdidas ou atrasadas? Com a solução apresentada nesse artigo você poderá monitorar os erros do Protheus direto no Telegram, inclusive em um grupo com todos envolvidos e detalhes do que aconteceu!!
Protheus no Telegram
O Telegram possui muita flexibilidade para integrações e bots, podendo assim ter uma infinidade de casos de uso para ele. Vamos começar pelo processo mais simples, que é o envio de mensagens automaticamente para grupos selecionados.
Vamos começar criando então o nosso BOT, que será responsável por enviar as mensagens para o Telegram sempre que ocorrer algum erro na importação do pedido de venda.
Para criá-lo, vá no aplicativo do Telegram e pesquise por @BotFather e clique sobre ele:

Clique em “COMEÇAR” no rodapé do chat do BotFather:

Agora envie a mensagem: /newbot

O BotFather vai pedir para você informar o nome do seu bot, esse é o nome que vai aparecer no chat.

Para esse exemplo, eu escolhi o nome: Code Vix BOT … fique a vontade para nomear o seu do jeito que preferir.
O próximo passo é escolher um username para o bot, esse será o nome único do bot no Telegram e obrigatoriamente deverá terminar com BOT no final, exemplo: CodeBot, Code_Bot, etc.
Irei utilizar para esse exemplo: CodeVixBot
Com isso o nosso BOT do Telegram já está criado e pronto para utilizar, na última mensagem enviada o BotFather te envia o TOKEN para acessar a API do Telegram e utilizar esse bot.

Escondi uma parte do Token por segurança, mas você deverá utilizar o token completo enviado.
Agora precisamos adicionar o nosso amigo bot ao grupo em que ele poderá enviar as mensagem, então vamos criar um novo grupo:

Na criação do grupo incluímos o nosso bot @CodeVixBot ao grupo e em seguida daremos um nome ao grupo, fique a vontade para escolher o nome.

Agora com o grupo criado e o BOT fazendo parte dele, precisamos pegar o ID desse grupo para enviar as mensagens via API, para isso vá no navegador e acesse o seguinte endereço:
https://api.telegram.org/bot<TOKEN>/getUpdates
Substitua <TOKEN> pelo token recebido na criação do Bot, ficando o endereço parecido com: https://api.telegram.org/bot3256985236:AAHz99QPXW_AA_bdsecHiQffz5vqfxyzf0I/getUpdates
Fazendo isso será retornado um JSON com o ID do chat que o bot faz parte, procure por “chat” e salve o ID informado nele.

Agora temos o ID do Chat e o Token, podemos utilizar o bot no Protheus via instruções ADVPL.
Bora Codar!!
Vou usar como exemplo para esse artigo um execauto de inclusão do pedido de venda no Protheus através da rotina MATA410 e caso o mesmo falhe será enviado os detalhes do erro para o grupo do Telegram que criamos através do bot.
Vamos começar com a classe responsável por enviar mensagem para o telegram:
Class Telegram From FwRest
Data cUrl As String
Data cToken As String
Data aHeadOut As Array
Data cPath As String
Data cEndPoint As String
Data cChatId As String
Method New() Constructor
Method SetChat()
Method SendMessage()
EndClass
Method New () Class Telegram
Local cUrl := "https://api.telegram.org"
Local cToken := "3256985236:AAHz99QPXW_AA_bdsecHiQffz5vqfxyzf0I"
_Super:New(cUrl) // Inicializa metodo da classe pai
Self:cURL := cUrl
Self:cToken := cToken
Self:cPath := "/bot" + ::cToken
Self:cChatId := "-48721111"
Self:aHeadOut := {}
Self:cEndPoint := ""
Return( Self )
Method SetChat( cChatId ) Class Telegram
::cChatId := cChatId
Return( ::cChatId )
// ---------------------------------------------------------------------+
// Faz o envio de mensagens para determinad chat id - markdown ou HTML |
// ---------------------------------------------------------------------+
Method SendMessage( cMessage, lHtml ) Class Telegram
Local cParseMode := ""
Local lRet := .F.
Default cMessage := ""
Default lHtml := .F.
//-- Determina se a msg será no formato HTML ou normal
cParseMode := "parse_mode="
cParseMode += IIF( lHtml, "HTML", "markdown" )
::cEndPoint := ::cPath + "/sendMessage?" + cParseMode + "&use_aliases=true&chat_id=" + ::cChatId + "&text=" + cMessage
_Super:SetPath( ::cEndPoint )
lRet := _Super:Get()
Return( lRet )
Agora vamos desenvolver a função responsável por consumir a classe Telegram para envio das mensagens:
//----------------------------------------------------------+
// Envia a mensagem de erro para o BOT |
//----------------------------------------------------------+
User Function Telegram(cMsg)
Local xRet := ""
Default cMsg := ""
//|Remove caracteres invalidos e acentos |
cMsg := StrTran(cMsg, "<", "")
cMsg := StrTran(cMsg, ">", "")
cMsg := FwNoAccent(cMsg)
oTelegram := Telegram():New()
If ValType(oTelegram) == "O"
xRet := oTelegram:SetChat( "-48721111" /* ChatId */ )
//|Envio o Texto |
If ValType(xRet) == "C" .And. !Empty(xRet)
xRet := oTelegram:SendMessage( cMsg, .T. /* lHtml */ )
EndIf
EndIf
Return()
Agora o execauto e o tratamento para enviar o erro:
User Function CodeVix()
Local cEmp := "99"
Local cFil := "01"
Local cItem := "00"
Local cNumPed := ""
Local cError := ""
Local cPulaLn := "%0A"
Local nI := 0
Local nX := 0
Local aError := {}
Local aCab := {}
Local aItens := {}
Local aDet := {}
//|Inicializa ambiente |
RpcSetEnv( cEmp, cFil, "", " ", "FAT", "MATA410", , , , , )
cNumPed := GetSXENum( "SC5", "C5_NUM" )
//|Preenche cabeçalho |
aAdd(aCab, {"C5_FILIAL" , xFilial("SC5") ,Nil})
aAdd(aCab, {"C5_NUM" , cNumPed ,Nil})
aAdd(aCab, {"C5_TIPO" , "N" ,Nil})
aAdd(aCab, {"C5_CLIENTE" , "000001" ,Nil})
aAdd(aCab, {"C5_LOJACLI" , "01" ,Nil})
aAdd(aCab, {"C5_EMISSAO" , dDatabase ,Nil})
aAdd(aCab, {"C5_VEND1" , "000001" ,Nil})
aAdd(aCab, {"C5_CONDPAG" , "001" ,Nil})
dbSelectArea("SB1")
SB1->( dbSetOrder(1) )
For nI := 1 To 2
aDet := {}
cItem := Soma1(cItem)
SB1->( dbSeek( xFilial("SB1") + "000001" ) )
AAdd(aDet, {"C6_FILIAL" , xFilial("SC6") ,Nil})
aAdd(aDet, {"C6_NUM" , cNumPed ,Nil})
AAdd(aDet, {"C6_ITEM" , cItem ,Nil})
AAdd(aDet, {"C6_PRODUTO", SB1->B1_COD ,Nil})
AAdd(aDet, {"C6_UM" , SB1->B1_UM ,Nil})
AAdd(aDet, {"C6_QTDVEN" , 1 ,Nil})
AAdd(aDet, {"C6_PRCVEN" , 100 ,Nil})
AAdd(aDet, {"C6_PRUNIT" , 100 ,Nil})
AAdd(aDet, {"C6_TES" , SB1->B1_TS ,Nil})
AAdd(aDet, {"C6_DESCRI" , SB1->B1_DESC ,Nil})
AAdd(aDet, {"C6_LOCAL" , SB1->B1_LOCPAD ,Nil})
AAdd(aDet, {"C6_VALOR" , 100 ,Nil})
AAdd(aItens,AClone(aDet))
Next nI
Begin Transaction
lMsErroAuto := .F.
lMSHelpAuto := .F.
lAutoErrNoFile := .T.
MSExecAuto( { |x,y,z| Mata410( x,y,z ) }, aCab, aItens, 3 )
If lMsErroAuto
U_Telegram("[CODEVIX] Falha no execauto")
aError := GetAutoGRLog()
For nX := 1 To Len(aError)
cError += StrTran(aError[nX], CRLF, "") + cPulaLn
Next nX
RollBackSX8()
DisarmTransaction()
//|Notifica o TI via TELEGRAM |
U_Telegram(cError)
EndIf
End Transaction
RpcClearEnv()
Return
Repare que da linha 68 a 79 é armazenado os detalhes do erro na variável “cError” e logo em seguida enviado para o grupo do Telegram.
Veja como a mensagem chega no Telegram:

Só de olhar rapidamente, já sabemos que o execauto falou devido a não existir o vendedor 000001 no Protheus.
É isso aí jovens, espero que esse artigo seja útil… até a próxima!!
Agradecimento
Gostaria de agradecer ao grande Lucas Brustolin por disponibilizar para a comunidade a classe de integração com Telegram.
Já viu a tela de loading customizada que o Lucas fez? clique aqui e confira
Referências

Desenvolvedor e entusiasta de inovações e tecnologia.