How to make dialogflow session - node.js

I want to set different session for different users in dialogflow.
https://www.npmjs.com/package/dialogflow
I referred to the following site for this, but the program is not returning any output.
const dialogflow = require('dialogflow');
const uuid = require('uuid');
/**
* Send a query to the dialogflow agent, and return the query result.
* #param {string} projectId The project to be used
*/
async function runSample(projectId = 'your-project-id') {
// A unique identifier for the given session
const sessionId = uuid.v4();
// Create a new session
const sessionClient = new dialogflow.SessionsClient();
const sessionPath = sessionClient.sessionPath(projectId, sessionId);
// The text query request.
const request = {
session: sessionPath,
queryInput: {
text: {
// The query to send to the dialogflow agent
text: 'hello',
// The language used by the client (en-US)
languageCode: 'en-US',
},
},
};
// Send request and log result
const responses = await sessionClient.detectIntent(request);
console.log('Detected intent');
const result = responses[0].queryResult;
console.log(` Query: ${result.queryText}`);
console.log(` Response: ${result.fulfillmentText}`);
if (result.intent) {
console.log(` Intent: ${result.intent.displayName}`);
} else {
console.log(` No intent matched.`);
}
}

const functions = require('firebase-functions');
const dialogflow = require('dialogflow');
const cors = require('cors')({origin: true});
const admin = require('firebase-admin');
admin.initializeApp();
// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions
exports.connectChat = functions.https.onRequest((req, response) => {
cors(req, response, () => {
const projectId = '******';
const query = req.query.text;
const session= req.query.session;
const languageCode = 'en-US';
var result="";
let privateKey = "-----BEGIN PRIVATE KEY-----******\n-----END PRIVATE KEY-----\n";
// as per goolgle json
let clientEmail = "*****#.gserviceaccount.com";
let config = {
credentials: {
private_key: privateKey,
client_email: clientEmail
}
}
const sessionClient = new dialogflow.SessionsClient(config);
// Define session path
const sessionPath = sessionClient.sessionPath(projectId, session);
// The text query request.
const request = {
session: sessionPath,
queryInput: {
text: {
text: query,
languageCode: languageCode,
},
},
};
// Send request and log result
sessionClient
.detectIntent(request)
.then(responses => {
result = responses[0].queryResult;
response.send(result);
return null;
})
.catch(err => {
console.error('ERROR:', err);
response.send('ERROR');
return null;
});
});
});
projectId,clientEmail,privateKey are get from JSON file downloaded from https://console.cloud.google.com/iam-admin
create your session id (req.query.session) from client side in javascript

Related

telegram api signup return PHONE_CODE_INVALID

my code:
const { Api, TelegramClient } = require("telegram");
const { StringSession } = require("telegram/sessions");
const { Logger } = require("telegram/extensions");
const apiId = 22;
const apiHash = "333333";
const phoneNumber = "9996627328";
const phoneCode = "22222";
const createClient = async (stringSession) => {
const session = new StringSession(stringSession);
const options = { connectionRetries: 5, baseLogger: new Logger("debug") };
const client = new TelegramClient(session, apiId, apiHash, options);
client.session.setDC(2, "149.154.167.40", 443);
await client.connect();
return client;
};
const getLoginCodeCommand = (phoneNumber) => {
const settings = new Api.CodeSettings();
const args = { phoneNumber, apiId, apiHash, settings };
return new Api.auth.SendCode(args);
};
(async () => {
const client = await createClient("");
const response = await client.invoke(getLoginCodeCommand(phoneNumber));
console.log('responseļ¼š', response);
const { phoneCodeHash } = response;
const result22 = await client.invoke(
new Api.auth.SignUp({
phoneNumber: phoneNumber,
phoneCodeHash: phoneCodeHash,
firstName: "liu",
lastName: "some",
})
);
console.log("RESULT22", result22);
})();
response:
/Users/xizao/work/fm/project/telegram/node_modules/telegram/errors/index.js:28
return new RPCBaseErrors_1.RPCError(rpcError.errorMessage, request, rpcError.errorCode);
^
RPCError: 400: PHONE_CODE_INVALID (caused by auth.SignUp)
at RPCMessageToError (/Users/xizao/work/fm/project/telegram/node_modules/telegram/errors/index.js:28:12)
at MTProtoSender._handleRPCResult (/Users/xizao/work/fm/project/telegram/node_modules/telegram/network/MTProtoSender.js:517:58)
at MTProtoSender._processMessage (/Users/xizao/work/fm/project/telegram/node_modules/telegram/network/MTProtoSender.js:442:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async MTProtoSender._recvLoop (/Users/xizao/work/fm/project/telegram/node_modules/telegram/network/MTProtoSender.js:418:17) {
code: 400,
errorMessage: 'PHONE_CODE_INVALID'
}
No matter how you adjust it, the phone code is always invalid
The correct result should be direct registration success.
I haven't been able to find the problem because of what? Please help me to see why?
doc link: https://gram.js.org/tl/auth/SignUp#authsignup

createClickwrap returns 404 Not Found

When I call createClickwrap method, I got 404 error Not Found. If I run this method through Quickstart generated demo project, I don't get this error. However, if I run it through my project I get the error. If I debug the demo app and my app, the functions parameters are the same.
This is the code in my app:
docusign controller:
const docuSignService = require('./docusign_esign_service');
const demoDocumentsPath = path.resolve(__dirname, '../demo_documents');
const { createClickwrap } = require('./createClickWrap');
async getDocusignRecieptService() {
const authResponse = await docuSignService.authenticate();
if (authResponse) {
const docTermsPdf = 'Term_Of_Service.pdf';
const docFile = path.resolve(demoDocumentsPath, docTermsPdf);
const { basePath, accessToken, apiAccountId } = authResponse;
const { clickwrapId } = await createClickwrap({ docFile, basePath, accessToken, accountId: apiAccountId });
const res = await activateClickwrap({ clickwrapId, basePath, accessToken, accountId: apiAccountId });
console.log({ res });
}
}
docuSignService.js
const SCOPES = ['signature', 'impersonation', 'openid', 'click.manage', 'click.send'];
const fs = require('fs');
const docusign = require('docusign-esign');
class DocusingService {
async authenticate() {
const jwtLifeSec = 10 * 60, // requested lifetime for the JWT is 10 min
dsApi = new docusign.ApiClient();
dsApi.setOAuthBasePath(process.env.dsOauthServer.replace('https://', '')); // it should be domain only.
let rsaKey = fs.readFileSync(process.env.privateKeyLocation);
try {
const results = await dsApi.requestJWTUserToken(
process.env.dsJWTClientId,
process.env.impersonatedUserGuid,
SCOPES,
rsaKey,
jwtLifeSec
);
const accessToken = results.body.access_token;
// get user info
const userInfoResults = await dsApi.getUserInfo(accessToken);
// use the default account
let userInfo = userInfoResults.accounts.find((account) => account.isDefault === 'true');
return {
accessToken: results.body.access_token,
apiAccountId: userInfo.accountId,
basePath: `${userInfo.baseUri}/restapi`
};
} catch (e) {
let body = e.response && e.response.body;
// Determine the source of the error
if (body) {
// The user needs to grant consent
if (body.error && body.error === 'consent_required') {
if (this.getConsent()) {
return this.authenticate();
}
} else {
// Consent has been granted. Show status code for DocuSign API error
this._debug_log(`\nAPI problem: Status code ${e.response.status}, message body:
${JSON.stringify(body, null, 4)}\n\n`);
}
}
}
}
getConsent() {
var urlScopes = SCOPES.join('+');
// Construct consent URL
var redirectUri = 'https://developers.docusign.com/platform/auth/consent';
var consentUrl =
`${process.env.dsOauthServer}/oauth/auth?response_type=code&` +
`scope=${urlScopes}&client_id=${process.env.dsJWTClientId}&` +
`redirect_uri=${redirectUri}`;
throw new Error(`Open the following URL in your browser to grant consent to the application: ${consentUrl}`);
}
getArgs(apiAccountId, accessToken, basePath, signerEmail, signerName, id, agreementData, redirect_uri) {
const envelopeArgs = {
signerEmail: signerEmail,
signerName: signerName,
status: 'sent',
signerClientId: id,
dsReturnUrl: redirect_uri,
agreement: agreementData
};
const args = {
accessToken: accessToken,
basePath: basePath,
accountId: apiAccountId,
envelopeArgs: envelopeArgs
};
return args;
}
}
module.exports = new DocusingService();
createClickWrap.js
const createClickwrap = async ({ docFile, clickwrapName = 'clickwrapName', basePath, accessToken, accountId }) => {
// Step 3. Construct the request Body
// Create display settings model
const displaySettings = docusignClick.DisplaySettings.constructFromObject({
consentButtonText: 'I Agree',
displayName: 'Terms of Service',
downloadable: true,
format: 'modal',
hasAccept: true,
mustRead: true,
requireAccept: true,
documentDisplay: 'document'
});
// Create document model
// Read and encode file. Put encoded value to Document entity.
// The reads could raise an exception if the file is not available!
const documentPdfExample = fs.readFileSync(docFile);
const encodedExampleDocument = Buffer.from(documentPdfExample).toString('base64');
const document = docusignClick.Document.constructFromObject({
documentBase64: encodedExampleDocument,
documentName: 'Terms of Service',
fileExtension: 'pdf',
order: 0
});
// Create clickwrapRequest model
const clickwrapRequest = docusignClick.ClickwrapRequest.constructFromObject({
displaySettings,
documents: [document],
name: clickwrapName,
requireReacceptance: true
});
// Step 4. Call the Click API
const dsApiClient = new docusignClick.ApiClient();
dsApiClient.setBasePath(basePath);
dsApiClient.addDefaultHeader('Authorization', 'Bearer ' + accessToken);
const accountApi = new docusignClick.AccountsApi(dsApiClient);
// Create a clickwrap
let result = null;
try {
result = await accountApi.createClickwrap(accountId, {
clickwrapRequest
});
} catch (e) {
debugger;
console.log(e);
}
debugger;
console.log(`Clickwrap was created. ClickwrapId ${result.clickwrapId}`);
return result;
};
module.exports = { createClickwrap };
Parameters look like this in the demo app and it works:
and these are the parameters in my app:
The first parameter accountId is the same. Why I am getting this issue in my app if function gets the same parameters?
"Error: Not Found
at Request.callback (/Users/and/test/node_modules/docusign-click/node_modules/superagent/lib/node/index.js:696:15)
at IncomingMessage.<anonymous> (/Users/and/test/node_modules/docusign-click/node_modules/superagent/lib/node/index.js:906:18)
at IncomingMessage.emit (node:events:539:35)
at IncomingMessage.emit (node:domain:475:12)
at endReadableNT (node:internal/streams/readable:1345:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21)"
Thanks to pointing out in the comments, when I changed basePath ${userInfo.baseUri}/restapi to ${userInfo.baseUri}/clickapi, it works now.

Unable to get input contexts through to dialogflow using node js

I have been trying to get input contexts to flow into dialogflow via node.js but i cant seem to get it working in any way. Here is what I have so far and sorry I am not at node so any pointers would be a massive help.
It doesnt fail or say there is an error I just never see the input contexts hit the back end.
Thanks for you time
Steve
async function createContext(sessionId, contextId, parameters, lifespanCount = 1) {
const sessionPath = sessionClient.sessionPath(projectId, sessionId);
const contextsClient = new dialogflow.ContextsClient();
const contextPath = contextsClient.contextPath(
projectId,
sessionId,
contextId
);
const request = {
parent: sessionPath,
context: {
name: contextPath,
parameters: struct.encode(parameters),
lifespanCount: lifespanCount
}
};
const [context] = await contextsClient.createContext(request);
return context;
}
// hook it up to the question and answer through the chatbot api
async function detectIntent(
projectId,
sessionId,
query,
contexts,
languageCode
) {
// The path to identify the agent that owns the created intent.
const sessionPath = sessionClient.sessionPath(projectId, sessionId);
// The text query request.
const request = {
session: sessionPath,
queryInput: {
text: {
text: query,
languageCode: languageCode,
},
},
queryParams: {
contexts: [contexts],
}
};
const responses = await sessionClient.detectIntent(request);
return responses[0];
}
async function requestChatBot(textdata) {
let intentResponse;
let context = "";
const parameters = {
welcome: true
};
context = await createContext(callId, 'welcome-context', parameters);
intentResponse = await detectIntent(
projectId,
callId,
textdata,
context,
languageCode
);
}
modify your "request" to
const request = {
session: sessionPath,
queryParams: {
contexts: [{
name: 'projects/' + projectId + '/agent/sessions/' + sessionId + '/contexts/' + "Name of the context you want to pass",
lifespanCount: provide life span of your context (Integer Value),
}]
},
queryInput: {
text: {
// The query to send to the dialogflow agent
text: userQuery,
// The language used by the client (en-US)
languageCode: 'en-US',
},
},
};
This works.

Domain-wide delegation using default credentials in Google Cloud Run

I'm using a custom service account (using --service-account parameter in the deploy command). That service account has domain-wide delegation enabled and it's installed in the G Apps Admin panel.
I tried this code:
app.get('/test', async (req, res) => {
const auth = new google.auth.GoogleAuth()
const gmailClient = google.gmail({ version: 'v1' })
const { data } = await gmailClient.users.labels.list({ auth, userId: 'user#domain.com' })
return res.json(data).end()
})
It works if I run it on my machine (having the GOOGLE_APPLICATION_CREDENTIALS env var setted to the path of the same service account that is assigned to the Cloud Run service) but when it's running in Cloud Run, I get this response:
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Bad Request",
"reason" : "failedPrecondition"
} ],
"message" : "Bad Request"
}
I saw this solution for this same issue, but it's for Python and I don't know how to replicate that behaviour with the Node library.
After some days of research, I finally got a working solution (porting the Python implementation):
async function getGoogleCredentials(subject: string, scopes: string[]): Promise<JWT | OAuth2Client> {
const auth = new google.auth.GoogleAuth({
scopes: ['https://www.googleapis.com/auth/cloud-platform'],
})
const authClient = await auth.getClient()
if (authClient instanceof JWT) {
return (await new google.auth.GoogleAuth({ scopes, clientOptions: { subject } }).getClient()) as JWT
} else if (authClient instanceof Compute) {
const serviceAccountEmail = (await auth.getCredentials()).client_email
const unpaddedB64encode = (input: string) =>
Buffer.from(input)
.toString('base64')
.replace(/=*$/, '')
const now = Math.floor(new Date().getTime() / 1000)
const expiry = now + 3600
const payload = JSON.stringify({
aud: 'https://accounts.google.com/o/oauth2/token',
exp: expiry,
iat: now,
iss: serviceAccountEmail,
scope: scopes.join(' '),
sub: subject,
})
const header = JSON.stringify({
alg: 'RS256',
typ: 'JWT',
})
const iamPayload = `${unpaddedB64encode(header)}.${unpaddedB64encode(payload)}`
const iam = google.iam('v1')
const { data } = await iam.projects.serviceAccounts.signBlob({
auth: authClient,
name: `projects/-/serviceAccounts/${serviceAccountEmail}`,
requestBody: {
bytesToSign: unpaddedB64encode(iamPayload),
},
})
const assertion = `${iamPayload}.${data.signature!.replace(/=*$/, '')}`
const headers = { 'content-type': 'application/x-www-form-urlencoded' }
const body = querystring.encode({ assertion, grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer' })
const response = await fetch('https://accounts.google.com/o/oauth2/token', { method: 'POST', headers, body }).then(r => r.json())
const newCredentials = new OAuth2Client()
newCredentials.setCredentials({ access_token: response.access_token })
return newCredentials
} else {
throw new Error('Unexpected authentication type')
}
}
What you can do here is define ENV variables in your yaml file as described in this documentation to set the GOOGLE_APPLICATION_CREDENTIALS to the path of the JSON key.
Then use a code such as the one mentioned here.
const authCloudExplicit = async ({projectId, keyFilename}) => {
// [START auth_cloud_explicit]
// Imports the Google Cloud client library.
const {Storage} = require('#google-cloud/storage');
// Instantiates a client. Explicitly use service account credentials by
// specifying the private key file. All clients in google-cloud-node have this
// helper, see https://github.com/GoogleCloudPlatform/google-cloud-node/blob/master/docs/authentication.md
// const projectId = 'project-id'
// const keyFilename = '/path/to/keyfile.json'
const storage = new Storage({projectId, keyFilename});
// Makes an authenticated API request.
try {
const [buckets] = await storage.getBuckets();
console.log('Buckets:');
buckets.forEach(bucket => {
console.log(bucket.name);
});
} catch (err) {
console.error('ERROR:', err);
}
// [END auth_cloud_explicit]
};
Or follow an approach similar to the one mentioned here.
'use strict';
const {auth, Compute} = require('google-auth-library');
async function main() {
const client = new Compute({
serviceAccountEmail: 'some-service-account#example.com',
});
const projectId = await auth.getProjectId();
const url = `https://dns.googleapis.com/dns/v1/projects/${projectId}`;
const res = await client.request({url});
console.log(res.data);
}
main().catch(console.error);

Triggering intent in Dialogflow?(Using V2 api)

How to trigger an intent in Dialogflow?I need to trigger an intent without response from user. I know we need to call an event here, but don't know how to do the same in V2 api?
You trigger event from dialogflow, it's as easy to detectIntent
const dialogflow = require('dialogflow');
const config = require('../config');
// Import the JSON to gRPC struct converter
const credentials = {
client_email: config.GOOGLE_CLIENT_EMAIL,
private_key: config.GOOGLE_PRIVATE_KEY,
};
const sessionClient = new dialogflow.SessionsClient(
{
projectId: config.GOOGLE_PROJECT_ID,
credentials
}
);
module.exports = {
async sendEventToDialogFlow(event, params = {}) {
const sessionPath = sessionClient.sessionPath(config.GOOGLE_PROJECT_ID, sessionId);
const request = {
session: sessionPath,
queryInput: {
event: {
name: event,
languageCode: config.DF_LANGUAGE_CODE,
},
}
};
const responses = await sessionClient.detectIntent(request);
return responses[0].queryResult;
}
}

Resources