-
-
Save danperrout/b27197056fa38d0d669332647ab89d7a to your computer and use it in GitHub Desktop.
/* | |
* @return Acesse radaropcoes.com Retorna a cotação atual de um título específico do Tesouro Direto. | |
* Fonte: https://www.tesourodireto.com.br/titulos/precos-e-taxas.htm | |
**/ | |
function TESOURODIRETO(bondName, argumento="r") { | |
let srcURL = "https://api.radaropcoes.com/bonds.json"; | |
let jsondata = UrlFetchApp.fetch(srcURL); | |
let parsedData = JSON.parse(jsondata.getContentText()).response; | |
for(let bond of parsedData.TrsrBdTradgList) { | |
let currBondName = bond.TrsrBd.nm; | |
if (currBondName.toLowerCase() === bondName.toLowerCase()) | |
if(argumento == "r") | |
return bond.TrsrBd.untrRedVal; | |
else | |
return bond.TrsrBd.untrInvstmtVal; | |
} | |
throw new Error("Título não encontrado."); | |
} |
Alegria de pobre dura pouco, o link não atualiza…
aqui ainda funciona (com o selenium)
Coloquei o caminho "https://raw.githubusercontent.com/ghostnetrn/bot-tesouro-direto/714896cbcfc4100e241006cd29fef1bc3fcbcc65/tesouro.json" no script do Google Sheets e funcionou...
Eu coloquei esse link e funcionou no Google Sheets, mas o preço do título veio diferente.
O problema é que esse link é de um JSON estático. Se não me engano dia dia 05/09/2024.
Então ele sempre irá repetir os valores desse dia.
Alguém saberia alguma forma de pegar o JSON para o dia atual?
Pessoal, implementei minha própria abstração do json do Tesouro Direto. Na verdade, é uma cópia exata do JSON fornecidos por eles que pode ser acessado em:
Oficial: https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json
Mirror: https://api.radaropcoes.com/bonds.json
Esse json é atualizado de 15 em 15 minutos, mas o próprio TD só atualiza de hora em hora, por isso as datas podem estar "atrasadas" em algumas horas.
Fiquem a vontade para utilizar, além disso, no site Radar Opções, incluí a possibilidade de COPIAR o nome do Título para a área de transferência:
Alguém saberia alguma forma de pegar o JSON para o dia atual?
Código atualizado com o novo endereço de json: https://api.radaropcoes.com/bonds.json
Alguém sabe explicar como resolver o seguinte erro:
Erro TypeError: Cannot read properties of undefined (reading 'toLowerCase')
TESOURODIRETO @ TESOURODIRETO.gs:12
O erro é por conta do comentário que declara a função, segue a versão corrigida:
/**
* Retorna a cotação atual de um título específico do Tesouro Direto.
*
* @param {string} nome do título
* @return Retorna a cotação atual de um título específico do Tesouro Direto.
* @customfunction
* Fonte: https://www.tesourodireto.com.br/titulos/precos-e-taxas.htm
*/
function TESOURODIRETO(bondName="Tesouro IPCA+ 2029", argumento="r") {
let srcURL = "https://api.radaropcoes.com/bonds.json";
let jsondata = UrlFetchApp.fetch(srcURL);
let parsedData = JSON.parse(jsondata.getContentText()).response;
for(let bond of parsedData.TrsrBdTradgList) {
let currBondName = bond.TrsrBd.nm;
console.log(typeof(currBondName))
if (currBondName.toLowerCase() === bondName.toLowerCase())
if(argumento == "r")
return bond.TrsrBd.untrRedVal;
else
return bond.TrsrBd.untrInvstmtVal;
}
throw new Error("Título não encontrado.");
}
Perfeito Artur! Valeu!
Os valores unitário de cada título está certo para vcs? o meu não mostra no google sheets (c/script) igual a do site do Tesouro.
Os valores unitário de cada título está certo para vcs? o meu não mostra no google sheets (c/script) igual a do site do Tesouro.
O script consegue acessar dois valores, se vc colocar:
=TESOURODIRETO("Nome do Titulo")
retorna os valores da aba Resgate
=TESOURODIRETO("Nome do Titulo";"i")
retorna os valores da aba Investimento
Os valores unitário de cada título está certo para vcs? o meu não mostra no google sheets (c/script) igual a do site do Tesouro.
O script consegue acessar dois valores, se vc colocar:
=TESOURODIRETO("Nome do Titulo")
retorna os valores da aba Resgate=TESOURODIRETO("Nome do Titulo";"i")
retorna os valores da aba Investimento
Putz, valeu irmão. Aprendi contigo no seu canal a colocar os dados no script e agora mais essa, ajudou muito. Tudo de bom para vc.
pessoal,
aparentemente o endpoint oficial (https://www.tesourodireto.com.br/json/br/com/b3/tesourodireto/service/api/treasurybondsinfo.json) voltou a funcionar para as chamadas a partir do google app script.
[]'s
Aqui está a função do IPCA para quem quisar utilizar.
function IPCA(strBegin, strEnd){ let srcURL = "https://servicodados.ibge.gov.br/api/v1/conjunturais?&d=s&user=ibge&t=1737&v=2266&p="+ strBegin + "," + strEnd+"&ng=1(1)&c="; let jsondata = UrlFetchApp.fetch(srcURL); let parsedData = JSON.parse(jsondata) let dDiv = 1; let dDiv2 = 1; for (let tag of parsedData){ if (tag["p_cod"] == strBegin) { dDiv = tag["v"]; }else dDiv2 = tag["v"]; } return (dDiv2/dDiv) - 1; }
Pra quem está precisando de uma função no backend, php laravel,
use Illuminate\Support\Facades\Http; ////<<<<<<<< declare no seu Helper
public static function IPCA($inicio='202501',$fim='202502'){
try {
$params = [
'd' => 's',
'user' => 'ibge',
't' => '1737',
'v' => '2266',
'p' => Functions::somenteNumeros($inicio).','.Functions::somenteNumeros($fim),
'ng' => '1(1)',
'c' => ''
];
$response = Http::timeout(120)
->withoutVerifying()
->withHeaders(['Accept' => 'application/json'])
->get('https://servicodados.ibge.gov.br/api/v1/conjunturais', $params);
$dDiv = 1; $dDiv2 = 1; $data = $response->json();
foreach ($data as $tag) {
if ($tag['p_cod'] == $inicio) {
$dDiv = floatval($tag['v']);
} else {
$dDiv2 = floatval($tag['v']);
}
}
$ret = ($dDiv2/$dDiv) - 1;
return response()->json(['ipca' => $ret, 'ipca-data'=>$response->json() ?? ($response->json()['message']) ]);
} catch (\Exception $e){
return response()->json(['error'=>[$e->getMessage(), $e->getFile(), $e->getLine()]]);
}
}
public static function somenteNumeros($string){
return preg_replace("/[^0-9]/", "", $string);
}
Aqui está a função do IPCA para quem quisar utilizar.
function IPCA(strBegin, strEnd){ let srcURL = "https://servicodados.ibge.gov.br/api/v1/conjunturais?&d=s&user=ibge&t=1737&v=2266&p="+ strBegin + "," + strEnd+"&ng=1(1)&c="; let jsondata = UrlFetchApp.fetch(srcURL); let parsedData = JSON.parse(jsondata) let dDiv = 1; let dDiv2 = 1; for (let tag of parsedData){ if (tag["p_cod"] == strBegin) { dDiv = tag["v"]; }else dDiv2 = tag["v"]; } return (dDiv2/dDiv) - 1; }
Pra quem está precisando de uma função no backend, php laravel,
use Illuminate\Support\Facades\Http; ////<<<<<<<< declare no seu Helper public static function IPCA($inicio='202501',$fim='202502'){ try { $params = [ 'd' => 's', 'user' => 'ibge', 't' => '1737', 'v' => '2266', 'p' => Functions::somenteNumeros($inicio).','.Functions::somenteNumeros($fim), 'ng' => '1(1)', 'c' => '' ]; $response = Http::timeout(120) ->withoutVerifying() ->withHeaders(['Accept' => 'application/json']) ->get('https://servicodados.ibge.gov.br/api/v1/conjunturais', $params); $dDiv = 1; $dDiv2 = 1; $data = $response->json(); foreach ($data as $tag) { if ($tag['p_cod'] == $inicio) { $dDiv = floatval($tag['v']); } else { $dDiv2 = floatval($tag['v']); } } $ret = ($dDiv2/$dDiv) - 1; return response()->json(['ipca' => $ret, 'ipca-data'=>$response->json() ?? ($response->json()['message']) ]); } catch (\Exception $e){ return response()->json(['error'=>[$e->getMessage(), $e->getFile(), $e->getLine()]]); } } public static function somenteNumeros($string){ return preg_replace("/[^0-9]/", "", $string); }
Legal a idéia.
Qual seria o endpoint para resgatar informações mais básicas do IPCA.
Por exemplo, esses três dessa página do IBGE: https://www.ibge.gov.br/explica/inflacao.php
IPCA do último mês, IPCA acumulado de 12 meses, e INPC do último mês.
Teria como ter uma versão modificada?
Grato,
podes usar o Curl pra isso
function obterConteudoElementoJson($url, $elementSelector) {
// Inicializa o cURL
$curl = curl_init();
// Configura as opções do cURL
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // Desativa a verificação SSL (não recomendado em produção)
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // Desativa a verificação do host SSL (não recomendado em produção)
// Executa a requisição cURL
$html = curl_exec($curl);
// Verifica se houve erro
if ($html === false) {
echo 'Erro cURL: ' . curl_error($curl);
curl_close($curl);
return false;
}
// Fecha a conexão cURL
curl_close($curl);
// Cria um objeto DOMDocument para analisar o HTML
$dom = new DOMDocument();
@$dom->loadHTML('<?xml encoding="utf-8" ?>' . $html); // Supressão de erros de parsing (ex: tags não fechadas)
// Cria um objeto DOMXPath para executar consultas XPath
$xpath = new DOMXPath($dom);
// Executa a consulta XPath para encontrar o elemento desejado
$elementList = $xpath->query('//*[contains(@id, "' . str_replace('#', '', $elementSelector) . '")]');
if ($elementList->length > 0) {
$element = $elementList->item(0);
// Extrai os dados relevantes do elemento
$data = [];
$listItems = $xpath->query('./li', $element); // Seleciona todos os <li> dentro do elemento
foreach ($listItems as $listItem) {
$titulo = $xpath->query('./h3[@class="variavel-titulo"]/text()', $listItem)->item(0)->textContent;
$dado = $xpath->query('./p[@class="variavel-dado"]/text()', $listItem)->item(0)->textContent;
$periodo = $xpath->query('./p[@class="variavel-periodo"]/text()', $listItem)->item(0)->textContent;
$data[] = [
'titulo' => trim($titulo),
'dado' => trim($dado),
'periodo' => trim($periodo),
];
}
// Converte o array para JSON
return json_encode($data, JSON_UNESCAPED_UNICODE);
} else {
return false; // Elemento não encontrado
}
}
// Exemplo de uso:
$url = 'https://www.ibge.gov.br/explica/inflacao.php';
$elementSelector = '#dadoBrasil';
$json = obterConteudoElementoJson($url, $elementSelector);
if ($json !== false) {
header('Content-Type: application/json'); // Define o cabeçalho para JSON
echo $json;
} else {
echo "Não foi possível obter o conteúdo do elemento '$elementSelector' do site '$url'.";
}
Colocaram o Cloudflare na frente ou já tinha mas ativaram para que bots não possam acessar, exigindo aquela verificação de que é humano. :(
o 403 é do Cloudflare, tanto que funciona no navegador mas com scripts falha sempre.
Como eles não fornecem a chave de API para pessoas físicas, talvez a solução é baixar manualmente o arquivo quando se quiser ver a atualização. Alguma outra ideia?