Vinculação de conta com o Login do Google

O Login do Google com o Assistente oferece a experiência mais simples e fácil para usuários e desenvolvedores, tanto para vinculação quanto para criação de contas. Sua Ação pode solicitar acesso ao perfil do Google do usuário durante uma conversa, incluindo o nome, o endereço de e-mail e a foto do perfil do usuário.

As informações do perfil podem ser usadas para criar uma experiência do usuário personalizada na sua Ação. Se você tem apps em outras plataformas e eles usam o Login do Google, também é possível encontrar e vincular a uma conta de usuário existente, criar uma nova e estabelecer um canal direto de comunicação com o usuário.

Para vincular a conta com o Login do Google, você precisa pedir que o usuário dê consentimento para acessar o perfil do Google. Em seguida, use as informações no perfil da pessoa, por exemplo, o endereço de e-mail, para identificar o usuário no seu sistema.

Implementar a vinculação de contas do Login do Google

Siga as etapas nas seções a seguir para adicionar a vinculação da conta do Login do Google à sua ação.

Configurar o projeto

Para configurar seu projeto para usar a vinculação de contas do Login do Google, siga estas etapas:

  1. Abra o Console do Actions e selecione um projeto.
  2. Clique na guia Desenvolver e escolha Vinculação de contas.
  3. Ative a chave ao lado de Vinculação de contas.
  4. Na seção Criação de conta, selecione Sim.
  5. Em Tipo de vinculação, selecione Login do Google.

  6. Abra Informações do cliente e anote o valor do ID do cliente emitido pelo Google para suas ações.

  7. Clique em Salvar.

Projetar a interface do usuário de voz para o fluxo de autenticação

Conferir se o usuário foi verificado e iniciar o fluxo de vinculação da conta

  1. Abra seu projeto do Actions Builder no Actions Console.
  2. Crie um novo cenário para começar a vinculação da conta na sua Ação:
    1. Clique em Cenas.
    2. Clique no ícone add (+) para adicionar uma nova cena.
  3. No cenário recém-criado, clique no ícone de adição para Condições.
  4. Adicione uma condição que verifica se o usuário associado à conversa é um usuário verificado. Se a verificação falhar, a Ação não poderá fazer a vinculação da conta durante a conversa e vai voltar a fornecer acesso a recursos que não exijam a vinculação de conta.
    1. No campo Enter new expression em Condição, insira a seguinte lógica: user.verificationStatus != "VERIFIED"
    2. Em Transição, selecione uma cena que não exija vinculação de conta ou uma cena que seja o ponto de entrada para a funcionalidade exclusiva para convidados.

  1. Clique no ícone de adição para Condições.
  2. Adicione uma condição para acionar um fluxo de vinculação de conta se o usuário não tiver uma identidade associada.
    1. No campo Enter new expression em Condição, insira a seguinte lógica: user.verificationStatus == "VERIFIED"
    2. Em Transição, selecione a cena do sistema Vinculação de contas.
    3. Clique em Salvar.

Depois de salvar, uma nova cena do sistema de vinculação de contas chamada <SceneName>_AccountLinking será adicionada ao projeto.

Personalizar o cenário de vinculação da conta

  1. Em Scenes, selecione a cena do sistema de vinculação de contas.
  2. Clique em Enviar solicitação e adicione uma frase curta para descrever ao usuário por que a ação precisa acessar a identidade dele (por exemplo, "Para salvar suas preferências").
  3. Clique em Salvar.

  1. Em Condições, clique em Se o usuário concluir a vinculação da conta.
  2. Configure como o fluxo deve proceder se o usuário concordar em vincular a conta. Por exemplo, chame o webhook para processar qualquer lógica de negócios personalizada necessária e fazer a transição de volta para a cena de origem.
  3. Clique em Salvar.

  1. Em Condições, clique em Se o usuário cancelar ou dispensar a vinculação da conta.
  2. Configure como o fluxo deve proceder se o usuário não concordar em vincular a conta. Por exemplo, envie uma mensagem de confirmação e redirecione para cenas que fornecem funcionalidades que não exigem vinculação de conta.
  3. Clique em Salvar.

  1. Em Condições, clique em Se ocorrer um erro de sistema ou rede.
  2. Configure como o fluxo vai proceder se não for possível concluir o fluxo de vinculação da conta devido a erros no sistema ou na rede. Por exemplo, envie uma mensagem de confirmação e redirecione para cenas que fornecem funcionalidades que não exigem vinculação de conta.
  3. Clique em Salvar.

Acessar informações do perfil no back-end

Depois que o usuário autorizar a ação de acessar o perfil do Google dele, você receberá um token de ID do Google com as informações do perfil do Google em todas as solicitações subsequentes à ação.

Para acessar as informações do perfil do usuário, primeiro valide e decodifique o token fazendo o seguinte:

  1. Use uma biblioteca de decodificação de JWT na sua linguagem para decodificar o token e use as chaves públicas do Google (disponíveis no formato JWK ou PEM) para verificar a assinatura do token.
  2. Verifique se o emissor do token (campo iss no token decodificado) é https://accounts.google.com e se o público (campo aud no token decodificado) é o valor do ID do cliente emitido pelo Google para suas ações, que é atribuído ao projeto no Console do Actions.

Confira a seguir um exemplo de token decodificado:

{
  "sub": 1234567890,        // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The token's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Client ID assigned to your Actions project
  "iat": 233366400,         // Unix timestamp of the token's creation time
  "exp": 233370000,         // Unix timestamp of the token's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "locale": "en_US"
}

Se você usar a biblioteca de Fulfillment do Actions on Google para Node.js, ela vai validar e decodificar o token para você e conceder acesso ao conteúdo do perfil, conforme mostrado nos snippets de código a seguir.

...
const app = conversation({
  // REPLACE THE PLACEHOLDER WITH THE CLIENT_ID OF YOUR ACTIONS PROJECT
  clientId: CLIENT_ID,
});
...
// Invoked on successful completion of account linking flow, check if we need to
// create a Firebase user.
app.handle('linkAccount', async conv => {
  let payload = conv.headers.authorization;
  if (payload) {
  // Get UID for Firebase auth user using the email of the user
    const email = payload.email;
    if (!conv.user.params.uid && email) {
      try {
        conv.user.params.uid = (await auth.getUserByEmail(email)).uid;
      } catch (e) {
        if (e.code !== 'auth/user-not-found') {
          throw e;
        }
        // If the user is not found, create a new Firebase auth user
        // using the email obtained from Google Assistant
        conv.user.params.uid = (await auth.createUser({email})).uid;
      }
    }
  }
});

Processar solicitações de acesso a dados

Para processar a solicitação de acesso a dados, verifique se o usuário declarado pelo token de ID do Google já está presente no seu banco de dados. O snippet de código a seguir mostra um exemplo de como verificar se os pedidos de um usuário já existem em um banco de dados do Firestore:

...
app.handle('Place_Order', async conv => {
  const order = conv.session.params.order;
  const userDoc = dbs.user.doc(conv.user.params.uid);
  const orderHistory = userDoc.collection("orderHistory");
  if (orderHistory) {
    // Order history exists, so the user already placed an order.
    // Update counter for order type.
    await orderHistory.doc(order).update({ count: admin.firestore.FieldValue.increment(1)});
  } else {
    // First order they place
    await orderHistory.doc(order).set({ option: order, count: 1});
    options.forEach(opt => {
      if (opt != order) {
        orderHistory.doc(opt).set({ option: opt, count: 0});
      }
    });
  }
  return conv.add(`Your ${order} has been placed. ` +
      'Thanks for using Boba Bonanza, see you soon!');
});