Configurar notificações push na API Gmail

Este documento explica como gerenciar notificações push na API Gmail.

A API Gmail fornece notificações push de servidor que permitem monitorar mudanças nas caixas de e-mail do Gmail. Use esse recurso para melhorar a performance do seu aplicativo. Ele elimina os custos extras de rede e computação de recursos de sondagem para determinar se eles mudaram. Sempre que uma caixa de e-mails muda, a API Gmail notifica seu aplicativo de servidor de back-end.

Configuração inicial do Cloud Pub/Sub

A API Gmail usa a API Cloud Pub/Sub para enviar notificações push. Isso permite notificações usando vários métodos, incluindo webhooks e sondagem em um único endpoint de assinatura.

Pré-requisitos

Para concluir essa configuração, atenda aos pré-requisitos do Cloud Pub/Sub e configure um cliente do Cloud Pub/Sub.

Criar um tópico

Usando seu cliente do Cloud Pub/Sub, crie o tópico para que a API Gmail envie notificações. O nome do tópico pode ser qualquer nome que você escolher no seu projeto (por exemplo, projects/myproject/topics/* correspondente, em que myproject é o ID do projeto listado no console do Google Cloud).

Crie uma assinatura

Para configurar uma assinatura do tópico criado, siga o guia Tipos de assinatura do Cloud Pub/Sub. Configure o tipo de assinatura como um push de webhook (ou seja, um callback HTTP POST) ou um pull (ou seja, iniciado pelo seu app). É assim que seu aplicativo recebe notificações de atualizações.

Conceder direitos de publicação no tópico

O Cloud Pub/Sub exige que você conceda permissões ao Gmail para publicar notificações no seu tópico.

Para fazer isso, conceda privilégios de publish a gmail-api-push@system.gserviceaccount.com. Para isso, use o console de permissões do Cloud Pub/Sub no console do Google Cloud seguindo estas instruções de controle de acesso.

A configuração de compartilhamento restrito ao domínio da sua organização pode impedir que você conceda permissões de publicação. Para resolver isso, configure uma exceção para essa conta de serviço.

Receber atualizações da caixa de e-mails do Gmail

Depois que a configuração inicial do Cloud Pub/Sub for concluída, configure contas do Gmail para enviar notificações de atualizações da caixa de correio.

Solicitação de assistir

Para configurar contas do Gmail para enviar notificações ao seu tópico do Cloud Pub/Sub, use o cliente da API Gmail para chamar o método watch na caixa de e-mail do usuário do Gmail. Isso é semelhante a qualquer outra chamada de API do Gmail. Forneça o nome do tópico criado e outras opções na solicitação watch, como labels para filtrar. Por exemplo, use a seguinte solicitação para receber uma notificação sempre que uma mudança for feita na caixa de entrada:

Protocolo

POST "https://www.googleapis.com/gmail/v1/users/me/watch"
Content-type: application/json

{
  topicName: "projects/myproject/topics/mytopic",
  labelIds: ["INBOX"],
  labelFilterBehavior: "INCLUDE",
}

Python

request = {
  'labelIds': ['INBOX'],
  'topicName': 'projects/myproject/topics/mytopic',
  'labelFilterBehavior': 'INCLUDE'
}
gmail.users().watch(userId='me', body=request).execute()

Resposta do relógio

Se a solicitação watch for bem-sucedida, você vai receber uma resposta como esta:

{ historyId: 1234567890 expiration: 1431990098200 }

A resposta contém o historyId atual da caixa de e-mails do usuário. Seu cliente recebe notificações de todas as mudanças depois dessa data historyId. Se você precisar processar mudanças antes desse historyId, consulte Sincronizar clientes com a API Gmail.

Além disso, uma chamada watch bem-sucedida faz com que uma notificação seja enviada imediatamente ao seu tópico do Cloud Pub/Sub.

Se você receber um erro da chamada watch, os detalhes vão explicar a origem do problema. Normalmente, isso é um problema com a configuração do tópico e da assinatura do Cloud Pub/Sub. Consulte a documentação do Cloud Pub/Sub para confirmar se a configuração está correta e receber ajuda para depurar problemas de tópicos e assinaturas.

Renovar a observação da caixa de e-mails

Você precisa chamar o watch pelo menos uma vez a cada sete dias. Caso contrário, o usuário não vai mais receber atualizações. Recomendamos chamar watch uma vez por dia. A resposta do método watch também tem um campo expiration com o carimbo de data/hora do vencimento do watch.

Receber notificações

Sempre que houver uma atualização na caixa de e-mails que corresponda ao seu watch, o aplicativo receberá uma mensagem de notificação descrevendo a mudança.

Se você configurou uma assinatura por push, uma notificação de webhook para seu servidor está de acordo com um PubsubMessage:

POST https://yourserver.example.com/yourUrl
Content-type: application/json

{
  message:
  {
    // This is the actual notification data, as Base64URL-encoded JSON.
    data: "eyJlbWFpbEFkZHJlc3MiOiAidXNlckBleGFtcGxlLmNvbSIsICJoaXN0b3J5SWQiOiAiMTIzNDU2Nzg5MCJ9",

    // This is a Cloud Pub/Sub message id, unrelated to Gmail messages.
    "messageId": "2070443601311540",

    // This is the publish time of the message.
    "publishTime": "2021-02-26T19:13:55.749Z",
  }

  subscription: "projects/myproject/subscriptions/mysubscription"
}

O corpo da solicitação HTTP POST é JSON, e o payload real da notificação do Gmail está no campo message.data. O campo message.data é uma string codificada em Base64URL que decodifica para um objeto JSON contendo o endereço de e-mail e o novo ID do histórico da caixa de e-mails do usuário:

{"emailAddress": "user@example.com", "historyId": "9876543210"}

Em seguida, use o método history.list para receber os detalhes da mudança do usuário desde o último historyId, conforme descrito em Sincronizar clientes com a API Gmail.

Por exemplo, use o método history.list para identificar mudanças que ocorreram entre sua solicitação watch inicial e o recebimento da mensagem de notificação compartilhada no exemplo anterior. Transmita 1234567890 como o startHistoryId para history.list. Depois, você pode manter 9876543210 como o último historyId conhecido para casos de uso futuros.

Se você configurou uma assinatura por pull, consulte os exemplos de código no guia de assinaturas por pull do Cloud Pub/Sub para mais detalhes sobre como receber mensagens.

Responder a notificações

Todas as notificações precisam ser confirmadas. Se você usar a entrega por push de webhook, responder com sucesso (por exemplo, HTTP 200) confirma a notificação.

Se você usa a entrega por pull (REST Pull, RPC Pull ou RPC StreamingPull), é necessário fazer uma chamada de confirmação (REST ou RPC). Consulte os exemplos de código no guia de assinaturas de pull do Cloud Pub/Sub para mais detalhes sobre como confirmar o recebimento de mensagens de forma assíncrona ou síncrona usando as bibliotecas de cliente oficiais baseadas em RPC.

Se você não confirmar as notificações (por exemplo, se o callback do webhook retornar um erro ou atingir o tempo limite), o Cloud Pub/Sub vai tentar de novo mais tarde.

Interromper atualizações da caixa de e-mails

Para parar de receber atualizações em uma caixa de e-mails, chame o método stop. Todas as novas notificações devem parar em alguns minutos.

Limitações

Confira abaixo as limitações de trabalhar com notificações push do servidor:

Taxa máxima de notificações

Cada usuário do Gmail monitorado tem uma taxa máxima de notificação de um evento por segundo. Todas as notificações de usuário que excederem essa taxa serão descartadas. Ao processar notificações, tome cuidado para não acionar outra, o que pode iniciar um loop de notificações.

Confiabilidade

Normalmente, todas as notificações são entregues de forma confiável em alguns segundos. No entanto, em algumas situações extremas, elas podem ser atrasadas ou descartadas. Lide com essa possibilidade de maneira adequada para que o aplicativo ainda seja sincronizado mesmo que nenhuma mensagem push seja recebida. Por exemplo, volte a chamar periodicamente o método history.list depois de um período sem notificações para um usuário.

Limitações do Cloud Pub/Sub

A API Cloud Pub/Sub também tem limitações próprias, detalhadas na documentação de preços e cotas.