O Penguin Adinfo é um recurso que tem como objetivo o controle e padronização do uso de parametrização e nomenclatura de mídia digital.
A solução proposta é uma API open source que através de rotas de requisição trabalha inputs de URLs a parametrizar e seus respectivos campos para devolver a parametrização já com uma validação dos campos preenchidos e de status de requisição dos links.
Os principais componentes no uso da aplicação são a configuração, um JSON contendo quais campos são aceitos na taxonomia de mídia, o permissionamento para controle de ações permitidas por nível de acesso, e o arquivo de parametrização, um CSV contendo a lista de URLs e os campos preenchidos conforme o que foi configurado.
- Independência de qualquer programa para a abertura das planilhas durante o processo de parametrização, o que comumente compromete a performance pelo uso extensivo de fórmulas.
- Possibilidade do uso da API em planilhas, externalizando o processamento para uma transformação puramente sobre os dados.Controle de permissões com 3 níveis, cada qual incluindo os seguintes: Controle de acessos, edição de configurações, realização da parametrização.
- Os acessos podem ser divididos em grupos ou projetos, para que por exemplo diferentes agências possam todas ter seu nível de configuração, mas apenas para suas próprias campanhas.
- Escalabilidade de uso por suportar grandes tamanhos de arquivo e histórico.
- start: executa a aplicação;
- unit-test: Realiza uma bateria de testes unitários dos arquivos de typescript presentes na pasta test/;
- test: Realiza uma bateria de testes unitários dos arquivos de typescript presentes na pasta test/;
- lint: Submete o código a uma avaliação do ESLint;
- lint-fix: Submete o código a uma avaliação do ESLint e aplica correções automaticamente ao código;
- compile: Compila o código do typescript para javascript, guardando-o na pasta dist/;
- auto-compile: Realiza a compilação dos arquivos typescript em tempo real, armazenando o resultado dentro da pasta dist/, sem excluir o conteúdo anterior;
- prettier: Formata todo o código das pastas src/ e test/, utilizando o Prettier, de acordo com a configuração descrita no arquivo .prettierrc;
- coverage: Análise da cobertura dos testes;
- build: Executa o compile do código typescript para javascript.
- Ambiente de hospedagem de aplicações, em nuvem ou on-premise;
- Banco de dados para armazenamento de arquivos no formato csv;
- Banco de dados NoSQL para armazenamento de objetos JSON.
O adinfo pode ser implementado em diferentes provedores de nuvem ou em ambientes on-premise. Listaremos aqui sugestões de serviços do GCP que podem ser utilizados para complementar a infraestrutura da API.
- App Engine
- Cloud Storage
- Firestore
Clone o projeto do github para sua máquina local ou Cloud Shell
git clone https://github.com/DP6/penguin-adinfo.git
- Google Cloud SDK;
- Pacote zip;
- Terraform;
- Habilitar o App Engine em ambiente de execução Node.js, Firestore e Cloud Storage (necessário ter um billing ativo), no GCP;
- Gerar uma senha com o Bcrypt Generator para informar no usuário owner do adinfo;
- Criar o arquivo gcp_key_terraform.json contendo a chave json de uma conta de serviço GCP com as permissões necessárias para as subidas dos serviços via terraform;
- Criação do arquivo .env especificado na sessão Configuração do ambiente de desenvolvimento.
-
Execute o script terraform_deploy.sh;
-
Informe o nome da empresa, ferramenta analítica utilizada para a criação de um exemplo de configuração (Adobe Analytics ou Google Analytics) e o id do projeto. Também é possível informar o número da porta onde o adinfo irá rodar, entretanto esse último valor é opcional, caso nenhuma porta seja específica, por padrão ele executará na porta 443;
-
Crie uma coleção no Firestore com o nome de tokens e insira um primeiro token com os seguintes campos (deixe o id do documento vazio para que seja gerado automaticamente):
{
company: "NOME_EMPRESA" (string),
agency: "agencia do usuário" (string,
permission: "owner" (string)
email: "email_do_usuario" (string)
password: "senha_criptografada" (string),
activate: true (boolean)
}
Durante toda a etapa de desenvolvimento do adinfo ele é hospedado no serviço de App Engine do GCP, além de armazenar informações no Firestore e Storage.
Por padrão, ao utilizar o adinfo dentro do App Engine, basta conceder acesso à conta de serviço para o Storage e Firestore para que todos os recursos funcionem corretamente. Caso o adinfo esteja hospedado fora do GCP ou em outro projeto, é necessário informar a chave de autenticação na inicialização das classes, dentro nos arquivos FirestoreConnectionSingleton e StorageConnectionSingleton.
Crie um bucket para armazenar os arquivos do adinfo, o bucket em questão deve ser informado no .env. Por padrão os arquivos serão salvos dentro do bucket informado e separados dentro de pastas para cada agência.
Para a configuração inicial do Firestore, são necessárias quatro coleções.
-
companies: essa coleção deve deve conter um documento com o nome da empresa. Dentro desse documento, uma segunda coleção deve ser criada com o nome config. Seguindo a estrutura: companies > [nome_empresa] > config;
-
blocklist: coleção criada para armazenar tokens bloqueados de login;
-
campaigns: coleção criada para armazenar as campanhas de cada agência;
-
agencies: coleção criada para armazenar as agências que utilizam o adinfo;
-
tokens: essa coleção também deve ser criada com um documento seguindo a estrutura:
{ company: "NOME_EMPRESA" (string), agency: "agencia do usuário" (string, permission: "owner" (string), email: "email_do_usuario" (string), password: "senha_criptografada" (string), activate: true (boolean) }
Para esse documento, é importante manter o Código do Documento gerado automaticamente pelo google, pois ele será utilizado como o ID do usuário em alguns processos. O campo password deve ser informado com a criptografia. Para preenchimento manual é possível utilizar o Bcrypt Generator para gerar a senha criptografada. O campo agency diz respeito a agência a qual pertence o usuário que está sendo criado. Caso o nível de permissão desse usuário seja "owner" ou "admin", deixe este campo em branco.
-
campaigns: Essa coleção deve ser criada na raiz do firestore , mas não há a necessidade de criar nenhum documento dentro dela. Os documentos serão gerados automaticamente conforme o uso do adinfo, armazenando as campanhas que serão criadas e seus atributos
-
blocklist: Essa coleção deve ser criada na raiz do firestore , mas não há a necessidade de criar nenhum documento dentro dela. Os documentos serão gerados automaticamente conforme o uso do adinfo, adicionando os tokens dos usuários que derem logout na aplicação, pois este token, mesmo que ainda válido, não deve ser usado ainda para acessar a interface.
Para utilizar a API, é necessário criar um documento de configuração no Firestore dentro da coleção: companies > [nome_empresa] > config. O nome do documento deve ser config_1 e ele deve conter os campos: version inicialmente com o valor 1 (number), insertTime no formato yyyyMMddHHmmss, csvSeparator, separator, spaceSeparator, columns e um campo para a ferramenta de analytics, sendo esse o valor de ga ou adobe.
Todos estes campos serão utilizados para realizar a parametrização do arquivo CSV que a API irá receber.
Aqui a API disponibiliza a funcionalidade de definirmos no campo csvSeparator uma lista contendo a prioridade de todos os possíveis caracteres que poderão ser utilizados como separadores no arquivo CSV pelos usuários. Com isso, a aplicação irá consultar essa fonte e utilizar o devido separador para parametrizar o arquivo submetido.
Entretanto, este campo no arquivo de configuração não é obrigatório. Caso o campo não seja preenchido, a aplicação irá tentar verificar se o arquivo submetido está utilizando vírgula ou ponto e vírgula como separador e utilizar o separador identificado para a parametrização. Caso não encontre nenhum dos dois caracteres, a API irá utilizar a vírgula como separador.
Abaixo segue uma explicação e um exemplo de todos os campos das configurações.
Chave | Tipo | Descrição | Obrigatório |
---|---|---|---|
csvSeparator | Array | Array que irá conter todos os separadores de colunas que os arquivos CSV poderão conter. | Não |
separator | String | String que será utilizada na concatenação dos campos. | Sim |
spaceSeparator | String | String que substituirá o espaço na URL, caso alguma campo tenha preenchido com mais de uma palavra. | Sim |
columns | Objeto | Objeto contendo as colunas do CSV e seus valores de aceitação. | Sim |
dependenciesConfig | Objeto | Objeto contendo as regras de dependências de validação. | Não |
insertTime | String | Data da criação do config no formato YYYYMMDDHHmmSS. | Sim |
version | Number | Número da versão do config. | Sim |
{{veículo}} | Objeto | Chave do veículo de mídia com suas configurações e quais colunas pertencem a cada configuração. | Não |
{{ferramenta de analytics}} | Objeto | Chave da ferramenta de analytics com suas configurações e quais colunas pertencem a cada configuração. Essa chave precisa obrigatoriamente receber o valor ga ou adobe. | Sim |
Exemplo de configuração:
{
"separator": ":",
"spaceSeparator": "_",
"csvSeparator": [",", ";", "|"],
"version": 1,
"insertTime": "20220101000000",
"columns": {
//Colunas que aparecerão no CSV
//A chave representa a coluna do CSV e o vetor de valores
//representam os possíveis valores de preenchimento dos campos.
//É possível informar valores ou expressões regulares para a validação.
//As expressão regulares devem estar entre /,
//assim como na chave "Produto"
"Tipo de Compra": ["cpa", "cpc"],
"Dispositivo": ["desktop e mobile"],
"Produto": ["/.*/"]
},
"ga": {
//Ferramenta de analytics, um outro valor possível seria "adobe"
//As chaves são os parâmetros que a ferramenta aceita
//Os valores passados no vetor são referentes às
//colunas do CSV que o formam
"utm_source": ["Tipo de Compra", "Dispositivo"],
"utm_campaign": ["Produto"]
},
"googleads": {
//Configuração do veículo de mídia
//As chaves são os parâmetros do veículos.
//Os valores passados no vetor são referentes às
//colunas do CSV que o formam,
//semelhante à ferramenta de analytics.
"campanha": ["Tipo de Compra", "Dispositivo"],
"ad": ["Produto"]
},
"dependenciesConfig": [
//Campo de configurações de depêndencias
{
//De acordo com o exemplo, se a coluna "Dispositivo"
//for preenchida com algum valor que contenha
//a palavra "mobile", então a coluna "Tipo de Compra"
//só poderá ser preenchida com os valores: cpc ou cpa.
//Se a chave hasMatch estivesse com o valor "false"
//significaria que a regra para a coluna "Tipo de Compra"
//só seria aplicada, caso o valor preenchido na coluna "Dispositivo"
//não contivesse a palavra "mobile".
"columnReference": "Dispositivo",
"valuesReference": ["/.*mobile.*/"],
"hasMatch": true,
"columnDestiny": "Tipo de Compra",
"matches": ["cpc", "cpa"]
}
],
"insertTime": "20211201193242",
"version": 1,
}
Atualmente o adinfo não disponibiliza por padrão um código de acesso à banco de dados diferentes do Storage e Firestore. Para conexões com outros ambientes a criação dos scripts se faz necessária.
Caso o usuário opte por utilizar um banco de arquivos diferentes do Storage, é necessário que o script da nova classe herde de FileStore.
No caso de substituir o uso do Firestore para armazenamento de chaves. A nova classe deve herdar de ObjectStore.
- Arquivo .env: O arquivo .env deve estar localizado na raiz do projeto. É necessário editar as seguintes variáveis
- ENV: Deve apresentar o valor 'development', caso o ambiente atual seja o ambiente de desenvolvimento local, ou 'prod', caso o ambiente seja de produção;
- PORT: Deve conter o número da porta onde a API será acessada. Em caso de omissão desse parâmetro, a porta considerada será 443;
- BUCKET: Deve conter o nome do bucket do storage onde os arquivos CSVs serão salvos. Para o deplou via Terraform, preencher o nome do bucket seguindo o padrão: {gcp_project_id}-adinfo-files-{company};
- GCP_PROJECT_ID: Deve conter o id do projeto no GCP, caso o adinfo esteja hospedado no GCP;
- GCP_KEY: Deve conter o JSON da chave de acesso aos serviços do GCP;
- JWT_KEY: Chave para geração de assinaturas do JWT;
- SALT: Configuração de salt do JWT;
- EXPIRES_TOKEN: Duração do token JWT.
- Arquivo .gitignore: Checar se o arquivo .gitignore está ignorando do arquivo .env.
Pull requests são bem-vindos! Nós vamos adorar ajuda para evoluir esse modulo. Sinta-se livre para navegar por issues abertas buscando por algo que possa fazer. Caso tenha uma nova feature ou bug, por favor abra uma nova issue para ser acompanhada pelo nosso time.
Só serão aceitas contribuições que estiverem seguindo os seguintes requisitos:
A documentação do código pode ser encontrada em docs/index.html.
A documentação de rotas da API se encontra no arquivo Routes.md.
DP6 Koopa-troopa Team
e-mail: [email protected]