Documentation menu

Bloco Adicionar ao calendário

Um bloco de um toque para "adicionar isso ao meu calendário", e a solução prática para convites entre fusos horários diferentes. Um e-mail enviado não tem JavaScript para detectar o fuso horário do próprio destinatário, então este bloco codifica o início e o fim do evento como um instante absoluto, em vez de uma string de horário local pré-calculada. Dessa forma, o aplicativo de calendário de cada participante exibe o horário corretamente no seu próprio fuso horário local, automaticamente.

Como funciona

O bloco é conteúdo puro, como Local: não há nada a responder, então ele nunca aparece no painel de respostas nem na exportação de CSV. Os três links que ele renderiza usam o mesmo slot genérico de rastreamento de clique que todo bloco simples com link usa, em vez de uma capability sob medida.

Os links são bloqueados por ter um startsAt válido: um evento sem horário de início definido renderiza apenas o texto de título e descrição, sem links mortos apontando para lugar nenhum. Se startsAt está definido mas endsAt não (ou resolve para algo antes de startsAt), o bloco define a duração padrão como uma hora após o início — preencher apenas "quando começa" é tratado como o caso comum, e todo consumidor a jusante (o arquivo .ics, Google Calendar, Outlook.com) precisa que algum instante de término exista. location é um campo de texto livre digitado à mão, preenchido a partir do próprio texto do seu bloco Local ou Link de reunião; os três blocos não estão vinculados automaticamente nesta primeira versão, então atualize-o você mesmo se o local mudar.

A partir dessas propriedades, três links são renderizados, compartilhando um blockId para fins de rastreamento de clique (o mapa de calor agrupa por bloco, não por link individual, a mesma convenção que os links sociais usam para seus múltiplos ícones):

  • Baixar .ics — um link assinado para GET /api/calendar que transmite um arquivo RFC 5545 (iCalendar) feito à mão. Não há dependência npm por trás disso — um arquivo .ics é texto simples, construído da mesma forma "puramente do zero" que o codificador de GIF de contagem regressiva. Os campos DTSTART/DTEND do arquivo são emitidos como instantes UTC absolutos (um Z no final, sem componente TZID/VTIMEZONE necessário) — essa é a solução real para fusos horários diferentes, não algo calculado no momento da renderização, apenas uma consequência de startsAt/endsAt do bloco já serem armazenados como milissegundos em época (epoch) desde o início. O UID do evento é um hash sha256 determinístico do título/descrição/local/início/fim, então baixar novamente o mesmo link assinado atualiza uma única entrada de calendário, em vez de criar uma duplicata. Texto livre digitado é escapado conforme a RFC 5545 §3.3.11 (barras invertidas, vírgulas, ponto e vírgula, quebras de linha literais) e linhas longas são quebradas no limite de 75 octetos exigido pela especificação, para que a descrição longa de um organizador não produza um arquivo tecnicamente inválido. A própria URL é assinada da mesma forma que os endpoints de contagem regressiva/fórmula/gráfico são — todo o payload do evento é serializado na string de consulta (sem leitura no Firestore no caminho GET), separado por domínio de toda outra família de URL assinada do app por meio de um prefixo "calendar:" embutido na entrada do HMAC, então uma assinatura gerada para este endpoint nunca pode ser verificada contra outro.
  • Adicionar ao Google Calendar — um deep link simples calendar.google.com/calendar/render?action=TEMPLATE&... construído no momento da emissão, sem ida e volta ao servidor.
  • Adicionar ao Outlook.com — um deep link simples outlook.live.com/calendar/0/action/compose?..., também construído no momento da emissão.

Título, descrição e local são cada um cortados de forma defensiva em tamanhos máximos fixos (200 / 2.000 / 300 caracteres) antes de qualquer um dos três links ser construído, para que um campo de texto livre muito longo não produza um link .ics quebrado ou uma string de consulta descomunal nos dois links da web.

Campos configuráveis:

  • Título do evento.
  • Descrição (opcional).
  • Começa em — obrigatório para que qualquer link seja renderizado.
  • Termina em (padrão de 1 hora após o início).
  • Local (opcional, texto livre).
  • Cor de fundo, preenchimento (padding), borda e raio da borda no cartão.
  • Cor/tamanho do título do evento, e substituições de cor/fundo compartilhadas pelos três links.

Exemplos

Subject

Save the date: our fall meetup

Todo projeto de propósito "Evento" já começa com um bloco Adicionar ao calendário pronto ao lado de Link de reunião, Local e RSVP — veja Eventos e webinars para o padrão completo de convite até lembrete do qual este bloco faz parte. Um clube esportivo reutiliza o mesmo bloco semana após semana para horários de treino e partida, para que o calendário de cada família reflita a programação corretamente, independentemente do fuso horário em que estejam viajando — veja Times e clubes esportivos. Uma série de webinars pode incluir este bloco em um e-mail de confirmação enviado logo após a inscrição, para que o destinatário o adicione ao calendário no mesmo momento em que se inscreveu, em vez de depender de que ele se lembre depois.

Como é o fallback estático

<div style="margin:12px 0;background-color:transparent">
  <p style="margin:0 0 8px;font-weight:600;font-size:16px;color:#111827">Q3 Product Launch</p>
  <a href="https://mailinapp.com/api/calendar?d=eyJ0aXRsZSI6...&s=abc123..."
     style="display:inline-block;padding:10px 20px;background-color:#4f46e5;color:#ffffff;
            border-radius:6px;text-decoration:none;font-size:14px;font-weight:600;margin:0 8px 8px 0">
    Download .ics
  </a>
  <a href="https://calendar.google.com/calendar/render?action=TEMPLATE&text=Q3+Product+Launch&dates=20260901T170000Z%2F20260901T180000Z"
     style="display:inline-block;padding:10px 20px;background-color:#4f46e5;color:#ffffff;
            border-radius:6px;text-decoration:none;font-size:14px;font-weight:600;margin:0 8px 8px 0">
    Add to Google Calendar
  </a>
</div>

Este é o bloco enviado por e-mail por completo — três links simples (o terceiro, Outlook.com, omitido aqui por brevidade) construídos a partir dos mesmos detalhes do evento, sem imagem ou conteúdo bloqueado envolvido.

Veja também