Get location/address of Amazon Echo device - node.js

I am making an Alexa skill which needs to send the location of the Echo being used to an API within my Lambda function.
https://www.amazon.com/gp/help/customer/display.html?nodeId=201601980 says we can access many details about the Echo, such as Device Location, but in my skill, I don't see this is available in the session:
exports.handler = function (event, context) {
try {
console.log("event.session: " + event.session);
How can I get this data?
The point is, while we have the address of the user coming from my App API, they may have set an address where they're not currently at (aka, they've placed an order from an Echo that's not the same as their address).
Thanks!

Access to the profile information doesn't appear to be available. If the account is linked, the only option I see is to route them back to your web site to provide information necessary to complete the order.

You can now get the address of the device, as specified in the customer’s device settings.
This is new as of 2017-04-05. See Amazon's blog post about their new Device Address API.

Related

Twilio Autopilot Handof with memory for on call conversation

I have an twilio autopilot similar to appointment schedule sample in twilio, I want it to have a memory before its even initiated, I have a B2C service, where I provide the platform to connect with their customers. Now each business offers different service so I want to be able to identify whose call my bot is attending and respond to the person based on that information.
Right now I have hardcoded business ID, but I want businesses to be able to handover to the bot with their business ID, I have read the documentation but it doesn't say how to handle call redirect as my Bot would be handling calls only.
Twilio developer evangelist here.
You can do this with Twilio Studio!
"Inbound Context lets you add data to the Autopilot Memory before starting a dialogue with the bot. In a Studio flow, it allows you to pass Flow variables created by other widgets in your flow seamlessly into Autopilot to be used in bot conversations. You can then parse these variables directly from the Memory JSON included in Autopilot's request to your application" (more info here):
-Memory.CarMake
-Memory.CarModel
You could alternatively use a URL like this one to pass Inbound Context with Memory where any message sent to a bot with this URL will insert CarModel, CarMake, and CarYear into the Autopilot Memory.
https://channels.autopilot.twilio.com/v1/<ACCOUNT_SID>/<ASSISTANT_SID>/twilio-messaging?Memory={"CarModel":"Diablo","CarMake":"Lamborghini","CarYear":"2019"}
That URL would go for a SMS bot and go in where you place the webhook URL for your Twilio phone number, but you could similarly modify it for WhatsApp (https://channels.autopilot.twilio.com/v1///twilio-messaging/whatsapp?Memory={"CarModel":"Diablo","CarMake":"Lamborghini","CarYear":"2019"}), Voice, Custom Channels (https://channels.autopilot.twilio.com/v1///custom/{YourCustomChannelName}?Memory={"CarModel":"Diablo","CarMake":"Lamborghini","CarYear":"2019"}) etc.
TwiML for voice would look like this:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Connect action="https://www.example.com/autopilot">
<Autopilot Memory={"CarModel":"Diablo","CarMake":"Lamborghini","CarYear":"2019"}>UAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</Autopilot>
</Connect>
</Response>
Let me know if this helps at all!:D
You can utilize Inbound Context, as detailed below.
Inbound Context
https://www.twilio.com/changelog/inbound-context
Inbound Context lets you add data to the Autopilot Memory before
starting a dialogue with the bot. It can help you make the bot
experience more personalized and contextual by making information like
names, purchase histories, account numbers etc. stored in third-party
systems available directly in the bot conversation.
I found a way to handle it, and it may not be the best way, but its really helpful for me.
So what I have done is I created an API that responds back with Twml
Similar to this
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Connect action="https://www.example.com/autopilot">
<Autopilot Memory={"CarModel":"Diablo","CarMake":"Lamborghini","CarYear":"2019"}>UAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</Autopilot>
</Connect>
</Response>
Now I purchased number and set its webhook URL to the API I created, within that API, I can pass parameter and then create memory with those params
Here is my API handler in Nodejs:
const VoiceResponse = require('twilio').twiml.VoiceResponse
const voice = (req, res, next) => {
const response = new VoiceResponse()
const connect = response.connect()
connect.autopilot({
TargetTask: 'greeting',
Memory: `{"companyId": "${req.params.id}"}`
},
process.env.AUTOPILOT_SID)
res.type('text/xml')
res.send(response.toString())
}
I hope this helps somebody who is looking to create dynamic memory based on different numbers, or to create a bot that works for multi-tenant platform

How to replace default response in account linking on Google Assistant

As part of an action configured for account linking with the following topology:
Actions-on-Google->Dialogflow->Webhook,
I'm seeing Google Assistant injecting its own message prior to going through the account linking flow, as follows:
"I need to link your <action-name> to Google. Is that ok?"
The linking flow is triggered by the following in the webhook:
public ActionResponse launchRequestHandler(ActionRequest request) throws Exception {
ResponseBuilder responseBuilder = getResponseBuilder(request);
responseBuilder.add(new SignIn());
}
I'd like to be able to replace the above stock message with a custom one, however when attaching a context to a sign in card with our own message, like so:
String speech = "Hi, I see that your account isn't connected. "
+ "I've sent a link to your Google Assistant app that will get you started and set up in just several simple steps. "
+ "Don't worry, I'll be here waiting, just call me when you're ready.";
responseBuilder.add(
new SignIn()
.setContext(speech));
I'm still seeing the default message tacked at the end:
"Hi, I see that your account isn't connected.
I've sent a link to your Google Assistant app that will get you started and set up in just several simple steps.
Don't worry, I'll be here waiting, just call me when you're ready.,
I need to link your <action-name> to Google. Is that ok? "
How can I replace the Google default message with my own?
To ensure a consistent experience for users, you cannot replace the default message. You can only set the context, which lets you provide your custom information for the user ahead of the generic question.
The context is an additional piece of information which may be more relevant to your Action. Let's say it's connecting to your example.com account. You would add the context as a string:
app.intent('Login', conv => {
conv.ask(new SignIn('To provide you with personalized info from example.com'))
})
The user would hear this message, with the generic prompt appended:
To provide you with personalized info from example.com, I need to link your Example Action to Google. Is that ok?
Then you can say yes or no, and go through the OAuth flow / Google Sign-In flow.

Node.js Azure sdk - getting the Virtual Machine state

I've started to look into the azure sdk for node.js (link below) and interestingly enough I've hit a wall in what I'd image would be one of the most common tasks one would want to achieve using Azure's REST endpoints which is checking the status of a virtual machine.
I can easily get a list of all machine, or one in particular but the response from this services don't include the current status of the VM (running,stopped etc.)
There's absolutely no info out there regarding this particular scenario in the docos or the web other than a blog post (https://github.com/Azure/azure-xplat-cli/issues/2565) which is actually in regards of a different library.
Please not that I'm using the azure-arm-compute library which is part of the Node.js azure sdk.
Any help would be very much appreciated
github repo: https://github.com/Azure/azure-sdk-for-node
To get Virtual Machine statuses, please use function get(resourceGroupName, vmName, optionsopt, optionalCallbackopt), and pass the vaule {expand: 'instanceView'} as the options parameter.
var msRestAzure = require('ms-rest-azure');
var computeManagementClient = require('azure-arm-compute');
// Interactive Login
// It provides a url and code that needs to be copied and pasted in a browser and authenticated over there. If successful,
// the user will get a DeviceTokenCredentials object.
msRestAzure.interactiveLogin(function(err, credentials) {
var client = new computeManagementClient(credentials, 'ed0caab7***');
client.virtualMachines.get('<resourceGroupName>', '<vmName>', {expand: 'instanceView'}, function(err, result, request, response) {
if (err) console.log(err);
console.log(result.instanceView);
});
});

Getting customized message from GCM using Web push notifications

I'm using Web push notifications with Chrome, and they work great. But now I want to deliver a custom message in my notifications. I can have my Service Worker call out to my site to get content, as is done at https://simple-push-demo.appspot.com/—which is fine if I want every recipient to see the same message.
Is there any way to get either the recipient’s registration_id or the message_id that GCM returns? If I could get either of these and include them in the callback to the service, I could customize the response.
Also, any info on when we might be able to include a payload in the call to GCM?
The registration_id and message_id fields aren't exposed, but if the user is previously authenticated to your app, any fetch() to the server from your Service Worker will include credentials (and session information) which you can use to identify them.
If that doesn't work for your case, you can store user/session information in IndexedDB.
Payloads are coming soon—likely Chrome 50 or 51—based on the Web Push protocol. It's a bit of extra overhead and work to configure the (required) encryption.
It's possible, but I wouldn't do it since it's specific to GCM, while other browsers use other services.
You can either create a unique ID for each user (like we're doing in Mercurius) and store it in IndexedDB, or you can use the entire endpoint URL as an ID.
Here's the snippet to get the registration_id:
self.registration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
var endpoint = subscription.endpoint;
var endpointParts = endpoint.split('/');
var gcmRegistrationID = endpointParts[endpointParts.length - 1];
console.log(gcmRegistrationID);
}
});
P.S.: It returns a promise, so make sure your service worker waits for the promise to be resolved.

Change a document's permissions via Google Apps Script

I'm looking for sample script that resets the default permissions on an external spreadsheet based on the email address and DocumentID passed to the script. I intent to create a script that can parse information from an email message to acquire the DocumentID and email, execute the permission change from default to anyone with a link, then email the passed address with that link.
It appears that perms are controlled by the DocList API and I'm not finding samples of GAS interacting with that API.
At Google I/O 2013, DriveApp was launched. This allows developers to build use cases like Sharing to Anyone with link
https://developers.google.com/apps-script/reference/drive/
Sample code -
var quizTemplate = DriveApp.getFileById(QUIZ_TEMPLATE_ID);
quizTemplate.setSharing(DriveApp.Access.DOMAIN_WITH_LINK, DriveApp.Permission.VIEW);
or
var openFile = DriveApp.getFileById(WIDE_OPEN_ID)
openFile.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.COMMENT);
AFAIK DocsList Services does not have a function to change the sharing mode, between private/anyone with a link/public, only to add/remove editors and viewers. But we can still achieve this by previously setting manually the share settings of a specific folder to "anyone with a link". Then, we have just to add the file to that folder to have it shared.
A script to do that is particularly simple. e.g.
function shareWithAnyoneAndEmail(documentID,email) {
var sharedFolder = DocsList.getFolderById('id-to-your-previously-shared-folder');
var file = DocsList.getFileById(documentID);
file.addToFolder(sharedFolder);
MailApp.sendEmail(email, 'Here is your file', file.getName()+'\n'+file.getUrl());
}

Resources