This is an article describing a custom function built into Zoho Flow that will accept as parameter the document_id and request_id. It then retrieves the Deal Reference (entered by an office signee) on the ZohoSign document and searches for the relevant Deal record in CRM.
Why?
A client wants that when this field is entered and the document signed and returned, it attached the signed document to the Deal record.
How?
The following is the process from registering the app to call on the full API (grant code > refresh token > access token) and then the code to attach the document to the CRM record.
STEP 1: REGISTER A NEW CLIENT
First, you need to register your application with Zoho’s developer console to get your Client ID and Client Secret. (Login as the client super admin or ascentcloud admin account)
- Log in to https://accounts.zoho.com/developerconsole
- Click on Add Client ID
- Select "Self Client"
- Provide the details and register your application
STEP 2: GENERATE A GRANT CODE
- On the above screen (Zoho API Console - Applications @ https://api-console.zoho.com/)
- Select your "Self Client"
- Enter in the applicable Scope(s): eg. ZohoSign.documents.ALL,ZohoSign.templates.ALL (possibly incl. ZohoSign.account.ALL)
- Click on "Create"
STEP 3: GENERATE A REFRESH TOKEN
- For the following, browse to Zoho Sign, login as the customer, click on Settings > API Tokens > then API token - deployment > Get Started
- Fill out the client ID and client secret along with the Grant Code
- Click the button and you will get a refresh token which you can copy for the next step.
STEP 4: THE REST
A Zoho Flow would submit the request ID and document ID as part of a map to the following function:
void fn_SignDataAndAttach(int v_RequestId, int v_DocumentId)
{
//
// TLD as com or eu depending on whether you access zoho.com or zoho.eu
v_TLD = "com";
//
// enter client ID, secret and refresh token as noted from above steps (the below are sample ones and will not work)
v_ClientID = "1000.ABCDEFGHIJKLMNOPQRSTUVWXYZ1234";
v_ClientSecret = "aaaabbbbccccddddeeeeffff111122223333444455";
v_RefreshToken = "1000.aaaabbbbccccddddeeeeffff11112222.33334444555566667777888899990000";
//
// build URL to query
l_Params = List();
l_Params.add("refresh_token="+v_RefreshToken);
l_Params.add("client_id="+v_ClientID);
l_Params.add("client_secret="+v_ClientSecret);
l_Params.add("redirect_uri=https%3A%2F%2Fsign.zoho." + v_TLD);
l_Params.add("grant_type=refresh_token");
v_Url = "https://accounts.zoho."+v_TLD+"/oauth/v2/token?" + l_Params.toString("&");
r_AccessToken = invokeUrl
[
url: v_Url
type: POST
];
//
// output
v_AccessToken = ifnull(r_AccessToken.get("access_token"), "");
//
// use the access token to query requests
m_Header = Map();
m_Header.put("Authorization","Zoho-oauthtoken " + v_AccessToken);
v_Url = "https://sign.zoho.com/api/v1/requests/" + v_RequestId;
r_RequestDetails = invokeurl
[
url :v_Url
type :GET
headers:m_Header
];
//
// retrieve the value of field "Deal_Ref" from the ZohoSign Document Request
v_DealRef = "";
if(!isnull(r_RequestDetails.get("requests")))
{
if(!isnull(r_RequestDetails.get("requests").get("actions")))
{
l_Actions = r_RequestDetails.get("requests").get("actions");
for each r_Action in l_Actions
{
if(!isnull(r_Action.get("fields")))
{
for each r_Field in r_Action.get("fields")
{
if(r_Field.get("field_name") == "Deal_Ref")
{
v_DealRef = r_Field.get("field_value");
}
}
}
}
}
}
//
// Search ZohoCRM for the Deal with that Deal Ref
v_DealID = 0;
if(v_DealRef != "")
{
l_SearchResults = zoho.crm.searchRecords("Deals","(Reference_ID:equals:" + v_DealRef + ")",1,200,{"converted":"both","approved":"both"});
for each r_Result in l_SearchResults
{
if(!isnull(r_Result.get("id")))
{
v_DealID = r_Result.get("id").toLong();
}
}
}
//
// if Deal ID is not zero, then it was found!
if(v_DealID != 0)
{
r_DealDetails = zoho.crm.getRecordById("Deals",v_DealID,{"converted":"both","approved":"both"});
//
// do stuff here such as updating the deal if required
m_UpdateDeal = Map();
r_UpdateDeal = zoho.crm.updateRecord("Deals", v_DealID, m_UpdateDeal);
}
//
// now we have deal ID, retrieve the request documents
if(!isnull(r_RequestDetails.get("requests")))
{
if(!isnull(r_RequestDetails.get("requests").get("document_ids")))
{
l_Documents = r_RequestDetails.get("requests").get("document_ids");
for each r_Document in l_Documents
{
v_DocumentName = r_Document.get("document_name");
v_ThisDocumentId = r_Document.get("document_id");
if(v_ThisDocumentId == v_DocumentId)
{
r_File = invokeurl
[
url :"https://sign.zoho."+v_TLD+"/api/v1/requests/" + v_RequestId + "/documents/" + v_DocumentId + "/pdf"
type :GET
headers:m_Header
];
// if this doesn't work, enable one of the following 2 lines
//r_File.setParamName("attachment");
//r_File.setParamName("file");
r_File.setFileName(v_DocumentName);
r_Attach = zoho.crm.attachFile("Deals",v_DealID,r_File);
info r_Attach;
//
// to send this as an email as well
sendmail
[
from :zoho.adminuserid
to :"This email address is being protected from spambots. You need JavaScript enabled to view it."
subject :"ZohoSign Test - Request: " + v_RequestId + " - Document: " + v_DocumentId
message :"Please find attached your requested document(s)"
Attachments :file:r_File
];
}
}
}
}
}
- void fn_SignDataAndAttach(int v_RequestId, int v_DocumentId)
- {
- //
- // TLD as com or eu depending on whether you access zoho.com or zoho.eu
- v_TLD = "com";
- //
- // enter client ID, secret and refresh token as noted from above steps (the below are sample ones and will not work)
- v_ClientID = "1000.ABCDEFGHIJKLMNOPQRSTUVWXYZ1234";
- v_ClientSecret = "aaaabbbbccccddddeeeeffff111122223333444455";
- v_RefreshToken = "1000.aaaabbbbccccddddeeeeffff11112222.33334444555566667777888899990000";
- //
- // build URL to query
- l_Params = List();
- l_Params.add("refresh_token="+v_RefreshToken);
- l_Params.add("client_id="+v_ClientID);
- l_Params.add("client_secret="+v_ClientSecret);
- l_Params.add("redirect_uri=https%3A%2F%2Fsign.zoho." + v_TLD);
- l_Params.add("grant_type=refresh_token");
- v_Url = "https://accounts.zoho."+v_TLD+"/oauth/v2/token?" + l_Params.toString("&");
- r_AccessToken = invokeUrl
- [
- url: v_Url
- type: POST
- ];
- //
- // output
- v_AccessToken = ifnull(r_AccessToken.get("access_token"), "");
- //
- // use the access token to query requests
- m_Header = Map();
- m_Header.put("Authorization","Zoho-oauthtoken " + v_AccessToken);
- v_Url = "https://sign.zoho.com/api/v1/requests/" + v_RequestId;
- r_RequestDetails = invokeUrl
- [
- url :v_Url
- type :GET
- headers:m_Header
- ];
- //
- // retrieve the value of field "Deal_Ref" from the ZohoSign Document Request
- v_DealRef = "";
- if(!isnull(r_RequestDetails.get("requests")))
- {
- if(!isnull(r_RequestDetails.get("requests").get("actions")))
- {
- l_Actions = r_RequestDetails.get("requests").get("actions");
- for each r_Action in l_Actions
- {
- if(!isnull(r_Action.get("fields")))
- {
- for each r_Field in r_Action.get("fields")
- {
- if(r_Field.get("field_name") == "Deal_Ref")
- {
- v_DealRef = r_Field.get("field_value");
- }
- }
- }
- }
- }
- }
- //
- // Search ZohoCRM for the Deal with that Deal Ref
- v_DealID = 0;
- if(v_DealRef != "")
- {
- l_SearchResults = zoho.crm.searchRecords("Deals","(Reference_ID:equals:" + v_DealRef + ")",1,200,{"converted":"both","approved":"both"});
- for each r_Result in l_SearchResults
- {
- if(!isnull(r_Result.get("id")))
- {
- v_DealID = r_Result.get("id").toLong();
- }
- }
- }
- //
- // if Deal ID is not zero, then it was found!
- if(v_DealID != 0)
- {
- r_DealDetails = zoho.crm.getRecordById("Deals",v_DealID,{"converted":"both","approved":"both"});
- //
- // do stuff here such as updating the deal if required
- m_UpdateDeal = Map();
- r_UpdateDeal = zoho.crm.updateRecord("Deals", v_DealID, m_UpdateDeal);
- }
- //
- // now we have deal ID, retrieve the request documents
- if(!isnull(r_RequestDetails.get("requests")))
- {
- if(!isnull(r_RequestDetails.get("requests").get("document_ids")))
- {
- l_Documents = r_RequestDetails.get("requests").get("document_ids");
- for each r_Document in l_Documents
- {
- v_DocumentName = r_Document.get("document_name");
- v_ThisDocumentId = r_Document.get("document_id");
- if(v_ThisDocumentId == v_DocumentId)
- {
- r_File = invokeUrl
- [
- url :"https://sign.zoho."+v_TLD+"/api/v1/requests/" + v_RequestId + "/documents/" + v_DocumentId + "/pdf"
- type :GET
- headers:m_Header
- ];
- // if this doesn't work, enable one of the following 2 lines
- //r_File.setParamName("attachment");
- //r_File.setParamName("file");
- r_File.setFileName(v_DocumentName);
- r_Attach = zoho.crm.attachFile("Deals",v_DealID,r_File);
- info r_Attach;
- //
- // to send this as an email as well
- sendmail
- [
- from :zoho.adminuserid
- to :"This email address is being protected from spambots. You need JavaScript enabled to view it."
- subject :"ZohoSign Test - Request: " + v_RequestId + " - Document: " + v_DocumentId
- message :"Please find attached your requested document(s)"
- Attachments :file:r_File
- ];
- }
- }
- }
- }
- }