Search code examples
gogoogle-cloud-platformgmailgoogle-cloud-pubsub

Setting up Gmail Push notifications through GCP pub/sub using Go


I'm looking to basically setup my application such that it receives notifications every time a mail hits a Gmail inbox.

I'm following the guide here.

  • I have a Topic and subscription created.
  • My credentials are working. I can retrieve my emails using the credentials and a Go script as shown here.
  • I have enabled permissions on my topic gmail with [email protected] as a Pub/Sub Publisher.
  • I have tested the topic in pub/sub by manually sending a message through the console. The message shows up in the simple subscription I made.

main.go

func main() {
    ctx := context.Background()
    // Sets your Google Cloud Platform project ID.
    projectID := "xxx"

    // Creates a client.
    // client, err := pubsub.NewClient(ctx, projectID)
    _, err := pubsub.NewClient(ctx, projectID)
    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }

    b, err := ioutil.ReadFile("credentials.json")
    if err != nil {
        log.Fatalf("Unable to read client secret file: %v", err)
    }

    // If modifying these scopes, delete your previously saved token.json.
    config, err := google.ConfigFromJSON(b, gmail.GmailReadonlyScope)
    if err != nil {
        log.Fatalf("Unable to parse client secret file to config: %v", err)
    }
    gmailClient := getClient(config)

    svc, err := gmail.New(gmailClient)
    if err != nil {
        log.Fatalf("Unable to retrieve Gmail client: %v", err)
    }

    var watchRequest gmail.WatchRequest
    watchRequest.TopicName = "projects/xxx/topics/gmail"

    svc.Users.Watch("[email protected]", &watchRequest)
  ...

The script runs fine although there's no stdout with any confirmation the Watch service is running.

However, with the above setup, I sent a mail from [email protected] to itself but the mail does not show up in my topic/subscription.

What else must I do to enable Gmail push notification through pub/sub using Go?


Solution

  • Make sure you are calling the Do method on your UsersWatchCall. The svc.Users.Watch returns only the structure, doesn't do the call immediately.

    It would look something like this:

    res, err := svc.Users.Watch("[email protected]", &watchRequest).Do()
    if err != nil {
      // don't forget to check the error
    }