Ações em massa úteis com a API do Octo Browser
24/03/2026


Alex Phillips
Customer Service Specialist
API (Application Programming Interface) é uma interface que permite que vários aplicativos interajam entre si. No caso do Octo Browser, a API permite que você envie solicitações HTTP para os servidores da Octo e automatize o gerenciamento de perfis de navegador.
Anteriormente, explicamos em detalhes o que é uma API, cobrimos maneiras de executar scripts e explicamos a estrutura das requisições. Agora, vamos apresentar vários exemplos úteis que são os mais procurados entre nossos usuários. Depois de ler este artigo, você aprenderá como recuperar e salvar nomes de perfis, adicionar extensões em massa, páginas iniciais e favoritos aos perfis criados, e exportar dados de perfil para uma planilha. Abaixo você encontrará instruções detalhadas e código pronto para uso.
Índice
Preparação
Baixe e instale o VS Code.
Baixe e instale o Node.js.
Crie uma pasta em um local conveniente e nomeie-a, por exemplo, octo_api.
Abra esta pasta no VS Code.
Crie um arquivo com extensão .js. É melhor nomeá-lo de acordo com a ação que o código irá executar para evitar confusão: por exemplo, get_titles.js.
Abra o terminal e execute o comando npm install axios para instalar uma dependência para o Node.js.
Se o VS Code mostrar um erro, abra o Windows PowerShell como administrador, insira o comando Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned e confirme. Em seguida, repita a etapa anterior.
Inicie o Octo Browser.
Onde encontrar seu token de API
Para interagir com o Octo Browser via API, você precisará de um token de API. Está disponível para usuários com uma assinatura Base e superior. O token de API é exibido no Octo Browser nas configurações da conta principal, na guia "Adicional" (outros membros da equipe não podem ver o token de API).

Limites de API (limites de taxa)
Lembre-se de que a API do Octo Browser tem limites de requisição. Os trechos fornecidos usam a função check_limits, que verifica os cabeçalhos de limites de taxa da API e pausa automaticamente se o número de requisições restantes for baixo. Isso ajuda a evitar erros 429 Too Many Requests.
Ao fazer requisições para a API Pública, 1 RPM e 1 RPH são consumidos por requisição. Quando usa a API Local, RPM/RPH não são consumidos, exceto para POST Start Profile (1 RPM e 1 RPH) e POST One-time profile (4 RPM e 4 RPH).
O número exato de perfis que você pode iniciar, criar e excluir sob uma assinatura específica depende totalmente de seus scripts e sua lógica. Você pode calcular de forma independente o número de requisições necessárias para seu fluxo de trabalho com base em quais requisições afetam os limites de RPH e RPM.
Algumas requisições de API podem exigir um processamento mais complexo, o que significa que sua execução pode custar mais do que uma única requisição. Isso é necessário para balancear a carga do servidor e garantir desempenho otimizado para todos os usuários.
RPM significa requisições por minuto.
RPH significa requisições por hora.
Os valores de limite de requisição dependem da sua assinatura.
Com a configuração completa, vamos passar para trechos de código úteis.
Recuperando nomes de perfil e salvando-os em um arquivo .txt
Este trecho é útil quando você precisa coletar rapidamente uma lista de todos os perfis criados em um único lugar. Ele ajuda a simplificar o rastreamento de perfis, verificar sua existência real e realizar outras ações com eles.
Crie um arquivo get_titles.js na pasta octo_api e cole o código do trecho nele.
Substitua OCTO_API_TOKEN no campo octo_token pelo seu token de API do Octo Browser.

Salve o arquivo.
Insira o comando node get_titles.js no terminal e execute o script.

Os nomes dos perfis serão salvos linha por linha no arquivo profiles_titles.txt na mesma pasta que o script.
Trecho para salvar nomes de perfis em um arquivo .txt
const fs = require('fs').promises; const axios = require('axios'); //This is the configuration. Specify your Octo API Token here const config = { octo_token: "OCTO_API_TOKEN", // Specify your API token here octo_api_base_url: "https://app.octobrowser.net/api/v2/automation/", } const OCTO_REMOTE_API = axios.create({ baseURL: config.octo_api_base_url, timeout: 10000, headers: { 'X-Octo-Api-Token': config.octo_token, 'Content-Type': "application/json" } }); async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms * 1000)); } async function check_limits(response) { function parse_int_safe(value) { const parsed = parseInt(value, 10); return isNaN(parsed) ? 0 : parsed; } const ratelimit_header = response.headers.ratelimit; if (!ratelimit_header) { console.warn('No ratelimit header found!'); return; } const limit_entries = ratelimit_header.split(',').map(entry => entry.trim()); for (const entry of limit_entries) { const name_match = entry.match(/^([^;]+)/); const r_match = entry.match(/;r=(\d+)/); const t_match = entry.match(/;t=(\d+)/); if (!r_match || !t_match) { console.warn(`Invalid ratelimit format: ${entry}`); continue; } const limit_name = name_match ? name_match[1] : 'unknown_limit'; const remaining_quantity = parse_int_safe(r_match[1]); const window_seconds = parse_int_safe(t_match[1]); if (remaining_quantity < 5) { const wait_time = window_seconds + 1; console.log(`Waiting ${wait_time} seconds due to ${limit_name} limit`); await sleep(wait_time); } } } async function get_total_pages() { const response = await OCTO_REMOTE_API.get('/profiles?page=0&page_len=10'); const total_profiles = response.data.total_count; const total_pages = Math.ceil(response.data.total_count / 100); console.log(`Total Profiles: ${total_profiles}\nTotal Pages: ${total_pages}`); await check_limits(response); return total_pages; } async function get_all_profiles_titles(total_pages) { let profiles = []; for (let i = 0; i < total_pages; i++) { let response = await OCTO_REMOTE_API.get(`/profiles?page=${i}&page_len=100&fields=title`); await check_limits(response); profiles.push(...response.data.data); } return profiles; } async function write_file(profiles) { const titles = profiles.map(item => item.title).filter(Boolean); try { await fs.writeFile('./profiles_titles.txt', titles.join('\n'), 'utf-8'); } catch (error) { console.error(`ERROR: While trying writing the file some error occured:\n${error}`); } } (async () => { const total_pages = await get_total_pages(); const profiles = await get_all_profiles_titles(total_pages); await write_file(profiles); console.log('Finished. Check profiles_titles.txt file...'); })()
const fs = require('fs').promises; const axios = require('axios'); //This is the configuration. Specify your Octo API Token here const config = { octo_token: "OCTO_API_TOKEN", // Specify your API token here octo_api_base_url: "https://app.octobrowser.net/api/v2/automation/", } const OCTO_REMOTE_API = axios.create({ baseURL: config.octo_api_base_url, timeout: 10000, headers: { 'X-Octo-Api-Token': config.octo_token, 'Content-Type': "application/json" } }); async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms * 1000)); } async function check_limits(response) { function parse_int_safe(value) { const parsed = parseInt(value, 10); return isNaN(parsed) ? 0 : parsed; } const ratelimit_header = response.headers.ratelimit; if (!ratelimit_header) { console.warn('No ratelimit header found!'); return; } const limit_entries = ratelimit_header.split(',').map(entry => entry.trim()); for (const entry of limit_entries) { const name_match = entry.match(/^([^;]+)/); const r_match = entry.match(/;r=(\d+)/); const t_match = entry.match(/;t=(\d+)/); if (!r_match || !t_match) { console.warn(`Invalid ratelimit format: ${entry}`); continue; } const limit_name = name_match ? name_match[1] : 'unknown_limit'; const remaining_quantity = parse_int_safe(r_match[1]); const window_seconds = parse_int_safe(t_match[1]); if (remaining_quantity < 5) { const wait_time = window_seconds + 1; console.log(`Waiting ${wait_time} seconds due to ${limit_name} limit`); await sleep(wait_time); } } } async function get_total_pages() { const response = await OCTO_REMOTE_API.get('/profiles?page=0&page_len=10'); const total_profiles = response.data.total_count; const total_pages = Math.ceil(response.data.total_count / 100); console.log(`Total Profiles: ${total_profiles}\nTotal Pages: ${total_pages}`); await check_limits(response); return total_pages; } async function get_all_profiles_titles(total_pages) { let profiles = []; for (let i = 0; i < total_pages; i++) { let response = await OCTO_REMOTE_API.get(`/profiles?page=${i}&page_len=100&fields=title`); await check_limits(response); profiles.push(...response.data.data); } return profiles; } async function write_file(profiles) { const titles = profiles.map(item => item.title).filter(Boolean); try { await fs.writeFile('./profiles_titles.txt', titles.join('\n'), 'utf-8'); } catch (error) { console.error(`ERROR: While trying writing the file some error occured:\n${error}`); } } (async () => { const total_pages = await get_total_pages(); const profiles = await get_all_profiles_titles(total_pages); await write_file(profiles); console.log('Finished. Check profiles_titles.txt file...'); })()
Adicionar extensões, páginas iniciais e favoritos aos perfis
Este script de automação permite que você padronize rapidamente as configurações de perfil e evite adicionar manualmente os mesmos parâmetros.
Para adicionar extensões, você precisará dos UUIDs delas:
Abra um perfil com a extensão instalada.
Na barra de endereços do perfil, insira chrome://extensions/ e pressione Enter.
Na extensão desejada, clique no botão “Detalhes”.

No final da página, copie o UUID da extensão junto com sua versão.

Você pode encontrar métodos para recuperar UUIDs via API na documentação.
Em seguida, você precisa editar o código:
Crie um arquivo nomeado adding_info.js na pasta octo_api.
Cole o trecho nele.
Insira seu token de API no campo octo_token.
Adicione os UUIDs das extensões necessárias ao campo extensions.
Adicione o nome (título do favorito) e o URL (endereço do site) ao campo bookmarks.
Adicione os URLs dos sites que você deseja abrir automaticamente ao iniciar o perfil no campo start_pages.
Se você só precisa adicionar extensões, favoritos ou páginas iniciais, pode remover os parâmetros desnecessários do trecho:
data: { extensions: ["nkbihfbeogaeaoehlefnkodbefgpgknn@12.17.2"], //remove if you don’t need to add extensions bookmarks: [ { name: "google", url: "https://google.com" }, { name: "facebook", url: "https://facebook.com" } ],//remove if you don’t need bookmarks start_pages: ["https://google.com", "https://facebook.com"] //remove if you don’t need start pages }data: { extensions: ["nkbihfbeogaeaoehlefnkodbefgpgknn@12.17.2"], //remove if you don’t need to add extensions bookmarks: [ { name: "google", url: "https://google.com" }, { name: "facebook", url: "https://facebook.com" } ],//remove if you don’t need bookmarks start_pages: ["https://google.com", "https://facebook.com"] //remove if you don’t need start pages }

Salve o arquivo adding_info.js.
Execute-o usando o comando node adding_info.js.
As extensões, favoritos e páginas iniciais necessários serão adicionados a todos os seus perfis. Se você precisar aplicar alterações apenas a perfis específicos, consulte o exemplo na documentação.

Antes de executar o script, certifique-se de que os perfis que deseja atualizar não estejam em execução. Perfis em execução não serão atualizados.
Trecho para adicionar extensões, páginas iniciais e favoritos aos perfis
const axios = require('axios'); // This is the configuration. Specify your Octo API Token here; you can modify this for your personal needs const config = { octo_token: "OCTO_API_TOKEN", // Specify your API token here octo_api_base_url: "https://app.octobrowser.net/api/v2/automation/", data: { "extensions": ["aapfglkgnhmiaabhiijkjpfmhllaodgp@4.2.3"], "bookmarks": [ { "name": "google", "url": "https://google.com" }, { "name": "facebook", "url": "https://facebook.com" } ], "start_pages": ["https://google.com", "https://facebook.com"] } } const OCTO_REMOTE_API = axios.create({ baseURL: config.octo_api_base_url, timeout: 10000, headers: { 'X-Octo-Api-Token': config.octo_token, 'Content-Type': "application/json" } }); //functions async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms * 1000)); } async function check_limits(response) { function parse_int_safe(value) { const parsed = parseInt(value, 10); return isNaN(parsed) ? 0 : parsed; } const ratelimit_header = response.headers.ratelimit; if (!ratelimit_header) { console.warn('No ratelimit header found!'); return; } const limit_entries = ratelimit_header.split(',').map(entry => entry.trim()); for (const entry of limit_entries) { const name_match = entry.match(/^([^;]+)/); const r_match = entry.match(/;r=(\d+)/); const t_match = entry.match(/;t=(\d+)/); if (!r_match || !t_match) { console.warn(`Invalid ratelimit format: ${entry}`); continue; } const limit_name = name_match ? name_match[1] : 'unknown_limit'; const remaining_quantity = parse_int_safe(r_match[1]); const window_seconds = parse_int_safe(t_match[1]); if (remaining_quantity < 5) { const wait_time = window_seconds + 1; console.log(`Waiting ${wait_time} seconds due to ${limit_name} limit`); await sleep(wait_time); } } } async function get_total_profiles() { const response = await OCTO_REMOTE_API.get('/profiles?page=0&page_len=10'); const total_profiles = response.data.total_count; const total_pages = Math.ceil(response.data.total_count / 100); console.log(`Total Profiles: ${total_profiles}\nTotal Pages: ${total_pages}`); await check_limits(response); return total_pages; } async function get_all_profiles_uuids(total_pages) { let profiles = []; for (let i = 0; i < total_pages; i++) { let response = await OCTO_REMOTE_API.get(`/profiles?page=${i}&page_len=100`); await check_limits(response); profiles.push(...response.data.data); } return profiles; } async function patch_all_profiles(profiles) { let updated = []; let not_updated = []; for (let profile of profiles) { try { const response = await OCTO_REMOTE_API.patch(`/profiles/${profile.uuid}`, config.data); await check_limits(response); updated.push(profile); console.log(`Successfully updated ${profile.uuid}`); } catch (error) { not_updated.push(profile); console.error(`ERROR: Can't patch profile ${profile.uuid}`); } } return [updated, not_updated]; } (async () => { const total = await get_total_profiles(); const profiles = await get_all_profiles_uuids(total); const [updated, not_updated] = await patch_all_profiles(profiles); console.log(`Finished process:\nUpdated: ${updated.length}\nNot updated: ${not_updated.length}`); })();
const axios = require('axios'); // This is the configuration. Specify your Octo API Token here; you can modify this for your personal needs const config = { octo_token: "OCTO_API_TOKEN", // Specify your API token here octo_api_base_url: "https://app.octobrowser.net/api/v2/automation/", data: { "extensions": ["aapfglkgnhmiaabhiijkjpfmhllaodgp@4.2.3"], "bookmarks": [ { "name": "google", "url": "https://google.com" }, { "name": "facebook", "url": "https://facebook.com" } ], "start_pages": ["https://google.com", "https://facebook.com"] } } const OCTO_REMOTE_API = axios.create({ baseURL: config.octo_api_base_url, timeout: 10000, headers: { 'X-Octo-Api-Token': config.octo_token, 'Content-Type': "application/json" } }); //functions async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms * 1000)); } async function check_limits(response) { function parse_int_safe(value) { const parsed = parseInt(value, 10); return isNaN(parsed) ? 0 : parsed; } const ratelimit_header = response.headers.ratelimit; if (!ratelimit_header) { console.warn('No ratelimit header found!'); return; } const limit_entries = ratelimit_header.split(',').map(entry => entry.trim()); for (const entry of limit_entries) { const name_match = entry.match(/^([^;]+)/); const r_match = entry.match(/;r=(\d+)/); const t_match = entry.match(/;t=(\d+)/); if (!r_match || !t_match) { console.warn(`Invalid ratelimit format: ${entry}`); continue; } const limit_name = name_match ? name_match[1] : 'unknown_limit'; const remaining_quantity = parse_int_safe(r_match[1]); const window_seconds = parse_int_safe(t_match[1]); if (remaining_quantity < 5) { const wait_time = window_seconds + 1; console.log(`Waiting ${wait_time} seconds due to ${limit_name} limit`); await sleep(wait_time); } } } async function get_total_profiles() { const response = await OCTO_REMOTE_API.get('/profiles?page=0&page_len=10'); const total_profiles = response.data.total_count; const total_pages = Math.ceil(response.data.total_count / 100); console.log(`Total Profiles: ${total_profiles}\nTotal Pages: ${total_pages}`); await check_limits(response); return total_pages; } async function get_all_profiles_uuids(total_pages) { let profiles = []; for (let i = 0; i < total_pages; i++) { let response = await OCTO_REMOTE_API.get(`/profiles?page=${i}&page_len=100`); await check_limits(response); profiles.push(...response.data.data); } return profiles; } async function patch_all_profiles(profiles) { let updated = []; let not_updated = []; for (let profile of profiles) { try { const response = await OCTO_REMOTE_API.patch(`/profiles/${profile.uuid}`, config.data); await check_limits(response); updated.push(profile); console.log(`Successfully updated ${profile.uuid}`); } catch (error) { not_updated.push(profile); console.error(`ERROR: Can't patch profile ${profile.uuid}`); } } return [updated, not_updated]; } (async () => { const total = await get_total_profiles(); const profiles = await get_all_profiles_uuids(total); const [updated, not_updated] = await patch_all_profiles(profiles); console.log(`Finished process:\nUpdated: ${updated.length}\nNot updated: ${not_updated.length}`); })();
Exportando dados de perfil para o Google Sheets
Você pode exportar seus dados de perfil para uma planilha. Isso facilita a estruturação das informações, bem como classificá-las e analisá-las. Você pode exportar os seguintes parâmetros de perfil:
UUID,
tags,
nome,
descrição.
Crie um arquivo nomeado google_sheets.js na pasta octo_api.
Adicione o código do trecho ao arquivo.
Preencha o campo octo_token. O token de API pode ser encontrado no Octo Browser.
Preencha o campo table_id. Este é o ID do seu documento Google Sheets.
Preencha o campo table_sheet_name. Este é o nome da folha dentro do documento Google Sheets onde você deseja exportar os dados.

Salve as alterações.
Adicione os arquivos credentials.json e token.json à pasta octo_api.
Execute o script no terminal do VS Code usando o comando node google_sheets.js.
Uma vez que o script termine, os dados serão carregados na planilha especificada.

Trecho para exportar dados de perfil para o Google Sheets
const axios = require('axios'); const { google } = require('googleapis'); const token = require('./token.json'); const credentials = require('./credentials.json'); const oAuth2Client = new google.auth.OAuth2( credentials.installed.client_id, credentials.installed.client_secret, credentials.installed.redirect_uris[0] ); oAuth2Client.setCredentials(token); //configuration //Paste your Octo API token, spreadsheet ID and sheet name here const config = { octo_token: "OCTO_API_TOKEN", table_id: "1pqnVysHymZSI5Lzx6odasdasAqE022fqUEf6q5LnOqAhylLSM", table_sheet_name: "Profiles", octo_api_base_url: "https://app.octobrowser.net/api/v2/automation/", } const OCTO_REMOTE_API = axios.create({ baseURL: config.octo_api_base_url, timeout: 10000, headers: { 'X-Octo-Api-Token': config.octo_token, 'Content-Type': "application/json" } }); //functions async function check_limits(response) { function parse_int_safe(value) { const parsed = parseInt(value, 10); return isNaN(parsed) ? 0 : parsed; } const ratelimit_header = response.headers.ratelimit; if (!ratelimit_header) { console.warn('No ratelimit header found!'); return; } const limit_entries = ratelimit_header.split(',').map(entry => entry.trim()); for (const entry of limit_entries) { const name_match = entry.match(/^([^;]+)/); const r_match = entry.match(/;r=(\d+)/); const t_match = entry.match(/;t=(\d+)/); if (!r_match || !t_match) { console.warn(`Invalid ratelimit format: ${entry}`); continue; } const limit_name = name_match ? name_match[1] : 'unknown_limit'; const remaining_quantity = parse_int_safe(r_match[1]); const window_seconds = parse_int_safe(t_match[1]); if (remaining_quantity < 5) { const wait_time = window_seconds + 1; console.log(`Waiting ${wait_time} seconds due to ${limit_name} limit`); await sleep(wait_time); } } } async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms * 1000)); } async function get_total_pages() { const response = await OCTO_REMOTE_API.get('/profiles?page=0&page_len=10'); const total_profiles = response.data.total_count; const total_pages = Math.ceil(response.data.total_count / 100); console.log(`Total Profiles: ${total_profiles}\nTotal Pages: ${total_pages}`); await check_limits(response); return total_pages; } async function get_all_profiles_data(total_pages) { let profiles = []; for (let i = 0; i < total_pages; i++) { let response = await OCTO_REMOTE_API.get(`/profiles?page=${i}&page_len=100&fields=title,description,tags`); await check_limits(response); profiles.push(...response.data.data); } return profiles; } async function fill_sheet_with_data(oAuth2Client, spreadsheet_id, list_name, data) { const sheets = google.sheets({ version: 'v4', auth: oAuth2Client }); try { const sheetInfo = await sheets.spreadsheets.get({ spreadsheetId: spreadsheet_id, }); const sheetExists = sheetInfo.data.sheets.some( sheet => sheet.properties.title === list_name ); if (!sheetExists) { await sheets.spreadsheets.batchUpdate({ spreadsheetId: spreadsheet_id, resource: { requests: [{ addSheet: { properties: { title: list_name } } }] } }); console.log(`Создан новый лист "${list_name}".`); } const headers = ['Uuid', 'Tags', 'Title', 'Description']; const values = data.map(item => [ item.uuid, Array.isArray(item.tags) ? item.tags.join(', ') : item.tags, item.title, item.description || '' ]); await sheets.spreadsheets.values.update({ spreadsheetId: spreadsheet_id, range: `${list_name}!A1:D1`, valueInputOption: 'RAW', resource: { values: [headers] } }); await sheets.spreadsheets.values.update({ spreadsheetId: spreadsheet_id, range: `${list_name}!A2:D${values.length + 1}`, valueInputOption: 'RAW', resource: { values: values } }); console.log(`Данные успешно записаны в лист "${list_name}".`); } catch (err) { console.error('Ошибка при обновлении таблицы:', err); throw err; } } (async () => { const total_pages = await get_total_pages(); const profiles_data = await get_all_profiles_data(total_pages); await fill_sheet_with_data(oAuth2Client, config.table_id, config.table_sheet_name, profiles_data); })()
const axios = require('axios'); const { google } = require('googleapis'); const token = require('./token.json'); const credentials = require('./credentials.json'); const oAuth2Client = new google.auth.OAuth2( credentials.installed.client_id, credentials.installed.client_secret, credentials.installed.redirect_uris[0] ); oAuth2Client.setCredentials(token); //configuration //Paste your Octo API token, spreadsheet ID and sheet name here const config = { octo_token: "OCTO_API_TOKEN", table_id: "1pqnVysHymZSI5Lzx6odasdasAqE022fqUEf6q5LnOqAhylLSM", table_sheet_name: "Profiles", octo_api_base_url: "https://app.octobrowser.net/api/v2/automation/", } const OCTO_REMOTE_API = axios.create({ baseURL: config.octo_api_base_url, timeout: 10000, headers: { 'X-Octo-Api-Token': config.octo_token, 'Content-Type': "application/json" } }); //functions async function check_limits(response) { function parse_int_safe(value) { const parsed = parseInt(value, 10); return isNaN(parsed) ? 0 : parsed; } const ratelimit_header = response.headers.ratelimit; if (!ratelimit_header) { console.warn('No ratelimit header found!'); return; } const limit_entries = ratelimit_header.split(',').map(entry => entry.trim()); for (const entry of limit_entries) { const name_match = entry.match(/^([^;]+)/); const r_match = entry.match(/;r=(\d+)/); const t_match = entry.match(/;t=(\d+)/); if (!r_match || !t_match) { console.warn(`Invalid ratelimit format: ${entry}`); continue; } const limit_name = name_match ? name_match[1] : 'unknown_limit'; const remaining_quantity = parse_int_safe(r_match[1]); const window_seconds = parse_int_safe(t_match[1]); if (remaining_quantity < 5) { const wait_time = window_seconds + 1; console.log(`Waiting ${wait_time} seconds due to ${limit_name} limit`); await sleep(wait_time); } } } async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms * 1000)); } async function get_total_pages() { const response = await OCTO_REMOTE_API.get('/profiles?page=0&page_len=10'); const total_profiles = response.data.total_count; const total_pages = Math.ceil(response.data.total_count / 100); console.log(`Total Profiles: ${total_profiles}\nTotal Pages: ${total_pages}`); await check_limits(response); return total_pages; } async function get_all_profiles_data(total_pages) { let profiles = []; for (let i = 0; i < total_pages; i++) { let response = await OCTO_REMOTE_API.get(`/profiles?page=${i}&page_len=100&fields=title,description,tags`); await check_limits(response); profiles.push(...response.data.data); } return profiles; } async function fill_sheet_with_data(oAuth2Client, spreadsheet_id, list_name, data) { const sheets = google.sheets({ version: 'v4', auth: oAuth2Client }); try { const sheetInfo = await sheets.spreadsheets.get({ spreadsheetId: spreadsheet_id, }); const sheetExists = sheetInfo.data.sheets.some( sheet => sheet.properties.title === list_name ); if (!sheetExists) { await sheets.spreadsheets.batchUpdate({ spreadsheetId: spreadsheet_id, resource: { requests: [{ addSheet: { properties: { title: list_name } } }] } }); console.log(`Создан новый лист "${list_name}".`); } const headers = ['Uuid', 'Tags', 'Title', 'Description']; const values = data.map(item => [ item.uuid, Array.isArray(item.tags) ? item.tags.join(', ') : item.tags, item.title, item.description || '' ]); await sheets.spreadsheets.values.update({ spreadsheetId: spreadsheet_id, range: `${list_name}!A1:D1`, valueInputOption: 'RAW', resource: { values: [headers] } }); await sheets.spreadsheets.values.update({ spreadsheetId: spreadsheet_id, range: `${list_name}!A2:D${values.length + 1}`, valueInputOption: 'RAW', resource: { values: values } }); console.log(`Данные успешно записаны в лист "${list_name}".`); } catch (err) { console.error('Ошибка при обновлении таблицы:', err); throw err; } } (async () => { const total_pages = await get_total_pages(); const profiles_data = await get_all_profiles_data(total_pages); await fill_sheet_with_data(oAuth2Client, config.table_id, config.table_sheet_name, profiles_data); })()
Como obter table_id
Abra ou crie uma planilha no Google Sheets.
Copie o ID da tabela. Esta é a parte do URL entre
/d/e/edit.
Por exemplo, se seu link parecer https://docs.google.com/spreadsheets/d/1GoPnhkStxFFxDzGZjjXSyjT_H_msHlSDx51tBROewOA/edit, então o table_id é 1GoPnhkStxFFxDzGZjjXSyjT_H_msHlSDx51tBROewOA.
Como obter o arquivo credentials.json
Faça login em uma conta pessoal (não organizacional) do Gmail.
Selecione qualquer país europeu na lista e clique em Concordar e continuar.
Clique em Selecionar um projeto, depois em Novo projeto.
Insira qualquer nome de projeto e clique em Criar.
Acesse https://console.cloud.google.com/auth e clique em Começar.
Insira qualquer Nome do App, seu e-mail, e clique em Próximo.
Selecione Externo, insira seu e-mail novamente, clique em Próximo, marque a caixa de consentimento, depois clique em Continuar e Finalizar.
Na seção Testar Usuários, clique em Adicionar Usuários.

Adicione seu e-mail e clique em Salvar.
Na página https://console.cloud.google.com/auth/overview, clique em Criar Cliente OAuth.

Selecione Aplicativo de escritório na lista, insira qualquer nome e clique em Criar.
Uma janela pop-up aparecerá. Baixe o arquivo JSON dela.

Pesquise por Google Sheets API.
Selecione-o e clique em Ativar.
Abra o arquivo JSON baixado anteriormente.
Altere o valor de
redirect_urisdehttp://localhostpara"redirect_uris": ["urn:ietf:wg:oauth:2.0:oob","http://localhost"].
Faça a alteração com cuidado para não remover acidentalmente os colchetes.

Salve o arquivo.
Renomeie-o para credentials.json.
Adicione-o à pasta octo_api.
Como obter o arquivo token.json
Crie um arquivo chamado get_token.js na pasta octo_api e abra-o no VS Code.
Execute o comando Npm install googleapis no terminal do VS Code.
Cole o script de geração de token em get_token.js e salve o arquivo.
Execute o script usando node get_token.js.
Você verá um link dizendo Abra essa URL no navegador:
https://accounts.google.com/o/oauth2/…Abra o link.
Faça login na sua conta Google.
Clique nas telas de consentimento.
Na página final, o Google exibirá um código de autorização.

Cole o código no terminal e pressione Enter.
O script então criará um arquivo token.json na pasta onde você o executou.

Script de geração de token
const fs = require('fs'); const readline = require('readline'); const { google } = require('googleapis'); const CREDENTIALS_PATH = 'credentials.json'; const TOKEN_PATH = 'token.json'; const credentials = JSON.parse(fs.readFileSync(CREDENTIALS_PATH)); const { client_secret, client_id, redirect_uris } = credentials.installed; const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]); const SCOPES = ['https://www.googleapis.com/auth/spreadsheets']; const authUrl = oAuth2Client.generateAuthUrl({ access_type: 'offline', scope: SCOPES, }); console.log('Open this URL in browser:', authUrl); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.question('Enter the code from that page here: ', (code) => { rl.close(); oAuth2Client.getToken(code, (err, token) => { if (err) return console.error('Error retrieving access token', err); fs.writeFileSync(TOKEN_PATH, JSON.stringify(token)); console.log('Token stored to', TOKEN_PATH); }); });
const fs = require('fs'); const readline = require('readline'); const { google } = require('googleapis'); const CREDENTIALS_PATH = 'credentials.json'; const TOKEN_PATH = 'token.json'; const credentials = JSON.parse(fs.readFileSync(CREDENTIALS_PATH)); const { client_secret, client_id, redirect_uris } = credentials.installed; const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]); const SCOPES = ['https://www.googleapis.com/auth/spreadsheets']; const authUrl = oAuth2Client.generateAuthUrl({ access_type: 'offline', scope: SCOPES, }); console.log('Open this URL in browser:', authUrl); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.question('Enter the code from that page here: ', (code) => { rl.close(); oAuth2Client.getToken(code, (err, token) => { if (err) return console.error('Error retrieving access token', err); fs.writeFileSync(TOKEN_PATH, JSON.stringify(token)); console.log('Token stored to', TOKEN_PATH); }); });
Conclusão
Usamos a linguagem de programação Node.js nos exemplos deste artigo. Você pode encontrar trechos úteis em outras linguagens na nossa documentação.

Neste artigo, cobrimos:
como preparar seu ambiente;
como obter seu token de API do Octo Browser;
como recuperar um UUID de extensão;
como obter nomes de perfis usando API e salvá-los em um arquivo de texto;
como adicionar extensões, favoritos e páginas iniciais em massa a perfis existentes;
como exportar dados de perfil para o Google Sheets.
Se você ainda tiver dúvidas ou não conseguiu encontrar o exemplo que precisa na documentação, sinta-se à vontade para entrar em contato com nosso Atendimento ao Cliente no Telegram ou usando nosso chat do site ou o widget do navegador.
Preparação
Baixe e instale o VS Code.
Baixe e instale o Node.js.
Crie uma pasta em um local conveniente e nomeie-a, por exemplo, octo_api.
Abra esta pasta no VS Code.
Crie um arquivo com extensão .js. É melhor nomeá-lo de acordo com a ação que o código irá executar para evitar confusão: por exemplo, get_titles.js.
Abra o terminal e execute o comando npm install axios para instalar uma dependência para o Node.js.
Se o VS Code mostrar um erro, abra o Windows PowerShell como administrador, insira o comando Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned e confirme. Em seguida, repita a etapa anterior.
Inicie o Octo Browser.
Onde encontrar seu token de API
Para interagir com o Octo Browser via API, você precisará de um token de API. Está disponível para usuários com uma assinatura Base e superior. O token de API é exibido no Octo Browser nas configurações da conta principal, na guia "Adicional" (outros membros da equipe não podem ver o token de API).

Limites de API (limites de taxa)
Lembre-se de que a API do Octo Browser tem limites de requisição. Os trechos fornecidos usam a função check_limits, que verifica os cabeçalhos de limites de taxa da API e pausa automaticamente se o número de requisições restantes for baixo. Isso ajuda a evitar erros 429 Too Many Requests.
Ao fazer requisições para a API Pública, 1 RPM e 1 RPH são consumidos por requisição. Quando usa a API Local, RPM/RPH não são consumidos, exceto para POST Start Profile (1 RPM e 1 RPH) e POST One-time profile (4 RPM e 4 RPH).
O número exato de perfis que você pode iniciar, criar e excluir sob uma assinatura específica depende totalmente de seus scripts e sua lógica. Você pode calcular de forma independente o número de requisições necessárias para seu fluxo de trabalho com base em quais requisições afetam os limites de RPH e RPM.
Algumas requisições de API podem exigir um processamento mais complexo, o que significa que sua execução pode custar mais do que uma única requisição. Isso é necessário para balancear a carga do servidor e garantir desempenho otimizado para todos os usuários.
RPM significa requisições por minuto.
RPH significa requisições por hora.
Os valores de limite de requisição dependem da sua assinatura.
Com a configuração completa, vamos passar para trechos de código úteis.
Recuperando nomes de perfil e salvando-os em um arquivo .txt
Este trecho é útil quando você precisa coletar rapidamente uma lista de todos os perfis criados em um único lugar. Ele ajuda a simplificar o rastreamento de perfis, verificar sua existência real e realizar outras ações com eles.
Crie um arquivo get_titles.js na pasta octo_api e cole o código do trecho nele.
Substitua OCTO_API_TOKEN no campo octo_token pelo seu token de API do Octo Browser.

Salve o arquivo.
Insira o comando node get_titles.js no terminal e execute o script.

Os nomes dos perfis serão salvos linha por linha no arquivo profiles_titles.txt na mesma pasta que o script.
Trecho para salvar nomes de perfis em um arquivo .txt
const fs = require('fs').promises; const axios = require('axios'); //This is the configuration. Specify your Octo API Token here const config = { octo_token: "OCTO_API_TOKEN", // Specify your API token here octo_api_base_url: "https://app.octobrowser.net/api/v2/automation/", } const OCTO_REMOTE_API = axios.create({ baseURL: config.octo_api_base_url, timeout: 10000, headers: { 'X-Octo-Api-Token': config.octo_token, 'Content-Type': "application/json" } }); async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms * 1000)); } async function check_limits(response) { function parse_int_safe(value) { const parsed = parseInt(value, 10); return isNaN(parsed) ? 0 : parsed; } const ratelimit_header = response.headers.ratelimit; if (!ratelimit_header) { console.warn('No ratelimit header found!'); return; } const limit_entries = ratelimit_header.split(',').map(entry => entry.trim()); for (const entry of limit_entries) { const name_match = entry.match(/^([^;]+)/); const r_match = entry.match(/;r=(\d+)/); const t_match = entry.match(/;t=(\d+)/); if (!r_match || !t_match) { console.warn(`Invalid ratelimit format: ${entry}`); continue; } const limit_name = name_match ? name_match[1] : 'unknown_limit'; const remaining_quantity = parse_int_safe(r_match[1]); const window_seconds = parse_int_safe(t_match[1]); if (remaining_quantity < 5) { const wait_time = window_seconds + 1; console.log(`Waiting ${wait_time} seconds due to ${limit_name} limit`); await sleep(wait_time); } } } async function get_total_pages() { const response = await OCTO_REMOTE_API.get('/profiles?page=0&page_len=10'); const total_profiles = response.data.total_count; const total_pages = Math.ceil(response.data.total_count / 100); console.log(`Total Profiles: ${total_profiles}\nTotal Pages: ${total_pages}`); await check_limits(response); return total_pages; } async function get_all_profiles_titles(total_pages) { let profiles = []; for (let i = 0; i < total_pages; i++) { let response = await OCTO_REMOTE_API.get(`/profiles?page=${i}&page_len=100&fields=title`); await check_limits(response); profiles.push(...response.data.data); } return profiles; } async function write_file(profiles) { const titles = profiles.map(item => item.title).filter(Boolean); try { await fs.writeFile('./profiles_titles.txt', titles.join('\n'), 'utf-8'); } catch (error) { console.error(`ERROR: While trying writing the file some error occured:\n${error}`); } } (async () => { const total_pages = await get_total_pages(); const profiles = await get_all_profiles_titles(total_pages); await write_file(profiles); console.log('Finished. Check profiles_titles.txt file...'); })()
Adicionar extensões, páginas iniciais e favoritos aos perfis
Este script de automação permite que você padronize rapidamente as configurações de perfil e evite adicionar manualmente os mesmos parâmetros.
Para adicionar extensões, você precisará dos UUIDs delas:
Abra um perfil com a extensão instalada.
Na barra de endereços do perfil, insira chrome://extensions/ e pressione Enter.
Na extensão desejada, clique no botão “Detalhes”.

No final da página, copie o UUID da extensão junto com sua versão.

Você pode encontrar métodos para recuperar UUIDs via API na documentação.
Em seguida, você precisa editar o código:
Crie um arquivo nomeado adding_info.js na pasta octo_api.
Cole o trecho nele.
Insira seu token de API no campo octo_token.
Adicione os UUIDs das extensões necessárias ao campo extensions.
Adicione o nome (título do favorito) e o URL (endereço do site) ao campo bookmarks.
Adicione os URLs dos sites que você deseja abrir automaticamente ao iniciar o perfil no campo start_pages.
Se você só precisa adicionar extensões, favoritos ou páginas iniciais, pode remover os parâmetros desnecessários do trecho:
data: { extensions: ["nkbihfbeogaeaoehlefnkodbefgpgknn@12.17.2"], //remove if you don’t need to add extensions bookmarks: [ { name: "google", url: "https://google.com" }, { name: "facebook", url: "https://facebook.com" } ],//remove if you don’t need bookmarks start_pages: ["https://google.com", "https://facebook.com"] //remove if you don’t need start pages }

Salve o arquivo adding_info.js.
Execute-o usando o comando node adding_info.js.
As extensões, favoritos e páginas iniciais necessários serão adicionados a todos os seus perfis. Se você precisar aplicar alterações apenas a perfis específicos, consulte o exemplo na documentação.

Antes de executar o script, certifique-se de que os perfis que deseja atualizar não estejam em execução. Perfis em execução não serão atualizados.
Trecho para adicionar extensões, páginas iniciais e favoritos aos perfis
const axios = require('axios'); // This is the configuration. Specify your Octo API Token here; you can modify this for your personal needs const config = { octo_token: "OCTO_API_TOKEN", // Specify your API token here octo_api_base_url: "https://app.octobrowser.net/api/v2/automation/", data: { "extensions": ["aapfglkgnhmiaabhiijkjpfmhllaodgp@4.2.3"], "bookmarks": [ { "name": "google", "url": "https://google.com" }, { "name": "facebook", "url": "https://facebook.com" } ], "start_pages": ["https://google.com", "https://facebook.com"] } } const OCTO_REMOTE_API = axios.create({ baseURL: config.octo_api_base_url, timeout: 10000, headers: { 'X-Octo-Api-Token': config.octo_token, 'Content-Type': "application/json" } }); //functions async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms * 1000)); } async function check_limits(response) { function parse_int_safe(value) { const parsed = parseInt(value, 10); return isNaN(parsed) ? 0 : parsed; } const ratelimit_header = response.headers.ratelimit; if (!ratelimit_header) { console.warn('No ratelimit header found!'); return; } const limit_entries = ratelimit_header.split(',').map(entry => entry.trim()); for (const entry of limit_entries) { const name_match = entry.match(/^([^;]+)/); const r_match = entry.match(/;r=(\d+)/); const t_match = entry.match(/;t=(\d+)/); if (!r_match || !t_match) { console.warn(`Invalid ratelimit format: ${entry}`); continue; } const limit_name = name_match ? name_match[1] : 'unknown_limit'; const remaining_quantity = parse_int_safe(r_match[1]); const window_seconds = parse_int_safe(t_match[1]); if (remaining_quantity < 5) { const wait_time = window_seconds + 1; console.log(`Waiting ${wait_time} seconds due to ${limit_name} limit`); await sleep(wait_time); } } } async function get_total_profiles() { const response = await OCTO_REMOTE_API.get('/profiles?page=0&page_len=10'); const total_profiles = response.data.total_count; const total_pages = Math.ceil(response.data.total_count / 100); console.log(`Total Profiles: ${total_profiles}\nTotal Pages: ${total_pages}`); await check_limits(response); return total_pages; } async function get_all_profiles_uuids(total_pages) { let profiles = []; for (let i = 0; i < total_pages; i++) { let response = await OCTO_REMOTE_API.get(`/profiles?page=${i}&page_len=100`); await check_limits(response); profiles.push(...response.data.data); } return profiles; } async function patch_all_profiles(profiles) { let updated = []; let not_updated = []; for (let profile of profiles) { try { const response = await OCTO_REMOTE_API.patch(`/profiles/${profile.uuid}`, config.data); await check_limits(response); updated.push(profile); console.log(`Successfully updated ${profile.uuid}`); } catch (error) { not_updated.push(profile); console.error(`ERROR: Can't patch profile ${profile.uuid}`); } } return [updated, not_updated]; } (async () => { const total = await get_total_profiles(); const profiles = await get_all_profiles_uuids(total); const [updated, not_updated] = await patch_all_profiles(profiles); console.log(`Finished process:\nUpdated: ${updated.length}\nNot updated: ${not_updated.length}`); })();
Exportando dados de perfil para o Google Sheets
Você pode exportar seus dados de perfil para uma planilha. Isso facilita a estruturação das informações, bem como classificá-las e analisá-las. Você pode exportar os seguintes parâmetros de perfil:
UUID,
tags,
nome,
descrição.
Crie um arquivo nomeado google_sheets.js na pasta octo_api.
Adicione o código do trecho ao arquivo.
Preencha o campo octo_token. O token de API pode ser encontrado no Octo Browser.
Preencha o campo table_id. Este é o ID do seu documento Google Sheets.
Preencha o campo table_sheet_name. Este é o nome da folha dentro do documento Google Sheets onde você deseja exportar os dados.

Salve as alterações.
Adicione os arquivos credentials.json e token.json à pasta octo_api.
Execute o script no terminal do VS Code usando o comando node google_sheets.js.
Uma vez que o script termine, os dados serão carregados na planilha especificada.

Trecho para exportar dados de perfil para o Google Sheets
const axios = require('axios'); const { google } = require('googleapis'); const token = require('./token.json'); const credentials = require('./credentials.json'); const oAuth2Client = new google.auth.OAuth2( credentials.installed.client_id, credentials.installed.client_secret, credentials.installed.redirect_uris[0] ); oAuth2Client.setCredentials(token); //configuration //Paste your Octo API token, spreadsheet ID and sheet name here const config = { octo_token: "OCTO_API_TOKEN", table_id: "1pqnVysHymZSI5Lzx6odasdasAqE022fqUEf6q5LnOqAhylLSM", table_sheet_name: "Profiles", octo_api_base_url: "https://app.octobrowser.net/api/v2/automation/", } const OCTO_REMOTE_API = axios.create({ baseURL: config.octo_api_base_url, timeout: 10000, headers: { 'X-Octo-Api-Token': config.octo_token, 'Content-Type': "application/json" } }); //functions async function check_limits(response) { function parse_int_safe(value) { const parsed = parseInt(value, 10); return isNaN(parsed) ? 0 : parsed; } const ratelimit_header = response.headers.ratelimit; if (!ratelimit_header) { console.warn('No ratelimit header found!'); return; } const limit_entries = ratelimit_header.split(',').map(entry => entry.trim()); for (const entry of limit_entries) { const name_match = entry.match(/^([^;]+)/); const r_match = entry.match(/;r=(\d+)/); const t_match = entry.match(/;t=(\d+)/); if (!r_match || !t_match) { console.warn(`Invalid ratelimit format: ${entry}`); continue; } const limit_name = name_match ? name_match[1] : 'unknown_limit'; const remaining_quantity = parse_int_safe(r_match[1]); const window_seconds = parse_int_safe(t_match[1]); if (remaining_quantity < 5) { const wait_time = window_seconds + 1; console.log(`Waiting ${wait_time} seconds due to ${limit_name} limit`); await sleep(wait_time); } } } async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms * 1000)); } async function get_total_pages() { const response = await OCTO_REMOTE_API.get('/profiles?page=0&page_len=10'); const total_profiles = response.data.total_count; const total_pages = Math.ceil(response.data.total_count / 100); console.log(`Total Profiles: ${total_profiles}\nTotal Pages: ${total_pages}`); await check_limits(response); return total_pages; } async function get_all_profiles_data(total_pages) { let profiles = []; for (let i = 0; i < total_pages; i++) { let response = await OCTO_REMOTE_API.get(`/profiles?page=${i}&page_len=100&fields=title,description,tags`); await check_limits(response); profiles.push(...response.data.data); } return profiles; } async function fill_sheet_with_data(oAuth2Client, spreadsheet_id, list_name, data) { const sheets = google.sheets({ version: 'v4', auth: oAuth2Client }); try { const sheetInfo = await sheets.spreadsheets.get({ spreadsheetId: spreadsheet_id, }); const sheetExists = sheetInfo.data.sheets.some( sheet => sheet.properties.title === list_name ); if (!sheetExists) { await sheets.spreadsheets.batchUpdate({ spreadsheetId: spreadsheet_id, resource: { requests: [{ addSheet: { properties: { title: list_name } } }] } }); console.log(`Создан новый лист "${list_name}".`); } const headers = ['Uuid', 'Tags', 'Title', 'Description']; const values = data.map(item => [ item.uuid, Array.isArray(item.tags) ? item.tags.join(', ') : item.tags, item.title, item.description || '' ]); await sheets.spreadsheets.values.update({ spreadsheetId: spreadsheet_id, range: `${list_name}!A1:D1`, valueInputOption: 'RAW', resource: { values: [headers] } }); await sheets.spreadsheets.values.update({ spreadsheetId: spreadsheet_id, range: `${list_name}!A2:D${values.length + 1}`, valueInputOption: 'RAW', resource: { values: values } }); console.log(`Данные успешно записаны в лист "${list_name}".`); } catch (err) { console.error('Ошибка при обновлении таблицы:', err); throw err; } } (async () => { const total_pages = await get_total_pages(); const profiles_data = await get_all_profiles_data(total_pages); await fill_sheet_with_data(oAuth2Client, config.table_id, config.table_sheet_name, profiles_data); })()
Como obter table_id
Abra ou crie uma planilha no Google Sheets.
Copie o ID da tabela. Esta é a parte do URL entre
/d/e/edit.
Por exemplo, se seu link parecer https://docs.google.com/spreadsheets/d/1GoPnhkStxFFxDzGZjjXSyjT_H_msHlSDx51tBROewOA/edit, então o table_id é 1GoPnhkStxFFxDzGZjjXSyjT_H_msHlSDx51tBROewOA.
Como obter o arquivo credentials.json
Faça login em uma conta pessoal (não organizacional) do Gmail.
Selecione qualquer país europeu na lista e clique em Concordar e continuar.
Clique em Selecionar um projeto, depois em Novo projeto.
Insira qualquer nome de projeto e clique em Criar.
Acesse https://console.cloud.google.com/auth e clique em Começar.
Insira qualquer Nome do App, seu e-mail, e clique em Próximo.
Selecione Externo, insira seu e-mail novamente, clique em Próximo, marque a caixa de consentimento, depois clique em Continuar e Finalizar.
Na seção Testar Usuários, clique em Adicionar Usuários.

Adicione seu e-mail e clique em Salvar.
Na página https://console.cloud.google.com/auth/overview, clique em Criar Cliente OAuth.

Selecione Aplicativo de escritório na lista, insira qualquer nome e clique em Criar.
Uma janela pop-up aparecerá. Baixe o arquivo JSON dela.

Pesquise por Google Sheets API.
Selecione-o e clique em Ativar.
Abra o arquivo JSON baixado anteriormente.
Altere o valor de
redirect_urisdehttp://localhostpara"redirect_uris": ["urn:ietf:wg:oauth:2.0:oob","http://localhost"].
Faça a alteração com cuidado para não remover acidentalmente os colchetes.

Salve o arquivo.
Renomeie-o para credentials.json.
Adicione-o à pasta octo_api.
Como obter o arquivo token.json
Crie um arquivo chamado get_token.js na pasta octo_api e abra-o no VS Code.
Execute o comando Npm install googleapis no terminal do VS Code.
Cole o script de geração de token em get_token.js e salve o arquivo.
Execute o script usando node get_token.js.
Você verá um link dizendo Abra essa URL no navegador:
https://accounts.google.com/o/oauth2/…Abra o link.
Faça login na sua conta Google.
Clique nas telas de consentimento.
Na página final, o Google exibirá um código de autorização.

Cole o código no terminal e pressione Enter.
O script então criará um arquivo token.json na pasta onde você o executou.

Script de geração de token
const fs = require('fs'); const readline = require('readline'); const { google } = require('googleapis'); const CREDENTIALS_PATH = 'credentials.json'; const TOKEN_PATH = 'token.json'; const credentials = JSON.parse(fs.readFileSync(CREDENTIALS_PATH)); const { client_secret, client_id, redirect_uris } = credentials.installed; const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]); const SCOPES = ['https://www.googleapis.com/auth/spreadsheets']; const authUrl = oAuth2Client.generateAuthUrl({ access_type: 'offline', scope: SCOPES, }); console.log('Open this URL in browser:', authUrl); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); rl.question('Enter the code from that page here: ', (code) => { rl.close(); oAuth2Client.getToken(code, (err, token) => { if (err) return console.error('Error retrieving access token', err); fs.writeFileSync(TOKEN_PATH, JSON.stringify(token)); console.log('Token stored to', TOKEN_PATH); }); });
Conclusão
Usamos a linguagem de programação Node.js nos exemplos deste artigo. Você pode encontrar trechos úteis em outras linguagens na nossa documentação.

Neste artigo, cobrimos:
como preparar seu ambiente;
como obter seu token de API do Octo Browser;
como recuperar um UUID de extensão;
como obter nomes de perfis usando API e salvá-los em um arquivo de texto;
como adicionar extensões, favoritos e páginas iniciais em massa a perfis existentes;
como exportar dados de perfil para o Google Sheets.
Se você ainda tiver dúvidas ou não conseguiu encontrar o exemplo que precisa na documentação, sinta-se à vontade para entrar em contato com nosso Atendimento ao Cliente no Telegram ou usando nosso chat do site ou o widget do navegador.
Mantenha-se atualizado com as últimas notícias do Octo Browser
Ao clicar no botão, você concorda com a nossa Política de Privacidade.
Mantenha-se atualizado com as últimas notícias do Octo Browser
Ao clicar no botão, você concorda com a nossa Política de Privacidade.
Mantenha-se atualizado com as últimas notícias do Octo Browser
Ao clicar no botão, você concorda com a nossa Política de Privacidade.

Junte-se ao Octo Browser agora mesmo
Ou entre em contato com a equipe de suporte no chat para tirar dúvidas a qualquer momento.

Junte-se ao Octo Browser agora mesmo
Ou entre em contato com a equipe de suporte no chat para tirar dúvidas a qualquer momento.
Junte-se ao Octo Browser agora mesmo
Ou entre em contato com a equipe de suporte no chat para tirar dúvidas a qualquer momento.