Skip to content

Commit

Permalink
Merge pull request #18 from electricimp/develop
Browse files Browse the repository at this point in the history
v2.0.1
  • Loading branch information
Pavel Petroshenko authored Nov 28, 2018
2 parents 6746cd2 + e0de084 commit 80f104d
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 26 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This library wraps the [Force.com REST API](https://www.salesforce.com/us/developer/docs/api_rest/). Force.com is a suite of point-and-click tools for creating custom employee-facing apps. The Electric Imp Salesforce library enables you to interact with your Force.com objects, allowing you to easily create products that can interact with a powerful CRM backend.

**To add this library to your project, add** `#require "Salesforce.agent.lib.nut:2.0.0"` **to the top of your agent code.**
**To add this library to your project, add** `#require "Salesforce.agent.lib.nut:2.0.1"` **to the top of your agent code.**

## Callbacks ##

Expand All @@ -19,7 +19,7 @@ If no callback is supplied (ie. a synchronous request was made), the method will
To create a new Salesforce object you will need the Consumer Key and Consumer Secret of a Connected App. Information about creating a Connected App can be found [here](https://help.salesforce.com/apex/HTViewHelpDoc?id=connected_app_create.htm). The constructor also allows you to pass in two additional parameters to override defaults: *loginService* (default value is `"login.salesforce.com"`) and *version* (default value is `"v33.0"`). If you are working in a Salesforce sandbox environment, you should pass `"test.salesforce.com"` as *loginService*.

```squirrel
#require "Salesforce.agent.lib.nut:2.0.0"
#require "Salesforce.agent.lib.nut:2.0.1"
force <- Salesforce("<-- CONSUMER_KEY -->", "<-- CONSUMER_SECRET -->");
```
Expand Down Expand Up @@ -54,6 +54,10 @@ force.login(USERNAME, PASSWORD, SECURITY_TOKEN, function(err, data) {

This method immediately returns a boolean value indicating whether or not the Salesforce object has completed a login request and stored the authentication token.

### setRefreshToken(*refreshToken*) ###

This method can be used to set or change the refresh token for the Firebase account, when necessary. Application is not required to call the method. But it might be useful if refresh token is persisted and restored on the application side and no login operation is required when device is rebooted.

### setVersion(*versionString*) ###

This method can be used to set or change the version of the Force.com REST API you are working with. For example:
Expand Down
14 changes: 9 additions & 5 deletions Salesforce.agent.lib.nut
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
class Salesforce {

// Library version
static VERSION = "2.0.0";
static VERSION = "2.0.1";

// service URLs
_loginServiceBase = "https://login.salesforce.com/";
Expand Down Expand Up @@ -71,6 +71,10 @@ class Salesforce {
_token = token;
}

function setRefreshToken(refreshToken) {
_refreshToken = refreshToken;
}

function login(username, password, securityToken = null, cb = null) {
// Add token if required
if (securityToken != null) password = password+securityToken;
Expand Down Expand Up @@ -114,10 +118,10 @@ class Salesforce {
return { err = err, data = null };
}
try {
this._userUrl = data.id;
this._instanceUrl = data.instance_url;
this._token = data.access_token;
if("refresh_token" in data) this._refreshToken = data.refresh_token;
this._userUrl = data.id;
this._instanceUrl = data.instance_url;
this._token = data.access_token;
if("refresh_token" in data) this._refreshToken = data.refresh_token;
} catch (ex) {
return { err = [{"errorCode": "NO_AUTH", "message": "Could not find auth token with supplied login information"}], data = null };
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#require "Salesforce.agent.lib.nut:2.0.0"
#require "Salesforce.agent.lib.nut:2.0.1"
#require "Rocky.class.nut:1.2.3"


Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#require "Salesforce.agent.lib.nut:2.0.0"
#require "Salesforce.agent.lib.nut:2.0.1"
#require "Rocky.class.nut:1.2.3"


Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#require "Salesforce.agent.lib.nut:2.0.0"
#require "Salesforce.agent.lib.nut:2.0.1"
#require "Rocky.class.nut:1.2.3"


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#require "Rocky.class.nut:1.2.3"

// Web Integration Library
#require "Salesforce.agent.lib.nut:2.0.0"
#require "Salesforce.agent.lib.nut:2.0.1"

// Extends Salesforce Library to handle authorization
class SalesforceOAuth2 extends Salesforce {
Expand Down Expand Up @@ -60,6 +60,9 @@ class SalesforceOAuth2 extends Salesforce {
// Set the credentials in the Salesforce object
setInstanceUrl(oAuth.instance_url);
setToken(oAuth.access_token);
if ("refresh_token" in oAuth) {
setRefreshToken(oAuth.refresh_token);
}

// Log a message
server.log("Loaded OAuth Credentials!");
Expand Down Expand Up @@ -90,13 +93,7 @@ class SalesforceOAuth2 extends Salesforce {
return;
}

// If it was successful, save the data locally
local persist = { "oAuth" : respData };
server.save(persist);

// Set/update the credentials in the Salesforce object
setInstanceUrl(persist.oAuth.instance_url);
setToken(persist.oAuth.access_token);
storeAuthData(respData);

// Finally - inform the user we're done!
context.send(200, "Authentication complete - you may now close this window");
Expand Down Expand Up @@ -142,7 +139,9 @@ class SalesforceOAuth2 extends Salesforce {
local err = null;

// If there was an error, set the error code
if (resp.statuscode != 200) err = data.message;
if (resp.statuscode != 200) {
err = "message" in respData ? respData.message : "generic error: " + resp.body;
}

// Invoke the callback
if (cb) {
Expand All @@ -152,6 +151,18 @@ class SalesforceOAuth2 extends Salesforce {
}
});
}

function storeAuthData(authData) {

// If it was successful, save the data locally
local persist = {"oAuth" : authData};
server.save(persist);

// Set/update the credentials in the Salesforce object
setInstanceUrl(persist.oAuth.instance_url);
setToken(persist.oAuth.access_token);
}

}

// Door status strings
Expand Down Expand Up @@ -194,36 +205,51 @@ class SmartFridgeApplication {
server.error("Not logged into Salesforce.")
return;
}

// Log the data being sent to the cloud
server.log(http.jsonencode(body));

// Send Salesforce platform event with device readings
_force.request("POST", _sendReadingUrl, http.jsonencode(body), function (err, respData) {
if (err) {
if (err[0].errorCode == "INVALID_SESSION_ID") {
_force.getStoredCredentials();
_force.refreshOAuthToken(_force.getRefreshToken(),
function(e, resp, respData) {
if (e) {
server.error(e);
return;
}
_force.storeAuthData(respData);
}.bindenv(this)
);
}
server.error(http.jsonencode(err));
}
else {
server.log("Readings sent successfully");
}
});
}.bindenv(this));
}

// Converts timestamp to "2017-12-03T00:54:51Z" format
function formatTimestamp(ts = null) {
local d = ts ? date(ts) : date();
return format("%04d-%02d-%02dT%02d:%02d:%02dZ", d.year, d.month + 1, d.day, d.hour, d.min, d.sec);
}

}

// RUNTIME
// ---------------------------------------------------------------------------------

// SALESFORCE CONSTANTS
// ----------------------------------------------------------
const CONSUMER_KEY = "<YOUR_CONSUMER_KEY_HERE>";
const CONSUMER_SECRET = "<YOUR_CONSUMER_SECRET_HERE>";
//
// NOTE: Please replace values of these constants with real user credentials
// ---------------------------------------------------------------------------------
const CONSUMER_KEY = "@{SALESFORCE_CONSUMER_KEY}";
const CONSUMER_SECRET = "@{SALESFORCE_CONSUMER_SECRET}";
const READING_EVENT_NAME = "Smart_Fridge_Reading__e";

// Start Application
SmartFridgeApplication(CONSUMER_KEY, CONSUMER_SECRET, READING_EVENT_NAME);
SmartFridgeApplication(CONSUMER_KEY, CONSUMER_SECRET, READING_EVENT_NAME);

0 comments on commit 80f104d

Please sign in to comment.