You need to sign in to do that
Don't have an account?
Arnaud Combes
SOQL from external website (forcejs, api, ...)
Hello,
I'm trying to get salesforce data from my website with SOQL query but I don't manage to do it.
For that I have tried all the JS libraries I have found like forcejs, but I always have some errors. Is there a library to do this ? And how can I do it ?
Thank you very much.
Regards,
I'm trying to get salesforce data from my website with SOQL query but I don't manage to do it.
For that I have tried all the JS libraries I have found like forcejs, but I always have some errors. Is there a library to do this ? And how can I do it ?
Thank you very much.
Regards,
error=redirect_uri_mismatch&error_description=redirect_uri%20must%20match%20configuration
So after that, I have changed the callback in force.js file to put the one I have defined in my remote app (in Salesforce) and now, I have each time a popup which open :
So my first question is : is it mandatory to display this popup each time ? And if I click on "Allow", I have then this error message :
<OAuth>
<error>unsupported_grant_type</error>
<error_description>grant type not supported</error_description>
</OAuth>
I don't know what is wrong as I have followed the explanation on GIT, but there certainly something missing.
Any idea ?
Thanks again !
Regards,
It is the first time I create one and I tried to define as I have seen on Google.
So I have just defined a name for the connected app, then check the chekbox "Callback URL" but actually I don't know what to write inside this callback url. I have seen that it must be something like xxx.com/services/oauth2/token, but xxx must be the name of my website, or something else ?
Thank you for all these information. I have only tested now, but unfortunately I still have the issue. I will write everything changes I have made, maybe you will can help me if you have already use forcejs.
So first I have created a remote app in Salesforce with the Remote app name "mysampleapp", api name "mysampleapp" and callbackURL "
mysampleapp://auth/success".
Is the callbackURL used in the code (html/javascript) file ?
Then I have put on my server the three files
index.html
oauthcallback.html
force.js
In the index.html file, I have :
- Uncommented the function force.init
- Change AppId by my Consumer Key (of the connected app)
- Change loginURL from https://login.salesforce.com to https://test.salesforce.com'
- delete proxyURL (as I don't use proxy)
-
In force.js :
- Change loginURL from https://login.salesforce.com to https://test.salesforce.com'
- Change AppId by my Consumer Key (of the connected app)
I hope it is clear enough, do you see sometihng wrong in this ?
Thanks a lot again for your help !
Regards,
The page at lolcalhos says : An error has occured. See console for details.
And in Chrome, when I look at the console, I just see "useProxy: true" but nothing else...
Then my connected app is :
And my code is :
index.html :
<html>
<head>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">ForceJS</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="javascript:login()">Login</a></li>
<li><a href="javascript:discardToken()">Discard Token</a></li>
<li><a href="javascript:isLoggedIn()">Is Logged In?</a></li>
</ul>
</div>
</div>
</div>
<div class="container" style="padding-top: 60px;">
<div class="row">
<div class="col-xs-12 col-sm-4">
<p><button type="button" class="btn btn-default" onclick="query()"><i class="glyphicon glyphicon-refresh"></i> Get Contacts</button></p>
<ul id="list" class="list-group"></ul>
</div>
<div class="col-xs-12 col-sm-8">
<p><button type="button" class="btn btn-default" onclick="newContact()"><i class="glyphicon glyphicon-plus"></i> New</button></p>
<form role="form">
<div class="form-group">
<label for="contactId">Id</label>
<input type="text" class="form-control" id="contactId" disabled>
</div>
<div class="form-group">
<label for="firstName">First Name</label>
<input type="text" class="form-control" id="firstName">
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input type="text" class="form-control" id="lastName">
</div>
<button type="button" class="btn btn-default" id="createBtn" onclick="create()" style="display:none">Create</button>
<button type="button" class="btn btn-default" id="updateBtn" onclick="update()" style="display:none">Update</button>
<button type="button" class="btn btn-default" id="deleteBtn" onclick="del()" style="display:none">Delete</button>
</form>
</div>
</div>
</div>
<script src="force.js"></script>
<script>
var contactList = document.getElementById('contact-list'),
idField = document.getElementById('contactId'),
firstNameField = document.getElementById('firstName'),
lastNameField = document.getElementById('lastName'),
createBtn = document.getElementById('createBtn'),
updateBtn = document.getElementById('updateBtn'),
deleteBtn = document.getElementById('deleteBtn');
// ForceJS is built to work out of the box with sensible defaults.
// Uncomment the force.init() function call below to provide specific runtime parameters
force.init({
appId: '3MVG9OI03ecbG2VrZvChgcHVDtTGOrpzUkoLvJn7t7NkAMKUfOIa7_2jmhBx__wY8OofT4pXxrdGCbpB8CIAT',
apiVersion: 'v32.0',
loginUrl: 'https://test.salesforce.com',
oauthRedirectURL: 'http://mywebsite.com/oauthcallback.html',
proxyURL: 'http://myproxy.com'
});
function login() {
force.login(
function() {
console.log('Salesforce login succeeded');
},
function(error) {
console.log(error);
alert('Salesforce login failed');
});
}
function query() {
// Empty list
list.innerHTML = '';
// Retrieve contacts
force.query('select id, firstName, lastName from contact LIMIT 50',
function(response) {
var str = '';
var contacts = response.records;
for (var i=0; i < contacts.length; i++) {
str += '<a href="#' + contacts[i].Id + '" class="list-group-item">' + contacts[i].FirstName + ' '
+ contacts[i].LastName + '</a>';
}
list.innerHTML = str;
},
function(error) {
alert("An error has occurred. See console for details.");
});
}
function request() {
// Empty list
list.innerHTML = '';
// Retrieve contacts
force.request({path: '/services/apexrest/contact',
success: function(response) {
console.log('request');
var str = '';
var contacts = response;
for (var i=0; i < contacts.length; i++) {
str += '<li><a href="#' + contacts[i].Id + '" class="list-group-item">' + contacts[i].Name + '</a></li>';
}
list.innerHTML = str;
},
error: function(error) {
alert("An error has occurred. See console for details.");
}});
}
function create() {
force.create('contact', {FirstName: firstNameField.value, LastName: lastNameField.value},
function(response) {
console.log(response);
},
function(error) {
alert("An error has occurred. See console for details.");
});
}
function update() {
force.update('contact', {Id: idField.value, FirstName: firstNameField.value, LastName: lastNameField.value},
function(response) {
console.log(response);
},
function(error) {
alert("An error has occurred. See console for details.");
});
}
function del() {
force.del('contact', idField.value,
function(response) {
console.log(response);
},
function(error) {
alert("An error has occurred. See console for details.");
});
}
function retrieve(id) {
force.retrieve('contact', id, null,
function(contact) {
console.log(contact);
idField.value = contact.Id;
firstNameField.value = contact.FirstName;
lastNameField.value = contact.LastName;
createBtn.style.display = 'none';
updateBtn.style.display = 'inline';
deleteBtn.style.display = 'inline';
},
function(error) {
alert("An error has occurred. See console for details.");
});
}
function discardToken() {
force.discardToken();
alert('Token discarded');
}
function isLoggedIn() {
alert(force.isLoggedIn());
}
function newContact() {
idField.value = "";
firstNameField.value = "";
lastNameField.value = "";
createBtn.style.display = 'inline';
updateBtn.style.display = 'none';
deleteBtn.style.display = 'none';
}
window.onhashchange = function () {
var id = window.location.hash.substr(1);
retrieve(id);
}
</script>
</body>
</html>
/**
* ForceJS - REST toolkit for Salesforce.com
* Author: Christophe Coenraets @ccoenraets
* Version: 0.6
*/
var force = (function () {
"use strict";
// The login URL for the OAuth process
// To override default, pass loginURL in init(props)
var loginURL = 'https://test.salesforce.com',
// The Connected App client Id. Default app id provided - Not for production use.
// This application supports http://localhost:8200/oauthcallback.html as a valid callback URL
// To override default, pass appId in init(props)
appId = 'myconsumerkey',
// The force.com API version to use.
// To override default, pass apiVersion in init(props)
apiVersion = 'v33.0',
// Keep track of OAuth data (access_token, refresh_token, and instance_url)
oauth,
// By default we store fbtoken in sessionStorage. This can be overridden in init()
tokenStore = {},
// if page URL is http://localhost:3000/myapp/index.html, context is /myapp
context = window.location.pathname.substring(0, window.location.pathname.lastIndexOf("/")),
// if page URL is http://localhost:3000/myapp/index.html, serverURL is http://localhost:3000
serverURL = window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : ''),
// if page URL is http://localhost:3000/myapp/index.html, baseURL is http://localhost:3000/myapp
baseURL = serverURL + context,
// Only required when using REST APIs in an app hosted on your own server to avoid cross domain policy issues
// To override default, pass proxyURL in init(props)
proxyURL = baseURL,
// if page URL is http://localhost:3000/myapp/index.html, oauthCallbackURL is http://localhost:3000/myapp/oauthcallback.html
// To override default, pass oauthCallbackURL in init(props)
oauthCallbackURL = baseURL + '/oauthcallback.html',
// Because the OAuth login spans multiple processes, we need to keep the login success and error handlers as a variables
// inside the module instead of keeping them local within the login function.
loginSuccessHandler,
loginErrorHandler,
// Reference to the Salesforce OAuth plugin
oauthPlugin,
// Whether or not to use a CORS proxy. Defaults to false if app running in Cordova, in a VF page,
// or using the Salesforce console. Can be overriden in init()
useProxy = (window.cordova || window.SfdcApp || window.sforce) ? false : true;
/*
* Determines the request base URL.
*/
function getRequestBaseURL() {
var url;
if (useProxy) {
url = proxyURL;
} else if (oauth.instance_url) {
url = oauth.instance_url;
} else {
url = serverURL;
}
// dev friendly API: Remove trailing '/' if any so url + path concat always works
if (url.slice(-1) === '/') {
url = url.slice(0, -1);
}
return url;
}
function parseQueryString(queryString) {
var qs = decodeURIComponent(queryString),
obj = {},
params = qs.split('&');
params.forEach(function (param) {
var splitter = param.split('=');
obj[splitter[0]] = splitter[1];
});
return obj;
}
function toQueryString(obj) {
var parts = [],
i;
for (i in obj) {
if (obj.hasOwnProperty(i)) {
parts.push(encodeURIComponent(i) + "=" + encodeURIComponent(obj[i]));
}
}
return parts.join("&");
}
Install force-server
Because of the browser's cross-origin restrictions, your JavaScript application hosted on your own server (or localhost) will not be able to make API calls directly to the *.salesforce.com domain. The solution is to proxy your API calls through your own server. You can use your own proxy server, but ForceJS is tightly integrated with ForceServer, a simple development server for Force.com.
To install ForceServer, make sure Node.js is installed on your system, open a command prompt and execute the following command: npm install -g force-server
For CORS set up please review the following linkhttps://developer.salesforce.com/blogs/developer-relations/2015/01/spring-15-preview-cors-force-com-rest-api.html
To sum up you have to install the following as per the sequence-
1. Node.js - https://nodejs.org/en/
2. ForceServer - npm install -g force-server
3. Set up COR as per the link I mentioned earlier
npm install -g force-server to install the ForceServer globally
Thanks !
To sum up, if I follow the steps to install force server and forcejs, I manage to display data from my account. But I have 2 issues :
1) Each time I run the index.html file to get data, I have these two popup :
One to log in
Another one to "Allow" :
So the issue is that the users can't see that, if each time I execute a SOQL query I have these 2 popup, it is an issue. So is there a way to disable them ?
2) The other issue is that, when I replace the appId there is in the force.js file by my appId (the consumerKey of my conneted app), it no longer works. I have this error message :
And I don't see any data.
Do you know what can be the problem ?
Thanks again :)
Regards,
The Popups are for authentication. Please click on Allow. Please check the Web App setting of your connected app and let me know.
I still have the issue.
I will try the example of Gmail connected app, but for the moment I can't see what is wrong. But it is sure, it comes frmo my connected app as it works with the default connected app of forcejs.
I have just one last issue you have already replied, but each time I tried to run a SOQL query, I have the popup where I need to click on button "Allow". Is it possible to hide this popup ? Because I can't display it to our customer. It should connect automatically without this popup.
Thanks again !