No artigo de hoje, vamos demonstrar em como fazer a integração com a API da Zoho via AdvPL e TL++.
Pessoal, antes de começarmos, esse artigo foi originalmente publicado pelo Giulliano Pinheiro ( LinkedIn ) .
Ele me enviou o link, achei bem interessante e decidi compartilhar aqui com vocês. Então a partir da próxima linha é o conteúdo que ele redigiu no artigo, e no fim dessa página tem um link de referência apontando para o link original.
Aproveitando o mesmo projeto do Zoho com Python, hoje trago uma forma de usar alguns recursos ‘modernos’ no advpl para consumir uma API (outra modernidade).
Utilizei os mesmos acessos usados anteriormente neste artigo (clique aqui), portanto, para ver funcionando, é preciso criar sua conta no Zoho Commerce e criar uma loja virtual de testes.
A Classe
A classe nos ajuda a economizar códigos futuros, podemos aplicar orientação a objeto, facilita implementar novos métodos e mantém a casa organizada.
Nossa classe será o ‘meio de campo’ entre a plataforma do Zoho e o Protheus, criamos os métodos que consomem as APIs do Zoho e chamaremos os métodos em nosso main para nos auxiliar nas tarefas, no caso do exemplo, o get de produtos.
Esta classe utiliza dois métodos:
+ Login: responsável por gerar um token de acesso a cada requisição de consumo no Zoho
+ getProduto: Utiliza o método login para gerar um token e faz a requisição de um get de produtos da plataforma.
Utilizei a tipagem do tlpp que inclusive, acusa em tempo de compilação se sua variável está esperando N e recebeu C, por exemplo.
Outra utilização do tlpp, foram os nomes de variáveis maiores, isso ajuda muito a criar um programa mais fácil de ler, onde suas variáveis são auto explicativas. No programa em produção, tenho um método chamado ‘postMarcaPedidoComoPago’, se estivesse usando prw, teria que usar a criatividade e fazer um comentário para explicar um método enigmático pMPCP (pcp? matéria prima?)
#include 'TOTVS.ch'
#include 'tlpp-core.th'
/*/{Protheus.doc} ZOHO
Classe responsável por realizar a integração entre Zoho Commerce
e Protheus.
@type class
@author Giulliano Pinheiro
@since 05/06/2023
@link https://www.zoho.com/commerce/api/introduction.html
/*/
Class ZOHO
Data cToken as Character
Data cURL as Character
Data cURLAuth as Character
Data cProdPath as Character
Data aMetodoData as Array
PUBLIC METHOD New()
PRIVATE METHOD Login()
PUBLIC METHOD getProduto()
EndClass
/*/{Protheus.doc} New
Construtor
@type method
@author Giulliano Pinheiro
@since 05/06/2023
/*/
Method New() Class ZOHO
::cURL := 'https://commerce.zoho.com'
::cURLAuth := 'https://accounts.zoho.com/oauth/v2/'
::cProdPath := '/store/api/v1/products/'
Return ::self
/*/{Protheus.doc} Login
Realiza o login utilizando o refresh_token do Self-Client criado em
Zoho API Console
https://api-console.zoho.com/
@type method
@author Giulliano Pinheiro
@since 05/06/2023
@return character, cToken, Token para consumo de APIs do Zoho Commerce.
@link https://www.zoho.com/commerce/api/oauth.html
/*/
METHOD Login() CLASS ZOHO
Local aArea := FWGetArea() as Array
Local aHeader := {} as Array
Local oRestClient := FWRest():New(::cURLAuth) as Object
Local jResponse := JSonObject():New()
//Params
Local cRefreshToken := 'O SEU REFRESH TOKEN' as Character
Local cClientID := 'O SEU ID DE CLIENTE' as Character
Local cClientSecret := 'O SEU CLIENT SECRET' as Character
Local cGrantType := 'refresh_token' as Character
Local cPath := 'token?refresh_token='+cRefreshToken+'&client_id='+cClientID+'&client_secret='+cClientSecret+'&grant_type='+cGrantType as Character
aadd(aHeader,'User-Agent: Mozilla/4.0 (compatible; Protheus '+GetBuild()+')')
aAdd(aHeader,'Content-Type: application/json; charset=utf-8')
// Se existir o token
if !EMPTY(cRefreshToken)
oRestClient:SetPath(cPath)
// tenta realizar o post
if (oRestClient:Post(aHeader))
//Coleta o Json da resposta
jResponse:FromJson(oRestClient:cResult)
//Coleta o token do json da resposta
::cToken := IIF( ValType(jResponse['access_token']) != "U", jResponse['access_token'], "" )
lRet := .T.
else
FWLogMsg("ERROR", /*cTransactionId*/, "Zoho", FunName()+":Login", /*cStep*/, /*cMsgId*/, "Erro ao gerar o token. ", /*nMensure*/, /*nElapseTime*/, /*aMessage*/)
endif
ENDIF
FWRestArea(aArea)
Return
/*/{Protheus.doc} getProduto
Get Produtos no Zoho
@type method
@author Giulliano Pinheiro
@since 05/06/2023
@return json, oJson, resultado do get de produtos.
@link https://www.zoho.com/commerce/api/list-all-products.html
/*/
Method getProduto() CLASS ZOHO
Local aArea := FWGetArea() as array
Local aHeader := {} as array
Local oRestClient := FWRest():New(::cURL) as object
Local oJson := JSonObject():New() as json
Local lRet := .F.
// Recebe o token da função Login
::Login()
AADD(aHeader, 'Authorization:Zoho-oauthtoken '+::cToken)
AADD(aHeader, 'X-com-zoho-store-organizationid:633414070')
oRestClient:SetPath(::cProdPath)
// Tenta realizar o get
if oRestClient:Get(aHeader)
// Captura o Json de retorno
oJson:FromJson(oRestClient:CRESULT)
lRet := .T.
else
FWLogMsg("ERROR", /*cTransactionId*/, "Zoho", FunName()+":getProduto", /*cStep*/, /*cMsgId*/, "Erro ao tentar realizar o get. ", /*nMensure*/, /*nElapseTime*/, /*aMessage*/)
endif
FWRestArea(aArea)
Return oJson
O Main
No main, vamos consumir o getProduto da classe que acabamos de criar. Neste programa, a classe é chamada instanciando a variável oZoho na declaração e consumindo um método para alimentar o jJson.
#Include "TOTVS.ch"
#include 'tlpp-core.th'
/*/{Protheus.doc} ZohoProdutoExemplo
Realiza um get utilizando a classe Zoho
@type function
@author Giulliano Pinheiro
@since 06/06/2023
/*/
User Function ZohoProdutoExemplo()
Local aArea := FWGetArea() as array
Local oZoho := ZOHO():New() as object
Local jJson as Json
jJson := oZoho:getProduto()
FWRestArea(aArea)
Return
Por fim, compilando os dois programas e realizando um debug, recebemos nosso json no main.
Referências:
Bom pessoal, por hoje é só.
Abraços e até a próxima.
