Alexa Proactive Events API returns 403 for unicast type -- No enablement for clientId - alexa

I am using Amazon's Alexa skills API and proactive events API to send notifications to my Alexa skill. I am able to send notification with multicast, but it does not work for delivery type "Unicast"
I am getting HTTP status code: 403 and error message as:
"No enablement for clientId:amzn-*********"
I have followed the Alexa skills proactive API documentation
When sending notification to endpoint
https://api.amazonalexa.com/v1/proactiveEvents/stages/development
I obtain the accesstoken using skill credentials and add the accesstoken as bearer token to the request.
Note: I have already enabled the skill from https://alexa.amazon.in and
I got the Amazon userId, apiAccesstoken, and consentToken. I stored them in my database (mongoDB).
I use the Amazon userId to send the notification
<pre>
<code>
var uuid = require('node-uuid');
var accessToken = "This`enter code here` token will be obtained from amazon oauth api.";
var userId = "amzn1.ask.account.AH2ZEP5WGJGAEPWPOG3Getc.....";
var uuid = require('node-uuid');
var referenceId = uuid.v4();
var now = new Date();
var expiresOn = addMinutes(now, 300);
var eventData = {
"timestamp": new Date(),
"referenceId": uuid,
"expiryTime": expiresOn,
"event": {
"name": "AMAZON.MessageAlert.Activated",
"payload": {
"state": {
"status": "UNREAD",
"freshness": "NEW"
},
"messageGroup": {
"creator": {
"name": "Andy"
},
"count": 5,
"urgency": "URGENT"
}
}
},
"localizedAttributes": [
{
"locale": "en-US",
"MessageAlert": "UNREAD"
},
{
"locale": "en-GB",
"MessageAlert": "UNREAD"
}
],
"relevantAudience": {
"type": "Unicast",
"payload": {
"user": userId
}
}
};
var opt = {
data: eventData,
token: accessToken
}
sendRequest(opt, function(err, ret, code) {
console.log("err : ",JSON.stringify(err, null, 2));
console.log("ret : ",JSON.stringify(ret, null, 2));
console.log("code : ",JSON.stringify(code, null, 2));
});
function sendRequest(options, callback) {
var data = options.data;
var token = options.token;
var headers = {
"Content-Type": "application/json",
"Authorization":"Bearer "+token
};
var opt = {
url: "https://api.amazonalexa.com/v1/proactiveEvents/stages/development",
method: "POST",
headers: headers,
body: JSON.stringify(data)
};
request(opt, function(error, response, body){
var statusCode = (response && response.statusCode) ? response.statusCode : "";
if(error) {
return callback(error);
} else if(body) {
try {
var result = JSON.parse(body);
return callback(null, result, statusCode);
} catch(e) {
console.log("e.message : ",e.message);
return callback(null, body, statusCode);
}
} else {
return callback(null, body, statusCode);
}
});
}
</code>
</pre>
The result should be HTTP status code with 202.
But I receive the HTTP status code 403 and the error message as:
"No enablement for clientId: *************"

Related

Can Facebook Messenger Webview access the LocalStorage API to store data on client side?

I want to store 6 booleans on the user side, if he reaches 6 sites in a city.
Can I use LocalStorage or even cookies, inside the Messenger Webview ?
If I close the Webview and open it again, will the data be still there ?
After test, yes it can.
So you can easily open a button to the Webview like that in your botfile app.js on the server :
function openWebview(sender_psid, text,button_text){
let button_response = {
"attachment": {
"type": "template",
"payload": {
"template_type": "button",
"text": text,
"buttons": [
{
"type":"web_url",
"url":"<URL>",
"title":button_text,
"webview_height_ratio": "compact",
"messenger_extensions": "true",
"fallback_url": "<FB_URL>"
}
],
}
}
}
callSendAPI(sender_psid, button_response);
}
to be complete...
function callSendAPI(sender_psid, response) {
// Construct the message body
let request_body = {
"recipient": {
"id": sender_psid
},
"message": response
}
request({
"uri": "https://graph.facebook.com/v2.6/me/messages",
"qs": { "access_token": PAGE_ACCESS_TOKEN },
"method": "POST",
"json": request_body
}, (err, res, body) => {
if (!err) {
console.log('message sent!')
} else {
console.error("Unable to send message:" + err);
}
});
}
and on index.html on client side by example you can store simple data as easy as :
<div id='myDiv'>nothing for the moment</div>
<script>
localStorage.setItem('key1','myValue1')
var test = localStorage.getItem('key1')
document.getElementById('myDiv').innerHTML = test
</script>
You will now see 'myValue1' displayed on the Facebook Messenger Webview

SalesForce Create Lead Rest Api

My task is pretty simple, all i have to do is to create records in the lead section of the salesforce. I have created a free account and i am not able to figure it out that, what is https://yourinstance.saleforce.com in the below rest api:
https://yourinstance.salesforce.com/services/data/v39.0/sobjects/Lead
Body JSON:
{
"body": {
"Salutation": "Mr.",
"FirstName": "H",
"LastName": "Sam",
"Company": "Samosto"
}
}
Header:
Authorization: Bearer 00D0o0000015jPn!ARgAQPiIGhuYGUG_c0HDKNR0hxTX9zS82Fv1lIuqn4rapFJHPR422gLyi10rF8Auukb._hj9pj532DP7IajQV36lyKpUNEXdxvL
Content-Type: application/json
Sforce-Auto-Assign: TRUE
Any help will be highly appreciated!
This is the URL you have for the organization you want to login to. Since most of the orgs are using their own Domain names in guides or examples you will see this "https://yourinstance.saleforce.com" being used.
You can simply take it from the URL while logged in Salesforce or go to Setup -> quick search "My Domain" and you will see the domain name.
It is a good thing to check it from here as the generic URL can also be blocked as a login option.
fwiw i think the API has changed to Account. This is working for me
// to run:
// node create_new_account.js --config ./config_na150_scan_email_app.json
//
// links:
// https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_sobject_create.htm
const axios = require("axios");
const qs = require("qs");
const yargs = require("yargs");
const argv = yargs
.command('create_account', 'test creating salesforce leads', {
config: {
description: 'config',
alias: 'c',
type: 'string',
}
})
.help()
.alias('help', 'h')
.argv;
let { salesforce, scanResultsURL } = require(argv.config);
const auth_data = qs.stringify({"username": salesforce.username,
"password": salesforce.password + salesforce.security_token,
"grant_type": "password",
"client_id": salesforce.consumer_key,
"client_secret": salesforce.customer_secret,
"redirect_uri": salesforce.redirect_uri});
console.log("auth data", auth_data)
const auth_config = {
method: "post",
url: salesforce.oauth2_uri,
data: auth_data,
headers: {"Content-Type": "application/x-www-form-urlencoded"}
}
const action_url = "https://na<TBD>.salesforce.com/services/data/v51.0/sobjects/Account"
console.log('action url', action_url)
data = {
"Name" : "test Salesforce account API"
}
async function createAccout() {
// "get" token
axios(auth_config).then(function (response) {
auth_header = {"Authorization": "Bearer " + response["data"]["access_token"]}
action_config = {
method: "post",
url: action_url,
headers: auth_header,
data: data
}
// use valid token to send email
axios(action_config).then(function (response) {
console.log("action response", response["data"]); // TODO rm
}).catch(function (error) {
console.log("authenticated passed, action failed")
console.log("action error", error); // TODO something
})
}).catch(function (error) {
console.log("action token error", error); // TODO something
})
}

Can't get my Facebook messenger bot to respond with response from my service

I have made an Api.Ai bot and integrated it with both Slack and Facebook Messenger. When I write to it, it answers with the responses set up in Api.Ai for both Slack and Facebook Messenger, but on the fulfillment part, when Api.Ai makes a call to my service, it works fine in Slack, but I get no response from Facebook Messenger.
The format of the message I return from my service:
{
"contextOut": [
{
"lifespan": 2,
"name": "weather",
"parameters": {
"city": "Rome"
}
}
],
"data": {
"facebook": {
"message": {
"text": "Great success!"
},
"recipient": {
"id": "1454102654663349"
}
},
"slack": {
"attachments": [
{
"color": "#00A399",
"title": "Hello world!",
"title_link": "https://www.mywebsite.se"
}
],
"text": "Horray! Great success! :)"
}
},
"displayText": "Whatever!!",
"followupEvent": {
"followupEvent": {
"data": {
"parameter": "<parameter_value>"
},
"name": "<event_name>"
}
},
"source": "mywebsite.se",
"speech": "Whatever!?"
}
The Facebook recipient id comes from the request made to my service.
request.result.contexts[0].parameters.Facebook_sender_id
I have verified my webhook under the product settings tab in the Facebook app.
I have subscribed my app to the page using my page access token.
I have checked the following events under webhooks: messages, messaging_postbacks
I'm logged in as the admin user of the app, when trying the bot in Facebook.
I'm out of ideas, there must be something I've missed?
EDIT:
I've set up an Azure Function as my webhook for testing purposes.
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
var request = await req.Content.ReadAsAsync<ApiAiMessage>();
log.Info($"Incoming: {JsonConvert.SerializeObject(request)}");
var slack_message = new {
text = $"Horray! Great success! :)",
attachments = new[] {
new {
title = "Hello world!",
title_link = "https://www.mywebsite.se",
color = "#00A399"
}
}
};
var facebook_message = new {
recipient = new {
id = $"{request.result.contexts[0].parameters.Facebook_sender_id}"
},
message = new {
text = "Great success!"
}
};
var response = new
{
data = new
{
facebook = facebook_message,
slack = slack_message
},
speech = "Whatever!?",
displayText = "Whatever!!",
contextOut = new[] {
new {
name = "weather",
lifespan = 2,
parameters = new {
city = "Rome"
}
}
},
source = "mywebsite.se",
followupEvent = new {
followupEvent = new {
name = "<event_name>",
data = new {
parameter = "<parameter_value>"
}
}
}
};
log.Info($"Outgoing: {JsonConvert.SerializeObject(response)}");
return req.CreateResponse(HttpStatusCode.OK, response, new MediaTypeHeaderValue("application/json"));
}
Where are you actually sending the API.ai response back to Facebook Messenger? This requires some FB specifics like the 'page token' and the fact it works for Slack but not FB makes me believe it's just something simple left out like this. Here's an example in javascript of what the call would look like
function callSendAPI(messageData) {
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: {
access_token: config.FB_PAGE_TOKEN
},
method: 'POST',
json: messageData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
if (messageId) {
console.log("Successfully sent message with id %s to recipient %s",
messageId, recipientId);
} else {
console.log("Successfully called Send API for recipient %s",
recipientId);
}
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});
}

Node.js API - Works with Postman but not works in Angular.js

I am trying to create a mean application. as a sample, if I post the request through postman the data created at mlab.
in case if I post the same using $http way, it's not working getting the error as :
{
"message": "Family validation failed",
"name": "ValidationError",
"errors": {
"username": {
"message": "Path `username` is required.",
"name": "ValidatorError",
"properties": {
"type": "required",
"message": "Path `{PATH}` is required.",
"path": "username"
},
"kind": "required",
"path": "username"
},
"password": {
"message": "Path `password` is required.",
"name": "ValidatorError",
"properties": {
"type": "required",
"message": "Path `{PATH}` is required.",
"path": "password"
},
"kind": "required",
"path": "password"
}
}
}
and the node with mongoose :
.post(function( req, res ){
var family = new Family();
family.username = req.body.username,
family.password = req.body.password,
family.familyLeader = req.body.familyLeader,
family.husband = req.body.husband,
family.wife = req.body.wife,
family.kids = req.body.kids;
family.save(function( err, newFamily ) {
if( err ) {
if ( err.code == 11000) {
return res.json({ success: false, message: 'A user with that username already exists. '});
}
else {
return res.send( err );
}
}
res.json({ message: 'Family created!', newFamily: newFamily });
});
})
here is my angular code :
vm.createNewFamily = function() {
$http({
method : 'POST',
url : '/api/family',
data : vm.form,
headers : {'Content-Type': 'application/x-www-form-urlencoded'}
}).success( function ( data ) {
console.log('retured!', data );
})
}
my full api.js ( node )
var Family = require('../models/model_family');
module.exports = function( app, express ) {
var apiRoute = express.Router();
apiRoute.use(function( req, res, next ) {
console.log( 'some one using the app!' );
next();
})
apiRoute.get('/', function( req, res ) {
res.json({"namea" : "Arif"})
});
apiRoute.route('/family')
.get(function( req, res ){
res.send('family get processing');
})
.post(function( req, res ){
var family = new Family();
family.username = req.body.username,
family.password = req.body.password,
family.familyLeader = req.body.familyLeader,
family.husband = req.body.husband,
family.wife = req.body.wife,
family.kids = req.body.kids;
family.save(function( err, newFamily ) {
if( err ) {
if ( err.code == 11000) {
return res.json({ success: false, message: 'A user with that username already exists. '});
}
else {
return res.send( err );
}
}
res.json({ message: 'Family created!', newFamily: newFamily });
});
})
return apiRoute;
}
EDIT
If you only have problems with username then check you angular data bindings. Im thinking you have typo somewhere like this
<input ng-model="useranme">
Hope this helps.
Put your this code above all the routes in your main server file
----------
----------
var app=express();
app.use(bodyParser.urlencoded({
extended: true
}));
---------
---------

400 response from GAE Cloud Endpoints

I'm trying the following api call to my GAE Cloud Endpoint:
gapi.client.myapp.foo.update({
"value": "foobar",
"key": "keyvaluefromlistoperation"
}).execute(function(resp) {
console.log(resp);
});
Which responds with the following:
[
{
"error": {
"code": 400,
"message": "Bad Request",
"data": [
{
"domain": "usageLimits",
"reason": "keyInvalid",
"message": "Bad Request"
}
]
},
"id": "gapiRpc"
}
]
Note, prior to this call I have authenticated, inserted several foo objects, then call list to have them returned to the client. The api's explorer update call works fine and running the jQuery snippet below works fine as well. Any suggestions? Or am I just in experimental bug land.
var token = gapi.auth.getToken();
$.ajax({
type:"POST",
beforeSend: function (request) {
request.setRequestHeader("Content-Type","application/json");
request.setRequestHeader("Authorization", token.token_type+" "+token.access_token);
},
url: "https://myappid.appspot.com/_ah/api/myapp/v1/foo/update",
data:JSON.stringify({
"value": "foobar",
"key": "keyvaluefromlistoperation"
}),
processData: false,
dataType: "json",
success: function(msg) {
console.log(msg);
},
failure: function(msg) {
console.log(msg);
}
});
Here is the Java code:
#Api(
name = "myapp",
description = "This is the myapp rest interface",
scopes = {"https://www.googleapis.com/auth/userinfo.email"},
version = "v1",
clientIds = {Ids.WEB_CLIENT_ID}
)
public class FooV1 {
private static PersistenceManager getPersistenceManager() {
return PMF.get().getPersistenceManager();
}
#ApiMethod(
name = "foo.update",
httpMethod = HttpMethod.POST
)
public Foo update(Foo foo, User user) throws OAuthRequestException, IOException, UnauthorizedUpdateException {
PersistenceManager pm = PMF.get().getPersistenceManager();
if (user != null) {
try {
Foo f = pm.getObjectById(Foo.class, foo.getId());
if ( Security.isUpdateAuthorized(f, user) ) {
if( foo.getValue() != null ) f.setValue(foo.getValue());
} else {
throw new UnauthorizedUpdateException("");
}
} finally {
pm.close();
}
} else {
throw new OAuthRequestException("Invalid user.");
}
return foo;
}
}
I had the same problem. Apparently you can't use "key" as a field once you deploy to GAE. Locally it worked fine.

Resources