I was searching for a way to build an Angular app that can send requests and receive responses from the Zoho CRM. I tried all the possibilities documented in Zoho CRM documentation but nothing worked for me:
Steps I followed:
-
CodePudding user response:
- register your app on
- In your Angular app, create a RedirectComponent and include it in your app-routing.module.ts
- create zcrmsdk.js in your assets and put this code:
var libBase, headers, HTTP_METHODS, version; version = 2; HTTP_METHODS = { GET: "GET",//No I18N POST: "POST",//No I18N PUT: "PUT",//No I18N DELETE: "DELETE"//No I18N }; function promiseResponse(request) { return new Promise(function (resolve, reject) { var body, baseUrl, xhr, i, formData; libBase = localStorage.api_domain "/crm/v" version "/"; // console.log("libbase", libBase) baseUrl = libBase request.url; var token = ZCRM.API.AUTH.getAccess(); if (token == null) { return resolve('{}'); // in case of no ticket, returns empty json } if (request.params) { baseUrl = baseUrl '?' request.params; } xhr = new XMLHttpRequest(); xhr.withCredentials = true xhr.open(request.type, baseUrl); xhr.setRequestHeader("Authorization", "Zoho-oauthtoken " token) for (i in headers) { xhr.setRequestHeader(i, headers[i]); } if (request.download_file) { xhr.responseType = "blob";//No I18N } if (request.x_file_content) { formData = new FormData(); formData.append('file', request.x_file_content);//No I18N xhr.send(formData); } else { body = request.body || null; xhr.send(body); } xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status == 204) { var respObj = { "message": "no data", //No I18N "status_code": "204" //No I18N } resolve(JSON.stringify(respObj)); } else { if (request.download_file) { var filename; var disposition = xhr.getResponseHeader("Content-Disposition");//No I18N if (disposition && disposition.indexOf('attachment') !== -1) { var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; var matches = filenameRegex.exec(disposition); if (matches != null && matches[1]) { filename = matches[1].replace(/['"]/g, ''); filename = filename.replace('UTF-8', ''); } } var blob = xhr.response; var url = URL.createObjectURL(blob); var ttt = document.createElement('a'); ttt.href = url; ttt.download = filename; ttt.click(); } else { resolve(xhr.response); } } } } }) }; function createParams(parameters) { var params, key; for (key in parameters) { if (parameters.hasOwnProperty(key)) { params = parameters; } } return params; }; function constructRequestDetails(input, url, type, isModuleParam) { var requestDetails = {}; requestDetails.type = type; if (input != undefined) { if (input.id) { // console.log("IAM HERE 1"); url = url.replace("{id}", input.id); // url = url "/" input.id; } else { // console.log("IAM HERE 2"); url = url.replace("/{id}", ""); } if (input.params) { // console.log("IAM HERE1 3", input.params, "then", input.module, "hh", isModuleParam); requestDetails.params = createParams(input.params) (input.module && isModuleParam ? "module=" input.module : "");//No I18N } if (!requestDetails.params && isModuleParam) { // console.log("IAM HERE 4"); requestDetails.params = "module=" input.module;//No I18N } if (input.body && (type == HTTP_METHODS.POST || type == HTTP_METHODS.PUT)) { // console.log("IAM HERE 5"); requestDetails.body = JSON.stringify(input.body); } if (input.x_file_content) { // console.log("IAM HERE 6"); requestDetails.x_file_content = input.x_file_content; } if (input.download_file) { requestDetails.download_file = input.download_file; } } requestDetails.url = url; return requestDetails; }; function getParameterByName(name, url) { if (!url) url = window.location.href; name = name.replace(/[\[\]]/g, "\\$&"); var regex = new RegExp("[?&]" name "(=([^&#]*)|&|#|$)"); var results = regex.exec(url); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\ /g, " ")); } function sdk() { return { initialize: function (configuration) { if (document.getElementById("zes_client_scope") == null) { var elem = document.createElement('div'); elem.setAttribute("data-scope", configuration.scopes); elem.setAttribute("data-clientid", configuration.clientId); elem.setAttribute("data-accounts-url", configuration.accountUrl); elem.setAttribute("id", "zes_client_scope"); document.body.appendChild(elem); } // console.log("initialize", document.body) var input = {}; ZCRM.API.USERS.get(input).then(function (resp) { }); } } } function actions() { return { convert: function (input) { return promiseResponse(constructRequestDetails(input, "Leads/{id}/actions/convert", HTTP_METHODS.POST, false));//No I18N } } } function attachments() { return { uploadFile: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/Attachments", HTTP_METHODS.POST, false));//No I18N }, deleteFile: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/Attachments/" input.relatedId, HTTP_METHODS.DELETE, false));//No I18N }, downloadFile: function (input) { input.download_file = true; return promiseResponse(constructRequestDetails(input, input.module "/{id}/Attachments/" input.relatedId, HTTP_METHODS.GET, false));//No I18N }, uploadLink: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/Attachments", HTTP_METHODS.POST, false));//No I18N }, uploadPhoto: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/photo", HTTP_METHODS.POST, false));//No I18N }, downloadPhoto: function (input) { input.download_file = true; return promiseResponse(constructRequestDetails(input, input.module "/{id}/photo", HTTP_METHODS.GET, false));//No I18N }, deletePhoto: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/photo", HTTP_METHODS.DELETE, false));//No I18N } } } function org() { return { get: function (input) { return promiseResponse(constructRequestDetails(input, "org", HTTP_METHODS.GET, true));//No I18N } } } function records() { return { get: function (input) { // console.log("zcrm", input); return promiseResponse(constructRequestDetails(input, input.module "/{id}", HTTP_METHODS.GET, false));//No I18N }, post: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}", HTTP_METHODS.POST, false));//No I18N }, put: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}", HTTP_METHODS.PUT, false));//No I18N }, delete: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}", HTTP_METHODS.DELETE, false));//No I18N }, getNotes: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/Notes", HTTP_METHODS.GET, false));//No I18N }, getRelated: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/" input.relatedModule, HTTP_METHODS.GET, false));//No I18N }, getAllDeletedRecords: function (input) { if (input.params) { input.params.type = "all"; } else { input.params = { "type": "all"//No I18N }; } return promiseResponse(constructRequestDetails(input, input.module "/deleted", HTTP_METHODS.GET, false));//No I18N }, getRecycleBinRecords: function (input) { if (input.params) { input.type = "recycle"; } else { input.params = { "type": "recycle"//No I18N }; } return promiseResponse(constructRequestDetails(input, input.module "/deleted", HTTP_METHODS.GET, false));//No I18N }, getPermanentlyDeletedRecords: function (input) { if (input.params) { input.type = "permanent"; } else { input.params = { "type": "permanent"//No I18N }; } return promiseResponse(constructRequestDetails(input, input.module "/deleted", HTTP_METHODS.GET, false));//No I18N }, search: function (input) { return promiseResponse(constructRequestDetails(input, input.module "/search", HTTP_METHODS.GET, false));//No I18N } } } function settings() { return { getFields: function (input) { return promiseResponse(constructRequestDetails(input, "settings/fields/{id}", HTTP_METHODS.GET, true));//No I18N }, getLayouts: function (input) { return promiseResponse(constructRequestDetails(input, "settings/layouts/{id}", HTTP_METHODS.GET, true));//No I18N }, getCustomViews: function (input) { return promiseResponse(constructRequestDetails(input, "settings/custom_views/{id}", HTTP_METHODS.GET, true));//No I18N }, updateCustomViews: function (input) { return promiseResponse(constructRequestDetails(input, "settings/custom_views/{id}", HTTP_METHODS.PUT, true));//No I18N }, getModules: function (input) { return promiseResponse(constructRequestDetails(input, "settings/modules" ((input && input.module) ? "/" input.module : ""), HTTP_METHODS.GET, false));//No I18N }, getRoles: function (input) { return promiseResponse(constructRequestDetails(input, "settings/roles/{id}", HTTP_METHODS.GET, true));//No I18N }, getProfiles: function (input) { return promiseResponse(constructRequestDetails(input, "settings/profiles/{id}", HTTP_METHODS.GET, true));//No I18N }, getRelatedLists: function (input) { return promiseResponse(constructRequestDetails(input, "settings/related_lists/{id}", HTTP_METHODS.GET, true));//No I18N } } } function users() { return { get: function (input) { return promiseResponse(constructRequestDetails(input, "users/{id}", HTTP_METHODS.GET, true));//No I18N } } } var listener = 0; function auth() { return { getAccess: function () { // console.log("inside auth"); if (listener == 0) { // console.log("inside auth 1"); window.addEventListener("storage", function (e) { if (e.key === 'access_token' && e.oldValue != e.newValue && e.oldValue == null) { location.reload(); } if (e.key === 'access_token') { localStorage.removeItem('__auth_process'); } }, false); listener = 1; if (localStorage.getItem('__auth_process')) { // console.log("inside auth 2", localStorage.getItem('__auth_process')); localStorage.removeItem('__auth_process'); } } var valueInStore = localStorage.getItem('access_token'); // console.log("inside auth 3", valueInStore); var token_init = localStorage.getItem('__token_init'); // console.log("inside auth 4", token_init); if (token_init != null && valueInStore != null && Date.now() >= parseInt(token_init) 55 * 60 * 1000) { // check after 55 mins // console.log("inside auth 5"); valueInStore = null; localStorage.removeItem('access_token'); } var auth_process = localStorage.getItem('__auth_process'); // console.log("inside auth 6", auth_process); if (valueInStore == null && auth_process == null) { // console.log("inside auth 7"); var accountsUrl = document.getElementById("zes_client_scope").getAttribute("data-accounts-url"); // console.log("inside auth 8", accountsUrl); var endPoint = "/oauth/v2/auth"; var full_grant = localStorage.getItem('full_grant'); // console.log("inside auth 9", full_grant); if (full_grant != null && 'true' == full_grant && localStorage.getItem('__token_init') != null) { // console.log("inside auth 10"); endPoint = '/refresh'; } var client_id = document.getElementById("zes_client_scope").getAttribute("data-clientid"); var scope = document.getElementById("zes_client_scope").getAttribute("data-scope"); // console.log("inside auth 10", client_id, scope); var path = window.location.pathname; // console.log("inside auth 11", path); // console.log(location.hostname) var redirect_url = window.location.origin; // console.log("inside auth 12", redirect_url); var pathSplit = path.split('/'); var length = pathSplit.length for (var i = 0; i < length - 2; i ) { redirect_url = pathSplit[i] "/"; } if (location.hostname == "127.0.0.1" || location.hostname == "") { if (length - 2 == 0) { redirect_url = "/"; } redirect_url = "app/" } // if ( location.hostname == "localhost" ){ // } redirect_url = redirect_url "/redirect"; // console.log("rediret", redirect_url); if (client_id && scope) { // console.log("inside auth 13", valueInStore) localStorage.setItem('__token_init', Date.now()); localStorage.removeItem('access_token'); localStorage.setItem('__auth_process', 'true'); // var popup = window.open(accountsUrl endPoint "?scope=" scope "&client_id=" client_id "&response_type=token&state=zohocrmclient&redirect_uri=" redirect_url);//,'', 'width:' window.innerWidth ',height:' window.innerHeight); // popup.focus(); } else { throw 'missing auth params[clientId, redirectUri, scope]'; } } return valueInStore; }, revokeAccess: function () { localStorage.removeItem('crm_access_token'); } } } var ZCRM = (function (argument) { return { API: (function (argument) { return { SDK: new sdk(), AUTH: new auth(), RECORDS: new records(), SETTINGS: new settings(), ACTIONS: new actions(), USERS: new users(), ORG: new org(), ATTACHMENTS: new attachments() } })(this), init: function (data) { if (data.constructor === {}.constructor && data.hasOwnProperty('full_grant') && data['full_grant'] == true) { localStorage.setItem('full_grant', 'true'); } } } })(this)
Include the Zoho CRM SDK in your assets and add it to index.html:
<script src="/assets/js/zcrmsdk.js"></script>
create a globals.d.ts in your root path and declare the SDK:
declare var ZCRM : any;
Now you have access to the SDK in your project.
In your app.component.ts you need to initialize the SDK with the right configuration at ngOnInit:
var configuration = {}; configuration.client_id = CLIENT_ID; configuration.scopes = SCOPES; configuration.accounts_url = ACCOUNTS_URL; ZCRM.API.SDK.initialize(configuration);
continue next answer
CodePudding user response:
Run your project and you should be redirected to zoho to grant your access.
you should be also redirected to the redirect URL you set in the zoho console, please add the following in order to save the params to your localstorage, redirect.component.ts:
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-redirect', templateUrl: './redirect.component.html', styleUrls: ['./redirect.component.css'] }) export class RedirectComponent implements OnInit { constructor() { } ngOnInit(): void { this.setAccessToken(); } getPropertiesFromURL() { var props: any = {}; var propertyString = window.location.hash || window.location.search; if (propertyString && typeof propertyString === 'string') { propertyString = propertyString.slice(1); if (propertyString) { propertyString .split('&') .forEach(function (prop) { var key = prop.split('=')[0], value = prop.split('=')[1]; props[key] = value; }); } } return props; } // set the access token and grant access to localstorage setAccessToken() { var hashProps = this.getPropertiesFromURL(); console.log("hashprops", hashProps) if (hashProps) { for (var k in hashProps) { if (hashProps.hasOwnProperty(k)) { var key = (k === 'access_toke' || k === 'access_token') ? 'access_token' : k; var value = (k === 'api_domain') ? decodeURIComponent(hashProps[k]) : hashProps[k]; localStorage.setItem(key, value); } } } setTimeout(function () { window.close(); }, 0); } }
- Now you can add at you app.component.ts the following to get the response:
var input = {'module' : 'Leads'}; ZCRM.API.RECORDS.get(input).then(function(resp){ var data = JSON.parse(resp).data; console.log("data", data) });
- in point 3 I have modified the SDK a bit at line 377 to 387 and at line 84 the createParams to fit in my case and it should work for you as well, I will post the original SDK and you can configure it as well.
original SDK:
var libBase, headers, HTTP_METHODS, version; version = 2; HTTP_METHODS = { GET : "GET",//No I18N POST : "POST",//No I18N PUT : "PUT",//No I18N DELETE : "DELETE"//No I18N }; function promiseResponse(request) { return new Promise(function (resolve, reject) { var body, baseUrl, xhr, i, formData; libBase = localStorage.api_domain "/crm/v" version "/"; baseUrl = libBase request.url; var token = ZCRM.API.AUTH.getAccess(); if(token == null){ return resolve('{}'); // in case of no ticket, returns empty json } if (request.params) { baseUrl = baseUrl '?' request.params; } xhr = new XMLHttpRequest(); xhr.withCredentials = true xhr.open(request.type, baseUrl); xhr.setRequestHeader("Authorization", "Zoho-oauthtoken " token) for (i in headers) { xhr.setRequestHeader(i, headers[i]); } if (request.download_file){ xhr.responseType = "blob";//No I18N } if (request.x_file_content) { formData = new FormData(); formData.append('file', request.x_file_content);//No I18N xhr.send(formData); } else{ body = request.body || null; xhr.send(body); } xhr.onreadystatechange = function() { if(xhr.readyState == 4){ if (xhr.status == 204) { var respObj = { "message" : "no data", //No I18N "status_code" : "204" //No I18N } resolve(JSON.stringify(respObj)); } else { if (request.download_file){ var filename; var disposition = xhr.getResponseHeader("Content-Disposition");//No I18N if (disposition && disposition.indexOf('attachment') !== -1) { var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/; var matches = filenameRegex.exec(disposition); if (matches != null && matches[1]) { filename = matches[1].replace(/['"]/g, ''); filename = filename.replace('UTF-8',''); } } var blob = xhr.response; var url = URL.createObjectURL(blob); var ttt = document.createElement('a'); ttt.href = url; ttt.download = filename; ttt.click(); } else{ resolve(xhr.response); } } } } }) }; function createParams(parameters) { var params, key; for (key in parameters) { if (parameters.hasOwnProperty(key)) { if (params) { params = params key '=' parameters[key] '&'; } else { params = key '=' parameters[key] '&'; } } } return params; }; function constructRequestDetails(input, url, type, isModuleParam) { var requestDetails = {}; requestDetails.type = type; if (input != undefined) { if (input.id) { url = url.replace("{id}", input.id); // url = url "/" input.id; } else { url = url.replace("/{id}", ""); } if (input.params) { requestDetails.params = createParams(input.params) (input.module && isModuleParam ? "module=" input.module : "");//No I18N } if (!requestDetails.params && isModuleParam) { requestDetails.params = "module=" input.module;//No I18N } if (input.body && (type == HTTP_METHODS.POST || type == HTTP_METHODS.PUT)) { requestDetails.body = JSON.stringify(input.body); } if (input.x_file_content) { requestDetails.x_file_content = input.x_file_content; } if (input.download_file) { requestDetails.download_file = input.download_file; } } requestDetails.url = url; return requestDetails; }; function getParameterByName(name, url) { if (!url) url = window.location.href; name = name.replace(/[\[\]]/g, "\\$&"); var regex = new RegExp("[?&]" name "(=([^&#]*)|&|#|$)"); var results = regex.exec(url); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\ /g, " ")); } function sdk() { return { initialize : function (configuration) { if(document.getElementById("zes_client_scope") == null){ var elem = document.createElement('div'); elem.setAttribute("data-scope",configuration.scopes); elem.setAttribute("data-clientid",configuration.client_id); elem.setAttribute("data-accounts-url",configuration.accounts_url); elem.setAttribute("id","zes_client_scope"); document.body.appendChild(elem); } var input = {}; ZCRM.API.USERS.get(input).then(function(resp){ }); } } } function actions() { return { convert : function (input) { return promiseResponse(constructRequestDetails(input, "Leads/{id}/actions/convert", HTTP_METHODS.POST, false));//No I18N } } } function attachments() { return { uploadFile : function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/Attachments", HTTP_METHODS.POST, false));//No I18N }, deleteFile : function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/Attachments/" input.relatedId, HTTP_METHODS.DELETE, false));//No I18N }, downloadFile : function (input) { input.download_file = true; return promiseResponse(constructRequestDetails(input, input.module "/{id}/Attachments/" input.relatedId, HTTP_METHODS.GET, false));//No I18N }, uploadLink : function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/Attachments", HTTP_METHODS.POST, false));//No I18N }, uploadPhoto : function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/photo", HTTP_METHODS.POST, false));//No I18N }, downloadPhoto : function (input) { input.download_file = true; return promiseResponse(constructRequestDetails(input, input.module "/{id}/photo", HTTP_METHODS.GET, false));//No I18N }, deletePhoto : function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/photo", HTTP_METHODS.DELETE, false));//No I18N } } } function org() { return { get : function (input) { return promiseResponse(constructRequestDetails(input, "org", HTTP_METHODS.GET, true));//No I18N } } } function records() { return { get : function(input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}", HTTP_METHODS.GET, false));//No I18N }, post : function(input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}", HTTP_METHODS.POST, false));//No I18N }, put : function(input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}", HTTP_METHODS.PUT, false));//No I18N }, delete : function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}", HTTP_METHODS.DELETE, false));//No I18N }, getNotes : function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/Notes", HTTP_METHODS.GET, false));//No I18N }, getRelated : function (input) { return promiseResponse(constructRequestDetails(input, input.module "/{id}/" input.relatedModule, HTTP_METHODS.GET, false));//No I18N }, getAllDeletedRecords : function (input) { if (input.params) { input.params.type = "all"; } else { input.params = { "type" : "all"//No I18N }; } return promiseResponse(constructRequestDetails(input, input.module "/deleted", HTTP_METHODS.GET, false));//No I18N }, getRecycleBinRecords : function (input) { if (input.params) { input.type = "recycle"; } else { input.params = { "type" : "recycle"//No I18N }; } return promiseResponse(constructRequestDetails(input, input.module "/deleted", HTTP_METHODS.GET, false));//No I18N }, getPermanentlyDeletedRecords : function (input) { if (input.params) { input.type = "permanent"; } else { input.params = { "type" : "permanent"//No I18N }; } return promiseResponse(constructRequestDetails(input, input.module "/deleted", HTTP_METHODS.GET, false));//No I18N }, search : function (input) { return promiseResponse(constructRequestDetails(input, input.module "/search", HTTP_METHODS.GET, false));//No I18N } } } function settings() { return { getFields : function (input) { return promiseResponse(constructRequestDetails(input, "settings/fields/{id}", HTTP_METHODS.GET, true));//No I18N }, getLayouts : function (input) { return promiseResponse(constructRequestDetails(input, "settings/layouts/{id}", HTTP_METHODS.GET, true));//No I18N }, getCustomViews : function (input) { return promiseResponse(constructRequestDetails(input, "settings/custom_views/{id}", HTTP_METHODS.GET, true));//No I18N }, updateCustomViews : function (input) { return promiseResponse(constructRequestDetails(input, "settings/custom_views/{id}", HTTP_METHODS.PUT, true));//No I18N }, getModules : function (input) { return promiseResponse(constructRequestDetails(input, "settings/modules" ((input && input.module) ? "/" input.module : ""), HTTP_METHODS.GET, false));//No I18N }, getRoles : function (input) { return promiseResponse(constructRequestDetails(input, "settings/roles/{id}", HTTP_METHODS.GET, true));//No I18N }, getProfiles : function (input) { return promiseResponse(constructRequestDetails(input, "settings/profiles/{id}", HTTP_METHODS.GET, true));//No I18N }, getRelatedLists : function (input) { return promiseResponse(constructRequestDetails(input, "settings/related_lists/{id}", HTTP_METHODS.GET, true));//No I18N } } } function users() { return { get : function (input) { return promiseResponse(constructRequestDetails(input, "users/{id}", HTTP_METHODS.GET, true));//No I18N } } } var listener = 0; function auth() { return { getAccess : function(){ if(listener == 0){ window.addEventListener("storage", function(e){ if(e.key === 'access_token' && e.oldValue!=e.newValue && e.oldValue == null){ location.reload(); } if(e.key === 'access_token'){ localStorage.removeItem('__auth_process'); } }, false); listener = 1; if(localStorage.getItem('__auth_process')){ localStorage.removeItem('__auth_process'); } } var valueInStore = localStorage.getItem('access_token'); var token_init = localStorage.getItem('__token_init'); if(token_init != null && valueInStore != null && Date.now() >= parseInt(token_init) 55*60*1000){ // check after 55 mins valueInStore = null; localStorage.removeItem('access_token'); } var auth_process = localStorage.getItem('__auth_process'); if (valueInStore == null && auth_process == null) { var accountsUrl =document.getElementById("zes_client_scope").getAttribute("data-accounts-url"); var endPoint = "/oauth/v2/auth"; var full_grant = localStorage.getItem('full_grant'); if(full_grant != null && 'true' == full_grant && localStorage.getItem('__token_init') != null){ endPoint = '/refresh'; } var client_id = document.getElementById("zes_client_scope").getAttribute("data-clientid"); var scope = document.getElementById("zes_client_scope").getAttribute("data-scope"); var path = window.location.pathname; var redirect_url = window.location.origin; var pathSplit = path.split('/'); var length=pathSplit.length for (var i=0;i<length-2;i ){ redirect_url =pathSplit[i] "/"; } if(location.hostname=="127.0.0.1" ||location.hostname=="localhost" ||location.hostname=="" ){ if(length-2 == 0) { redirect_url = "/"; } redirect_url = "app/" } redirect_url = redirect_url "redirect.html"; if (client_id && scope){ localStorage.setItem('__token_init', Date.now()); localStorage.removeItem('access_token'); localStorage.setItem('__auth_process', 'true'); var popup = window.open(accountsUrl endPoint "?scope=" scope "&client_id=" client_id "&response_type=token&state=zohocrmclient&redirect_uri=" redirect_url);//,'', 'width:' window.innerWidth ',height:' window.innerHeight); //popup.focus(); } else{ throw 'missing auth params[clientId, redirectUri, scope]'; } } return valueInStore; }, revokeAccess : function (){ localStorage.removeItem('crm_access_token'); } } } var ZCRM = (function (argument) { return { API : (function (argument) { return{ SDK : new sdk(), AUTH : new auth(), RECORDS : new records(), SETTINGS : new settings(), ACTIONS : new actions(), USERS : new users(), ORG : new org(), ATTACHMENTS : new attachments() } })(this), init: function(data){ if(data.constructor === {}.constructor && data.hasOwnProperty('full_grant') && data['full_grant'] == true){ localStorage.setItem('full_grant', 'true'); } } } })(this)
I hope this make someones life easier and if any body has a better solution I would be glad to check it
- register your app on