- Direct Signi API call
- Example of a Signi API call from MS Power Automate
- Code example in .NET
- Code example in VBA
Direct Signi API call
The advantage of the Signi API direct call is flexibility, new Signi APIs are immediately available for use. It is possible to process multiple documents in parallel at once. It can be used from both cloud tenants and on premise installations. For calls from Microsoft Power Automate, HTTP and Webhook operations are used.
Before calling the API, you need to generate an API Key in the Signi application for the workspace / workspace to which you will be passing documents for signing, see Generating an API Key. You can then call any of the Signi API End Points.
The following examples show Signi API calls from three different Microsoft technologies
Microsoft Power Automate,
.NET code,
code in Visual Basic for Application - VBA.
Example of a Signi API call from MS Power Automate
MS Power Automate is an integration service that is part of the Microsoft Power Platform technology platform. The example Signi API call from MS Power Automate consists of three flows:
Signi Demo - Signing a document from a template- Invokes a signature on a document created from the "Test Agreement to Sign" template stored in Signi and made available in the Demo API test workspace,
Signi Demo - Sign PDF file - submits a PDF file for signature,
Signi Demo - Webhook - creates a webhook in the MS Power Automate environment to receive the results of the document signing, referenced by the first flow.
Example flow in MS Power Automate.
To try it out, it is on the Signi production workspace "Demo API" and has API key = “71c4123d242bdd38047bee838d17e3367dc3ea6748d0975217ce501e834a224c83cab8afd35c9b0e6ade806b7987fae80f97f5c8253cfbb9089cf21f”, when making your calls, replace this API key with your workspace's API key, which you get by subscribing to the "API Integration" and API Key Generation services.
You can download the individual flows from the examples below here.
Creating a flow for signing a document from a template
Create a new flow via MS Power Automate > Create (in the left panel) > Instant cloud flow (to run manually ) > Manually create flow.
Insert into flow operation via Next step > HTTP (select this operation type).
Parameters of the HTTP operation to invoke the pattern similarly as in Signi HELP > API Integration > Example 3 - Submitting the basis for the template :
POST request
The EndPoint address is https://api.signi.com/api/v1/contract/?type=template
In the HEAD to authenticate the API key in the field named x-api-key
For demo purposes, the Signi production environment is https://api.signi.com is workspace "Demo API" and has API key = “71c4123d242bdd38047bee838d17e3367dc3ea6748d0975217ce501e834a224c83cab8afd35c9b0e6ade806b7987fae80f97f5c8253cfbb9089cf21f”, when making your calls, replace this API key with your workspace's API key, which you get by subscribing to the "API Integration" and API Key Generation services.
The body is the required JSON with all parameters to create the document, the url of the webhook corresponds to the webhook created below, can be added after testing this flow.
You can change the demo+counterparty@signi.com email to yours.
{ "settings": { "signing_order": "proposers_before_counterparties", "autosign_proposers": "V Praze" }, "people": [ { "is_proposer": true, "email": "demo@signi.com", "contract_role": "sign" }, { "is_proposer": false, "party_order": 1, "email": "demo+counterparty@signi.com", "contract_role": "sign", "person_type": "nature", "first_name": "John", "last_name": "Doe2" } ], "webhooks": [ { "state": "completed", "url": "https://prod-174.westeurope.logic.azure.com:443/workflows/4255c88e046844319c27fdf997ee7eed/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=lJhO1j7pXPUUzQ6apYhS1TJmI6HoEyN4NS_cBMI-6rw" } ], "template": { "id": "7v1", "parameters": [ { "id": "112", "value": "Hnutí za digitalní revoluci" }, { "id": "131", "value": "Chci" }, { "id": "411", "value": "V šíření zpráv" }, { "id": "421", "value": "27.5.2021" }, { "id": "431", "value": "v Praze" } ] } }
Save flow via Save.
For testing, select Test and Run Flow.
The result of the Signi API response to a request accessed in MS Power Automate:
Create a flow for signing a PDF file
Create a new flow via MS Power Automate > Create (in the left panel) > Instant cloud flow (to run manually ) > Manually create flow.
In the flow to sign a PDF file, you first need to get the file to sign into the flow, here we use the Get file content operator.
Then we call the HTTP operator again, HTTP operation parameters for calling the pattern similarly as in Signi HELP > API Integration > Example 2 - Passing a PDF document for signature
POST request
The EndPoint address is https://api.signi.com/api/v1/contract/?type=doc
In the HEAD for authentication, the API key in the field named x-api-key
For demo purposes, the Signi production environment is https://api.signi.com is workspace "Demo API" and has API key = “71c4123d242bdd38047bee838d17e3367dc3ea6748d0975217ce501e834a224c83cab8afd35c9b0e6ade806b7987fae80f97f5c8253cfbb9089cf21f”, when making your calls, replace this API key with your workspace's API key, which you get by subscribing to the "API Integration" and API Key Generation services.
The body is the required JSON with all the parameters to create the document, the url of the webhook corresponds to the webhook created below, can be added after testing this flow.
You can change the demo+counterparty@signi.com email to yours.
{ "$content-type": "multipart/form-data", "$multipart": [ { "headers": { "Content-Disposition": "form-data; name=\"metadata\"; filename=\"data.json\"" }, "body": { "name": "test", "number": "123456", "locale": "cs", "webhooks": [ { "state": "completed", "url": "https://prod-174.westeurope.logic.azure.com:443/workflows/4255c88e046844319c27fdf997ee7eed/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=lJhO1j7pXPUUzQ6apYhS1TJmI6HoEyN4NS_cBMI-6rw" } ], "settings": { "signing_order": "one_at_a_time", "missing_positions": "append_to_the_end" }, "people": [ { "is_proposer": true, "party_order": 1, "email": "demo@signi.com", "contract_role": "sign" }, { "is_proposer": false, "party_order": 2, "email": "demo+counterparty@signi.com", "phone": "723653670", "first_name": "John", "last_name": "Doe#1", "contract_role": "sign", "person_type": "nature" } ], "file": "file_key" } }, { "headers": { "Content-Disposition": "form-data; name=\"file_key\"; filename=\"test.pdf\"" }, "body": { "$content-type": "application/pdf", "$content": "@{body('Get_file_content')?['body']}" } } ] }
in JSON we need to refer to the file obtained in the previous step , for this we use the dynamic File Content.
The next testing flow is the same as the flow for creating a document from a template.
Creating the flow for the webhook to receive the signing result
Create a new flow via MS Power Automate in the left pane > Create > Instant cloud flow for manual execution > Manually create flow.
Insert an operation into the flow via Next step > When an HTTP request is received (select this operation type).
JAs a template for the data that the webhook receives, you need to insert a JSON example, see the example at https://signi.docs.apiary.io/#reference/webhooky/ze-vzoru-s-prilohami i.e,
{ "type": "object", "properties": { "contract_id": { "type": "integer" }, "state": { "type": "string" }, "file": { "type": "string" }, "attachments": { "type": "array", "items": { "type": "object", "properties": { "contract_id": { "type": "integer" }, "state": { "type": "string" }, "file": { "type": "string" } }, "required": [ "contract_id", "state", "file" ] } } } }
JThe second is the Parse JSON operation embedded in the flow, which says that the code from the Body will be processed and takes what the webhook gets from Signi as an example JSON schema, see above. At the same time, the Copy icon gets the URL of the webhook, which is then filled in as a parameter to the Signi call in the first and second flow examples.
You can see the result of a webhook call in MS Power Automate in the flow history Signi Demo - webhook, on the detail page at the bottom view the history of the last call , where you can see the results of the call.
- Direct Signi API call
- Example of a Signi API call from MS Power Automate
- Code example in .NET
- Code example in VBA
Code example in .NET
.NET is Microsoft's framework for application development.
On the Signi production environment, the workspace is "Demo API" and has API key = “71c4123d242bdd38047bee838d17e3367dc3ea6748d0975217ce501e834a224c83cab8afd35c9b0e6ade806b7987fae80f97f5c8253cfbb9089cf21f”, when making your calls, replace this API key with your workspace's API key, which you get by subscribing to the "API Integration" and API Key Generation services.
The RestSharp library, https://restsharp.dev/ is used to send HTTP requests.
Below are the calls to the various Signi API enpoints.
using Art.Gaia; using Art.IDocuments.Models; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using Newtonsoft.Json; using RestSharp; using System; using System.Collections.Generic; using System.Text; using BE = Art.BusinessEntity; namespace Art.IDocuments.Logic { public class AnnotationLogic { public Base _base; public AnnotationLogic(Base myBase) { _base = myBase; } // Upload From File public string Upload(EntityReference dokumentReference) { try { BE.art_idokument dokument = _base.Service.Retrieve(BE.art_idokument.EntityLogicalName, dokumentReference.Id, new ColumnSet(BE.art_idokument.Attr.art_customerid.LogicalName, BE.art_idokument.Attr.art_name.LogicalName, BE.art_idokument.Attr.art_sablonaid.LogicalName)).ToEntity<BE.art_idokument>(); BE.art_idokumentsablona sablona = _base.Service.Retrieve(dokument.art_sablonaid.LogicalName, dokument.art_sablonaid.Id, new ColumnSet(BE.art_idokumentsablona.Attr.art_emailautor.LogicalName, BE.art_idokumentsablona.Attr.art_mistopodpisu.LogicalName, BE.art_idokumentsablona.Attr.art_spolecnost.LogicalName, BE.art_idokumentsablona.Attr.art_stranapospisu.LogicalName)).ToEntity<BE.art_idokumentsablona>(); BE.contact contact = _base.Service.Retrieve(BE.contact.EntityLogicalName, dokument.art_customerid.Id, new ColumnSet(BE.contact.Attr.firstname.LogicalName, BE.contact.Attr.lastname.LogicalName, BE.contact.Attr.emailaddress1.LogicalName, BE.contact.Attr.mobilephone.LogicalName, BE.contact.Attr.address1_line1.LogicalName, BE.contact.Attr.description.LogicalName)).ToEntity<BE.contact>(); QueryExpression queryAnno = new QueryExpression { EntityName = BE.annotation.EntityLogicalName, NoLock = true, TopCount = 1, ColumnSet = new ColumnSet(BE.annotation.Attr.filename.LogicalName, BE.annotation.Attr.mimetype.LogicalName, BE.annotation.Attr.documentbody.LogicalName), Criteria = new FilterExpression(LogicalOperator.And) { Conditions = { new ConditionExpression(BE.annotation.Attr.objectid.LogicalName,ConditionOperator.Equal,dokument.Id) } } }; List<BE.annotation> annotations = _base.Service.RetrieveMultiple<BE.annotation>(queryAnno); if (annotations.Count == 0) return "Žádné přílohy"; BE.annotation anno = annotations[0]; byte[] bytes = Convert.FromBase64String(anno.documentbody); if (anno.filename.Contains("html")) { byte[] data = Convert.FromBase64String(anno.documentbody); string decodedString = Encoding.UTF8.GetString(data); string newBodyText = decodedString.Replace("{data_z_dynamics1}", contact.description).Replace("{data_z_dynamics2}", contact.address1_line1); bytes = Encoding.UTF8.GetBytes(newBodyText); } // Dokument stažený z Dynamics 365 DB var client = new RestClient("https://api.signi.com/api/v1/contract/sign/provided") { Timeout = -1 }; //client.UseNewtonsoftJson(); var request = new RestRequest(Method.POST); //request.UseNewtonsoftJson(); request.AddHeader("x-api-key", "71c4123d242bdd38047bee838d17e3367dc3ea6748d0975217ce501e834a224c83cab8afd35c9b0e6ade806b7987fae80f97f5c8253cfbb9089cf21f"); request.AddHeader("Content-Type", "multipart/form-data"); request.AddParameter("email_author", sablona.art_emailautor); request.AddParameter("email_signer", contact.emailaddress1); request.AddParameter("phone_signer", contact.mobilephone); request.AddParameter("firstname_signer", contact.firstname); request.AddParameter("lastname_signer", contact.lastname); request.AddParameter("proposer_sign", "true"); request.AddParameter("negotiator_sign", "true"); request.AddParameter("contract_name", dokument.art_name); request.AddParameter("contract_number", dokument.art_cislodokumentu); request.AddParameter("sign_date", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")); request.AddParameter("sign_place", sablona.art_mistopodpisu); request.AddParameter("last_document", "true"); request.AddParameter("person_type", "legal"); //request.AddParameter("date_of_birth", "1970-04-16"); //request.AddParameter("street", "5. května 67"); //request.AddParameter("city", "Libčice nad Vltavou"); //request.AddParameter("zip_code", "25266"); request.AddParameter("company_name", sablona.art_spolecnost); //request.AddParameter("ic", "28524322"); //request.AddParameter("dic", "CZ28524322"); //request.AddParameter("sign_proposer", "{\"position\": {\"x\": 15,\"y\": 84,\"page\": 0}}"); //request.AddParameter("sign_negotiator", "{\"position\": {\"x\": 78,\"y\": 84,\"page\": 0}}"); request.AddParameter("sign_proposer[position][x]", 8); request.AddParameter("sign_proposer[position][y]", 84); request.AddParameter("sign_proposer[position][page]", sablona.art_stranapospisu - 1); request.AddParameter("sign_negotiator[position][x]", 64); request.AddParameter("sign_negotiator[position][y]", 84); request.AddParameter("sign_negotiator[position][page]", sablona.art_stranapospisu - 1); request.AddParameter("webhooks[0][state]", "signed"); request.AddParameter("webhooks[0][url]", "https://artidocumentswebapi.azurewebsites.net/IDocument/WebHookSigned"); request.AddParameter("webhooks[1][state]", "rejected"); request.AddParameter("webhooks[1][url]", "https://artidocumentswebapi.azurewebsites.net/IDocument/WebHookRejected"); request.AddParameter("webhooks[2][state]", "expired"); request.AddParameter("webhooks[2][url]", "https://artidocumentswebapi.azurewebsites.net/IDocument/WebHookExpired"); request.AlwaysMultipartFormData = true; request.AddFileBytes("file", bytes, anno.filename, anno.mimetype); IRestResponse response = client.Execute(request); if (response.StatusCode == System.Net.HttpStatusCode.OK) { BE.art_idokument iDokumentUpdate = new BE.art_idokument { Id = dokument.Id, art_id = JsonConvert.DeserializeObject<UploadDokumentResponseClass>(response.Content).ContractId, art_idokumentid = dokument.Id, statuscode = new OptionSetValue(BE.art_idokument.Attr.statuscode.Options.A_Odeslany_k_podpisu) }; _base.Trace = true; _base.Debug(iDokumentUpdate, "iDokumentUpdate"); iDokumentUpdate.Update(_base.Service); return response.Content; } return response.Content; } catch (Exception e) { _base.Error(e, "Art.IDocuments.Logic.AnnotationLogic.Upload"); return e.Message; } } // Upload From Template public string UploadTemplate(EntityReference dokumentReference) { try { BE.art_idokument dokument = _base.Service.Retrieve(BE.art_idokument.EntityLogicalName, dokumentReference.Id, new ColumnSet(BE.art_idokument.Attr.art_customerid.LogicalName, BE.art_idokument.Attr.art_name.LogicalName, BE.art_idokument.Attr.art_sablonaid.LogicalName)).ToEntity<BE.art_idokument>(); BE.art_idokumentsablona sablona = _base.Service.Retrieve(dokument.art_sablonaid.LogicalName, dokument.art_sablonaid.Id, new ColumnSet(BE.art_idokumentsablona.Attr.art_emailautor.LogicalName, BE.art_idokumentsablona.Attr.art_mistopodpisu.LogicalName, BE.art_idokumentsablona.Attr.art_spolecnost.LogicalName, BE.art_idokumentsablona.Attr.art_stranapospisu.LogicalName)).ToEntity<BE.art_idokumentsablona>(); BE.contact contact = _base.Service.Retrieve(BE.contact.EntityLogicalName, dokument.art_customerid.Id, new ColumnSet(BE.contact.Attr.firstname.LogicalName, BE.contact.Attr.lastname.LogicalName, BE.contact.Attr.emailaddress1.LogicalName, BE.contact.Attr.mobilephone.LogicalName, BE.contact.Attr.address1_line1.LogicalName, BE.contact.Attr.description.LogicalName)).ToEntity<BE.contact>(); QueryExpression queryAnno = new QueryExpression { EntityName = BE.annotation.EntityLogicalName, NoLock = true, TopCount = 1, ColumnSet = new ColumnSet(BE.annotation.Attr.filename.LogicalName, BE.annotation.Attr.mimetype.LogicalName, BE.annotation.Attr.documentbody.LogicalName), Criteria = new FilterExpression(LogicalOperator.And) { Conditions = { new ConditionExpression(BE.annotation.Attr.objectid.LogicalName,ConditionOperator.Equal,dokument.Id) } } }; List<BE.annotation> annotations = _base.Service.RetrieveMultiple<BE.annotation>(queryAnno); if (annotations.Count == 0) { var client1 = new RestClient("https://api.signi.com/api/v1/contract/sign/template") { Timeout = -1 }; //client.UseNewtonsoftJson(); var request1 = new RestRequest(Method.POST); //request.UseNewtonsoftJson(); request1.AddHeader("x-api-key", "71c4123d242bdd38047bee838d17e3367dc3ea6748d0975217ce501e834a224c83cab8afd35c9b0e6ade806b7987fae80f97f5c8253cfbb9089cf21f"); request1.AddHeader("Content-Type", "multipart/form-data"); request1.AddParameter("email_author", sablona.art_emailautor); request1.AddParameter("email_signer", contact.emailaddress1); request1.AddParameter("phone_signer", contact.mobilephone); request1.AddParameter("firstname_signer", contact.firstname); request1.AddParameter("lastname_signer", contact.lastname); request1.AddParameter("proposer_sign", "true"); request1.AddParameter("negotiator_sign", "true"); request1.AddParameter("contract_name", dokument.art_name); request1.AddParameter("contract_number", dokument.art_cislodokumentu); request1.AddParameter("sign_date", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")); request1.AddParameter("sign_place", sablona.art_mistopodpisu); request1.AddParameter("last_document", "true"); request1.AddParameter("person_type", "legal"); //request.AddParameter("date_of_birth", "1970-04-16"); //request.AddParameter("street", "5. května 67"); //request.AddParameter("city", "Libčice nad Vltavou"); //request.AddParameter("zip_code", "25266"); request1.AddParameter("company_name", sablona.art_spolecnost); //request.AddParameter("ic", "28524322"); //request.AddParameter("dic", "CZ28524322"); //request.AddParameter("sign_proposer", "{\"position\": {\"x\": 15,\"y\": 84,\"page\": 0}}"); //request.AddParameter("sign_negotiator", "{\"position\": {\"x\": 78,\"y\": 84,\"page\": 0}}"); //request.AddParameter("sign_proposer[position][x]", 8); //request.AddParameter("sign_proposer[position][y]", 84); //request.AddParameter("sign_proposer[position][page]", sablona.art_stranapospisu - 1); //request.AddParameter("sign_negotiator[position][x]", 64); //request.AddParameter("sign_negotiator[position][y]", 84); //request.AddParameter("sign_negotiator[position][page]", sablona.art_stranapospisu - 1); request1.AddParameter("webhooks[0][state]", "signed"); request1.AddParameter("webhooks[0][url]", "https://artidocumentswebapi.azurewebsites.net/IDocument/WebHookSigned"); request1.AddParameter("webhooks[1][state]", "rejected"); request1.AddParameter("webhooks[1][url]", "https://artidocumentswebapi.azurewebsites.net/IDocument/WebHookRejected"); request1.AddParameter("webhooks[2][state]", "expired"); request1.AddParameter("webhooks[2][url]", "https://artidocumentswebapi.azurewebsites.net/IDocument/WebHookExpired"); request1.AddParameter("template_id", 170); request1.AddParameter("parameters", JsonConvert.SerializeObject( new[] { new { id = 411, value = contact.description } })); //request1.AddParameter("parameters[0][id]", 411); //request1.AddParameter("parameters[0][value]", contact.description); IRestResponse response1 = client1.Execute(request1); if (response1.StatusCode == System.Net.HttpStatusCode.OK) { BE.art_idokument iDokumentUpdate = new BE.art_idokument { Id = dokument.Id, art_id = JsonConvert.DeserializeObject<UploadDokumentResponseClass>(response1.Content).ContractId, art_idokumentid = dokument.Id, statuscode = new OptionSetValue(BE.art_idokument.Attr.statuscode.Options.A_Odeslany_k_podpisu) }; _base.Trace = true; _base.Debug(iDokumentUpdate, "iDokumentUpdate"); iDokumentUpdate.Update(_base.Service); return response1.Content; } return "Žádné přílohy"; } BE.annotation anno = annotations[0]; byte[] bytes = Convert.FromBase64String(anno.documentbody); //if (anno.filename.Contains("html")) //{ // byte[] data = Convert.FromBase64String(anno.documentbody); // string decodedString = Encoding.UTF8.GetString(data); // string newBodyText = decodedString.Replace("{data_z_dynamics1}", contact.description).Replace("{data_z_dynamics2}", contact.address1_line1); // bytes = Encoding.UTF8.GetBytes(newBodyText); //} // Dokument stažený z Dynamics 365 DB var client = new RestClient("https://api.signi.com/api/v1/contract/sign/provided") { Timeout = -1 }; //client.UseNewtonsoftJson(); var request = new RestRequest(Method.POST); //request.UseNewtonsoftJson(); request.AddHeader("x-api-key", "71c4123d242bdd38047bee838d17e3367dc3ea6748d0975217ce501e834a224c83cab8afd35c9b0e6ade806b7987fae80f97f5c8253cfbb9089cf21f"); request.AddHeader("Content-Type", "multipart/form-data"); request.AddParameter("email_author", sablona.art_emailautor); request.AddParameter("email_signer", contact.emailaddress1); request.AddParameter("phone_signer", contact.mobilephone); request.AddParameter("firstname_signer", contact.firstname); request.AddParameter("lastname_signer", contact.lastname); request.AddParameter("proposer_sign", "true"); request.AddParameter("negotiator_sign", "true"); request.AddParameter("contract_name", dokument.art_name); request.AddParameter("contract_number", dokument.art_cislodokumentu); request.AddParameter("sign_date", DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")); request.AddParameter("sign_place", sablona.art_mistopodpisu); request.AddParameter("last_document", "true"); request.AddParameter("person_type", "legal"); //request.AddParameter("date_of_birth", "1970-04-16"); //request.AddParameter("street", "5. května 67"); //request.AddParameter("city", "Libčice nad Vltavou"); //request.AddParameter("zip_code", "25266"); request.AddParameter("company_name", sablona.art_spolecnost); //request.AddParameter("ic", "28524322"); //request.AddParameter("dic", "CZ28524322"); //request.AddParameter("sign_proposer", "{\"position\": {\"x\": 15,\"y\": 84,\"page\": 0}}"); //request.AddParameter("sign_negotiator", "{\"position\": {\"x\": 78,\"y\": 84,\"page\": 0}}"); request.AddParameter("sign_proposer[position][x]", 8); request.AddParameter("sign_proposer[position][y]", 84); request.AddParameter("sign_proposer[position][page]", sablona.art_stranapospisu - 1); request.AddParameter("sign_negotiator[position][x]", 64); request.AddParameter("sign_negotiator[position][y]", 84); request.AddParameter("sign_negotiator[position][page]", sablona.art_stranapospisu - 1); request.AddParameter("webhooks[0][state]", "signed"); request.AddParameter("webhooks[0][url]", "https://artidocumentswebapi.azurewebsites.net/IDocument/WebHookSigned"); request.AddParameter("webhooks[1][state]", "rejected"); request.AddParameter("webhooks[1][url]", "https://artidocumentswebapi.azurewebsites.net/IDocument/WebHookRejected"); request.AddParameter("webhooks[2][state]", "expired"); request.AddParameter("webhooks[2][url]", "https://artidocumentswebapi.azurewebsites.net/IDocument/WebHookExpired"); request.AlwaysMultipartFormData = true; request.AddFileBytes("file", bytes, anno.filename, anno.mimetype); IRestResponse response = client.Execute(request); if (response.StatusCode == System.Net.HttpStatusCode.OK) { BE.art_idokument iDokumentUpdate = new BE.art_idokument { Id = dokument.Id, art_id = JsonConvert.DeserializeObject<UploadDokumentResponseClass>(response.Content).ContractId, art_idokumentid = dokument.Id, statuscode = new OptionSetValue(BE.art_idokument.Attr.statuscode.Options.A_Odeslany_k_podpisu) }; _base.Trace = true; _base.Debug(iDokumentUpdate, "iDokumentUpdate"); iDokumentUpdate.Update(_base.Service); return response.Content; } return response.Content; } catch (Exception e) { _base.Error(e, "Art.IDocuments.Logic.AnnotationLogic.Upload"); return e.Message; } } // Download Document public void DownloadTest() { BE.annotation anno = (BE.annotation)_base.Service.Retrieve(BE.annotation.EntityLogicalName, new Guid("54DC0A3F-75A5-EA11-A812-000D3AB7AF7A"), new ColumnSet(true)); RestClient client = new RestClient("https://api.signi.com/api/v1/contract/2842/download"); client.AddDefaultHeader("x-api-key", "71c4123d242bdd38047bee838d17e3367dc3ea6748d0975217ce501e834a224c83cab8afd35c9b0e6ade806b7987fae80f97f5c8253cfbb9089cf21f"); client.AddDefaultHeader("Content-Type", "application/json"); IRestRequest request = new RestRequest { Method = Method.GET }; IRestResponse response = client.Get(request); string fileBase64 = Convert.ToBase64String(response.RawBytes); //fileBase64 - serializovaný soubr, který je možné uložit do DB } public string Download(EntityReference dokumentReference) { try { string output = "OK"; BE.art_idokument dokument = _base.Service.Retrieve(BE.art_idokument.EntityLogicalName, dokumentReference.Id, new ColumnSet(BE.art_idokument.Attr.art_customerid.LogicalName, BE.art_idokument.Attr.art_name.LogicalName, BE.art_idokument.Attr.art_sablonaid.LogicalName, BE.art_idokument.Attr.art_id.LogicalName)).ToEntity<BE.art_idokument>(); QueryExpression queryAnno = new QueryExpression { EntityName = BE.annotation.EntityLogicalName, NoLock = true, TopCount = 1, ColumnSet = new ColumnSet(BE.annotation.Attr.filename.LogicalName), Criteria = new FilterExpression(LogicalOperator.And) { Conditions = { new ConditionExpression(BE.annotation.Attr.objectid.LogicalName,ConditionOperator.Equal,dokument.Id) } } }; List<BE.annotation> annotations = _base.Service.RetrieveMultiple<BE.annotation>(queryAnno); if (annotations.Count == 0) return "Žádné přílohy"; BE.annotation anno = annotations[0]; RestClient client = new RestClient($"https://api.signi.com/api/v1/contract/{dokument.art_id}/download"); client.AddDefaultHeader("x-api-key", "71c4123d242bdd38047bee838d17e3367dc3ea6748d0975217ce501e834a224c83cab8afd35c9b0e6ade806b7987fae80f97f5c8253cfbb9089cf21f"); client.AddDefaultHeader("Content-Type", "application/json"); IRestRequest request = new RestRequest { Method = Method.GET }; IRestResponse response = client.Get(request); string fileBase64 = Convert.ToBase64String(response.RawBytes); BE.annotation annotation = new BE.annotation { objectid = dokumentReference, documentbody = fileBase64, subject = $"Podepsaný dokument: {dokument.art_name}", filename = $"{anno.filename}_podpis.pdf" }; annotation.Create(_base.Service); return output; } catch (Exception e) { _base.Error(e, "Art.IDocuments.Logic.AnnotationLogic.Download"); return e.Message; } } } }
Code example in VBA
Visual Basic for Application is a development language used in the desktop versions of Microsoft Office . It is no longer supported in the Office 365 cloud environment.
On the Signi production environment, the workspace is "Demo API" and has API key = “71c4123d242bdd38047bee838d17e3367dc3ea6748d0975217ce501e834a224c83cab8afd35c9b0e6ade806b7987fae80f97f5c8253cfbb9089cf21f”, when making your calls, replace this API key with your workspace's API key, which you get by subscribing to the "API Integration" and API Key Generation services.
You need the code to run Micrisoft Excel for Desktop on MS Windows. VBA macros do not work on MS 356 cloud environment, and the object for HTTP requests is not accessible in Microsoft Execl for Mac.
Sub FillTemplateAndSend() Dim URL As String Dim JSONString As String Dim RowString As String Dim objHTTP As New WinHttpRequest Dim ConfProposerEmail As String Dim ConfAPIKey As String Dim ConfMapping As String Dim ConfURL As String Dim i As Integer Dim ContractFrom As Integer Dim ContractTo As Integer Dim Contracts As Range Dim SigniID As String Dim ResponseText As String Dim TemplateNo As Integer Dim TemplateRow As Integer 'Načtení parametrů konfigurace ConfURL = "https://api.signi.com/api/v1/contract/?type=template" ConfAPIKey = Worksheets("Config").Range("C6").Value ContractFrom = 5 'první řádek na kterém jsou data ContractTo = Worksheets("Data").UsedRange.Rows.Count 'poslední řádek na kterém jsou data objHTTP.Open "POST", ConfURL, False objHTTP.SetRequestHeader "x-api-key", ConfAPIKey objHTTP.SetRequestHeader "Content-Type", "application/json" 'procházení řádků , posílání do Signi a aktualizace řádků For i = ContractFrom To ContractTo If UCase(Worksheets("Data").Range("A" & i).Value) = "ODESLAT" Then TemplateNo = Worksheets("Data").Range("B" & i).Value If IsNumeric(TemplateNo) Then RowString = Worksheets("Config").Range("C" & (TemplateNo + 10)).Value RowString = Replace(RowString, "#proposeremail#", Worksheets("Config").Range("C7").Value) RowString = Replace(RowString, "#state#", Worksheets("Config").Range("C8").Value) RowString = Replace(RowString, "#locale#", Worksheets("Config").Range("C9").Value) If TemplateNo = "1" Then RowString = Replace(RowString, "#contract_name#", Worksheets("Data").Range("E" & i).Value) RowString = Replace(RowString, "#number#", Worksheets("Data").Range("F" & i).Value) RowString = Replace(RowString, "#firstname#", Worksheets("Data").Range("G" & i).Value) RowString = Replace(RowString, "#lastname#", Worksheets("Data").Range("H" & i).Value) RowString = Replace(RowString, "#email#", Worksheets("Data").Range("I" & i).Value) RowString = Replace(RowString, "#phone#", Worksheets("Data").Range("J" & i).Value) RowString = Replace(RowString, "#112#", Worksheets("Data").Range("K" & i).Value) RowString = Replace(RowString, "#122#", Worksheets("Data").Range("L" & i).Value) RowString = Replace(RowString, "#131#", Worksheets("Data").Range("M" & i).Value) RowString = Replace(RowString, "#411#", Worksheets("Data").Range("N" & i).Value) RowString = Replace(RowString, "#421#", Worksheets("Data").Range("O" & i).Value) RowString = Replace(RowString, "#431#", Worksheets("Data").Range("P" & i).Value) End If objHTTP.Send RowString ResponseText = objHTTP.ResponseText ResponseText = Replace(ResponseText, "{""contract_id"":", "") If InStr(ResponseText, """attachments""") >= 2 Then SigniID = Left(ResponseText, InStr(ResponseText, """attachments""") - 2) Else SigniID = ResponseText 'pokud chybí text "attachements", předpokládá se, že došlo k chybě End If Worksheets("Data").Range("D" & i) = RowString ' JSON použitý pro volání Worksheets("Data").Range("C" & i) = SigniID Worksheets("Data").Range("A" & i).Value = "Odesláno" End If End If Next i Dim Z As String End Sub Sub ReadStatus() Dim ConfURL As String Dim ConfAPIKey As String Dim URL As String Dim SigniID As String Dim ResponseText As String Dim i As Integer Dim ContractFrom As Integer Dim ContractTo As Integer Dim objHTTP As New WinHttpRequest 'Načtení parametrů konfigurace ConfAPIKey = Worksheets("Config").Range("C6").Value ConfURL = "https://api.signi.com/api/v1/contract/" ContractFrom = 5 ContractTo = Worksheets("Data").UsedRange.Rows.Count 'procházení řádků , posílání do Signi a aktualizace řádků For i = ContractFrom To ContractTo SigniID = Worksheets("Data").Range("B" & i).Value 'Načtení SigniID ze sloupce D If IsNumeric(SigniID) And Not (IsEmpty(SigniID)) Then 'když je hodnota numerická a neprázdná tj.j. je v ní pravděpodobně smysluplné ContractID URL = ConfURL & SigniID objHTTP.Open "GET", URL, False objHTTP.SetRequestHeader "x-api-key", ConfAPIKey objHTTP.SetRequestHeader "Content-Type", "application/json" objHTTP.Send ResponseText = objHTTP.ResponseText If InStr(ResponseText, """pending""") > 0 Then Worksheets("Data").Range("A" & i).Value = "Rozesláno" ElseIf InStr(ResponseText, """completed""") > 0 Then Worksheets("Data").Range("A" & i).Value = "Podepsáno" ElseIf InStr(ResponseText, """expired""") > 0 Then Worksheets("Data").Range("A" & i).Value = "Uplynula doba" ElseIf InStr(ResponseText, """refused""") > 0 Then Worksheets("Data").Range("A" & i).Value = "Odmítnuto" End If End If Next i End Sub
Was this article helpful?
That’s Great!
Thank you for your feedback
Sorry! We couldn't be helpful
Thank you for your feedback
Feedback sent
We appreciate your effort and will try to fix the article