Como Integrar a API do Google Calendar ao Seu Aplicativo
Índice
Integre todos os calendários usando uma única API
Integre todos os provedores de calendário à sua aplicação usando uma única API, sem necessidade de cartão de crédito.
Neste guia, explicaremos detalhadamente como integrar a API do Google Calendar ao seu aplicativo, cobrindo a configuração do projeto no Google Cloud, escopos necessários, armadilhas e um exemplo real de autorização.
Pré-requisitos
Este guia assume que você possui um endereço de e-mail, um domínio existente pronto para uso ao configurar o Projeto no Google Cloud, algum conhecimento em programação e uma ideia razoavelmente clara do que está tentando construir.
Este guia também é útil caso você nunca tenha trabalhado com a API do Google Calendar e queira se familiarizar com todas as etapas necessárias para integrá-la ao seu aplicativo.
Como usar e integrar a API do Google Calendar ao seu aplicativo
1. Inscreva-se no Google Developer Console
Caso você ainda não tenha uma conta no Google Developer Console, crie uma em https://console.cloud.google.com/.
2. Crie ou escolha um Projeto do Google Cloud existente
O Google Cloud permite que desenvolvedores e organizações tenham múltiplos projetos. Certifique-se de que você está no projeto correto ao realizar as operações seguintes.
Clique no menu suspenso de projetos no canto superior esquerdo da tela. O nome geralmente corresponde ao nome do seu projeto.

Selecione um projeto existente ou crie um novo projeto clicando em “Novo Projeto” no canto superior direito do modal.

3. Ative os serviços da API do Google Calendar
Depois de criar uma conta e garantir que está no projeto correto, siga estas etapas para ativar os serviços da API do Google Calendar:
- Vá para o Google Cloud Console
- Clique em “APIs e serviços”

- Clique em “Ativar APIs e serviços”

- Pesquise por “Google Calendar API”

- Clique em “Ativar” para ativar o serviço.

4. Configure a Tela de Consentimento OAuth
Após ativar os serviços da API do Google Calendar, o próximo passo é configurar a Tela de Consentimento OAuth. Esta é a interface que os usuários finais verão ao conectar seus calendários ao seu aplicativo. Normalmente, eles poderão ver o logotipo do seu app, nome, permissões requeridas e mais.
- Clique na aba “Tela de consentimento OAuth”.

- Clique em “Começar”.

- Preencha a seção “Informações do app”. Nessa seção, você deve inserir o nome do seu app e o e-mail de suporte ao cliente.

- Escolha o público-alvo. O público pode ser interno ou externo. Escolha interno se seu app não for público e apenas usuários da sua organização poderão conectar seus calendários. Escolha externo se qualquer conta pública poderá se autenticar, independentemente de pertencer ou não à sua organização.

- Preencha suas informações de contato. O Google exige que você informe um e-mail para notificações sobre alterações no projeto.

- Marque a caixa “Concordo com a Política de Dados do Usuário dos Serviços da API do Google”.

- Clique em “Criar”.

5. Crie seu Cliente OAuth
Depois de configurar a Tela de Consentimento OAuth, você pode criar o cliente OAuth para o projeto. Para isso, clique na aba “Clientes” e em seguida clique em “Criar cliente”.
Alternativamente, clique em “Criar cliente OAuth” na página de visão geral.

Você pode criar clientes para cada plataforma em que seu app rodará. Por exemplo, se estiver criando um aplicativo web e um app iOS, será necessário criar um ID de cliente OAuth separado para cada plataforma.

Neste exemplo, criaremos apenas um Cliente para “Aplicativo Web” e o chamaremos de “Web Client”.

Neste fluxo, também configuraremos nossas origens JavaScript autorizadas, bem como os URIs de redirecionamento autorizados.
No campo de origens JavaScript autorizadas, preencha o domínio/URL que hospeda seu aplicativo web, por exemplo: myapp.domain.com

Nos URLs de redirecionamento autorizados, preencha todos os URLs de redirecionamento que serão utilizados para redirecionar os usuários após a autenticação com o Google. A URL será acrescida do código de autorização de acesso e deve conter o protocolo.

Certifique-se também de colocar na lista de permissões as URLs de redirecionamento do seu localhost, caso este aplicativo seja usado durante a fase de desenvolvimento. Para fins deste exemplo, também colocaremos na lista de permissões nossa URL de redirecionamento do localhost.
Após preencher esses campos, clique em “Criar”. O Google abrirá um modal exibindo o ID do Cliente e o Segredo do Cliente. Certifique-se de copiar essas informações e armazená-las em um local seguro (geralmente no seu arquivo .env, pois as usaremos no fluxo de autenticação abaixo). Você também pode baixar o JSON contendo esses campos e armazená-lo em um gerenciador de senhas como o 1Password.

Certifique-se de baixar o arquivo JSON que contém o Client Secret ou de copiá-lo e salvá-lo em um local seguro, pois, após o fechamento do modal, você não poderá mais copiar o Client Secret.
6. Adicione alguns usuários de teste para fins de desenvolvimento
Durante o desenvolvimento do seu app localmente, não será possível conectar contas do Google Calendar a menos que você adicione usuários de teste à sua aplicação. Isso acontece porque seu app é externo e ainda não foi aprovado pelo Google.
Para adicionar usuários de teste, siga estas etapas:
- Clique na aba “Público-alvo”.

- Role até encontrar a seção “Usuários de teste”.

- Clique em “Adicionar usuários” e insira o e-mail do usuário.

7. Adicione os escopos de calendário que você pretende usar
Dependendo do caso de uso que deseja resolver ao integrar o Google Calendar ao seu app, você pode querer solicitar diferentes escopos do usuário no momento da autorização da conta do Google Calendar.
Pense nos escopos como permissões que você solicita aos usuários para usar em seu aplicativo e permitir o acesso a dados privados da Conta Google. Exemplos de escopos incluem a capacidade de listar calendários, visualizar eventos do calendário, entre outros.
O Google divide os escopos em sensíveis e não sensíveis. Se você adicionar escopos sensíveis, precisará submeter seu app para verificação. Isso também se aplica se o app já estiver verificado e você adicionar escopos sensíveis adicionais.
Após inserir todos os escopos necessários para o funcionamento do seu app, certifique-se de adicionar uma justificativa para cada escopo, além de um vídeo de demonstração. Eles são obrigatórios na submissão para verificação.
Para gerenciar os escopos, siga estas etapas:
- Clique na aba “Acesso a dados”.

- Clique em "Adicionar ou remover escopos"

- Pesquise o escopo pelo nome ou valor e adicione-o.

8. Familiarize-se com a API do Google Calendar
Agora que configuramos o App Cliente do Google e preenchemos todas as informações necessárias para permitir que os usuários conectem seus calendários ao nosso aplicativo, devemos nos familiarizar melhor com a API do Google Calendar.
Recomendo navegar pela página de visão geral da API do Google Calendar e explorar os endpoints importantes, como os endpoints de Eventos ou de Calendários.
9. Use uma API de Calendário Unificada para integrar múltiplos provedores com uma única API
Se o Google Calendar for o único calendário que você deseja integrar ao seu aplicativo, pode ignorar esta etapa. Caso contrário, recomendamos que utilize uma API de Calendário Unificada, que oferece uma API única para todos os provedores de calendário.
Usar uma API de calendário unificada oferece o benefício de ter apenas uma integração para todos os provedores. Caso você deseje suportar Outlook futuramente, poderá adicionar a integração sem precisar escrever nenhum código.
Além disso, você não precisará manter múltiplas integrações, lidar com mudanças quebráveis ou gastar tempo aprendendo os detalhes de cada API de provedor de calendário.
Exemplo de fluxo de autorização do Google Calendar
O fluxograma abaixo ilustra um fluxo simples de OAuth do Google Calendar que permite que os usuários conectem seus calendários ao seu aplicativo.

Lado do Cliente (UI)
A primeira parte é o lado do Cliente/UI, onde renderizaremos um botão “Conectar Google Calendar”.
const googleOauthUrl = getGoogleOAuthUrl()
<button href="googleOauthUrl" rel="noopener noreferrer"> Connect Google Calendar </button>
O ideal é usar uma função utilitária para obter a URL de OAuth do Google, pois isso melhora a legibilidade do código, além de facilitar o envio de parâmetros, como armazenar o estado do cliente, forçar permissões, etc.
const SCOPES = [
"openid",
"email",
"<https://www.googleapis.com/auth/calendar.calendarlist>",
"<https://www.googleapis.com/auth/calendar.events>",
"<https://www.googleapis.com/auth/calendar.readonly>",
// add more scopes as needed
];
export interface ClientState {
session: Session;
returnUrl?: string;
}
export function stateToB64(session: ClientState): string {
return encode(JSON.stringify(session));
}
export function getGoogleOAuthUrl(
state: ClientState,
) {
const params = new URLSearchParams({
client_id: process.env.GOOGLE_CLIENT_ID || "",
redirect_uri: `${getHostName()}/api/connect/google`, // change the redirect URL as needed
response_type: "code",
scope: SCOPES.join(" "),
prompt: "consent",
access_type: "offline",
state: stateToB64(state),
});
return `https://accounts.google.com/o/oauth2/v2/auth?${params}`;
}
O parâmetro prompt pode ter um dos três valores: none, consent ou select_account.
O parâmetro consent pode ser usado em casos em que o usuário já autorizou seus calendários uma vez, mas ainda assim queremos que o Google exiba novamente o modal de autorização. Isso pode ser útil quando adicionamos mais escopos ao nosso app e queremos que os usuários autorizem esses novos escopos.
Outro caso para usar consent é quando o usuário não selecionou todos os escopos exigidos pelo seu aplicativo, então você deseja solicitar novamente os escopos.
O valor select_account pode ser enviado para solicitar que o usuário selecione uma conta.
O none é usado para não exibir nenhuma tela de autenticação ou consentimento.
Lado da API (Backend)
Em seguida, vamos construir o manipulador da API, que é responsável por obter o código e os escopos do servidor do Google e trocá-los por tokens.
Neste exemplo, estamos usando zod para validação.
import { z } from "zod";
const successSchema = z.object({
code: z.string(),
scope: z.string(),
state: z.string(),
});
const errorSchema = z.object({
error: z.string(),
});
type ErrorParams = z.infer<typeof errorSchema>;
const querySchema = z.union([successSchema, errorSchema]);
// Handler
const googleHanlder: NextApiHandler = async (req, res) => {
try {
const result = querySchema.parse(req.query);
if (isError(result)) {
const q = new URLSearchParams({
error: "ACCESS_DENIED",
});
return res.redirect(`/?${q}`);
}
const { session, returnUr } = stateFromB64(
result.state
);
if (!hasRequiredScopes(result.scope)) {
const q = new URLSearchParams({
error: "MISSING_REQUIRED_PERMISSIONS",
});
return res.redirect(`/?${q}`);
}
const { access_token, refresh_token, id_token, expires_in } =
await exchangeCodeForTokens(result.code);
const { email } = decodeIdToken(id_token);
// Update or insert the calendar connection, depending on your use case
const connection = await upsertConnection(
{
email,
accessToken: access_token,
refreshToken: refresh_token,
expiresInSeconds: expires_in,
status: ConnectionStatus.ACTIVE,
provider: CalendarProvider.GOOGLE,
scopes: result.scope,
reminderCount: 0,
lastRemindedAt: null,
},
session.user
);
const q = new URLSearchParams({
cid: connection.id,
});
if (returnUrl) q.append("returnUrl", returnUrl);
// The API redirects back to the client side, returning the connection, or errors if any
res.redirect returnUrl ? returnUrl : `/calendars/google?${q}`
);
} catch (e: any) {
let error = JSON.stringify(e);
const querystr =
typeof req.query === "string" ? req.query : JSON.stringify(req.query);
console.error("Error in googleHandler", querystr);
console.error("Failed to connect Google account", e);
const q = new URLSearchParams({
error,
});
return res.redirect(`/?${q}`);
}
};
Semelhante ao lado do cliente, recomendamos ter essas funções utilitárias para trocar o código por tokens, decodificar o token de ID, obter o estado a partir do base 64, etc.
export async function exchangeCodeForTokens(code: string) {
const data = new FormData();
data.append("code", code);
data.append("client_id", process.env.GOOGLE_CLIENT_ID || "");
data.append("client_secret", process.env.GOOGLE_CLIENT_SECRET || "");
data.append("redirect_uri", `${getHostName()}/api/connect/google`); // your URL
data.append("grant_type", "authorization_code");
try {
const result = await fetch("<https://oauth2.googleapis.com/token>", {
method: "POST",
body: data,
});
const json = await result.json();
if (json.error) throw json;
const parsed = responseSchema.parse(json);
return parsed;
} catch (e) {
console.error("Exchange failed");
throw e;
}
}
export function decodeIdToken(idToken: string) {
const data = jwt.decode(idToken);
if (typeof data === "string" || !data?.email) {
throw new Error(`Could not parse id_token: ${idToken}`);
}
return data;
}
function isError(query: Record<string, any>): query is ErrorParams {
return Boolean(query.error);
}
export function stateFromB64(encoded: string): ClientState {
const str = decode(encoded);
return JSON.parse(str) as ClientState;
}
As variáveis de ambiente process.env.GOOGLE_CLIENT_ID e process.env.GOOGLE_CLIENT_SECRET que usamos na implementação acima são o Client ID e o Client Secret mencionados na Etapa 5: Criar seu Cliente OAuth. Certifique-se de copiá-los ao criar o Cliente OAuth, caso contrário, você não poderá copiar o Client Secret após fechar o modal.
Detalhes importantes sobre a integração com a API do Google Calendar
- A verificação pode levar algumas semanas, então planeje com antecedência antes do lançamento e leve esse atraso em consideração na sua linha do tempo. O processo de aprovação pode levar algum tempo e, muitas vezes, você pode ser rejeitado na primeira vez em que submeter seu app para verificação. Por isso, recomendo que você leve isso em conta no seu cronograma e avise todos os stakeholders sobre esse possível atraso.
- Webhooks param após cerca de 24 horas; você deve sempre renová-los. Você pode registrar webhooks para detectar alterações em um calendário, mas certifique-se de renová-los, pois eles expiram após 24 horas. Você pode usar cron jobs para detectar webhooks que irão expirar nos próximos 20 minutos e renová-los.
- Solicite apenas os escopos que você realmente precisa. Pode parecer uma boa ideia solicitar o máximo de escopos possível, já que você nunca sabe o que será necessário na próxima iteração do seu app, mas recomendo solicitar apenas o que for necessário para o funcionamento do seu app. O primeiro motivo é que o Google é muito rigoroso durante o processo de verificação do app, então eles irão rejeitar seu app e você terá que ir e voltar até conseguir a aprovação. O segundo motivo é que os usuários podem ficar relutantes em conceder acesso a todos os escopos solicitados se eles não fizerem sentido ou forem além do que o app realmente faz.
- Gerencie cotas e limitações de taxa. O Google possui cotas por minuto por projeto e por minuto por usuário por projeto. Se você exceder qualquer uma delas, o Google retornará um código 403 usageLimits ou 429 rateLimitExceeded. Certifique-se de usar back-off exponencial e outras táticas para garantir que você não atinja esses limites.
- Cuidado para não registrar dados pessoais nos logs. Fazer logging de dados é aceitável, mas certifique-se de remover qualquer dado pessoal de eventos, pois eles geralmente contêm descrição, e-mails de participantes, etc.
Integre vários provedores de calendário no seu app usando a API Unificada de Calendário da OneCal
Na OneCal, sincronizamos milhões de eventos de calendário entre Google Calendar, Outlook e iCloud. Sabemos o que é necessário para integrar múltiplos provedores de calendário, aprender os detalhes de cada API e fazer com que cada implementação funcione perfeitamente.
É por isso que criamos um produto de API de Calendário Unificada que oferece suporte ao Outlook, Google Calendar e iCloud Calendar por padrão, permitindo que você integre todos os principais provedores usando uma única API robusta e fácil de usar.
Você pode começar gratuitamente, testar a Unified Calendar API, ver suas funcionalidades e decidir fazer o upgrade depois.
FAQ
Por que preciso adicionar usuários de teste ao meu Cliente OAuth do Google?
Um aplicativo externo não verificado só pode ser usado por contas de teste permitidas enquanto você desenvolve o app e antes que o Google o aprove.
Por quanto tempo os webhooks do Google Calendar permanecem ativos?
Assinaturas de notificações push expiram em cerca de 24 horas, então seu backend deve renová-las antes que expirem.
Existe uma maneira mais simples de adicionar calendários do Outlook ou iCloud depois?
Sim. Uma API de calendário unificada como a API de Calendário Unificada da OneCal permite integrar Google, Outlook e iCloud por meio de uma única API, economizando tempo e custos de desenvolvimento com integrações e manutenção separadas.
Eu preciso de “offline_access” para tarefas em segundo plano?
Sim. Adicionar access_type=offline na URL de consentimento retorna um refresh token, permitindo que seu servidor chame a API mesmo quando o usuário estiver ausente.