gogoogle-people-apigoogle-hangoutshangouts-api

Get name and email of any google directory user via service account


I have a chat bot that connects to the Google People API with a google service account. The bot receives an event that contains the message sender's Google ID (ie 1234567890987654321). I would like to look up the message sender's name and email address using the service account.

I believe that the https://www.googleapis.com/auth/directory.readonly scope should allow this, with domain-wide delegation set for the service account. But the response does not include the requested fields, only Etag and ResourceName are populated.

What can I change or configure to include the name and email of an arbitrary directory user in a People.Get call with a service account?

package main

import (
        "context"
        "log"

        "google.golang.org/api/option"
        "google.golang.org/api/people/v1"
)

func main() {
        // Service account's credentials
        apiKeyFile := "credentials.json"
        // Google ID of a person within your directory
        resourceName := "people/1234567890987654321"
        fields := "names,emailAddresses"

        ctx := context.Background()
        // directory.readonly scope is included by default
        s, _ := people.NewService(ctx, option.WithCredentialsFile(apiKeyFile))
        pCall := s.People.Get(resourceName)
        pCall.PersonFields(fields)
        person, _ := pCall.Do()
        log.Print(person.Etag)
        for _, address := range person.EmailAddresses {
                log.Print(address.Value)
        }
        for _, name := range person.Names {
                log.Print(name.DisplayName)
        }
}

Go Playground


Solution

  • It turns out that Google Chat is returning the email address in the json response, it is just missing from chat.DeprecatedEvent. I created new structs to capture the other data, avoiding the person API altogether.

    package lib
    
    // This package creates a customized chat.DeprecatedEvent from v0.37.0 of the google chat api
    import chat "google.golang.org/api/chat/v1"
    
    // ChatEvent Google Chat event with customized User object
    // Both ChatEvent.User and ChatEvent.Message.Sender should have the same fields,
    // but only ChatEvent.User is modified to use ChatUser for simplicity
    type ChatEvent struct {
        // Action: The form action data associated with an interactive card that
        // was clicked. Only populated for CARD_CLICKED events. See the
        // Interactive Cards guide (/hangouts/chat/how-tos/cards-onclick) for
        // more information.
        Action *chat.FormAction `json:"action,omitempty"`
    
        // ConfigCompleteRedirectUrl: The URL the bot should redirect the user
        // to after they have completed an authorization or configuration flow
        // outside of Google Chat. See the Authorizing access to 3p services
        // guide (/hangouts/chat/how-tos/auth-3p) for more information.
        ConfigCompleteRedirectURL string `json:"configCompleteRedirectUrl,omitempty"`
    
        // EventTime: The timestamp indicating when the event was dispatched.
        EventTime string `json:"eventTime,omitempty"`
    
        // Message: The message that triggered the event, if applicable.
        Message *chat.Message `json:"message,omitempty"`
    
        // Space: The room or DM in which the event occurred.
        Space *chat.Space `json:"space,omitempty"`
    
        // ThreadKey: The bot-defined key for the thread related to the event.
        // See the thread_key field of the `spaces.message.create` request for
        // more information.
        ThreadKey string `json:"threadKey,omitempty"`
    
        // Token: A secret value that bots can use to verify if a request is
        // from Google. The token is randomly generated by Google, remains
        // static, and can be obtained from the Google Chat API configuration
        // page in the Cloud Console. Developers can revoke/regenerate it if
        // needed from the same page.
        Token string `json:"token,omitempty"`
    
        // Type: The type of the event.
        //
        // Possible values:
        //   "UNSPECIFIED" - Default value for the enum. DO NOT USE.
        //   "MESSAGE" - A message was sent in a room or direct message.
        //   "ADDED_TO_SPACE" - The bot was added to a room or DM.
        //   "REMOVED_FROM_SPACE" - The bot was removed from a room or DM.
        //   "CARD_CLICKED" - The bot's interactive card was clicked.
        Type string `json:"type,omitempty"`
    
        // User: The customized hangouts chat user that triggered the event.
        User *ChatUser `json:"user,omitempty"`
    }
    
    // ChatUser A custom hangouts chat user that contains the fields currently sent from google as of 26-Jan-2021
    type ChatUser struct {
        // Name: Google's name for the user, such as users/1234567890987654321
        Name string `json:"name"`
        // DisplayName: The first and last name of the user, such as John Doe
        DisplayName string `json:"displayName"`
        // AvatarURL: full URL to an avatar image
        AvatarURL string `json:"avatarUrl"`
        // Email: standard email address
        Email string `json:"email"`
        // Type: see chat.User.Type, typically this will be HUMAN
        Type string `json:"type"`
        // DomainID: see chat.User.DomainId
        DomainID string `json:"domainId"`
    }