This library allows your agent code to work with the Amazon Dash Replenishment Service via the RESTful API.
This version of the library supports the following functionality:
- Device authentication on the Dash Replenishment Service
- Placing test orders for Amazon goods
- Canceling test orders
- Placing real orders for Amazon goods
To add this library to your project, add #require "AmazonDRS.agent.lib.nut:1.0.0"
to the top of your agent code.
Before using the library you need to have:
- An Amazon Developer account
- Client ID and Secret of your LWA Security Profile
- A DRS device
This library needs a Refresh Token
to be able to call the Amazon's DRS API.
The Refresh Token
can be acquired with the login() method. Also, it can be acquired with any other application-specific way and then passed in with the setRefreshToken() method.
The login() method provides the following authentication flow:
- a user opens the agent's URL in a browser
- the library handles this request and redirects the user to the Amazon login page or to the Amazon device's settings page if the user is already logged in
- the user sets up the device in the Amazon's UI
- the Amazon's LWA redirects the user back to the agent's URL with an authorization code
- the agent receives this code and acquires security tokens (
Refresh Token
andAccess Token
)
More about authentication here and here. Also, see the provided example.
Note: After each restart of the agent the Refresh Token
should be passed in to the library. So if you don't want to go through the authentication steps again, you may save the token in the agent's persistent storage and set it with the setRefreshToken() method after each restart of the agent.
For testing purposes, Amazon DRS allows making test orders. Test orders are those that made by a DRS device authenticated as a test device. So it is determined at the step of authentication whether the device is for testing or not.
Due to this the login() method has a parameter testDevice. But if you set a Refresh Token
manually with the setRefreshToken() method, only you know whether this token was obtained for testing or not and such testDevice parameter is not required here.
Only test orders can be canceled with the cancelTestOrder() method.
All requests that are made to the Amazon platform occur asynchronously. Every method that sends a request has an optional parameter which takes a callback function that will be executed when the operation is completed, whether successfully or not. The callback’s parameters are listed in the corresponding method description, but every callback has at least one parameter, error. If error is 0
, the operation has been executed successfully. Otherwise, error is a code of an error.
This method returns a new AmazonDRS instance.
Parameter | Data Type | Required? | Description |
---|---|---|---|
clientId | String | Yes | Client ID of your LWA Security Profile. For information, please see here. |
clientSecret | String | Yes | Client Secret of your LWA Security Profile. For information, please see here. |
This method allows to authenticate the agent on the Amazon and get required security tokens. The method automatically sets the obtained tokens to be used for DRS API calls, so you do not need to call the setRefreshToken() method. For more information, please read about authentication.
Either this method or setRefreshToken() should be called and authentication should be done before making any DRS-related requests.
If you are going to use this method, please add #require "Rocky.class.nut:2.0.1"
to the top of your agent code.
If the Rocky library is not included, the method will throw an exception.
Parameter | Data Type | Required? | Description |
---|---|---|---|
deviceModel | String | Yes | Device Model . For information, please see here. |
deviceSerial | String | Yes | Device Serial . For information, please see here. |
onAuthenticated | Function | Optional | Callback called when the operation is completed or an error happens. |
testDevice | Boolean | Optional | True if it is a test device. False by default. For more information, please see here and the Test Orders section. |
The method returns nothing. A result of the operation may be obtained via the onAuthenticated callback if specified in this method.
Parameter | Data Type | Description |
---|---|---|
error | Integer | 0 if the authentication is successful, an error code otherwise. See possible HTTP error codes here. |
response | Table | Key-value table with the response provided by Amazon server. May be null . See here about the response format. Also may contain error details described here and here. |
#require "Rocky.class.nut:2.0.1"
#require "AmazonDRS.agent.lib.nut:1.0.0"
const AMAZON_DRS_CLIENT_ID = "<YOUR_AMAZON_CLIENT_ID>";
const AMAZON_DRS_CLIENT_SECRET = "<YOUR_AMAZON_CLIENT_SECRET>";
const AMAZON_DRS_DEVICE_MODEL = "<YOUR_AMAZON_DEVICE_MODEL>";
const AMAZON_DRS_DEVICE_SERIAL = "<YOUR_AMAZON_DEVICE_SERIAL>";
testDevice <- true;
function onAuthenticated(error, response) {
if (error != 0) {
server.error("Error authenticating: code = " + error + " response = " + http.jsonencode(response));
return;
}
server.log("Successfully authenticated!");
}
client <- AmazonDRS(AMAZON_DRS_CLIENT_ID, AMAZON_DRS_CLIENT_SECRET);
client.login(AMAZON_DRS_DEVICE_MODEL, AMAZON_DRS_DEVICE_SERIAL, onAuthenticated.bindenv(this), testDevice);
This method allows setting a Refresh Token
manually. For more information, please read about authentication.
Either this method or login() should be called and authentication should be done before making any DRS-related requests.
Parameter | Data Type | Required? | Description |
---|---|---|---|
refreshToken | String | Yes | A Refresh Token used to acquire an Access Token and refresh it when expired. |
The method returns nothing.
#require "AmazonDRS.agent.lib.nut:1.0.0"
const AMAZON_DRS_CLIENT_ID = "<YOUR_AMAZON_CLIENT_ID>";
const AMAZON_DRS_CLIENT_SECRET = "<YOUR_AMAZON_CLIENT_SECRET>";
const AMAZON_DRS_REFRESH_TOKEN = "<YOUR_AMAZON_VALID_REFRESH_TOKEN>";
client <- AmazonDRS(AMAZON_DRS_CLIENT_ID, AMAZON_DRS_CLIENT_SECRET);
client.setRefreshToken(AMAZON_DRS_REFRESH_TOKEN);
The method returns a string with the Refresh Token
or null
if it is not set.
This method places an order for a device/slot combination. For more information, please see the Amazon DRS documentation.
Parameter | Data Type | Required? | Description |
---|---|---|---|
slotId | String | Yes | ID of a slot to place an order for it. |
onReplenished | Function | Optional | Callback called when the operation is completed or an error happens. |
The method returns nothing. A result of the operation may be obtained via the onReplenished callback if specified in this method.
Parameter | Data Type | Description |
---|---|---|
error | Integer | 0 if the operation is completed successfully, an error code otherwise. See possible HTTP error codes here. |
response | Table | Key-value table with the response provided by Amazon server. May be null . See response example. Also may contain error details. |
const AMAZON_DRS_SLOT_ID = "<YOUR_AMAZON_SLOT_ID>";
function onReplenished(error, response) {
if (error != 0) {
server.error("Error replenishing: code = " + error + " response = " + http.jsonencode(response));
return;
}
server.log("An order has been placed. Response from server: " + http.jsonencode(response));
}
// It is supposed that the client has been authenticated with either login() method or setRefreshToken() method
client.replenish(AMAZON_DRS_SLOT_ID, onReplenished.bindenv(this));
This method cancels test orders for one or all slots in the device. For more information, please see the Amazon DRS documentation.
The method can only be used for the orders made by a test device (a device authenticated as a test one). The library does not check if your device authenticated as a test one or not, so you are responsible for this check. See the Test Orders section.
Parameter | Data Type | Required? | Description |
---|---|---|---|
slotId | String | Optional | ID of a slot to be canceled. If is null or not specified, test orders for all slots in the device will be canceled. |
onCanceled | Function | Optional | Callback called when the operation is completed or an error happens. |
The method returns nothing. A result of the operation may be obtained via the onCanceled callback if specified in this method.
Parameter | Data Type | Description |
---|---|---|
error | Integer | 0 if the operation is completed successfully, an error code otherwise. See possible HTTP error codes here. |
response | Table | Key-value table with the response provided by Amazon server. May be null . See response example. Also may contain error details. |
const AMAZON_DRS_SLOT_ID = "<YOUR_AMAZON_SLOT_ID>";
function onCanceled(error, response) {
if (error != 0) {
server.error("Error canceling: code = " + error + " response = " + http.jsonencode(response));
return;
}
server.log("The order has been canceled. Response from server: " + http.jsonencode(response));
}
// It is supposed that client has been authenticated with either login() method or setRefreshToken() method
// as a test DRS device
client.cancelTestOrder(AMAZON_DRS_SLOT_ID, onCanceled.bindenv(this));
This method enables (value is true
) or disables (value is false
) the library debug output (including error logging). It is disabled by default. The method returns nothing.
An Integer error code which specifies a concrete error (if any) happened during an operation.
Error Code | Description |
---|---|
0 | No error. |
1-99 | Internal errors of the HTTP API. |
100-999 | HTTP error codes from Amazon server. See methods' descriptions for more information. |
1000 | The client is not authenticated. E.g. Refresh Token is invalid or not set. |
1001 | The authentication process is already started. |
1010 | General error. |
Working examples are provided in the examples directory and described here.
The following example shows proper usage of login(), setRefreshToken() and getRefreshToken() methods.
#require "Rocky.class.nut:2.0.1"
#require "AmazonDRS.agent.lib.nut:1.0.0"
const AMAZON_DRS_CLIENT_ID = "<YOUR_AMAZON_CLIENT_ID>";
const AMAZON_DRS_CLIENT_SECRET = "<YOUR_AMAZON_CLIENT_SECRET>";
const AMAZON_DRS_DEVICE_MODEL = "<YOUR_AMAZON_DEVICE_MODEL>";
const AMAZON_DRS_DEVICE_SERIAL = "<YOUR_AMAZON_DEVICE_SERIAL>";
function getStoredRefreshToken() {
local persist = server.load();
local amazonDRS = {};
if ("amazonDRS" in persist) amazonDRS = persist.amazonDRS;
// Load credentials if we have them
if ("refreshToken" in amazonDRS) {
server.log("Refresh Token found!");
return amazonDRS.refreshToken;
}
return null;
}
client <- AmazonDRS(AMAZON_DRS_CLIENT_ID, AMAZON_DRS_CLIENT_SECRET);
refreshToken = getStoredRefreshToken();
if (refreshToken != null) {
client.setRefreshToken(refreshToken);
} else {
function onAuthenticated(error, response) {
if (error != 0) {
server.error("Error authenticating: code = " + error + " response = " + http.jsonencode(response));
return;
}
refreshToken = client.getRefreshToken();
client.setRefreshToken(refreshToken);
local persist = server.load();
persist.amazonDRS <- { "refreshToken" : refreshToken };
server.save(persist);
server.log("Successfully authenticated!");
server.log("Refresh Token saved!");
}
local testDevice = true;
client.login(AMAZON_DRS_DEVICE_MODEL, AMAZON_DRS_DEVICE_SERIAL, onAuthenticated.bindenv(this), testDevice);
server.log("Log in please!");
}
Tests for the library are provided in the tests directory and described here.
The AmazonDRS library is licensed under the MIT License