Dialogflow fulfilment accessing entities in code - javascript

I am working on a chat bot in Dialogflow and want to validate someones age. A quick bit of context: I'm creating a chat bot for identifying care needs such as residential or dementia care. In the initial enquiry I want to be able to make sure that the user is 65 years or older by doing a quick IF statement in the fulfilment code in Dialogflow!
Here are my current intents:
Current Intents
Here is the getUserInfo intent:
getUserInfo intent
Here is the fulfilment code:
'use strict';
// Import the Dialogflow module from the Actions on Google client library.
const {dialogflow} = require('actions-on-google');
// Import the firebase-functions package for deployment.
const functions = require('firebase-functions');
// Instantiate the Dialogflow client.
const app = dialogflow({debug: true});
app.intent('careEqnuiry - yourself - getUserInfo', (conv, {age}) => {
const userAge = age;
if (userAge < 65) {
conv.add("You're not old enough to recieve care!");
}
});
// Set the DialogflowApp object to handle the HTTPS POST request.
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
This is all new to me.

The second argument to the callback of the intent handler is an object that contains all the parameters (entities) from Dialogflow.
In your current code you are deconstructing this object for the age parameter (i.e.: {age}).
I noticed you have two different parameters, age and given-name.
You can get these values by doing the following:
'use strict';
// Import the Dialogflow module from the Actions on Google client library.
const {dialogflow} = require('actions-on-google');
// Import the firebase-functions package for deployment.
const functions = require('firebase-functions');
// Instantiate the Dialogflow client.
const app = dialogflow({debug: true});
app.intent('careEqnuiry - yourself - getUserInfo', (conv, params) => {
const name = params['given-name'];
const age = params['age'];
if (age.amount < 65) {
conv.ask("You're not old enough to receive care!");
}
});
// Set the DialogflowApp object to handle the HTTPS POST request.
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
Also, the correct way to return a response from a conversation is to use the ask() or close() methods on the conversation object. ask() sends a response while allowing the conversation to continue, and close sends a response and ends the conversation.

Related

Can you call a Solidity contract method with only Metamask?

I’m wanting to use Metamask in my app to let users pay a fixed ETH fee (plus gas) to call a method from my Solidity contract. I looked at the Metamask documentation and the eth_sendTransaction method seems close to what I need; eth_sendTransaction would certainly allow me to request ETH from a user, but the “data” parameter is a bit confusing.
The Metamask docs say:
data is optional, but used for defining smart contract creation and interaction
and
also used for specifying contract methods and their parameters.
So “data” represents my method and its parameters, but how does Metamask (or window.ethereum, rather) know the contract whose methods I’m trying to call?
Don’t you normally have to provide a contract address and ABI/JSON in order to interact with a deployed contract? In short, is it possible to do what I’ve described with just Metamask alone? Or do you have to do other client-side setups in order to call a method with eth_sendTransaction?
Edit: by the way TylerH, the answer involved using web3.js. Maybe don't edit people's posts unless you know what the hell you're talking about. Just a thought...
Yes you will need the contract abi in order to get the information you need to include in the data that you're passing to the contract. There are also a few other things that you will need to accomplish this:
First you will need to make sure you download the ethers.js, and #alch/alchemy-web3 npm libraries into your application. Secondly you will need a provider API key from a platform like Alchemy in order to communicate with the contract abi. Lastly, you will need the contract abi which can be found at the bottom of the contract section of etherscan. There is plenty of information on how to obtain these things online, so I won't go over how to configure them here.
Once you have these, you are ready for the next step.
I suggest creating this in a utilities file somewhere in your applications file system, but the idea is this:
const alchemyKey = process.env.ALCHEMY_KEY;
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS;
const { createAlchemyWeb3 } = require("#alch/alchemy-web3");
const web3 = createAlchemyWeb3(alchemyKey);
const contractABI = require('../contract-abi.json');
export const contract = new web3.eth.Contract(contractABI, CONTRACT_ADDRESS);
export const yourMethod = () => {
if(window.ethereum.request({method: 'eth_requestAccounts'})){
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const address = await signer.getAddress();
const tx = {
from: address,
to: CONTRACT_ADDRESS,
value: "some wei value", // this is the value in wei to send
data: contract.methods.YOUR_CONTRACT_METHOD_HERE().encodeABI()
}
const txHash = await window.ethereum.request({
method: 'eth_sendTransaction',
params: [tx]
});
// do something with your transaction hash here
console.log({txHash});
}else{
console.log('user must connect wallet');
}
}
So the value that is populated in the data field of our transaction comes from calling the method that we are trying to invoke in our contract. This is encoded, and then we pass this information along with the rest of our transaction data.
This is a very short and brief description as to what this does, and I hope this is what you're looking for. If you need any more help I'm always available to chat on Twitter #_syndk8.

Accessing a private Google sheet with a google cloud service account

I have a private Google Spreadsheet and I’m trying to access it programmatically using Google Visualization/Google Charts. I've created the service account, and I have tried using the google-auth-library and googleapis npm packages to create an access token that I can then use to access the spreadsheet. But, when I try to use that access token to read from the spreadsheet, the request fails with HTTP code 401 (Unauthorized). What do I need to do in order to make this work?
This is my code:
const { auth } = require('google-auth-library');
const keys = require('./jwt.keys.json');
const id = '{Spreadsheet ID}';
const sheetId = '{Sheet ID}';
const query = "{Query}";
async function getClient(){
const client = auth.fromJSON(keys);
client.scopes = ['https://www.googleapis.com/auth/spreadsheets.readonly'];
console.log(client);
return client;
}
async function main(){
const client = await getClient();
const token = await client.getAccessToken();
console.log(token);
console.log(token.token);
const url = `https://docs.google.com/spreadsheets/d/${id}/gviz/tq?tqx=out:csv&tq=${encodeURIComponent(query)}&access_token=${token.token}#gid=${sheetId}`;
const res = await client.request({url});
console.log(res);
}
main().catch(console.error);
When I saw your script, I thought that it is required modifying the scope. I had got the same situation as you (the status code 401 using your endpoint). Unfortunately, it seems that your endpoint cannot be used using the scope of https://www.googleapis.com/auth/spreadsheets.readonly. So, for example, how about changing it as follows, and testing it again?
From:
https://www.googleapis.com/auth/spreadsheets.readonly
To:
https://www.googleapis.com/auth/spreadsheets
or
https://www.googleapis.com/auth/drive.readonly
Note:
When I tested your endpoint using the modified scope, I confirmed that no error occurred. But if you tested it and when an error occurs, please check other part, again.

How do I receive the context parameter in the a cloud function onCall?

I have a cloud function that is called by my front-side app in React Native. Here is my cloud function:
exports.listProducts = functions.https.onCall((temp, context) => {
console.log("fired");
return context;
});
And here is how I call the function:
let temp = await functions().httpsCallable("listProducts")(
null,
firebase.auth().currentUser
);
However, I can't acccess the context variable in my cloud function which according to docs should be the Firebase auth. And the console.log in that function does not give me a log.
Any parameters you pass to the callable function are available in the first parameter, which you call temp, but that the Firebase documentation refers to as data.
You don't need to pass the current user to the callable function yourself, as the Firebase SDK already handles that for you, and the server already decoded the current user into context.auth.
For more on both parameters and the auth context, have a look at the Firebase documentation on writing and deploying callable functions, which contains:
Use functions.https.onCall to create an HTTPS callable function. This method takes two parameters: data, and optional context:
// Saves a message to the Firebase Realtime Database but sanitizes the text by removing swearwords.
exports.addMessage = functions.https.onCall((data, context) => {
// ...
});
For a callable function that saves a text message to the Realtime Database, for example, data could contain the message text, while context parameters represent user auth information:
// Message text passed from the client.
const text = data.text;
// Authentication / user information is automatically added to the request.
const uid = context.auth.uid;
const name = context.auth.token.name || null;
const picture = context.auth.token.picture || null;
const email = context.auth.token.email || null;

How can I make the bot work?

I am trying to send messages to a bot based on Microsoft bot framework.
Here is my code.
const builder = require("botbuilder");
\\I have id and password, did not show them here
const config = {
appId: "**********************",
appPassword: "********************"
};
const connector = new builder.ChatConnector(config);
const bot = new builder.UniversalBot(connector);
// respond to bot messages
app.post("/bot", () => console.log('being called') ,connector.listen());
// define bot dialog routes
bot.dialog("/", session => {
console.log('++++++++++++++>', session.message.text)
});
It is printing the "being called ", but not printing "++++++++++++++>".
I got no error message.
How can I check the problem and fix this?
Note: this is not emulator, i ma trying this within an app locally.
Whilst there appears to be missing code (e.g. app isn't defined), I'm going to presume you're using Express and that side of things is fine. Your root dialog will not be triggered until it has an input from the user.
Take this super simple ConsoleConnector example:
const builder = require('botbuilder')
let connector = new builder.ConsoleConnector().listen()
let bot = new builder.UniversalBot(connector)
bot.dialog('/', (session) => {
console.log('Testing')
})
Paste that into a file and run it. You'll notice that you won't get any error messages, but you won't see the console log either. Now type anything in and press return. This will trigger the root dialog and the console.log will fire.
If you want to send a proactive message when the conversation starts, check out the 'Greet a user' example in the Bot Framework documentation.
Edit:
Additional Echo Bot example using Express:
const express = require('express')
const builder = require('botbuilder')
const app = express()
const port = 8080
const connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
})
const bot = new builder.UniversalBot(connector)
bot.dialog('/', (session) => {
console.log('Testing')
session.send(session.message.text)
})
app.post('/api/messages', connector.listen())
app.listen(port)
I realise you're not using the Emulator at this point, but for the sake of testing, point it at localhost:8080/api/messages and type something. You'll see the console.log message appear and the message you entered will be echoed back to you.

Outbound networking HTTP trigger to App store

const functions = require('firebase-functions');
import iapReceiptValidator from 'iap-receipt-validator';
const password = 'abcdefghijkac64beb900889e1'; // Shared Secret from iTunes connect
const production = false; // use sandbox or production url for validation
async validate(receiptData) {
try {
const validationData = await validateReceipt(receiptData);
// check if Auto-Renewable Subscription is still valid
validationData['latest_receipt_info'][0].expires_date > today
} catch(err) {
console.log(err.valid, err.error, err.message)
}
}
exports.validateReceipt = functions.https.onRequest((req, res) => {
const validateReceipt = iapReceiptValidator(password, production);
}
This is what I have so far. I am using this external library. I am using firebase cloud functions and I am on flame plan. I want to make POST request to send receipt JSON object to app store server for auto-renewable purchase verification. I am not sure how to go forward with this. Can i please get some help in regards to structuring my cloud function. The firebase documentation isn't very helpful.
Appreciate any help!

Categories