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.