How can I use Botkit Middleware with Watson Assistant dialog server actions? - ibm-cloud

I followed this tutorial to deploy a Slackbot with Watson Assistant. The tutorial uses server actions in the dialog to directly interface with a database. To connect Slack with Watson Assistant the tutorial uses the Conversation connector. That works fine, but I am interested in how to do the same with Botkit and the Botkit Middleware provided by Watson Developer Cloud.
How can I use the serverless actions, how do I obtain and pass the necessary API key?

There is actually code that demonstrates how to configure the API key for IBM Cloud Functions and pass it as context variable to Watson Assistant. It makes use of the before method to add the API key to the context variable. The value is configured in a separate file together with the other app-related credentials. The code tests whether the context variable and the key exist, else it is added:
middleware.before = function(message, conversationPayload, callback) {
// Code here gets executed before making the call to Conversation.
// retrieve API Key from environment and split it into user / password
var arr=process.env.ICF_KEY.split(":");
// check if context exists
if (typeof(conversationPayload.context) === 'undefined') {
var context={context: {}}
Object.assign(conversationPayload, context);
}
// if credentials already exists, we don't have to add them
// else add credentials under private element in context
if (typeof(conversationPayload.context.icfcreds) === 'undefined') {
var privcontext = {"private": {icfcreds: {user: arr[0], password: arr[1]}}};
Object.assign(conversationPayload.context, privcontext);
}
// log the payload structure for debugging
// console.log(conversationPayload)
callback(null, conversationPayload);
}

Related

How to interact with html response from http request in Flutter

I have a Flutter app where I am running a Google Apps Script through an http request. The purpose of the script is to create a Form and link the responses to a spreadsheetID that is passed in. The script is configured to only allow Google accounts access it and I've set up the flutter app to use a Service Account to access the script using the format:
getCredentials().then( (AuthClient client){
response = client.get(url, headers{"Authorization": "Bearer ${client.access_token}");
});
Issue: The issue is that the first time that the Service Account makes a request it will get an HTML response saying that it the account needs to give permission to the script to access its data and I'm not sure how to do that.
I'm fairly new to making http requests and using it with the GoogleAPI so I'm stuck. Any advice?
Goal
Create a web page which anyone can use to submit a Google sheet link and for the app to create a form and link the sheet to that.
Authorization
For this users will require a google account and they will be required to go through the OAuth process to authorize your app.
To create the form and link it from client-side JavaScript you would indeed need to call the Apps Script API, though you cannot do this with a service account.
From: https://developers.google.com/apps-script/api/how-tos/execute
Warning: The Apps Script API doesn't work with service accounts.
Luckily, you don't need a service account to do this.
Instructions
Create an Apps Script project with a function something like:
function createForm(ssID){
form = FormApp.create("Your New Form");
form.setDestination(FormApp.DestinationType.SPREADSHEET, ssID);
let formLink = form.getPublishedUrl();
return formLink;
}
Save and take a note of the ID of the script project.
Set up a GCP project (sounds like you already have one).
Make sure the Apps Script API is enabled in your GCP.
Configure the OAuth consent screen and add the scope - https://www.googleapis.com/auth/forms.
Create an API key and a Client ID - add http://localhost:8000 or whatever port you are testing on to the "Authorized JavaScript Origins"
Create OAuth credentials "web browser (JavaScript)".
Link your Apps Script project to the same GCP project - Instructions
Deploy the Apps Script project as an API executable - take not of the deployment ID, although the documentation says that you need the script ID, it is wrong, at least with the new Apps Script IDE.
Write the client-side JavaScript in your app like what is found in the quickstart. Which will enable users to authorize the app. You need to add in the scopes and keys there too. I recommend just following the quick start steps first to get a feel for it. You can use the authorization parts without modification.
Then add in the function that will call your Apps Script, something like this:
function appsScriptCreateForm(ssId) {
var scriptId = "<DEPLOYMENT_ID>";
// Run your Apps Script function
gapi.client.script.scripts
.run({
scriptId: scriptId,
resource: {
function: "createForm",
parameters: [ssId],
},
})
.then(function (resp) {
var result = resp.result;
// ERROR HANDLING
if (result.error && result.error.status) {
appendPre("Error calling API:");
appendPre(JSON.stringify(result, null, 2));
} else if (result.error) {
var error = result.error.details[0];
appendPre("Script error message: " + error.errorMessage);
if (error.scriptStackTraceElements) {
appendPre("Script error stacktrace:");
for (var i = 0; i < error.scriptStackTraceElements.length; i++) {
var trace = error.scriptStackTraceElements[i];
appendPre("\t" + trace.function + ":" + trace.lineNumber);
}
}
// IF SUCCESSFUL
} else {
console.log("success", resp);
}
});
}
Write your HTML with the buttons and inputs necessary.
Add event listeners where appropriate.
Profit!
Please note
This set up is your project running with the authorization of other accounts.
The API requests count against your quota.
You can see details of all the executions in your GCP Project Dashboard.
Users require a Google account and need to authorize the app.
In the Apps Script function above, you just need to pass in the Spreadsheet ID. Not the whole link. You could ask for the whole link and then use Regex to extract the ID if you wanted.
This can be quite tricky and easy to miss a step or make a mistake, so double check your work.
If, after successful authorization, when trying to run the script you get a 404 error, the request has been built wrong, check your IDs. If you get a 500 error, that can mean that the Apps Script function has successfully been called, but, there was an error within Apps Script and failed, check the executions page of the Apps Script editor.
References
Apps Script How to Execute
Apps Script JS Quickstart - Highly recommended you follow these steps first and get that working!
How to link your Apps Script to GCP

How can I create a fulfillment for intent in Google Actions?

I created a Google Action using the Google Actions console, then pulled it using the gactions CLI and now I am trying to connect my intents to a fulfillment webhook but don't know how.
I tried using the following code for the fulfillment from the Google Action help:
const { conversation } = require('actions-on-google');
const functions = require{'firebase-functions'};
const app = conversation();
app.handle('sayHello', conv => {
conv.add("Hi there! It\'s good to see you!");
})
exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app)
Conversation doesn't seem to exist and I am having trouble finding other ways of accepting requests.
This is my current directory:
How can I send requests to the fulfillment webhook from intents?
The conversation is the term for the container when using Actions Builder or Actions SDK along with the #assistant/conversation library.
If you are using either one, you should change libraries.
If you are using Dialogflow, you would want to keep actions-on-google as the library and switch the method from app.handle to app.intent.
Additionally, this may be an encoding problem, but when your handler contains conv => { there should be a 'greater than' symbol instead:
conv => {

IBM Connections Cloud custom contextual data

I followed the official documentation and created a minor community app for my website.
What I'd like to know is if there's a way "to shim" custom data to IBM Connections Cloud when uploading my app as a JSON and then retrieve it inside the message handler after my app loads:
window.addEventListener('message', function(event) {
if (event.origin === "https://apps.collabservnext.com"){
// event.data contains the full context
console.log("Running in community named " + event.data.source.resourceId);
}
}, false);
parent.postMessage("appReady", "*");
So far I'm only getting the extraContent, source and user JSON keys in event.data. It would be awesome if there was a way to retrieve say hello: world.
Thanks.

SAP Fiori Get logged in user details in UI5 application

I've a SAP Fiori application and I need to get the current logged in user details.
I've searched web but unable to find a solution.
is there any way to get current logged in user details from launchpad.
There is a UserInfo service from the FLP shell which can be retrieved like this:
{ // In Controller
doSomethingUserDetails: async function() {
const oUserInfo = await this.getUserInfoService();
const sUserId = oUserInfo.getId(); // And in SAPUI5 1.86, those became public: .getEmail(), .getFirstName(), .getLastName(), .getFullName(), ...
// ...
},
getUserInfoService: function() {
return new Promise(resolve => sap.ui.require([
"sap/ushell/library"
], oSapUshellLib => {
const oContainer = oSapUshellLib.Container;
const pService = oContainer.getServiceAsync("UserInfo"); // .getService is deprecated!
resolve(pService);
}));
},
}
To align with the current best practices, avoid calling sap.ushell.Container.getService directly!
getService is deprecated. Use getServiceAsync instead.
Require the library instead of referencing the Container via global namespace (sap.ushell.*) as shown above.
Alternatively, information about the the current user can be also retrieved via the user API service exposed by the application router from the SAP Business Technology Platform (SAP BTP).
* In case the app is deployed to the old Neo environment, see the previous edit.
The User-ID can be retrieved from SDK.
Please refer to class sap.ushell.services.UserInfo
Try this:
new sap.ushell.services.UserInfo().getId()
If you want to access the user detail when you are running your application in launchpad. then you can retrieve current user detail by adding following code snippet:
var userInfo = sap.ushell.Container.getService("UserInfo");
var email = userInfo.getEmail();
Then further detail about the user can be retrieved like email and fullname. See the API here.

From where get subscription key for api.ai chatbot to be deployed on Microsoft Cortana

I'm trying to build a chatbot using api.ai. I want to integrate this bot with Microsoft Cortana. I followed every step given at this link: https://docs.api.ai/docs/cortana-integration but then to initialize api.ai instance, I have written following code. Client access token is available to me. My question here is from where to get the subscription key?
var config = new AIConfiguration("String subscription key",
"String client_access_token",
SupportedLanguage.English);
apiAi = new ApiAi(config);
apiAi.DataService.PersistSessionId();
Are you sure about the code that you have because at the URL mentioned : https://docs.api.ai/docs/cortana-integration, the code is something like this:
var config = new AIConfiguration("YOUR_CLIENT_ACCESS_TOKEN", SupportedLanguage.English);
So, all you will need is just the Client Access Token, which is available from the Agent Settings page in API.AI