main Ideas
This idea will maximize DRS benefits to not limit it to consumer usage only but extend it to include SME & enterprise also.
All companies or Organization have warehouse or inventory in some way or another. Those inventories can contains items to serve
- internal staff such as: stationary, computers, suppliers, printers inks ,..
- Outside customers.
So when certain item in inventory hit certain minimum level, DRS can purchase directly this item or related things needed for this item.
Automatic request based on needs will maximize the benefit of JIT (just in time, Term usually thought of as describing inventory arriving or being produced just in time for the shipment or next process).
Proof of concept
To apply above concept, I developed an Alexa skill that will be used by internal staff to request certain items from company inventory (ex: batteries, monitors, ..etc). Figure below explain the proposed life cycle.
cycle will be:
- Alexa gives order to deliver item to employee, and
- Alexa checks if we have enough quantity of this item. if not, lambda function will trigger request to purchase more quantities of this item by calling Amazon gateway API.
- Amazon gateway API will pass request to another Lambda function which will communicate with amazon DRS to get tokens and purchase needed quantities.
In Video, user test Alexa back-end lambda "callCenter.js" using "Actions->Configure Test Events".
In test event, user chose intent type to be "ProductTypeIntent" and value of "ProductType" to be "batteries".
"callCenter.js" checked DynamoDB table "HardwareInventory" to find if "batteries" stock is enough or not after decreasing the stock amount by 1 to fulfill user current request to have "batteries"
. As there is only one item from this product type, "callCenter.js" call another Lambda function "getToken.js" through API gateway. "getToken" will read the refresh token from DynamoDB table "RefreshToken", then ask amazon for new refresh token, save it in DB and initiate DRS request.
"getToken" successfully return to "callCenter.js" which will return to user that his request is recorded.
How to build the proof of conceptCreate Device
Follow below steps to prepare security profile & allowed URLs
Follow below steps to create Amazon simple notification service (SNS)
To create Device & slots follow below steps
Create Alexa Skill
We have already created an Alexa Skill called "Dummy Products", skill is already certified and can be accessed from this link. Scenario of conversation between user and Alexa will be as below
Alexa, launch dummy products
Hi, we are really happy to support you. Kindly advise how we can help you. if you want to report an issue you have, say issue. if you want to replace your existing hardware with new one, say hardware.
hardware
Which Hardware type you want to replace? Your can choose : Printer, laptop, batteries or monitor.
batteries
You've chosen batteries. Do you want to ask for something else?
No
Good bye.
Code will check if requested item (batteries in above scenario) has enough quantity in the store. if not it will call requestDRS() function
var MIN_NOF_QUNTITIES = 1 ;
if(newProductCount <= MIN_NOF_QUNTITIES )
{
requestDRS(productType , event, context , intent, session,
function()
{
handleFinishSessionRequest("<speak>We are working on your request and will return to you soon. Good bye!</speak>" , session, callback); context.done();
}
) ;
}
- requestDRS() function trigger product back-end URL (which is responsible to communicate with amazon APIs). function will pass product name to back-end so back-end can act accordingly.
var https = require('https');
var GATEWAY_URL = ".......east-1.amazonaws.com";
var GATEWAY_PATH = "/prod/getToken";
function requestDRS(productType , event, context , intent, session, callback)
{
var output = "";
var para = "Alexa=true&productType="+ encodeURIComponent(productType);
var options = {
host: GATEWAY_URL,
port: 443,
path: GATEWAY_PATH + "?" + para,
method: 'POST',
agent: false,
headers:
{
'Content-Type': 'application/x-www-form-urlencoded'
}
};
try
{
var req = https.request(options,
function(res) {
res.setEncoding('utf8');
var responseString = '';
res.on('data', function (chunk) {
responseString += chunk;
});
res.on('end', function() {
output = JSON.parse(responseString);
callback();
});
});
req.on('error', context.fail);
req.end();
}
catch(e)
{
console.log("Error:" +e);
}
}
We have created table using DynamoDB to save products & their quantities
To create new Alexa Skill & it is back-end lambda function, follow steps in this tutorial
To create new DynamoDB table, follow steps in this tutorial
Create product back-end
Product back-end is the page that will communicate with Amazon API to get "refresh_token" & "access_token" given "code". This done using API Gateway that trigger Lambda function, please follow steps in this tutorial
1- Getting the refresh_token from authorization_token at first time:
- At First time, user will select product and setup his DRS request. In our case this needed to be done once by the organization. As this task done only once, no need to create create customer facing website for this task. I used postman to handle this request
https://www.amazon.com/ap/oa?client_id=amzn1.application-oa2-client.......&scope=dash%3Areplenish&scope_data=%7B%22dash%3Areplenish%22%3A%7B%22device_model%22%3A%22........%22%2C%22serial%22%3A%22......%22%2C%22is_test_device%22%3Atrue%7D%7D&response_type=code&redirect_uri=https%3A%2F%2F.......execute-api.us-east-1.amazonaws.com%2Fprod%2FgetToken
- Please ensure to set "is_test_device=true" for now or request will be handled as a real request.
- After user click done, amazon API will redirect the authorization code to redirect URI written in the request. redirect URI written is the URL of product back-end (lambda function).
- Back-end will call Amazon API with old refresh_token to get the new refresh_token &
var https = require('https');
var DRS_URL = "api.amazon.com";
var DRS_PATH = "/auth/o2/token";
function getAccessToken(code,context, callback)
{
var para = "grant_type="+ code +"&client_id="+encodeURIComponent("amzn1.application-oa2-.......")+"&client_secret="+encodeURIComponent(".......")+ "&redirect_uri="+encodeURIComponent("https://.....us-east-1.amazonaws.com/prod/getToken");
console.info("para = " + para );
var options = {
host: DRS_URL,
port: 443,
path: DRS_PATH,
method: 'POST',
agent: false,
headers:
{
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': para.length
}
};
try
{
var req = https.request(options,
function(res) {
res.setEncoding('utf8');
var access_token ;
var refresh_token ;
var responseString = '';
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
responseString += chunk;
});
res.on('end', function() {
output = JSON.parse(responseString);
access_token = output.access_token ;
refresh_token = output.refresh_token ;
callback(refresh_token , access_token);
});
});
req.on('error', context.fail);
req.write(para);
req.end();
}
catch(e)
{
console.log("Error:" +e);
}
}
- Save the refresh_token value in DynamoDB
2- Getting the refresh_code & access_token from old saved refresh_code:
- This happen every time Alexa check product quantity and found it below MIN_NOF_QUNTITIES then trigger the back-end URL.
- Back-end page will read old_refresh_token from DB, ask for new refresh_token & access_token given the old_refresh_token. Then save the new refresh_token to be used in comming transaction.
if(event.queryStringParameters.Alexa)
{
readRefreshToken(
function (old_refresh_token) {
getAccessTokenFromRefreshToken(old_refresh_token, context,
function (refresh_token , access_token)
{
updateRefreshToken( refresh_token ,
function()
{
dashReplenish( access_token ,
function()
{
context.succeed();
}
);
}
);
}
);
}
);
}
- Then request Amazon replenishment API using new access_token.
function dashReplenish( access_token, callback )
{
var para = "" ;
var options = {
host: 'dash-replenishment-service-na.amazon.com',
port: 443,
path: '/replenish/.....-....-....-....-c.....c1',
method: 'POST',
agent: false,
headers: {
'Authorization' : 'Bearer ' + access_token ,
'x-amzn-accept-type': 'com.amazon.dash.replenishment.DrsReplenishResult@1.0', 'x-amzn-type-version': 'com.amazon.dash.replenishment.DrsReplenishInput@1.0'
}
};
var req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.log("we have a error");
console.error(e);
});
req.end();
}
- Amazon place a new order
- and confirmation email sent
In this phase we depend on Alexa skill to keep track number of items for each product in warehouse. Next step is supporting products that care about quantities and measuring it using sensors (ex: weight, volume,..)
Comments