Mobile – Como as redes de anúncios (Ad Networks) realizam o tracking de campanhas

Olá pessoal,

Uma dúvida muito comum e também uma informação muito importante, é saber como fazer o tracking (ou rastreamento) de um usuário que fez o download e instalou um determinado aplicativo através de um link, banner ou uma campanha em geral.

É importante entender que não existe um jeito fácil, simples e universal para que isso aconteça e pode ser que alguma informação se perca no meio do caminho dependendo das ações dos usuários. Cada plataforma resolveu este problema de um jeito diferente.

No caso da Apple funciona assim:

Um usuário utiliza uma ferramenta de anúncios que irá exibir um banner, link ou algo do tipo no dispositivo do usuário. O link contido neste banner é um link que contém uma informação especial chamada pela Apple de IDFA, que consiste em um token específico para anúncios e é único por device. A Apple não permite o uso desse token outro fim além de usá-lo para tracking de anúncios e qualquer tentativa fora esta terá o app rejeitado, como está em sua documentação (Link 1, Link 2, Link 3).

Vou usar o exemplo do Google Analytics para explicar como ele consegue através do IDFA fazer o tracking de suas campanhas.

Um anúncio exibido pelo Google em suas redes de anúncio teria um link com uma estrutura parecida com esta:

http://click.google-analytics.com/redirect?
tid=UA-1234-1 // Google Analytics Tracking ID.
&idfa=BBA44F63-E469-42BA-833A-2AC550310CB3 // Identifier for Advertising (IDFA)
&aid=com.bundle.myapp // App ID.
&cs=network // Campaign source.
&cm=cpc // Campaign medium.
&cn=campaign_name // Campaign name.
&url=https%3A//itunes.apple.com/us/app/myApp/id123%3Fmt%3D8 // Redirect URL to iTunes.

Esse link do anúncio do Google vai registrar no servidor deles que você clicou nele e vai gravar as informações que ele deseja para depois juntar as peças e cruzar as informações. Após gravar o que ele precisa, ele vai redirecionar você para a loja da Apple, indo direto para o aplicativo desejado quando você clicou no anúncio.

Quando você instalar o aplicativo desejado, o SDK do Google contido dentro do seu aplicativo vai obter o IDFA do seu aparelho e enviar para o servidor deles. Seria algo assim:

Ah, então você é o IDFA “ABC123456” que clicou na campanha “C123”, estou adicionando +1 no contador de instalação, bem como todas as informações do seu dispositivo. Obrigado.

Na documentação do Google, tem mais detalhes, mas a regra é esta.

https://developers.google.com/analytics/solutions/ios-install-tracking#redirect 

Segue uma imagem que o Google fez para exemplificar seu fluxo:

ios-install-tracking-redirect

A segunda solução do Google Analytics é fazer com que a rede de anúncios envie assincronamente um “ping” para a URL:

click.google-analytics.com/ping?param1=value1&param2=value2

E com isso poderá ser feita a contabilidade também server-side posteriormente pelas ferramentas.

 

No caso do Google funciona assim:

O Google criou uma classe que atua como um Broadcast Receiver, que receberá estes dados assincronamente quando um usuário instalar o aplicativo através de uma campanha.

Basicamente o Google Play vai fazer um broadcast com a informação somente quando o aplicativo for instalado pela loja e os dados da campanha estiverem disponíveis, ou seja, se ele veio com os parâmetros de campanha definidos quando ocorreu a instalação.

Estes dados serão consumidos pelo seu broadcast que irá submeter os dados para sua plataforma de anúncios. Se você usa o SDK do Google Analytics e definiu que ele será o “recebedor” destas informações, ele será o responsável por jogar estas informações de campanha para o servidor do Google, ou então você captura e repassa isso para diversas ferramentas manualmente, pois uma limitação do Android é que só pode existir um Broadcast Receiver para Install Referrer.

O AppsFlyer fez um Broadcast Receiver especial que consegue receber estes dados e depois repassar para todos os outros Broadcast Receivers que você tiver, automaticamente (Link de como usar), permitindo então você possuir diversos Broadcast Receivers.

Documentação:

https://developers.google.com/android/reference/com/google/android/gms/tagmanager/InstallReferrerReceiver

https://developers.google.com/android/reference/com/google/android/gms/analytics/CampaignTrackingReceiver

 

Basicamente o link no padrão para o Google Play seria assim:

https://play.google.com/store/apps/details?id=com.example.application&referrer=utm_source%3Dgoogle%26utm_medium%3Dcpc%26utm_term%3Drunning%252Bshoes%26utm_content%3Dlogolink%26utm_campaign%3Dspring_sale

É importante entender que a informação que você terá é o texto dentro do parâmetro “referrer”, que deverá estar no padrão URL Encoded, ou seja, sem os símbolos “%, &, =, etc”.

É importante também usar o gerador de URL para o Google Play para criar a URL dentro do padrão esperado (Link 1, Link 2):

Se você deseja simular isso no Android, sem ter que instalar o aplicativo pela loja, afim de testar o funcionamento, execute os comandos abaixo trocando os parâmetros (Link):

adb shell 
am broadcast -a com.android.vending.INSTALL_REFERRER -n <your.package>/.<path.up.until.your.BroadcastReceiver> --es "referrer" "utm_source=test_source\&utm_medium=test_medium\&utm_term=test_term\&utm_content=test_content\&utm_campaign=test_name"

E caso você queira criar seu Broadcast Receiver crie uma classe com o conteúdo:

public class InstallReferrerReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String referrer = intent.getStringExtra("referrer");

        //Use the referrer
    }
}

E no seu AndroidManifest.xml adicione:

<receiver
    android:name="com.example.android.InstallReferrerReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="com.android.vending.INSTALL_REFERRER" />
    </intent-filter>
</receiver>

 

 

Como funciona no caso do AppsFlyer:

Agora que você já entendeu como as plataformas se utilizam desses recursos, veja como o AppsFlyer mostrou esse funcionamento na rede deles:

Links:

https://support.appsflyer.com/hc/en-us/articles/207032096-Accessing-AppsFlyer-Attribution-Conversion-Data-from-the-SDK-Deferred-Deeplinking-

https://support.appsflyer.com/hc/en-us/articles/207032146-How-Can-I-Get-the-Install-Referrer-URL-from-my-Android-App-Context-

Imagem:

appsflyer-attribution-data

 

No caso do Google, basicamente o usuário vai clicar em um link como este:

app.appsflyer.com/angry-birds-android?pid=tapjoy_int&clickid=1020fe4c7e875&c=Ad1&af_siteid=2684

E quando o Broadcast Receiver for notificado, irá receber algo como:

af_tranid=3M69WKEKDHFPRXPG&pid=tapjoy_int&clickid=1020fe4c7e875&c=Ad1&af_siteid=2684

O AppsFlyer também possui uma aplicação para testar as campanhas antes de enviar o aplicativo para a loja:

Para Android:

https://support.appsflyer.com/hc/en-us/articles/207032136-Testing-AppsFlyer-Android-SDK-Integration-Before-After-Submitting-to-Google-Play

Para iOS:

https://support.appsflyer.com/hc/en-us/articles/207032046-Testing-AppsFlyer-iOS-SDK-Integration-Before-Submitting-to-the-App-Store-

 

Funcionamento geral:

Há diversas formas de fazer este tracking, como por exemplo, por IP. Mas usuários que usam WIFI ou estão dentro de redes específicas podem ter o mesmo IP de saída e esta regra acaba falhando.

O IDFA, no caso da Apple, ajuda neste sentido, pois você sabe quem é o usuário pois o mesmo IDFA clicado é o mesmo que gerou o evento após o aplicativo ser aberto.

É claro que as informações podem se perder, o usuário podem nem mesmo abrir o aplicativo, um problema de conexão pode impedir o envio dos dados, ou ele pode simplesmente desinstalar, enfim, como regra geral essas técnicas funcionam bem e fica fácil entender como este processo funciona agora.

 

Espero ter ajudado com este artigo.

Obrigado e até o próximo post pessoal.

Golandy – Game multiplayer open-source em HTML5 com Phaser + Golang e WebSocket – Versão para desktop, browser, android e iOS

Olá pessoal,

A um tempinho atrás fiz um game bem simples, usando HTML5 + Phaser e Go + WebSocket.

Fiz também os arquivos necessários para rodar o projeto tanto em desktop, web, android e iOS usando o Apache Cordova.

O link do game rodando é:

http://golandy.prsolucoes.com

Os links para baixar se encontram no meu Github, segue:

Cliente: https://github.com/prsolucoes/golandy-web

Servidor: https://github.com/prsolucoes/golandy-server

 

Sobre o jogo, ele é um tipo de clone do clássico bomberman. É multiplayer em tempo real. Fiz usando a engine Phaser e o servidor em Go. Toda a comunicação usa WebSocket e a versão nativa do Google, pois o desempenho da versão Gorilla é horrível.

Os mapas podem ser editados usando o MapEditor/Tiled (padrão tmx).

O game funciona no navegador, no desktop, no android, no iOS e onde mais o Apache Cordova suportar, pois como é em HTML5, qualquer browser roda ele. Em casa por exemplo, minha filha joga na TV.

É claro que o jogo não é perfeito e a comunidade da engine não ajuda muito.

Segue imagem:

Golandy Game Screenshot

 

Espero com este projeto, que a idéia e a arquitetura possam servir de inspiração para outros projetos e trabalhos.

Obrigado e até o próximo post pessoal.

 

Novos projetos open-source: GoCI e GoHC (integração contínua e healthcheck)

Olá pessoal,

Gostaria de compartilhar com vocês os meus dois novos projetos open-source em Go (golang).

1 – GoCI

O GoCI é um projeto para integração contínua de fácil instalação, manutenção e configuração.

Com ele você pode criar suas tarefas de integração através de execuções em CLI ou através de arquivos Javascript.

A inicialização do projeto é feita por dois arquivos principais, o config.ini e o arquivo do seu projeto em JSON, que podem ser vários na verdade.

O GoCI exporta algumas variáveis pro Javascript, a fim de que você possa implementar sua lógica de teste, deploy ou qualquer outra tarefa e ainda controlar cada um destes objetos. Ao manipular estes objetos você acompanha todos os resultados em tempo real através da interface web do GoCI, como os outputs, a barra de progresso, a duração da execução, etc.

Cada tarefa pode mostrar resultados em diversas abas, a aba principal é a Console, onde o output geral aparece ali, além do output normal, você tem output de erro, sucesso, alerta, etc.

Cada tarefa do seu projeto pode ter vários passos (steps), sendo cada passo baseado em um plugin, que como falamos, podem ser “cli” ou “js”.

Porém o projeto não se limita somente a desenvolvimento ou testes e deploy de uma aplicação. Você pode fazer o que quiser dentro dele. Você pode criar mais plugins, caso queira. Eu tenho algumas tarefas por exemplo, que enviam push pro meu device de teste, tenho outra que baixa os arquivos de linguagens atualizados da ferramenta de localização e coloca dentro do projeto.

O projeto vem com uma pasta “extras/sample” com os arquivos de exemplo, embora sejam bem simples.

Toda a interface foi pensada para funcionar perfeitamente em smartphones, tablets ou PCs.

Segue algumas imagens:

Link para o projeto:

https://github.com/prsolucoes/goci 

 

2 – GoHC

O GoHC é um sistema passivo de healthcheck com suporte a notificações quando entra em modo warning ou error. Ele é passivo por não ser de sua responsabilidade realizar a operação de validação, pois criaria um limite e o propósito do projeto é poder criar healthcheck para qualquer coisa que possa entrar em contato com o servidor onde estiver rodando.

Exemplos do que você pode fazer com ele:

  1. Validar se uma URL/servidor/IP está ativo.
  2. Medir tempo de determinadas operações, como o intervalo de tempo de processamento do pagamento do cliente com o seu gateway de pagamento. Você pega este intervalo em sua aplicação e envia pro healthcheck validar se ele está dentro do range de sucesso, alerta ou crítico/erro/falha.
  3. Validar de a quantidade de memória/cpu/disco/network está dentro de um range.
  4. Validar se a quantidade de humidade de uma planta está dentro de um range e emitir um alerta se estiver em nível crítico.

Com este sistema de healthcheck você possui 3 formas de validar a “saúde” do que você precisa monitor e esta validação pode ser automática dentro dos 3 ranges possíveis (sucesso, alerta, erro/falha) ou manual, onde você diz qual é o status manualmente.

  1. Ping – é o tipo mais simples, você chama o healthcheck e ele de acordo com o último ping enviado e o atual verifica em qual das áreas do range você está e envia alertas ou não – mas é você quem diz o tempo do ping para cada range.
  2. Range – é o tipo mais específico, onde você especifica as áreas dos ranges e ao receber um range qualquer, ele valida em qual dos ranges você está baseado no range enviado.
  3. Manual – é o tipo onde você diz o status diretamente, não tem informação de ping ou range neste tipo, o status que você enviar é o que ele vai assumir e pode enviar alertas também caso você especifique.

Tudo isso pode ser acompanhado através de uma interface web bem amigável e que foi pensada para funcionar perfeitamente em smartphones, tablets ou PCs.

Existe na interface hoje o modo lista de healthchecks e o modo dashboard, dependendo de como você quer ver os healthchecks você pode optar por um ou por outro. Se você quer deixar numa televisão, sugiro o modo dashboard.

Os alertas são baseados em plugins. Hoje eu criei apenas alguns, mas essenciais.

  1. CLI – executa algo no servidor no CLI
  2. SendGrid – envia um email usando o sendgrid
  3. PushBullet – envia um push usando o pushbullet
  4. Http Get – faz requisição HTTP GET em uma URL
  5. Slack – envia via webhook uma mensagem para o serviço Slack

A inicialização do projeto é feita por dois arquivos principais, o config.ini e um arquivo JSON chamado healthchecks.json com a lista de seus healthchecks e plugins de alerta.

O projeto vem com uma pasta “extras/sample” com os arquivos de exemplo, embora sejam bem simples.

No arquivo config.ini, você pode especificar uma propriedade chamada warmTime, que define um tempo após a inicialização para o sistema começar a processar os healthchecks.

Segue algumas imagens:

Segue o link do projeto:

https://github.com/prsolucoes/gohc

 

É isso pessoal, espero ter ajudado alguém com estes projetos.

Obrigado e até o próximo post pessoal.

OSX – Removendo todos os arquivos .DS_Store

Olá pessoal,

Um problema muito comum em meio aos usuários de MAC/OSX, principalmente para quem desenvolve, são os famosos arquivos .DS_Store.

Para remove-los completamente de uma pasta específica basta uma linha de comando.

Abra o seu Terminal, entre na pasta raiz do seu projeto ou na pasta raiz que você deseja limpar e execute:

find ./ -name ".DS_Store" -depth -exec rm {} \;

Caso você queira remover de todo o seu computador, use com o sudo e insira a senha do seu usuário, se solicitado:

sudo find / -name ".DS_Store" -depth -exec rm {} \;

Bom, espero ter ajudado com esta dica.

Obrigado e até o próximo post pessoal.

Android Studio – Corrigindo o erro “Unable to run mksdcard SDK tool.”

Olá pessoal,

Para aqueles que como eu, estão tendo problemas na hora de usar o Android Studio no Ubuntu ocorrendo o erro “Unable to run mksdcard SDK tool.”, segue uma dica bem simples. Instale as dependências seguintes e magicamente tudo estará resolvido.

sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0 lib32stdc++6

Em alguns casos, ocorrerá um erro ao instalar a dependência lib32bz2-1.0. Basta executar o mesmo comando sem esta dependência:

sudo apt-get install lib32z1 lib32ncurses5 lib32stdc++6

 

Bom, espero ter ajudado com esta dica.

Obrigado e até o próximo post pessoal.

OSX – Deixando o seu terminal colorido e com suporte ao Git

Olá pessoal,

Esta dica é bem simples e talvez ajude bastante no dia-a-dia em seu desenvolvimento, caso utilize o terminal do OSX.

Realizando estes processos seu terminal ficará colorido, facilitando e leitura e ainda aparecerá o nome da branch em que você está, caso utilize o Git.

Siga os passos:

1 – Edite o arquivo .bash_profile digitando no terminal:

nano ~/.bash_profile

2 – Adicione as linhas:

export CLICOLOR=1
export LSCOLORS=ExFxBxDxCxegedabagacad
export PS1="\[\033[36m\]\u\[\033[m\]@\[\033[32m\]\h:\[\033[33;1m\]\w\[\033[m\]\$(parse_git_branch) $ "

parse_git_branch() {
    git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}

3 – Salve o arquivo com CONTROL + O

4 – Feche o terminal e abra-o novamente ou caso queira manter a sessão com as modificações, execute:

source ~/.bash_profile

Obs: Esta dica funciona também com o iTerm2.

 

Bom, espero ter ajudado com esta dica.

Obrigado e até o próximo post pessoal.

Google Apps Scripts – Ferramenta do Google para integração entre seus apps, automatização de tarefas e aplicações na loja do Google Chrome

Olá pessoal,

O Google sempre surpreendendo e melhorando cada vez mais, lançou uma ferramenta chamada Google Apps Script.

Se eu pudesse comparar com algum produto, iria selecionar o VBScript da Microsoft integrado ao Office para este fim, porém o GAS (Google Apps Script) vai bem mais além, pois você pode automatizar qualquer coisa nas ferramentas do Google (docs, sheets, calendar, etc), acessando todas as ferramentas cloud do Google e usando JavaScript para tal.

Será difícil colocar aqui todos os detalhes, mas vou destacar aqueles que me chamaram a atenção:

  1. Editor de códigos JavaScript do Google com Auto Complete (online)
  2. Integração com todos os produtos do Google (docs, sheet, drive, calendar, etc)
  3. Integração com cloud (ex: banco de dados key-value)
  4. Editor visual de formulários (RAD)
  5. Reaproveitamento do script em todas as ferramentas (em qualquer ferramenta você pode chamar o script se houver esta opção, eles não são exclusivos de uma ferramenta, mas ficam gravados em sua conta)
  6. Publicação da aplicação na loja do Google Chrome (Google Chrome Web Store)

 

Fazendo alguns testes foi bem simples, por exemplo, exibir uma mensagem em um novo menu que criei no Google Spreadsheet:

O seu script pode se tornar um código para diversos tipos de aplicação no ambiente do Google, como pode ser visto na imagem abaixo:

É claro que este teste foi bem simples, mas você pode estudar toda a documentação e fazer seus testes, coletando dados de outras aplicações e montando aquilo que vai te ajudar no dia-a-dia ou automatizar o seu trabalho. Acesse o link da documentação completa em:

https://developers.google.com/apps-script/

Vou deixar também o código do teste que fiz:

function menuMostraMsg() {
  Browser.msgBox("Até funciona!")
}

function menuSobre() {
  Browser.msgBox("Visite: pcoutinho.com")
}

function createMenu() {
  var menuEntries = [
    { name : "Clique Aqui!", functionName : "menuMostraMsg" },
    null,
    { name : "Sobre", functionName : "menuSobre" }
   ];
  
   SpreadsheetApp.getActiveSpreadsheet().addMenu("Meu Menu", menuEntries );
}

function onOpen(e) {
  // quando todo os script é carregado
  createMenu(); 
}

function onInstall(e) {
  // quando alguém instala o add-on
  onOpen(e); 
}

function onEdit(e) {
  // quando alguém edita algum dado
}

 

Bom, espero ter ajudado com estas dicas.

Obrigado e até o próximo post pessoal.

Docker Toolbox – Nova ferramenta que ajuda na instalação e configuração do ambiente em forma de instalador

Olá pessoal,

O Docker vem ganhando espaço em todo o mundo com a novo método de criação de ambiente que usa um recurso do link chamado “container”. Veja aqui. É uma virtualização no nível do sistema operacional que torna capaz rodar múltiplos e isolados sistemas Linux (containers) em um único host com Linux.

Por ser um recurso exclusivo do Linux, sistemas como OSX e Windows precisam de uma máquina virtual com Linux por trás dos panos para que através desta máquina o Docker funcione.

Até ai nenhum problema, senão fosse pelos passos que precisam ser dados no OSX e Windows para que todo o ambiente funcione perfeitamente. Não é nada difícil, mas é um trabalho braçal. Pensando em facilitar a adoção do Docker e também em ajudar os usuários a montar este ambiente de forma mais rápida e prática, foi lançada a ferramenta “Docker Toolbox”. É uma ferramenta visual para OSX e Windows que já instala e configura o ambiente para você.

Ela pode ser baixada gratuitamente através do link:

https://www.docker.com/products/docker-toolbox

docker-toolbox-instalador

Eu instalei em meu Mac e após seguir os passos do instalador (next, next, finish), já estava tudo funcionando, bastava abrir o programa “Docker Quickstart Terminal” que vem no pacote que ele já montava tudo e já podia começar a usar.

Dependendo do seu container e da sua necessidade, pode ser que já exista um pronto no Docker Hub:

https://hub.docker.com/

 

Bom, espero ter ajudado com estas dicas.

 

Obrigado e até o próximo post pessoal.

Golang – Ferramenta para upload do arquivo DSYM para o Fabric/Crashlytics

Olá pessoal,

Lancei uma ferramenta para enviar o arquivo DSYM (arquivo contendo os “debugs symbols” gerado ao compilar uma aplicação para OSX ou iOS) para o Fabric/Crashlytics manualmente, via linha de comando.

Você pode integrar esta ferramenta em seu processo de deploy ou integração contínua, usando o Jenkins ou Fastlane por exemplo.

Uma dica para quem vai usar com o Fastlane é usar o comando abaixo para executar a ferramenta:

sh "cd .. && fabric-upload-dsym --bundleid=[YOUR-APP-BUNDLE] --fabricapikey=[YOUR-FABRIC-API-KEY] --file=[ZIPPED-DSYM-FILE]"

 

Obrigado e até o próximo post pessoal.

Golang – Nova versão 1.6 (suporte nativo a HTTP2)

Olá pessoal,

No dia 17 de fevereiro saiu a versão 1.6 da linguagem Go (Golang).

Em termos de velocidade o Google se empenhou na versão 1.5.1 em deixar ela o mais rápido possível e o garbage collector o mais otimizado também, então com relação a isso, não mudou tanto.

Os destaques desta nova versão ficam por conta dos itens:

  • Suporte ao protocolo HTTP2, habilitado por padrão
  • Suporte ao recurso “vendor”, que era experimental até então, para as bibliotecas
  • Em aplicações onde há um maior consumo de memória, a versão 1.6 está mais rápida
  • O algoritmo de ordenação da função “sort.Sort” está 10x mais rápido, porém pode causar alguma incompatibilidade, pois os itens não ficam na mesma ordem (use “sort.Stable” para manter a ordem original)
  • Algumas melhorias também ocorreram na parte de templates do Go

A lista completa você pode conferir aqui:

https://golang.org/doc/go1.6

 

Obrigado e até o próximo post pessoal.