This is an article to document how to use Zoho Deluge to download a file that was uploaded into a Zoho Creator form and then to attach it to a Sales Order in Zoho Books.
Why?
Because it took me so long to find out how to do this even after reading the official documentation and going through the online discussion forums to build this solution. As of May 2020, this is how I do it.
How?
So the trick is, go over the official documentation, but don't take it as gospel. You only really need the syntax for attaching a document to a Sales Order in Books and the documentation leaves certain bits out. Just getting the syntax right and using the . setParamName is key.
Let's make it even more interesting: I'm going to use a subform with the file upload field type so our record can have more than 1 file attached to it.
the CRM.attachFile command
Okay as a first example, there is a problem here, you asked for Books and this next bit shows how to attach it to a CRM record. This works in the scenario where you have disabled the transaction modules in CRM (so Sales Orders, Invoices, Purchase Orders) and integrated your Zoho CRM with your Zoho Books. Why? Because then Zoho Books will create 3 custom modules in your CRM under the tab "Zoho Finance".
There is a lag/delay in the synchronization of Zoho Books to Zoho CRM and vice-versa. Annoyingly the attachment does not appear to be included in any sync... This method would be enough if the action was instantaneous and the attachments were also attached to the Sales Order in Books... but it isn't and doesn't. It only attaches the file(s) to the CRM record. See my "Additional" note further below in this article on how to sync the attachments to the CRM record, however for now, check the logic of this as this is known to work on the CRM record:
// assuming I have a creator form called "myForm" // that the ID of the record is the value of the variable "myRecordID" // that a subform exists in the form called "Attachments" // that a field exists in the subform called "myUpload" // that the API name for the CRM Sales Orders module is "CustomModule5004" // that v_CrmSoID is the matched ID of the Sales Order in CRM r_CreatorForm = myForm[ID == myRecordID]; if(!isnull(r_CreatorForm.Attachments)) { for each row in r_CreatorForm.Attachments { r_AttachFile = zoho.crm.attachFile("CustomModule5004",v_CrmSoID, row.myUpload); } } // r_AttachFile should yield SUCCESS and if you check your CRM record it will have these under "attachments"
- // assuming I have a creator form called "myForm"
- // that the ID of the record is the value of the variable "myRecordID"
- // that a subform exists in the form called "Attachments"
- // that a field exists in the subform called "myUpload"
- // that the API name for the CRM Sales Orders module is "CustomModule5004"
- // that v_CrmSoID is the matched ID of the Sales Order in CRM
- r_CreatorForm = myForm[ID == myRecordID];
- if(!isnull(r_CreatorForm.Attachments))
- {
- for each row in r_CreatorForm.Attachments
- {
- r_AttachFile = zoho.crm.attachFile("CustomModule5004",v_CrmSoID, row.myUpload);
- }
- }
- // r_AttachFile should yield SUCCESS and if you check your CRM record it will have these under "attachments"
Setup a Zoho Oauth Connection
So that we can use invokeUrl and attempt the REST via API (see what I did there?), we need a Zoho Oauth2 connection in Zoho Books.
- In Zoho Creator, go to Setup (3 horizontal lines in top left if in edit mode » pops up the side bar to go to Home or Setup)
- Under "Extensions", click on "Connections"
- Click on "Add Connection"
- Click on "Zoho Oauth"
- Give the connection an easy name (will be lowercased) but descriptive. For this test I will call it "myconnector".
- Ensure that as a minimum, the scope ZohoBooks.salesorders.CREATE is ticked.
- Click on "Authorize"
- Read the notice saying Creator would like access to bla bla bla and click on "Accept"
Get the file URL (ie. the PermaLink)
So if you've been googling how to download a file that was uploaded into a Creator form, you may have come across forums that are over 10 years old; URLs that were so custom that they didn't apply to you because of the app owner, name, view link name, etc. The fastest way I know how to get to it is to publish the report and right-click on the attachment to see what the link should be:
- Ensure a report exists with your form and that one of the fields/columns viewable is the file upload or attachment field
- In Zoho Creator, in the "Edit" mode, go to "Settings"
- Under "Users and Control" click on "Publish"
- On the same row as your report, click on "Get embed Code" (ensure this report is published)
- Get the Permalink and copy and paste this into a new browser window/tab
- Right-click on one of the file upload/attachments and copy the link
- Return to your code and customize the permalink so it looks the same but appends the file name
// // attach to ZohoBooks (for EU portal) v_CreatorDownloadBase = "https://creator.zoho.eu/file"; v_AppOwnerName = zoho.adminuser; v_AppLinkName = zoho.appname; v_ViewLinkName = "myForm_View"; // put your own report name v_CreatorRecordID = v_CreatorQuoteID; // this is the creator record id that has the attachment v_SubFormName = "mySubform"; // put here the link name of your subform v_FieldName = "myField"; // put here the link name of the field in that subform v_PermalinkCode = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL"; v_FileInternalName = row.Upload_File; // looping through rows here but it wants the internal name here eg. "1234567890123_temp.pdf" // // build the URL l_BuildUrl = List:String(); l_BuildUrl.add(v_CreatorDownloadBase); l_BuildUrl.add(v_AppOwnerName); l_BuildUrl.add(v_AppLinkName); l_BuildUrl.add(v_ViewLinkName); l_BuildUrl.add(v_CreatorRecordID); l_BuildUrl.add(v_SubFormName + "." + v_FieldName); l_BuildUrl.add("download"); l_BuildUrl.add(v_PermalinkCode); v_DownloadUrl = l_BuildUrl.toString("/"); v_FileDownloadUrl = v_DownloadUrl + "?filepath=/" + v_FileInternalName; // // yields something like // https://creator.zoho.eu/file/myadmin/myapp/myForm_View/123456789012345678/mySubform.myField/download/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL?filepath=/1234567890123_temp.pdf
- //
- // attach to ZohoBooks (for EU portal)
- v_CreatorDownloadBase = "https://creator.zoho.eu/file";
- v_AppOwnerName = zoho.adminuser;
- v_AppLinkName = zoho.appname;
- v_ViewLinkName = "myForm_View";  // put your own report name
- v_CreatorRecordID = v_CreatorQuoteID;  // this is the creator record id that has the attachment
- v_SubFormName = "mySubform";  // put here the link name of your subform
- v_FieldName = "myField";  // put here the link name of the field in that subform
- v_PermalinkCode = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL";
- v_FileInternalName = row.Upload_File;  // looping through rows here but it wants the internal name here eg. "1234567890123_temp.pdf"
- //
- // build the URL
- l_BuildUrl = List:String();
- l_BuildUrl.add(v_CreatorDownloadBase);
- l_BuildUrl.add(v_AppOwnerName);
- l_BuildUrl.add(v_AppLinkName);
- l_BuildUrl.add(v_ViewLinkName);
- l_BuildUrl.add(v_CreatorRecordID);
- l_BuildUrl.add(v_SubFormName + "." + v_FieldName);
- l_BuildUrl.add("download");
- l_BuildUrl.add(v_PermalinkCode);
- v_DownloadUrl = l_BuildUrl.toString("/");
- v_FileDownloadUrl = v_DownloadUrl + "?filepath=/" + v_FileInternalName;
- //
- // yields something like
- // https://creator.zoho.eu/file/myadmin/myapp/myForm_View/123456789012345678/mySubform.myField/download/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL?filepath=/1234567890123_temp.pdf
The full code with attachment to CRM and Zoho Books
Note that for the example below, my Creator form is called "Quote", my subform is called "Attachments" and the file upload field within that is called "Upload_File". The respective report is called "Quote_View".
string Internal.Attachment_Testing(int p_QuoteID, int p_SoID) { v_CreatorQuoteID = ifnull(p_QuoteID,0); v_BooksSoID = ifnull(p_SoID,0); // // config v_BooksOrgID = "1234567890"; // put here your client's own Books Organization ID v_CrmSoModule = "CustomModule5004"; // ensure this is the corresponding module API name in CRM v_BooksAPIBase = "https://books.zoho.eu/api/v3"; // // init v_OutputMessage = ""; v_CrmSoRef = ""; v_CrmSoID = 0; // // get books so name (sales order number) r_BooksSoDetails = zoho.books.getRecordsByID("Salesorders",v_BooksOrgID,v_BooksSoID.toString()); for each r_SoBooks in r_BooksSoDetails { if(!isnull(r_SoBooks.get("salesorder_number"))) { v_CrmSoRef = r_SoBooks.get("salesorder_number").toString(); } } // // retrieve crm id if(v_CrmSoRef != "") { r_SearchResults = zoho.crm.searchRecords(v_CrmSoModule,"(Name:equals:" + v_CrmSoRef + ")"); for each r_Result in r_SearchResults { v_CrmSoID = r_Result.get("id").toLong(); } } // // loop through attachments and associate to crm record if(v_CrmSoID != 0) { r_CreatorQuoteDetails = Quote[ID == v_CreatorQuoteID]; if(!isnull(r_CreatorQuoteDetails.Attachments)) { // loop through subform for each row in r_CreatorQuoteDetails.Attachments { // // attach to ZohoCRM r_AttachCRM = zoho.crm.attachFile(v_CrmSoModule,v_CrmSoID,row.Upload_File); // // attach to ZohoBooks (for EU portal) v_CreatorDownloadBase = "https://creator.zoho.eu/file"; v_AppOwnerName = zoho.adminuser; v_AppLinkName = zoho.appname; v_ViewLinkName = "Quote_View"; // put your own report name v_CreatorRecordID = v_CreatorQuoteID; // this is the creator record id that has the attachment v_SubFormName = "Attachments"; // put here the link name of your subform v_FieldName = "Upload_Field"; // put here the link name of the field in that subform v_PermalinkCode = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL"; v_FileInternalName = row.Upload_File; // looping through rows here but it wants the internal name here eg. "1234567890123_temp.pdf" // // build the URL l_BuildUrl = List:String(); l_BuildUrl.add(v_CreatorDownloadBase); l_BuildUrl.add(v_AppOwnerName); l_BuildUrl.add(v_AppLinkName); l_BuildUrl.add(v_ViewLinkName); l_BuildUrl.add(v_CreatorRecordID); l_BuildUrl.add(v_SubFormName + "." + v_FieldName); l_BuildUrl.add("download"); l_BuildUrl.add(v_PermalinkCode); v_DownloadUrl = l_BuildUrl.toString("/"); v_FileDownloadUrl = v_DownloadUrl + "?filepath=/" + v_FileInternalName; // // download the file into cache r_FileDownload = invokeurl [ url :v_FileDownloadUrl type :GET ]; // // Important: use setParamName on the response r_FileDownload.setParamName("attachment"); // // evaluate endpoint of Books API v_AttachUrl = v_BooksAPIBase + "/salesorders/" + v_BooksSoID + "/attachment?organization_id=" + v_BooksOrgID; // // send the file r_AttachBooks = invokeurl [ url :v_AttachUrl type :POST files:r_FileDownload connection:"myconnector" ]; v_OutputMessage = v_OutputMessage + "File: " + v_FileInternalName.toString() + " CRM Response: " + r_AttachCRM.toString() + " Books Response: " + r_AttachBooks.toString(); } } } return v_OutputMessage; } // output message should be each file name and response to attaching the file to the CRM and Books record
- string Internal.Attachment_Testing(int p_QuoteID, int p_SoID)
- {
- v_CreatorQuoteID = ifnull(p_QuoteID,0);
- v_BooksSoID = ifnull(p_SoID,0);
- //
- // config
- v_BooksOrgID = "1234567890";  // put here your client's own Books Organization ID
- v_CrmSoModule = "CustomModule5004";  // ensure this is the corresponding module API name in CRM
- v_BooksAPIBase = "https://books.zoho.eu/api/v3";
- //
- // init
- v_OutputMessage = "";
- v_CrmSoRef = "";
- v_CrmSoID = 0;
- //
- // get books so name (sales order number)
- r_BooksSoDetails = zoho.books.getRecordsByID("Salesorders",v_BooksOrgID,v_BooksSoID.toString());
- for each r_SoBooks in r_BooksSoDetails
- {
- if(!isnull(r_SoBooks.get("salesorder_number")))
- {
- v_CrmSoRef = r_SoBooks.get("salesorder_number").toString();
- }
- }
- //
- // retrieve crm id
- if(v_CrmSoRef != "")
- {
- r_SearchResults = zoho.crm.searchRecords(v_CrmSoModule,"(Name:equals:" + v_CrmSoRef + ")");
- for each r_Result in r_SearchResults
- {
- v_CrmSoID = r_Result.get("id").toLong();
- }
- }
- //
- // loop through attachments and associate to crm record
- if(v_CrmSoID != 0)
- {
- r_CreatorQuoteDetails = Quote[ID == v_CreatorQuoteID];
- if(!isnull(r_CreatorQuoteDetails.Attachments))
- {
- // loop through subform
- for each row in r_CreatorQuoteDetails.Attachments
- {
- //
- // attach to ZohoCRM
- r_AttachCRM = zoho.crm.attachFile(v_CrmSoModule,v_CrmSoID,row.Upload_File);
- //
- // attach to ZohoBooks (for EU portal)
- v_CreatorDownloadBase = "https://creator.zoho.eu/file";
- v_AppOwnerName = zoho.adminuser;
- v_AppLinkName = zoho.appname;
- v_ViewLinkName = "Quote_View";  // put your own report name
- v_CreatorRecordID = v_CreatorQuoteID;  // this is the creator record id that has the attachment
- v_SubFormName = "Attachments";  // put here the link name of your subform
- v_FieldName = "Upload_Field";  // put here the link name of the field in that subform
- v_PermalinkCode = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL";
- v_FileInternalName = row.Upload_File;  // looping through rows here but it wants the internal name here eg. "1234567890123_temp.pdf"
- //
- // build the URL
- l_BuildUrl = List:String();
- l_BuildUrl.add(v_CreatorDownloadBase);
- l_BuildUrl.add(v_AppOwnerName);
- l_BuildUrl.add(v_AppLinkName);
- l_BuildUrl.add(v_ViewLinkName);
- l_BuildUrl.add(v_CreatorRecordID);
- l_BuildUrl.add(v_SubFormName + "." + v_FieldName);
- l_BuildUrl.add("download");
- l_BuildUrl.add(v_PermalinkCode);
- v_DownloadUrl = l_BuildUrl.toString("/");
- v_FileDownloadUrl = v_DownloadUrl + "?filepath=/" + v_FileInternalName;
- //
- // download the file into cache
- r_FileDownload = invokeUrl
- [
- url :v_FileDownloadUrl
- type :GET
- ];
- //
- // Important: use setParamName on the response
- r_FileDownload.setParamName("attachment");
- //
- // evaluate endpoint of Books API
- v_AttachUrl = v_BooksAPIBase + "/salesorders/" + v_BooksSoID + "/attachment?organization_id=" + v_BooksOrgID;
- //
- // send the file
- r_AttachBooks = invokeUrl
- [
- url :v_AttachUrl
- type :POST
- files:r_FileDownload
- connection:"myconnector"
- ];
- v_OutputMessage = v_OutputMessage + "file: " + v_FileInternalName.toString() + " CRM Response: " + r_AttachCRM.toString() + " Books Response: " + r_AttachBooks.toString();
- }
- }
- }
- return v_OutputMessage;
- }
- // output message should be each file name and response to attaching the file to the CRM and Books record
{ "code": 0, "message": "Your file has been attached to the sales order.", "documents": [ { "document_id": "12345678901234567", "file_name": "dummy.pdf", "file_type": "pdf", "file_size": 13264, "file_size_formatted": "13 KB" } ] }
- {
- "code": 0,
- "message": "Your file has been attached to the sales order.",
- "documents": [
- {
- "document_id": "12345678901234567",
- "file_name": "dummy.pdf",
- "file_type": "pdf",
- "file_size": 13264,
- "file_size_formatted": "13 KB"
- }
- ]
- }
Additional: Attach to Zoho Books Sales Order and Attach to Zoho CRM Zoho Finance Sales Order
If you want the attachments that you've attached the Zoho Books Sales Order to sync over to the respective CRM Sales Order (now under Zoho Finance), you can't do this in one workflow because of the delay/lag in that searchRecords will not find the corresponding CRM sales order record. Instead, do the above workflow to attach the files to the Sales Order in Zoho Books, then in your Creator app, do the following for a delayed secondary workflow:
- Add a single-line field to your Creator record called Zoho Books Sales Order Ref
- Add a decision box field to your Creator record called Attached Files in CRM
- Setup a workflow that when SO Ref changes, the tick box is unticked
- Form Workflows > New Workflow
- Select your form
- Run when Created or Edited
- When to trigger: User input of a field
- Choose Field: ZohoBooks Sales Order Ref
- Name it whatever: eg. OnUserInput_ZBSoRef
- Put the following Deluge code:
- Setup a scheduled task in Creator
- Schedules > New Workflow
- Choose a Date Field
- Start Date: select form and choose Modified_Time
- Run this process on condition "Attached Files in CRM equals false"
- Execute Workflow "After 2 Minutes"
- Repeat Interval = Once
- Name the workflow > Create Workflow
- Give it the codecopyraw
// // ********************************************************** // attach to CRM record // Note: Because record cannot be retrieved with search in 1 workflow, run this 2 minutes after Modified_Time // retrieve crm id v_CrmSoID=0; v_RecordID = ifnull(input.ID,0); if(v_RecordID != 0) { r_Record = Quote[ID == v_RecordID]; v_SoRef = ifnull(r_Record.ZohoBooks_Sales_Order_Ref,""); if(!isnull(r_Record.Attachments)) { for each r_Attachment in r_Record.Attachments { // retrieve crm id if(v_SoRef != "") { r_SearchResults = zoho.crm.searchRecords("CustomModule5004","(Name:equals:" + v_SoRef + ")",1,1); for each r_Result in r_SearchResults { v_CrmSoID = r_Result.get("id").toLong(); } } // attach to CRM sales order if(v_CrmSoID != 0) { r_AttachCRM = zoho.crm.attachFile("CustomModule5004",v_CrmSoID,r_Attachment.Upload_File); } } } r_Record.Attached_Files_in_CRM=true; }
- //
- // **********************************************************
- // attach to CRM record
- // Note: Because record cannot be retrieved with search in 1 workflow, run this 2 minutes after Modified_Time
- // retrieve crm id
- v_CrmSoID=0;
- v_RecordID = ifnull(input.ID,0);
- if(v_RecordID != 0)
- {
- r_Record = Quote[ID == v_RecordID];
- v_SoRef = ifnull(r_Record.ZohoBooks_Sales_Order_Ref,"");
- if(!isnull(r_Record.Attachments))
- {
- for each r_Attachment in r_Record.Attachments
- {
- // retrieve crm id
- if(v_SoRef != "")
- {
- r_SearchResults = zoho.crm.searchRecords("CustomModule5004","(Name:equals:" + v_SoRef + ")",1,1);
- for each r_Result in r_SearchResults
- {
- v_CrmSoID = r_Result.get("id").toLong();
- }
- }
- // attach to CRM sales order
- if(v_CrmSoID != 0)
- {
- r_AttachCRM = zoho.crm.attachFile("CustomModule5004",v_CrmSoID,r_Attachment.Upload_File);
- }
- }
- }
- r_Record.Attached_Files_in_CRM=true;
- }
Other timewasting activities but good code
Putting this code here on this article as it was the path I initially went down.
Send mail attachment: creator file upload field value as attached file
You might have tested using the trusty sendmail function and then got an error when adding the "attachments" parameter. As a reminder, content-type in the sendmail is not supported in Zoho Creator and nor is List when submitted as a file attachment.
sendmail
[
from: zoho.adminuserid
to: "This email address is being protected from spambots. You need JavaScript enabled to view it."
subject: "Testing an attachment"
message: "This is a test"
attachments: file: input.my_upload
];
// success!
- sendmail
- [
- from: zoho.adminuserid
- to: "This email address is being protected from spambots. You need JavaScript enabled to view it."
- subject: "Testing an attachment"
- message: "This is a test"
- attachments: file: input.my_upload
- ];
- // success!
Send mail attachment: creator report view as pdf
sendmail
[
from: zoho.adminuserid
to: "This email address is being protected from spambots. You need JavaScript enabled to view it."
subject: "Testing an attachment"
message: "This is a test"
attachments: view: myFormReport[ID == myRecordID] as PDF
];
// pretty cool: sends a report from Creator as a PDF attached to an email.
- sendmail
- [
- from: zoho.adminuserid
- to: "This email address is being protected from spambots. You need JavaScript enabled to view it."
- subject: "Testing an attachment"
- message: "This is a test"
- attachments: view: myFormReport[ID == myRecordID] as PDF
- ];
- // pretty cool: sends a report from Creator as a PDF attached to an email.
When attaching a file in CRM unlike in Books, you need the following line of code if invoking and attaching (NB: only does 1 attachment):
v_SoID = salesorder.get("salesorder_id"); v_SoRef = salesorder.get("salesorder_number"); v_BooksOrgID = organization.get("organization_id"); v_Url = "https://books.zoho.eu/api/v3/salesorders/" + v_SoID + "/attachment?organization_id=" + v_BooksOrgID; l_Attachments = invokeurl [ url :v_Url type :GET connection:"abbooks" ]; r_SearchResults = zoho.crm.searchRecords("CustomModule5004","(Name:equals:" + v_SoRef + ")",1,1); for each r_Result in r_SearchResults { v_CrmSoID = r_Result.get("id"); l_Attachments.setParamName("file"); // v1 // l_Attachments.setParamName("attachment"); // r_AttachCRM = zoho.crm.attachFile("CustomModule5004",v_CrmSoID,l_Attachments); // v2 v_AttachUrl = "https://www.zohoapis.eu/crm/v2/CustomModule5004/" + v_CrmSoID + "/Attachments"; r_AttachCRM = invokeurl [ url :v_AttachUrl type :POST files:l_Attachments connection:"mycrmconnector" ]; info r_AttachCRM; }
- v_SoID = salesorder.get("salesorder_id");
- v_SoRef = salesorder.get("salesorder_number");
- v_BooksOrgID = organization.get("organization_id");
- v_Url = "https://books.zoho.eu/api/v3/salesorders/" + v_SoID + "/attachment?organization_id=" + v_BooksOrgID;
- l_Attachments = invokeUrl
- [
- url :v_Url
- type :GET
- connection:"abbooks"
- ];
- r_SearchResults = zoho.crm.searchRecords("CustomModule5004","(Name:equals:" + v_SoRef + ")",1,1);
- for each r_Result in r_SearchResults
- {
- v_CrmSoID = r_Result.get("id");
- l_Attachments.setParamName("file");
- // v1
- // l_Attachments.setParamName("attachment");
- // r_AttachCRM = zoho.crm.attachFile("CustomModule5004",v_CrmSoID,l_Attachments);
- // v2
- v_AttachUrl = "https://www.zohoapis.eu/crm/v2/CustomModule5004/" + v_CrmSoID + "/Attachments";
- r_AttachCRM = invokeUrl
- [
- url :v_AttachUrl
- type :POST
- files:l_Attachments
- connection:"mycrmconnector"
- ];
- info r_AttachCRM;
- }
Encountered Error(s):
- {"code":57,"message":"You are not authorized to perform this operation"}: If you connect via a Zoho OAuth connection, check that the portal (Top Level Domain: TLD) is correct [EU for Europe // COM for USA] so books.zoho.eu for Europe and books.zoho.com for US.
- {"code":2,"message":"The request passed is not valid."}: The parameters you are sending are not in the right format.
- {"code":15,"message":"Please ensure that the attachment has less than 100 characters."}: The attachment parameter is populated with the file content instead of the internal file name.
- {"code":2,"message":"Invalid value passed for doc"}: The doc parameter contains special characters.
- Improper Statement Error might be due to missing ';' at end of the line or incomplete expression This could be a missing semi-colon somewhere in your code OR that you have included either "content-type" in your invokeUrl (not supported by Creator: use headers instead) or submitted a List of files under "files" (also not supported via Creator).
- Error due to - 'Error at line : -1, Error due to - 'Internal Exception'': Problem with your parameter format, ensure these are passed as a string (eg m_Params.toString()).
- {"code":33003,"message":"Receipt not attached."}: So close, are you sending attachment as a parameter with a value in it? Don't. The full code example above will work.
- Currently this only appears to accept Microsoft Word Documents and Adobe PDF files! Applicable to Zoho Books. If the user attaches text files (TXT) these will only attach to the Sales Order in the CRM record but not to the Sales Order in Zoho Books..
Source(s):