Configurar notificações push com a API Gmail

Este documento explica como gerenciar notificações push com a 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 o aplicativo do 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. Assim, você recebe notificações usando vários métodos, incluindo webhooks e pesquisas 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 projeto (por exemplo, correspondente a projects/myproject/topics/*, em que myproject é o ID do projeto listado para seu projeto 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 privilégios 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 de concluir a configuração inicial do Cloud Pub/Sub, configure contas do Gmail para enviar notificações sobre atualizações da caixa de correio.

Pedido 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 da API Gmail. Forneça o nome do tópico que você criou 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 houver uma mudança 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 de observação

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-mail do usuário. Seu cliente recebe notificações de todas as mudanças depois dessa historyId. Se você precisar processar mudanças antes de historyId, consulte Sincronizar clientes com o Gmail.

Além disso, uma chamada watch bem-sucedida envia imediatamente uma notificação para 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 o monitoramento da caixa de e-mails

Você precisa chamar o método 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 da expiração 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 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 correio 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 conhecido, conforme descrito em Sincronizar clientes com o 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 o recebimento de mensagens.

Responder a notificações

Você precisa confirmar todas as notificações. Se você usar a entrega por push de webhook, responder com sucesso (por exemplo, HTTP 200) confirma o recebimento da notificação.

Se você usar o recebimento por pull (REST pull, RPC pull ou RPC streaming pull), será necessário confirmar o recebimento das mensagens usando o método REST ou RPC acknowledge. Consulte os exemplos de código no guia de assinaturas de pull do Cloud Pub/Sub para mais detalhes sobre como confirmar 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 em outro momento.

Parar 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. O serviço descarta as notificações do usuário que excederem essa taxa. Ao processar notificações, tome cuidado para não acionar outra, o que pode iniciar um loop de notificações.

Confiabilidade

Normalmente, o Cloud Pub/Sub entrega notificações em alguns segundos. No entanto, em raras situações, as notificações podem atrasar ou não chegar. Lide com essa possibilidade de maneira adequada para que o aplicativo ainda seja sincronizado mesmo que não receba mensagens push. 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.