SlideShare uma empresa Scribd logo
1 de 82
Baixar para ler offline
Alvaro Viebrantz
aviebrantz.com.br
@alvaroviebrantz
Actions On Google

Dialogflow
Firebase
Codelab
✓ Utilizar e demonstrar os princípios de interfaces de voz e conversa
✓ Componentes de uma conversa:
✓ Intenções, Entidades e Ações
✓ Webhooks e conteúdo dinâmico
✓ Funções de negócio rodando no Firebase
✓ Permissões e dados do usuário
✓ Surface API
O que vamos aprender
Visão geral das ferramentas Actions on Google, Dialogflow e Firebase
Codelab
Baseado em outros Codelabs oficiais
O que vamos fazer
3 projetos envolvendo diversos conceitos do Actions on Google e Dialogflow
✓ AnimalJoker
• Piadas de animais
• Sem programação e mostrando os princípios de interfaces de voz e conversa.
✓ Cryptocurrency bot
• Informações sobre moedas digitais como o Bitcoin e Ethereum
• Webhooks e conteúdo dinâmico
• Funções de negócio rodando no Firebase
✓ Pizza bot
• Bot para pedido de pizza
• Permissões e dados do usuário
• Surface API
5
P1 - AnimalJoker
Explorando o DialogFlow
6
AnimalJoker
Crie a conta no Dialogflow
https://console.Dialogflow.com/
7
AnimalJoker
Crie o Agent no DialogFlow - AnimalJoker
8
AnimalJoker
Entidades - Entity
• Entidades são valores que queremos obter do que o usuário está
dizendo.
• Pense em campos em um formulário.
• O Dialogflow vai automaticamente extrai-los.
• Quanto mais exemplos você der, mais assertivo será o algoritmo
de Machine Learning
• Plurais não são necessários, o Dialogflow consegue inferir.
9
AnimalJoker
Crie a entidade Animal - Diferentes animais que queremos escutar piadas
🛠
10
AnimalJoker
Intenções - Intent
• As intenções são ativadas de acordo com o que o usuário diz.
• Pense em nas mais diferentes formas que usuário vai usar para uma mesma intenção
de atividade.
• Quanto mais exemplos você der, mais assertivo será o algoritmo de Machine Learning
• Por exemplo, para ouvir piadas o usuário pode falar de diversas formas:
• Please tell jokes of dogs
• Tell jokes about cats
• Tiger jokes
• Do you know jokes about lions ?
• A cat joke please
11
AnimalJoker
Crie a Intenção tell_joke
12
AnimalJoker
Entidades identificadas e quais são requeridas.
13
AnimalJoker
Prompts para preenchimento de parâmetros requeridos
🛠
14
AnimalJoker
Respostas
• Com o Dialogflow conseguimos colocar respostas padrões
• Não são dinâmicas, mas dando várias opções você tem uma
sensação de ser mais real a conversa.
• Podemos usar as variáveis capturadas.
• Podemos continuar ou não a conversa.
15
AnimalJoker
Respostas
🛠
16
AnimalJoker
É uma boa prática adicionar um Intent de saída
17
AnimalJoker
É uma boa prática adicionar um Intent de saída
🛠
18
AnimalJoker
Vamos criar um Intent para guiar o usuário.
19
AnimalJoker
Vamos criar um Intent para guiar o usuário.
🛠
20
AnimalJoker
Testando e compartilhando
21
AnimalJoker
Testando e compartilhando
🛠
22
Fim do P1 - AnimalJoker
Explorando o DialogFlow
23
P2 - Cryptocurrency Bot
Integrando o Dialogflow com Firebase e
Actions on Google
Develop Grow
Develop Grow
Functions
27
Actions on Google
Documentação em https://developers.google.com/actions/
28
Actions on Google
Documentação em https://developers.google.com/actions/
29
Cryptocurrency Bot
Fluxo da aplicação
30
Cryptocurrency Bot
Crie o Agent no DialogFlow
31
Cryptocurrency Bot
Crie a entidade CryptoCurrency - Moedas digitais
32
Cryptocurrency Bot
Crie a entidade Currency - Moedas tradicionais
🛠
33
Cryptocurrency Bot
Crie a Intenção Price - Buscar preço da moeda digital
34
Cryptocurrency Bot
Crie a Intenção Price - Nomear a ação que nosso backend vai resolver
🛠
35
Cryptocurrency Bot
Escrever o backend da nossa aplicação - Dois caminhos
• Usar o editor direto no DialogFlow
• Mais limitado, porém vai ser o suficiente para este Codelab
• Deploy direto pelo console
• Criar uma pasta no seu computador e rodar `firebase init`
• Associar com o projeto do Dialogflow
• Instalar libs usando NPM
• Rode `firebase deploy` para enviar o seu código
36
Cryptocurrency Bot Ativar a integração no DialogFlow com Webhook e Firebase
37
Cryptocurrency Bot
Deploy da primeira versão do webhook
const functions = require('firebase-functions');
const { DialogflowApp } = require('actions-on-google');
const ACTION_PRICE = 'price';
38
Cryptocurrency Bot
Deploy da primeira versão do webhook
function priceHandler(assistant) {
const msg = 'Getting current price via Firebase';
assistant.tell(msg);
}
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(
(req, res) => {
const assistant = new DialogflowApp({ request: req, response: res });
const actionMap = new Map();
actionMap.set(ACTION_PRICE, priceHandler);
assistant.handleRequest(actionMap);
}
);
39
Cryptocurrency Bot
Deploy da direto pelo Dialogflow
🛠
40
Cryptocurrency Bot
Obtendo as variáveis passadas pelo usuário
const ARG_CRYPTO_CURRENCY = 'CryptoCurrency';
const ARG_CURRENCY = 'Currency';
let cryptoCurrency = assistant.getArgument(ARG_CRYPTO_CURRENCY);
let currency = assistant.getArgument(ARG_CURRENCY) || 'USD';
const msg = `Getting current price for ${cryptoCurrency} in ${
currency
} via Firebase`;
🛠
41
Cryptocurrency Bot
Fazendo chamadas a um serviço externo
• Vamos usar o módulo node-fetch
• Padrão fetch do ES6, mais fácil de se utilizar
• API a ser consultada:
• https://api.cryptonator.com/api/ticker/btc-brl
• https://api.cryptonator.com/api/ticker/doge-usd
• https://api.cryptonator.com/api/ticker/eth-eur
• https://api.cryptonator.com/api/ticker/{CryptoCurrency}-{Currency}
• Lembre-se de dar uma resposta ao usuário se algo der errado.
42
Cryptocurrency Bot
Trecho de código para fazer chamada a API
const fetch = require('node-fetch');
const BASE_API_URL = 'https://api.cryptonator.com/api';
const TICKER_METHOD = '/ticker';
const url = BASE_API_URL + TICKER_METHOD + `/${cryptoCurrency}-${currency}`;
fetch(url)
.then(res => res.json())
.then(res => {
// Faz algo com a resposta
})
.catch(res => {
const msg = `Sorry, I cannot get the current price for ${
formattedCryptoCurrency
} right now. Try again later.`;
assistant.tell(msg);
});
43
Cryptocurrency Bot
Testando no Google Assistant
44
Cryptocurrency Bot
Testando no Google Assistant
🛠
t
45
Cryptocurrency Bot
[Extra] Contas sem cartão de credito não podem fazer chamada a url externa 😫
const CRYPTO_CURRENCY_PRICES = {
doge: {
brl: 0.01,
eur: 0.00229419,
usd: 0.00271395
},
btc: {
brl: 56200.0,
eur: 13495.25949889,
usd: 16047.28556707
},
eth: {
brl: 1559.53188079,
eur: 372.98900227,
usd: 426.70409479
}
};
t
46
Cryptocurrency Bot
[Extra] Contas sem cartão de credito não podem fazer chamada a url externa 😫
const formattedCryptoCurrency =
CRYPTO_CURRENCY_NAMES[cryptoCurrency] || cryptoCurrency;
const formattedCurrency = currency.toUpperCase();
let price = CRYPTO_CURRENCY_PRICES[cryptoCurrency][currency];
const formattedPrice = parseFloat(price).toFixed(2);
const msg = `Right now the price of a ${formattedCryptoCurrency} is ${
formattedPrice
} ${formattedCurrency}.`;
assistant.tell(msg);
47
Cryptocurrency Bot
Eventos e mensagem de inicio de conversa
• Eventos podem acionar Intents
• O mais tradicional é o de boas vindas e inicio
de chat
48
Cryptocurrency Bot
Textos de sugestão
• Use na maior parte das vezes que for esperar
resposta do usuário
• Quando houver poucas escolhas
• Quando houver escolhas demais, mostre as
mais populares
49
Cryptocurrency Bot
Textos de sugestão
const SUGGESTIONS = [
'How much bitcoin costs',
'dogecoin in brl',
'ethereum in eur'
];
function welcomeHandler(assistant) {
const msg = assistant
.buildRichResponse()
.addSimpleResponse(
'Welcome to CryptoCurrency Bot. Do you like to know the price for which
cryptocurrency ?'
)
.addSuggestions(SUGGESTIONS);
assistant.ask(msg);
}
🛠
50
Fim do P2 - Cryptocurrency Bot
Integrando o Dialogflow com Firebase e
Actions on Google
51
P3 - Pizza Bot
Tornando a experiência mais intima
com o usuário
52
Pizza Bot
Crie o Agent no DialogFlow e importe o modelo disponibilizado
https://github.com/alvarowolfx/codelab-aog/03-pizza-bot
53
Pizza Bot
Upload do Agent
🛠
54
Pizza Bot
Overview das entidades e intenções
• Entity
• Type, Toppings, Size, Sauce, Crust
• Intent order.pizza
• O usuário escolhe sabor, tamanho, espessura, adicionais, molho e hora
da entrega.
• Usa prompts para perguntar os items obrigatórios
• Intent user.data
• Confirma pedido com os dados do usuário e endereço.
55
Pizza bot
Reforce a conversa lembrando sobre o usuário
function welcomeHandler(assistant) {
const userId = assistant.getUser().userId;
let welcoming = 'Welcome to Mamma Mia Pizza, is awesome to have you
back!';
if (assistant.getLastSeen()) {
welcoming = 'Welcome to Mamma Mia Pizza!';
}
welcoming += ' What pizza do you want today ?';
assistant.ask(welcoming);
}
56
Pizza bot
Suporte a diferentes Superficies (Surface API)
SCREEN_OUTPUTAUDIO_OUTPUT
57
Pizza bot
Suport a diferentes Superficies (Surface API)
let hasScreen =

app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT);
let hasAudio =
app.hasSurfaceCapability(app.SurfaceCapabilities.AUDIO_OUTPUT);
58
Pizza bot
Suporte a voz e texto
let welcoming = 'Welcome to Mamma Mia Pizza, is awesome to
have you back!';
if (assistant.getLastSeen()) {
welcoming = 'Welcome to Mamma Mia Pizza!';
}
welcoming += ' What pizza do you want today ?';
assistant.ask({
speech: welcoming + ' Peperoni and Margherita are pretty
popular!',
displayText: welcoming
});
}
🛠
59
Pizza bot
Suporte a voz, texto e sugestões
function isScreenAvailable(assistant) {
return assistant.hasAvailableSurfaceCapabilities(
assistant.SurfaceCapabilities.SCREEN_OUTPUT
);
}
if (isScreenAvailable(assistant)) {
let msg = assistant
.buildRichResponse()
.addSimpleResponse(welcoming)
.addSuggestions(['margherita', 'peperoni', 'marinara']);
assistant.ask(msg);
} else {
assistant.ask({
speech: welcoming + ' Peperoni and Margherita are pretty popular!',
displayText: welcoming
});
}
🛠
60
Pizza Bot
Conheça o usuário, com sua permissão é claro
Google Home Mobile Device
NAME Registered device user’s full
name
Registered device user’s full
name
DEVICE_COARSE_LOCATION Zip code and city N/A
DEVICE_PRECISE_LOCATION Coordinates and street address Coordinates
let permission = app.SupportedPermissions.DEVICE_COARSE_LOCATION;

app.askForPermission('To find pizzas near you', permission);
61
Pizza Bot
function orderPizzaHandler(assistant) {
const order = getOrder(assistant);
assistant.setContext(CTX_ORDER_PIZZA, 5, { order });
if (order.address) {
assistant.askForPermission(
'To complete your order we need you name',
assistant.SupportedPermissions.NAME
);
} else {
assistant.askForPermissions(
'To complete your order we need you name and your location',
[
assistant.SupportedPermissions.DEVICE_PRECISE_LOCATION,
assistant.SupportedPermissions.NAME
]
);
}
} 🛠
62
Pizza Bot
Intent acionado pelo evento action_intent_PERMISSION
63
Pizza Bot
Outros eventos e Intents especiais
• Metodos askWith e askFor
• Permission, List, Carousel, SignIn, etc
64
Pizza Bot
function userDataHandler(assistant) {
let order = assistant.getContextArgument(CTX_ORDER_PIZZA, 'order');
if (order) {
order = order.value;
}
if (assistant.isPermissionGranted()) {
if (!order.address) {
order.location = assistant.getDeviceLocation();
order.address = order.location.address;
}
order.name = assistant.getUserName().displayName;
assistant.tell(
`Your order has been received ${order.name}. Soon your ${
order.type
} pizza will arrive.`
);
}
} 🛠
• Cloud-hosted NoSQL database
• Synchronization & conflict
resolution
• Access directly from your app
Cloud Messaging
Hosting
69
Pizza Bot
> firebase init
> npm install actions-on-google
> firebase deploy
• Criar uma pasta no seu computador e rodar `firebase init`
• Associar com o projeto do Dialogflow
• Instalar libs usando NPM dentro da pasta functions
• Rode `firebase deploy` para enviar o seu código
Configurar projeto local do Firebase
70
Pizza Bot
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const db = admin.database();
Necessário quando utiliza APIs diretas do Firebase
71
Pizza Bot
function getUser(userId) {
return db
.ref(`users/${userId}`)
.once('value')
.then(snapshot => snapshot.val());
}
function saveOrder(order) {
return db.ref('orders').push(order);
}
function saveUserData(userId, displayName, location, address) {
delete location.address;
return db.ref(`users/${userId}`).set({
displayName,
location: location || {},
address: address || ''
});
}
Salvando dados do usuário e do pedido no Firebase Database
72
Pizza Bot
const userId = assistant.getUser().userId;
order.name = assistant.getUserName().displayName;
order.userId = userId;
const saveUserPromise = saveUserData(
userId,
order.name,
order.location,
order.adress
);
const saveOrderPromise = saveOrder(order);
Promise.all([saveUserPromise, saveOrderPromise])
.then(() => {
tellOrderInfo(assistant, order);
})
.catch(e => {
assistant.tell('Sorry, but something bad happened with your order.');
});
Salvando o pedido no intent de UserData
🛠
73
Pizza Bot
function orderPizzaHandler(assistant) {
const order = getOrder(assistant);
const userId = assistant.getUser().userId;
getUser(userId).then(user => {
if (user) {
order.userId = userId;
order.name = user.displayName;
order.address = user.address;
order.location = user.location;
saveOrder(order).then(() => {
tellOrderInfo(assistant, order);
});
} else {
/* PEDE PERMISSÃO */
}
});
}
Verifica se já conhece o usuário e não pede por permissões
🛠
Cloud Messaging
Hosting
76
77
78
Pizza Bot
Até mesmo uma aplicação ligada com o bot
https://pizza-a0bec.firebaseapp.com
79
Pizza Bot
> npm build
> firebase deploy
• Depois do `firebase init` o projeto tem uma pasta `public`
• Todo conteúdo dessa pasta fica disponível no Hosting
• HTTPS
• Url *firebaseapp.com
Firebase hosting - Hospedagem de conteúdo estático
80
Fim do P3 - Pizza Bot
Tornando a experiência mais intima
com o usuário
OBRIGADO !!!
81
Alvaro Viebrantz
aviebrantz.com.br
@alvaroviebrantz
https://github.com/alvarowolfx/codelab-aog
Links úteis
• https://console.dialogflow.com/
• https://medium.com/@hitherejoe/exploring-dialogflow-understanding-agent-interaction-8f3323e3b738
• https://medium.com/google-developer-experts/build-multi-lingual-actions-for-the-google-
assistant-106d2b94aa1a
• https://github.com/frogermcs/WaterLog-assistant-app
• https://cloud.google.com/products/
• https://developers.google.com/assistant/sdk/
• https://www.youtube.com/user/GoogleDevelopers/videos
82

Mais conteúdo relacionado

Mais procurados

Mais procurados (6)

Do 0 a estar online no Google App Engine
Do 0 a estar online no Google App EngineDo 0 a estar online no Google App Engine
Do 0 a estar online no Google App Engine
 
Android com Firebase
Android com FirebaseAndroid com Firebase
Android com Firebase
 
Google home and actions
Google home and actionsGoogle home and actions
Google home and actions
 
Android Firebase
Android FirebaseAndroid Firebase
Android Firebase
 
Comparando as Hypes - React & Vue
Comparando as Hypes - React & VueComparando as Hypes - React & Vue
Comparando as Hypes - React & Vue
 
TDC 2015 Florianopolis
TDC 2015 FlorianopolisTDC 2015 Florianopolis
TDC 2015 Florianopolis
 

Semelhante a Codelab - Actions on Google

Construindo Chatbots em Node.js
Construindo Chatbots em Node.jsConstruindo Chatbots em Node.js
Construindo Chatbots em Node.jsFelipe Pedroso
 
Overview - Bot Framework
Overview - Bot FrameworkOverview - Bot Framework
Overview - Bot FrameworkRenato Romão
 
Open Source Bootcamp Mogi das Cruzes - Bot Framework
Open Source Bootcamp Mogi das Cruzes - Bot FrameworkOpen Source Bootcamp Mogi das Cruzes - Bot Framework
Open Source Bootcamp Mogi das Cruzes - Bot FrameworkDouglas Romão
 
Introdução a plataforma de aplicativos Redu
Introdução a plataforma de aplicativos ReduIntrodução a plataforma de aplicativos Redu
Introdução a plataforma de aplicativos ReduGuilherme
 
Git e Github: qual a importância dessas ferramentas para o desenvolvedor
Git e Github: qual a importância dessas ferramentas para o desenvolvedorGit e Github: qual a importância dessas ferramentas para o desenvolvedor
Git e Github: qual a importância dessas ferramentas para o desenvolvedorFelipe Pedroso
 
Aulas Google Android
Aulas Google AndroidAulas Google Android
Aulas Google AndroidIury Teixeira
 
Programação Orientada a Testes
Programação Orientada a TestesProgramação Orientada a Testes
Programação Orientada a TestesGregorio Melo
 
TypeScript - Campus party 2013
TypeScript - Campus party 2013TypeScript - Campus party 2013
TypeScript - Campus party 2013Giovanni Bassi
 
Comunicação em tempo real com WebRTC e PHP
Comunicação em tempo real com WebRTC e PHPComunicação em tempo real com WebRTC e PHP
Comunicação em tempo real com WebRTC e PHPMichael Douglas
 
Novidades do .NET Core 2.1 e do ASP.NET Core 2.1
Novidades do .NET Core 2.1 e do ASP.NET Core 2.1Novidades do .NET Core 2.1 e do ASP.NET Core 2.1
Novidades do .NET Core 2.1 e do ASP.NET Core 2.1Giovanni Bassi
 
Treze ferramentas/frameworks para desenvolvimento Android
Treze ferramentas/frameworks para desenvolvimento AndroidTreze ferramentas/frameworks para desenvolvimento Android
Treze ferramentas/frameworks para desenvolvimento AndroidAdriano Rocha
 
Treze ferramentas/frameworks para desenvolvimento android
Treze ferramentas/frameworks para desenvolvimento androidTreze ferramentas/frameworks para desenvolvimento android
Treze ferramentas/frameworks para desenvolvimento androidRicardo Longa
 
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com SwiftSemcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com SwiftJuliana Chahoud
 
Brasil.gov.br: Python Powered EGov
Brasil.gov.br: Python Powered EGovBrasil.gov.br: Python Powered EGov
Brasil.gov.br: Python Powered EGovSimples Consultoria
 
Criando Webservice REST com NodeJS, NoSQL & Docker
Criando Webservice REST com NodeJS, NoSQL & DockerCriando Webservice REST com NodeJS, NoSQL & Docker
Criando Webservice REST com NodeJS, NoSQL & DockerGiovanni Kenji Shiroma
 

Semelhante a Codelab - Actions on Google (20)

Construindo Chatbots em Node.js
Construindo Chatbots em Node.jsConstruindo Chatbots em Node.js
Construindo Chatbots em Node.js
 
Overview - Bot Framework
Overview - Bot FrameworkOverview - Bot Framework
Overview - Bot Framework
 
Open Source Bootcamp Mogi das Cruzes - Bot Framework
Open Source Bootcamp Mogi das Cruzes - Bot FrameworkOpen Source Bootcamp Mogi das Cruzes - Bot Framework
Open Source Bootcamp Mogi das Cruzes - Bot Framework
 
Google android pdf
Google android pdfGoogle android pdf
Google android pdf
 
Introdução a plataforma de aplicativos Redu
Introdução a plataforma de aplicativos ReduIntrodução a plataforma de aplicativos Redu
Introdução a plataforma de aplicativos Redu
 
Secomp 2018 - DO Ruby ao Elixir
Secomp 2018 - DO Ruby ao ElixirSecomp 2018 - DO Ruby ao Elixir
Secomp 2018 - DO Ruby ao Elixir
 
Hackaton
HackatonHackaton
Hackaton
 
Git e Github: qual a importância dessas ferramentas para o desenvolvedor
Git e Github: qual a importância dessas ferramentas para o desenvolvedorGit e Github: qual a importância dessas ferramentas para o desenvolvedor
Git e Github: qual a importância dessas ferramentas para o desenvolvedor
 
Aulas Google Android
Aulas Google AndroidAulas Google Android
Aulas Google Android
 
E so mais um campinho na tela
E so mais um campinho na telaE so mais um campinho na tela
E so mais um campinho na tela
 
Programação Orientada a Testes
Programação Orientada a TestesProgramação Orientada a Testes
Programação Orientada a Testes
 
TypeScript - Campus party 2013
TypeScript - Campus party 2013TypeScript - Campus party 2013
TypeScript - Campus party 2013
 
Comunicação em tempo real com WebRTC e PHP
Comunicação em tempo real com WebRTC e PHPComunicação em tempo real com WebRTC e PHP
Comunicação em tempo real com WebRTC e PHP
 
Apontador API (para programadores Python)
Apontador API (para programadores Python)Apontador API (para programadores Python)
Apontador API (para programadores Python)
 
Novidades do .NET Core 2.1 e do ASP.NET Core 2.1
Novidades do .NET Core 2.1 e do ASP.NET Core 2.1Novidades do .NET Core 2.1 e do ASP.NET Core 2.1
Novidades do .NET Core 2.1 e do ASP.NET Core 2.1
 
Treze ferramentas/frameworks para desenvolvimento Android
Treze ferramentas/frameworks para desenvolvimento AndroidTreze ferramentas/frameworks para desenvolvimento Android
Treze ferramentas/frameworks para desenvolvimento Android
 
Treze ferramentas/frameworks para desenvolvimento android
Treze ferramentas/frameworks para desenvolvimento androidTreze ferramentas/frameworks para desenvolvimento android
Treze ferramentas/frameworks para desenvolvimento android
 
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com SwiftSemcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
Semcomp - USP São Carlos - Desenvolvendo um aplicativo iOS com Swift
 
Brasil.gov.br: Python Powered EGov
Brasil.gov.br: Python Powered EGovBrasil.gov.br: Python Powered EGov
Brasil.gov.br: Python Powered EGov
 
Criando Webservice REST com NodeJS, NoSQL & Docker
Criando Webservice REST com NodeJS, NoSQL & DockerCriando Webservice REST com NodeJS, NoSQL & Docker
Criando Webservice REST com NodeJS, NoSQL & Docker
 

Mais de Alvaro Viebrantz

BigQuery Performance Improvements Storage API
BigQuery Performance Improvements Storage APIBigQuery Performance Improvements Storage API
BigQuery Performance Improvements Storage APIAlvaro Viebrantz
 
End to End IoT projects with Zephyr.pdf
End to End IoT projects with Zephyr.pdfEnd to End IoT projects with Zephyr.pdf
End to End IoT projects with Zephyr.pdfAlvaro Viebrantz
 
Carreira de Desenvolvimento
Carreira de DesenvolvimentoCarreira de Desenvolvimento
Carreira de DesenvolvimentoAlvaro Viebrantz
 
Construindo aplicações Cloud Native em Go
Construindo aplicações Cloud Native em GoConstruindo aplicações Cloud Native em Go
Construindo aplicações Cloud Native em GoAlvaro Viebrantz
 
Prototipação em hackathons
Prototipação em hackathonsPrototipação em hackathons
Prototipação em hackathonsAlvaro Viebrantz
 
Building REST APIs using gRPC and Go
Building REST APIs using gRPC and GoBuilding REST APIs using gRPC and Go
Building REST APIs using gRPC and GoAlvaro Viebrantz
 
TinyML - IoT e Machine Learning
TinyML -  IoT e Machine LearningTinyML -  IoT e Machine Learning
TinyML - IoT e Machine LearningAlvaro Viebrantz
 
Edge computing na prática com IoT, Machine Learning e Google Cloud
Edge computing na prática com IoT, Machine Learning e Google CloudEdge computing na prática com IoT, Machine Learning e Google Cloud
Edge computing na prática com IoT, Machine Learning e Google CloudAlvaro Viebrantz
 
Edge computing in practice using IoT, Tensorflow and Google Cloud
Edge computing in practice using IoT, Tensorflow and Google CloudEdge computing in practice using IoT, Tensorflow and Google Cloud
Edge computing in practice using IoT, Tensorflow and Google CloudAlvaro Viebrantz
 
Iniciando com LoRa, The Things Network e Google Cloud
Iniciando com LoRa, The Things Network e Google CloudIniciando com LoRa, The Things Network e Google Cloud
Iniciando com LoRa, The Things Network e Google CloudAlvaro Viebrantz
 
Construindo projetos para o Google Assistant - I/O 2019 Recap São Paulo
Construindo projetos para o Google Assistant - I/O 2019 Recap São PauloConstruindo projetos para o Google Assistant - I/O 2019 Recap São Paulo
Construindo projetos para o Google Assistant - I/O 2019 Recap São PauloAlvaro Viebrantz
 
Edge computing na prática com IoT, Machine Learning e Google Cloud
Edge computing na prática com IoT, Machine Learning e Google CloudEdge computing na prática com IoT, Machine Learning e Google Cloud
Edge computing na prática com IoT, Machine Learning e Google CloudAlvaro Viebrantz
 
Construindo projetos com Google Assistant e IoT
Construindo projetos com Google Assistant e IoTConstruindo projetos com Google Assistant e IoT
Construindo projetos com Google Assistant e IoTAlvaro Viebrantz
 
Explorando Go em Ambiente Embarcado
Explorando Go em Ambiente EmbarcadoExplorando Go em Ambiente Embarcado
Explorando Go em Ambiente EmbarcadoAlvaro Viebrantz
 
Soluções de IoT usando Google Cloud e Firebase
Soluções de IoT usando Google Cloud e FirebaseSoluções de IoT usando Google Cloud e Firebase
Soluções de IoT usando Google Cloud e FirebaseAlvaro Viebrantz
 
Criando soluções de IoT usando Javascript de Ponta a Ponta: do Hardware até a...
Criando soluções de IoT usando Javascript de Ponta a Ponta: do Hardware até a...Criando soluções de IoT usando Javascript de Ponta a Ponta: do Hardware até a...
Criando soluções de IoT usando Javascript de Ponta a Ponta: do Hardware até a...Alvaro Viebrantz
 
Arquitetura de IoT na prática com Google Cloud - Join Community 2018
Arquitetura de IoT na prática com Google Cloud - Join Community 2018Arquitetura de IoT na prática com Google Cloud - Join Community 2018
Arquitetura de IoT na prática com Google Cloud - Join Community 2018Alvaro Viebrantz
 
Codelab - Google Cloud IoT Core e MongooseOS - I/O Extended Cuiabá 2018
Codelab - Google Cloud IoT Core e MongooseOS - I/O Extended Cuiabá 2018Codelab - Google Cloud IoT Core e MongooseOS - I/O Extended Cuiabá 2018
Codelab - Google Cloud IoT Core e MongooseOS - I/O Extended Cuiabá 2018Alvaro Viebrantz
 
Arquitetura de Internet das Coisas usando Google Cloud
Arquitetura de Internet das Coisas usando Google CloudArquitetura de Internet das Coisas usando Google Cloud
Arquitetura de Internet das Coisas usando Google CloudAlvaro Viebrantz
 
Internet das coisas - Conectando seus dispositivos à nuvem de forma inteligente
Internet das coisas - Conectando seus dispositivos à nuvem de forma inteligenteInternet das coisas - Conectando seus dispositivos à nuvem de forma inteligente
Internet das coisas - Conectando seus dispositivos à nuvem de forma inteligenteAlvaro Viebrantz
 

Mais de Alvaro Viebrantz (20)

BigQuery Performance Improvements Storage API
BigQuery Performance Improvements Storage APIBigQuery Performance Improvements Storage API
BigQuery Performance Improvements Storage API
 
End to End IoT projects with Zephyr.pdf
End to End IoT projects with Zephyr.pdfEnd to End IoT projects with Zephyr.pdf
End to End IoT projects with Zephyr.pdf
 
Carreira de Desenvolvimento
Carreira de DesenvolvimentoCarreira de Desenvolvimento
Carreira de Desenvolvimento
 
Construindo aplicações Cloud Native em Go
Construindo aplicações Cloud Native em GoConstruindo aplicações Cloud Native em Go
Construindo aplicações Cloud Native em Go
 
Prototipação em hackathons
Prototipação em hackathonsPrototipação em hackathons
Prototipação em hackathons
 
Building REST APIs using gRPC and Go
Building REST APIs using gRPC and GoBuilding REST APIs using gRPC and Go
Building REST APIs using gRPC and Go
 
TinyML - IoT e Machine Learning
TinyML -  IoT e Machine LearningTinyML -  IoT e Machine Learning
TinyML - IoT e Machine Learning
 
Edge computing na prática com IoT, Machine Learning e Google Cloud
Edge computing na prática com IoT, Machine Learning e Google CloudEdge computing na prática com IoT, Machine Learning e Google Cloud
Edge computing na prática com IoT, Machine Learning e Google Cloud
 
Edge computing in practice using IoT, Tensorflow and Google Cloud
Edge computing in practice using IoT, Tensorflow and Google CloudEdge computing in practice using IoT, Tensorflow and Google Cloud
Edge computing in practice using IoT, Tensorflow and Google Cloud
 
Iniciando com LoRa, The Things Network e Google Cloud
Iniciando com LoRa, The Things Network e Google CloudIniciando com LoRa, The Things Network e Google Cloud
Iniciando com LoRa, The Things Network e Google Cloud
 
Construindo projetos para o Google Assistant - I/O 2019 Recap São Paulo
Construindo projetos para o Google Assistant - I/O 2019 Recap São PauloConstruindo projetos para o Google Assistant - I/O 2019 Recap São Paulo
Construindo projetos para o Google Assistant - I/O 2019 Recap São Paulo
 
Edge computing na prática com IoT, Machine Learning e Google Cloud
Edge computing na prática com IoT, Machine Learning e Google CloudEdge computing na prática com IoT, Machine Learning e Google Cloud
Edge computing na prática com IoT, Machine Learning e Google Cloud
 
Construindo projetos com Google Assistant e IoT
Construindo projetos com Google Assistant e IoTConstruindo projetos com Google Assistant e IoT
Construindo projetos com Google Assistant e IoT
 
Explorando Go em Ambiente Embarcado
Explorando Go em Ambiente EmbarcadoExplorando Go em Ambiente Embarcado
Explorando Go em Ambiente Embarcado
 
Soluções de IoT usando Google Cloud e Firebase
Soluções de IoT usando Google Cloud e FirebaseSoluções de IoT usando Google Cloud e Firebase
Soluções de IoT usando Google Cloud e Firebase
 
Criando soluções de IoT usando Javascript de Ponta a Ponta: do Hardware até a...
Criando soluções de IoT usando Javascript de Ponta a Ponta: do Hardware até a...Criando soluções de IoT usando Javascript de Ponta a Ponta: do Hardware até a...
Criando soluções de IoT usando Javascript de Ponta a Ponta: do Hardware até a...
 
Arquitetura de IoT na prática com Google Cloud - Join Community 2018
Arquitetura de IoT na prática com Google Cloud - Join Community 2018Arquitetura de IoT na prática com Google Cloud - Join Community 2018
Arquitetura de IoT na prática com Google Cloud - Join Community 2018
 
Codelab - Google Cloud IoT Core e MongooseOS - I/O Extended Cuiabá 2018
Codelab - Google Cloud IoT Core e MongooseOS - I/O Extended Cuiabá 2018Codelab - Google Cloud IoT Core e MongooseOS - I/O Extended Cuiabá 2018
Codelab - Google Cloud IoT Core e MongooseOS - I/O Extended Cuiabá 2018
 
Arquitetura de Internet das Coisas usando Google Cloud
Arquitetura de Internet das Coisas usando Google CloudArquitetura de Internet das Coisas usando Google Cloud
Arquitetura de Internet das Coisas usando Google Cloud
 
Internet das coisas - Conectando seus dispositivos à nuvem de forma inteligente
Internet das coisas - Conectando seus dispositivos à nuvem de forma inteligenteInternet das coisas - Conectando seus dispositivos à nuvem de forma inteligente
Internet das coisas - Conectando seus dispositivos à nuvem de forma inteligente
 

Codelab - Actions on Google

  • 1. Alvaro Viebrantz aviebrantz.com.br @alvaroviebrantz Actions On Google
 Dialogflow Firebase Codelab
  • 2. ✓ Utilizar e demonstrar os princípios de interfaces de voz e conversa ✓ Componentes de uma conversa: ✓ Intenções, Entidades e Ações ✓ Webhooks e conteúdo dinâmico ✓ Funções de negócio rodando no Firebase ✓ Permissões e dados do usuário ✓ Surface API O que vamos aprender Visão geral das ferramentas Actions on Google, Dialogflow e Firebase
  • 3. Codelab Baseado em outros Codelabs oficiais
  • 4. O que vamos fazer 3 projetos envolvendo diversos conceitos do Actions on Google e Dialogflow ✓ AnimalJoker • Piadas de animais • Sem programação e mostrando os princípios de interfaces de voz e conversa. ✓ Cryptocurrency bot • Informações sobre moedas digitais como o Bitcoin e Ethereum • Webhooks e conteúdo dinâmico • Funções de negócio rodando no Firebase ✓ Pizza bot • Bot para pedido de pizza • Permissões e dados do usuário • Surface API
  • 6. 6 AnimalJoker Crie a conta no Dialogflow https://console.Dialogflow.com/
  • 7. 7 AnimalJoker Crie o Agent no DialogFlow - AnimalJoker
  • 8. 8 AnimalJoker Entidades - Entity • Entidades são valores que queremos obter do que o usuário está dizendo. • Pense em campos em um formulário. • O Dialogflow vai automaticamente extrai-los. • Quanto mais exemplos você der, mais assertivo será o algoritmo de Machine Learning • Plurais não são necessários, o Dialogflow consegue inferir.
  • 9. 9 AnimalJoker Crie a entidade Animal - Diferentes animais que queremos escutar piadas 🛠
  • 10. 10 AnimalJoker Intenções - Intent • As intenções são ativadas de acordo com o que o usuário diz. • Pense em nas mais diferentes formas que usuário vai usar para uma mesma intenção de atividade. • Quanto mais exemplos você der, mais assertivo será o algoritmo de Machine Learning • Por exemplo, para ouvir piadas o usuário pode falar de diversas formas: • Please tell jokes of dogs • Tell jokes about cats • Tiger jokes • Do you know jokes about lions ? • A cat joke please
  • 13. 13 AnimalJoker Prompts para preenchimento de parâmetros requeridos 🛠
  • 14. 14 AnimalJoker Respostas • Com o Dialogflow conseguimos colocar respostas padrões • Não são dinâmicas, mas dando várias opções você tem uma sensação de ser mais real a conversa. • Podemos usar as variáveis capturadas. • Podemos continuar ou não a conversa.
  • 16. 16 AnimalJoker É uma boa prática adicionar um Intent de saída
  • 17. 17 AnimalJoker É uma boa prática adicionar um Intent de saída 🛠
  • 18. 18 AnimalJoker Vamos criar um Intent para guiar o usuário.
  • 19. 19 AnimalJoker Vamos criar um Intent para guiar o usuário. 🛠
  • 22. 22 Fim do P1 - AnimalJoker Explorando o DialogFlow
  • 23. 23 P2 - Cryptocurrency Bot Integrando o Dialogflow com Firebase e Actions on Google
  • 27. 27 Actions on Google Documentação em https://developers.google.com/actions/
  • 28. 28 Actions on Google Documentação em https://developers.google.com/actions/
  • 30. 30 Cryptocurrency Bot Crie o Agent no DialogFlow
  • 31. 31 Cryptocurrency Bot Crie a entidade CryptoCurrency - Moedas digitais
  • 32. 32 Cryptocurrency Bot Crie a entidade Currency - Moedas tradicionais 🛠
  • 33. 33 Cryptocurrency Bot Crie a Intenção Price - Buscar preço da moeda digital
  • 34. 34 Cryptocurrency Bot Crie a Intenção Price - Nomear a ação que nosso backend vai resolver 🛠
  • 35. 35 Cryptocurrency Bot Escrever o backend da nossa aplicação - Dois caminhos • Usar o editor direto no DialogFlow • Mais limitado, porém vai ser o suficiente para este Codelab • Deploy direto pelo console • Criar uma pasta no seu computador e rodar `firebase init` • Associar com o projeto do Dialogflow • Instalar libs usando NPM • Rode `firebase deploy` para enviar o seu código
  • 36. 36 Cryptocurrency Bot Ativar a integração no DialogFlow com Webhook e Firebase
  • 37. 37 Cryptocurrency Bot Deploy da primeira versão do webhook const functions = require('firebase-functions'); const { DialogflowApp } = require('actions-on-google'); const ACTION_PRICE = 'price';
  • 38. 38 Cryptocurrency Bot Deploy da primeira versão do webhook function priceHandler(assistant) { const msg = 'Getting current price via Firebase'; assistant.tell(msg); } exports.dialogflowFirebaseFulfillment = functions.https.onRequest( (req, res) => { const assistant = new DialogflowApp({ request: req, response: res }); const actionMap = new Map(); actionMap.set(ACTION_PRICE, priceHandler); assistant.handleRequest(actionMap); } );
  • 39. 39 Cryptocurrency Bot Deploy da direto pelo Dialogflow 🛠
  • 40. 40 Cryptocurrency Bot Obtendo as variáveis passadas pelo usuário const ARG_CRYPTO_CURRENCY = 'CryptoCurrency'; const ARG_CURRENCY = 'Currency'; let cryptoCurrency = assistant.getArgument(ARG_CRYPTO_CURRENCY); let currency = assistant.getArgument(ARG_CURRENCY) || 'USD'; const msg = `Getting current price for ${cryptoCurrency} in ${ currency } via Firebase`; 🛠
  • 41. 41 Cryptocurrency Bot Fazendo chamadas a um serviço externo • Vamos usar o módulo node-fetch • Padrão fetch do ES6, mais fácil de se utilizar • API a ser consultada: • https://api.cryptonator.com/api/ticker/btc-brl • https://api.cryptonator.com/api/ticker/doge-usd • https://api.cryptonator.com/api/ticker/eth-eur • https://api.cryptonator.com/api/ticker/{CryptoCurrency}-{Currency} • Lembre-se de dar uma resposta ao usuário se algo der errado.
  • 42. 42 Cryptocurrency Bot Trecho de código para fazer chamada a API const fetch = require('node-fetch'); const BASE_API_URL = 'https://api.cryptonator.com/api'; const TICKER_METHOD = '/ticker'; const url = BASE_API_URL + TICKER_METHOD + `/${cryptoCurrency}-${currency}`; fetch(url) .then(res => res.json()) .then(res => { // Faz algo com a resposta }) .catch(res => { const msg = `Sorry, I cannot get the current price for ${ formattedCryptoCurrency } right now. Try again later.`; assistant.tell(msg); });
  • 44. 44 Cryptocurrency Bot Testando no Google Assistant 🛠
  • 45. t 45 Cryptocurrency Bot [Extra] Contas sem cartão de credito não podem fazer chamada a url externa 😫 const CRYPTO_CURRENCY_PRICES = { doge: { brl: 0.01, eur: 0.00229419, usd: 0.00271395 }, btc: { brl: 56200.0, eur: 13495.25949889, usd: 16047.28556707 }, eth: { brl: 1559.53188079, eur: 372.98900227, usd: 426.70409479 } };
  • 46. t 46 Cryptocurrency Bot [Extra] Contas sem cartão de credito não podem fazer chamada a url externa 😫 const formattedCryptoCurrency = CRYPTO_CURRENCY_NAMES[cryptoCurrency] || cryptoCurrency; const formattedCurrency = currency.toUpperCase(); let price = CRYPTO_CURRENCY_PRICES[cryptoCurrency][currency]; const formattedPrice = parseFloat(price).toFixed(2); const msg = `Right now the price of a ${formattedCryptoCurrency} is ${ formattedPrice } ${formattedCurrency}.`; assistant.tell(msg);
  • 47. 47 Cryptocurrency Bot Eventos e mensagem de inicio de conversa • Eventos podem acionar Intents • O mais tradicional é o de boas vindas e inicio de chat
  • 48. 48 Cryptocurrency Bot Textos de sugestão • Use na maior parte das vezes que for esperar resposta do usuário • Quando houver poucas escolhas • Quando houver escolhas demais, mostre as mais populares
  • 49. 49 Cryptocurrency Bot Textos de sugestão const SUGGESTIONS = [ 'How much bitcoin costs', 'dogecoin in brl', 'ethereum in eur' ]; function welcomeHandler(assistant) { const msg = assistant .buildRichResponse() .addSimpleResponse( 'Welcome to CryptoCurrency Bot. Do you like to know the price for which cryptocurrency ?' ) .addSuggestions(SUGGESTIONS); assistant.ask(msg); } 🛠
  • 50. 50 Fim do P2 - Cryptocurrency Bot Integrando o Dialogflow com Firebase e Actions on Google
  • 51. 51 P3 - Pizza Bot Tornando a experiência mais intima com o usuário
  • 52. 52 Pizza Bot Crie o Agent no DialogFlow e importe o modelo disponibilizado https://github.com/alvarowolfx/codelab-aog/03-pizza-bot
  • 54. 54 Pizza Bot Overview das entidades e intenções • Entity • Type, Toppings, Size, Sauce, Crust • Intent order.pizza • O usuário escolhe sabor, tamanho, espessura, adicionais, molho e hora da entrega. • Usa prompts para perguntar os items obrigatórios • Intent user.data • Confirma pedido com os dados do usuário e endereço.
  • 55. 55 Pizza bot Reforce a conversa lembrando sobre o usuário function welcomeHandler(assistant) { const userId = assistant.getUser().userId; let welcoming = 'Welcome to Mamma Mia Pizza, is awesome to have you back!'; if (assistant.getLastSeen()) { welcoming = 'Welcome to Mamma Mia Pizza!'; } welcoming += ' What pizza do you want today ?'; assistant.ask(welcoming); }
  • 56. 56 Pizza bot Suporte a diferentes Superficies (Surface API) SCREEN_OUTPUTAUDIO_OUTPUT
  • 57. 57 Pizza bot Suport a diferentes Superficies (Surface API) let hasScreen =
 app.hasSurfaceCapability(app.SurfaceCapabilities.SCREEN_OUTPUT); let hasAudio = app.hasSurfaceCapability(app.SurfaceCapabilities.AUDIO_OUTPUT);
  • 58. 58 Pizza bot Suporte a voz e texto let welcoming = 'Welcome to Mamma Mia Pizza, is awesome to have you back!'; if (assistant.getLastSeen()) { welcoming = 'Welcome to Mamma Mia Pizza!'; } welcoming += ' What pizza do you want today ?'; assistant.ask({ speech: welcoming + ' Peperoni and Margherita are pretty popular!', displayText: welcoming }); } 🛠
  • 59. 59 Pizza bot Suporte a voz, texto e sugestões function isScreenAvailable(assistant) { return assistant.hasAvailableSurfaceCapabilities( assistant.SurfaceCapabilities.SCREEN_OUTPUT ); } if (isScreenAvailable(assistant)) { let msg = assistant .buildRichResponse() .addSimpleResponse(welcoming) .addSuggestions(['margherita', 'peperoni', 'marinara']); assistant.ask(msg); } else { assistant.ask({ speech: welcoming + ' Peperoni and Margherita are pretty popular!', displayText: welcoming }); } 🛠
  • 60. 60 Pizza Bot Conheça o usuário, com sua permissão é claro Google Home Mobile Device NAME Registered device user’s full name Registered device user’s full name DEVICE_COARSE_LOCATION Zip code and city N/A DEVICE_PRECISE_LOCATION Coordinates and street address Coordinates let permission = app.SupportedPermissions.DEVICE_COARSE_LOCATION;
 app.askForPermission('To find pizzas near you', permission);
  • 61. 61 Pizza Bot function orderPizzaHandler(assistant) { const order = getOrder(assistant); assistant.setContext(CTX_ORDER_PIZZA, 5, { order }); if (order.address) { assistant.askForPermission( 'To complete your order we need you name', assistant.SupportedPermissions.NAME ); } else { assistant.askForPermissions( 'To complete your order we need you name and your location', [ assistant.SupportedPermissions.DEVICE_PRECISE_LOCATION, assistant.SupportedPermissions.NAME ] ); } } 🛠
  • 62. 62 Pizza Bot Intent acionado pelo evento action_intent_PERMISSION
  • 63. 63 Pizza Bot Outros eventos e Intents especiais • Metodos askWith e askFor • Permission, List, Carousel, SignIn, etc
  • 64. 64 Pizza Bot function userDataHandler(assistant) { let order = assistant.getContextArgument(CTX_ORDER_PIZZA, 'order'); if (order) { order = order.value; } if (assistant.isPermissionGranted()) { if (!order.address) { order.location = assistant.getDeviceLocation(); order.address = order.location.address; } order.name = assistant.getUserName().displayName; assistant.tell( `Your order has been received ${order.name}. Soon your ${ order.type } pizza will arrive.` ); } } 🛠
  • 65. • Cloud-hosted NoSQL database • Synchronization & conflict resolution • Access directly from your app
  • 66.
  • 69. 69 Pizza Bot > firebase init > npm install actions-on-google > firebase deploy • Criar uma pasta no seu computador e rodar `firebase init` • Associar com o projeto do Dialogflow • Instalar libs usando NPM dentro da pasta functions • Rode `firebase deploy` para enviar o seu código Configurar projeto local do Firebase
  • 70. 70 Pizza Bot const admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase); const db = admin.database(); Necessário quando utiliza APIs diretas do Firebase
  • 71. 71 Pizza Bot function getUser(userId) { return db .ref(`users/${userId}`) .once('value') .then(snapshot => snapshot.val()); } function saveOrder(order) { return db.ref('orders').push(order); } function saveUserData(userId, displayName, location, address) { delete location.address; return db.ref(`users/${userId}`).set({ displayName, location: location || {}, address: address || '' }); } Salvando dados do usuário e do pedido no Firebase Database
  • 72. 72 Pizza Bot const userId = assistant.getUser().userId; order.name = assistant.getUserName().displayName; order.userId = userId; const saveUserPromise = saveUserData( userId, order.name, order.location, order.adress ); const saveOrderPromise = saveOrder(order); Promise.all([saveUserPromise, saveOrderPromise]) .then(() => { tellOrderInfo(assistant, order); }) .catch(e => { assistant.tell('Sorry, but something bad happened with your order.'); }); Salvando o pedido no intent de UserData 🛠
  • 73. 73 Pizza Bot function orderPizzaHandler(assistant) { const order = getOrder(assistant); const userId = assistant.getUser().userId; getUser(userId).then(user => { if (user) { order.userId = userId; order.name = user.displayName; order.address = user.address; order.location = user.location; saveOrder(order).then(() => { tellOrderInfo(assistant, order); }); } else { /* PEDE PERMISSÃO */ } }); } Verifica se já conhece o usuário e não pede por permissões 🛠
  • 76. 76
  • 77. 77
  • 78. 78 Pizza Bot Até mesmo uma aplicação ligada com o bot https://pizza-a0bec.firebaseapp.com
  • 79. 79 Pizza Bot > npm build > firebase deploy • Depois do `firebase init` o projeto tem uma pasta `public` • Todo conteúdo dessa pasta fica disponível no Hosting • HTTPS • Url *firebaseapp.com Firebase hosting - Hospedagem de conteúdo estático
  • 80. 80 Fim do P3 - Pizza Bot Tornando a experiência mais intima com o usuário
  • 82. Links úteis • https://console.dialogflow.com/ • https://medium.com/@hitherejoe/exploring-dialogflow-understanding-agent-interaction-8f3323e3b738 • https://medium.com/google-developer-experts/build-multi-lingual-actions-for-the-google- assistant-106d2b94aa1a • https://github.com/frogermcs/WaterLog-assistant-app • https://cloud.google.com/products/ • https://developers.google.com/assistant/sdk/ • https://www.youtube.com/user/GoogleDevelopers/videos 82