Pitch: como eu desenvolvi o módulo de analytics do meu micro-saas
Boa tarde pessoal, como vocês estão? Nesse post quero continuar as postagens a cerca do curto.io, o micro-saas de engajamento que estou desenvolvendo.
Uma das partes mais importantes de um micro-saas nesse segmento é a capability de medir a performance das ações feitas na plataforma, trazendo confiança e visibilidade a respeito do resultado das ações de engajamento.
Post anterior:
A idéia
A maioria esmagadora de SaaS nesse segmento como bit.ly, short.io possui em seu leque de funcionalidades uma forma muito bacana de conseguir fazer tracking de como cada um dos seus links estão performando, e com isso vem informações como:
- A evolução da quantidade de cliques dado um período
- Segmentação por aparelhos, navegador, localização, entre outras coisas
- Quais dias são mais "quentes" (quando os usuários acessaram mais)?
E muitas outras coisas, como você pode ver nesse print abaixo (do bitly.com):
O problema
Sei o que eu precisava fazer, agora como eu poderia fazer isso? Era o que me tirava o sono.
O ato de redirecionar um usuário funciona da seguinte maneira:
E a idéia era a partir desse módulo de analytics, era ser assim:
Onde antes de redirecionar o usuário para o destino desejado, era necessário fazer um POST para a API e salvar o registro do click do usuário, enviando todas as informações públicas do navegador que o usuário usou pra fazer aquela operação, que são:
- User-Agent
- Referrer
- IP
- Geolocalização
Com essas informações, meu desejo era ser capaz de ter um documento como esse no mongodb:
{
"urlId": "an_url_id",
"platform": "iOS",
"device": "Mobile",
"browser": "Safari",
"country": "BR",
"region": "SP",
"ua": "",
"browserVersion": "108.0.0",
"engine": "Blink",
"engineVersion": "10.1.1",
"platformVersion": "14.8",
"deviceModel": "iPhone 11",
"deviceVendor": "Apple",
"bot": false,
"referrer": "(direct)",
"referrerUrl": "(direct)",
"createdAt": "2023-03-25T03:09:01.504+00:00"
"updatedAt": "2023-03-25T03:09:01.504+00:00"
}
Edge Middleware, o salvador da pátrica
Fazendo uso de uma Edge Middleware da Vercel, conseguimos uma informação importante para atingir esse objetivo, que é a propriedade geo
dentro do objeto req
dentro de um middleware:
type Geo = {
city?: string | undefined;
country?: string | undefined;
region?: string | undefined;
latitude?: string | undefined;
longitude?: string | undefined;
}
E isso, aliado com um parser de User-Agent
, nós chegamos a esse método pra criação de novos cliques:
async function createNewClick(req: NextRequest, domainId: string, urlId: string) {
const ua = userAgent(req)
const referer = req.headers.get('referer');
const geo = req.geo ?? {};
const url = `${process.env.NEXT_PUBLIC_CURTO_API_BASE_URL}/clicks`
return fetch(url, {
method: 'POST',
body: JSON.stringify({
domain_id: domainId,
url_id: urlId,
country: geo.country || 'Unknown',
region: geo.region || "Unknown",
latitude: geo.latitude || "Unknown",
longitude: geo.longitude || "Unknown",
ua: ua.ua || "Unknown",
browser: ua.browser.name || "Unknown",
browser_version: ua.browser.version || "Unknown",
engine: ua.engine.name || "Unknown",
engine_version: ua.engine.version || "Unknown",
platform: ua.os.name || "Unknown",
platform_version: ua.os.version || "Unknown",
device: ua.device.type ? capitalize(ua.device.type) : "Desktop",
device_vendor: ua.device.vendor || "Unknown",
device_model: ua.device.model || "Unknown",
cpu_arch: ua.cpu?.architecture || "Unknown",
bot: ua.isBot,
referrer: getDomainWithoutWWW(referer) || "(direct)",
referrer_url: referer || "(direct)",
}),
headers: {
'Content-Type': 'application/json'
}
})
.then((res: any) => console.log('Response: ', res.status))
}
Tá, mas agora o que eu faço com isso?
Tenho todas as informações que eu preciso, agora o que eu posso fazer com isso?
Como estamos trabalhando com a criação de cliques por data, podemos criar alguns métodos interessantes, como:
- Pegar a quantidade de cliques agrupada por dia, hora, semana dentro de um período
- Dividir em % a quantidade de cliques que teve em aparelhos iOS, Android e Desktop
E pra conseguir fazer isso, a minha API deveria ser capaz de transformar uma lista disso:
{
"urlId": "an_url_id",
"platform": "iOS",
"device": "Mobile",
"browser": "Safari",
"country": "BR",
"region": "SP",
"ua": "",
"browserVersion": "108.0.0",
"engine": "Blink",
"engineVersion": "10.1.1",
"platformVersion": "14.8",
"deviceModel": "iPhone 11",
"deviceVendor": "Apple",
"bot": false,
"referrer": "(direct)",
"referrerUrl": "(direct)",
"createdAt": "2023-03-25T03:09:01.504+00:00"
"updatedAt": "2023-03-25T03:09:01.504+00:00"
}
Para isso:
[
{"key":"2023-02-28T00:00:00","clicks":1},
{"key":"2023-03-01T00:00:00","clicks":1},
{"key":"2023-03-02T00:00:00","clicks":2}
]
Onde a propriedade key
é o timestamp da data truncada para o período selecionado, e clicks
é a quantidade de cliques que teve naquele dia.
Resultado
E com alguns dias de tentativas, muitos problemas de timezone e alguns engradados de monster, consegui chegar nesse resultado, onde o link da imagem em questão é um link que eu postei na descrição de um video no meu canal do youtube:
Conclusão
E foi assim que eu fiz o meu novo módulo de analytics pro curto.io que ainda não está disponível por estar em desenvolvimento, mas que logo terá um beta fechado no qual darei mais detalhes depois.
Se tiver alguma dúvida sobre o processo ou quiser conversar mais a respeito, fique a vontade pra me procurar:
LinkedIn: https://curr.to/3V3aS
GitHub: https://curr.to/fb2uA
Instagram: https://curr.to/10dVt
YouTube: https://curr.to/kQv2e