Custom template fields with docusign_rest - ruby-on-rails

I'm using the docusign rest gem to create and send DocuSign envelopes. But I'm having problems having custom fields I have set on my template to show up. I have 2 signers on my template, that have common fields to both of them so I had to set up each custom field twice since DocuSign doesn't allow for shared fields it seems.
This is the API call I'm doing when setting up my envelope, as per the DocuSign API docs:
custom_fields = {
textCustomFields: [
{
name: "host_address",
value: "Testing Host Address",
required: "true",
show: "true",
},
{
name: "host_civil_status",
value: "Host Civil Status",
required: "true",
show: "true",
},
{
name: "host_id_number",
value: "123HOSTID",
required: "true",
show: "true",
},
{
name: "host_tax_number",
value: "123HOSTTAX",
required: "true",
show: "true",
},
{
name: "nomad_address",
value: "Testing Nomad Address",
required: "true",
show: "true",
},
{
name: "nomad_civil_status",
value: "Nomad Civil Status",
required: "true",
show: "true",
},
{
name: "nomad_id_number",
value: "123NOMADID",
required: "true",
show: "true",
},
{
name: "nomad_tax_number",
value: "123NOMADTAX",
required: "true",
show: "true",
},
{
name: "property_addres",
value: booking.listing.property.full_address,
required: "true",
show: "true",
},
{
name: "property_address",
value: booking.listing.property.full_address,
required: "true",
show: "true",
},
{
name: "property_deposit",
value: (booking.deposit * booking.price).to_s,
required: "true",
show: "true",
},
{
name: "property_description",
value: "Property Description",
required: "true",
show: "true",
},
{
name: "property_start_date",
value: booking.start_date.strftime("%d/%m/%Y"),
required: "true",
show: "true",
},
{
name: "property_end_date",
value: booking.end_date.strftime("%d/%m/%Y"),
required: "true",
show: "true",
},
{
name: "property_stay_length",
value: distance_of_time_in_words(booking.start_date, booking.end_date),
required: "true",
show: "true",
},
{
name: "property_montly_rent",
value: booking.price.to_s,
required: "true",
show: "true",
},
]
}
#envelope = client.create_envelope_from_template(
status: 'sent',
email: {
subject: "The test email subject envelope",
body: "Envelope body content here"
},
template_id: "77xxxxxxxxxxxxxxxxxxxxxxxxxx",
signers: [
{
embedded: true,
name: booking.listing.user.name,
email: booking.listing.user.email,
role_name: 'Host',
},
{
embedded: true,
name: booking.user.name,
email: booking.user.email,
role_name: 'Nomad',
}
],
custom_fields: custom_fields
)

Unfortunately, there are two different objects in the DocuSign system that essentially have the same name of "custom field." You're using the wrong one.
The two objects are:
1. Metadata custom data fields
These objects come in two flavors: textCustomFields and listCustomFields.
These objects can be set at the account level to require that every every (or some) envelopes sent include additional metadata at the envelope level.
The objects can also be set at the envelope level programmatically.
These "custom fields" are not visible to the signer. They are not fields (tabs) visible on the documents. They are associated with the envelope as additional metadata. These are the type of custom fields that your code example is using.
Adding/listing the custom fields set at the account level: docs.
Adding a custom metadata field to an envelope: use the customFields attribute of the envelope definition.
2. Customized tabs (fields)
A customized tab (called a 'field' in the DocuSign web tool) is a version of a DocuSign tab (text tab, sign here tab, date tab, etc) that has been customized. Then, later, instead of re-customizing another instance of the tab, the customized tab can be re-used.
This is what you want to use.
To use the API to list them, update them, etc: docs.
To use them in a document
Disclaimer: I'm reading the docs, I have not tried this. Please add a comment after you try it:
You will need the customTabId for the customized tab. Use the CustomTabs::list API call.
You also need to know the base tab type: Text, etc. Use the type value which is also returned by the CustomTabs::list API call.
Then, when creating your document, for each recipient who gets a customized, tab, create the tab as usual, but include the customTabId as part of the tab's definition. Eg, see the text tab object definition in Envelopes::create API call.

Related

How do I use entity listeners in TypeORM without using decorators?

I'm working on creating a users table. I want to be able to set the password field (which should ideally not be a saved field (not sure if typeorm allows that yet)) and on insert/update I want to look and see if the password field is set, if it is I want to save a new salt and a hashed password to the database instead. I found some thing that showed me how to do it with the #BeforeInsert entity listener, but i'm using javascript without decorators.
user.entity.js:
module.exports = new EntitySchema({
name: "User",
columns: {
id: { primary: true, type: "uuid", generated: "uuid" },
username: { type: "text", unique: true },
password: { type: "text"}, //i'd prefer this to be hashed_password and password to only be used in the listeners
salt: { type: "text" },
email: { type: "text", unique: true },
},
})

Elastalert Rules for slack integration (message formatting and Attachments)

I'm trying to use message formatting in slack. The Elastalert Testrule.yaml file is partially being parsed. The slack alert shows up with only slack_alert_fields and alert_text fields. I want to send attachments as well in the alerts.
How to use attachments or create buttons fort slack alerts?
es_host: elasticsearch
es_port: 9200
name: Test rule Alert
type: any
index: alerts-*
filter:
- term:
alertType.keyword: "New alert created"
alert:
- "slack"
slack_alert_fields:
- title: Network Name
value: networkName
short: true
- title: Alert Type
value: alertType
short: true
slack_actions:
- name: "network url"
text: "Network URL"
type: "button"
value: networkUrl
alert_text: |
alertData : {0}
alert_text_type: alert_text_only
alert_text_args: ["alertData"]
attachments: [
{
"fallback": "Required plain-text summary of the attachment.",
"color": "#37964f",
"pretext": "New alert created",
"title": alertData.reason ,
"fields": [
{
"title": "Network Name",
"value": networkName,
"short" : true
},
{
"title": "Timestamp",
"value": timestamp,
"short" : true
}
],
"actions": [
{
"name": "network url",
"text": "Network URL",
"type": "button",
"value": networkUrl
},
{
"name": "org_url",
"text": "Organization URL",
"type": "button",
"value": organizationUrl
}
]
}
]
slack_webhook_url:
- "https://hooks.slack.com/xxxxxxxxxxxxxxxxxxxxxxx"
Looking at the official documentation it appears that Elastalert does not support adding custom Slack attachments for alerts, because there is no property for it in the documentation.
In fact it seams that alerts are already formatted as attachment, which is why you can set a title and a title-URL. And also define additional "fields". Something that you can only do with attachments in Slack.
This also means that you can not specify buttons for your alerts (which are a special kind of attachments in Slack).
If you need this functionality I would suggest contacting the developer of Elastalert.

Embedded object in loopback model schema for Swagger

In the context of a remote method, I'm trying to define a model schema of a parameter passed in the body. This object looks like this:
{
name: "Alex",
credentials: {
user: "alex",
pass: "pass"
}
}
So, I have this code in my remote method definition:
MyModel.remoteMethod("postSomething", {
accepts: [
{arg: 'person', type: {
"name": "string",
"credentials": {
"type": "object",
"properties": {
"user": "string",
"pass: "string"
}
}
}, http: {source: 'body'}, required: true
}
],
.....
Unfortunatelly, the details of this embedded object (credentials) are not shown in the generated Swagger explorer. This is what I see:
{
"user": "string",
"credentials": {}
}
I've tried many different ways but I could not show the properties of the credentials object.
Any ideas?
Loopback 2.x
Edit: Note the following only works for Loopback 2.x, as the type registry changed in 3.x.
The problem is that the data you are providing needs to be on the type property for the nested value. This should work:
MyModel.remoteMethod('postSomething', {
accepts: [
{
arg: 'person',
type: {
name: 'string',
credentials: {
type: {
user: 'string',
pass: 'string'
}
}
},
http: {
source: 'body'
},
required: true
}
],
//...
This also works with arrays:
accepts: [
{
arg: 'Book',
type: {
title: 'string',
author: 'string',
pages: [{
type: {
pageNo: 'number',
text: 'string'
}
}]
}
}
],
// ...
Loopback 3.x
Since the model registry and strong remoting changed in Loopback 3.x to only allow string or array types, you can't really avoid creating a new model. If you would like to quickly 'inline' a model without going through the full process of adding the model json file, adding it to model-config.json etc. you can register it directly on the app:
app.registry.createModel('Person', {
firstName: 'string',
lastName: 'string'
}, { base: 'Model' });
You can set the base to one of your other models if you want to extend an existing model (e.g, add another property that is only accepted in the given remote method)
If you want to create the model without cluttering up your model registry, you can do so by calling createModel on loobpack itself:
const loopback = require('loopback')
const modl = loopback.createModel({
name: 'Person',
base: null,
properties: {
firstName: {
type: 'string',
id: true // means it won't have an id property
}
}
});
In both of the above examples, you refer to the model by name to attach it to the remote method:
accepts: [
{
arg: 'Person',
type: 'Person'
}
],
// ...
Note you will need to create a sub-model for every sub-property (e.g. credentials)
Loopback swagger only picks up the outer object ignoring the properties of the object.
If you want to show a nested object in the swagger docs for the request body, you will have to make nested model.
Assuming you have a model called as person. You have to create another model named "credentials" having properties user and password. Then define the relationship in your person model's config
{
"name": "Person",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {
"credentials": {
"type": "embedsOne",
"model": "credentials",
"property": "credentials",
"options": {
"validate": true,
"forceId": false
}
}
},
"acls": [],
"methods": {}
}
And add a reference to this model where you define your remote method
MyModel.remoteMethod("postSomething", {
accepts: [
{arg: 'person', type: {Person},
http: {source: 'body'}, required: true
}
],
To avoid "Treating unknown remoting type" warning make sure your model is marked as "public" inside your "model-config.json"

Custom envelope fields using Docusign REST API

I'm using the docusign_rest gem to integrate with the Docusign REST API in my rails application. I have created a custom envelope field in the Docusign admin called SFID. I need to pass an ID into SFID inside of the envelope. I'm getting the following error with my JSON code:
{"errorCode"=>"INVALID_REQUEST_BODY", "message"=>"The request body is missing or improperly formatted. Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'API_REST.Models.v2.customFields' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON object (e.g. {\"name\":\"value\"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.\r\nPath 'customFields', line 1, position 1073."}
My controller code:
#envelope_response = client.create_envelope_from_template(
status: 'sent',
email: {
subject: "The test email subject envelope",
body: ""
},
template_id: '90B58E8F-xxxxx',
custom_fields: [
{
textCustomFields: [
{
name: 'SFID',
value:'12345',
required: 'false',
show: 'true'
}
]
}
],
signers: [
...
The Docusign API explorer says the following is the correct way to push an envelope custom field:
{
"customFields": {
"textCustomFields": [
{
"value": "0101010101",
"required": "true",
"show": "true",
"name": "SFID"
},
{
"required": "true",
"show": "true"
}
]
}
}
The Docusign_rest gem says the following on custom envelope fields:
customFields - (Optional) A hash of listCustomFields and textCustomFields.
# Each contains an array of corresponding customField hashes.
# For details, please see: http://bit.ly/1FnmRJx
What formatting changes to I need to make to my controller code to get it to successfully push a custom envelope field?
You have an extra array in your customFields node.
Remove the [] array from your custom_fields:
#envelope_response = client.create_envelope_from_template(
status: 'sent',
email: {
subject: "The test email subject envelope",
body: ""
},
template_id: '90B58E8F-xxxxx',
custom_fields:
{
textCustomFields: [
{
name: 'SFID',
value:'12345',
required: 'false',
show: 'true'
}
]
},
signers: [
...
Also I'm assuming that your client.create_envelope_from_template is converting your _'s into a camelCased string. if that is not happening, then that also needs to change.

Update node key index in batch operation

Short
I can't get neo to update existing node properties in a batched rest op.
Long
I want to create a batch operation that inserts/updates a node inside an index. It should handle three use-cases:
if the node does not exist, insert it with the given properties set
if the node exists, update it's properties set with the new values, if any.
I'm using the batch operation api, I wrote a test where I'm issuing two requests:
Short
1. first one inserts the node and indexes it's properties
2. second one simply updates some properties of the node
Here's the first request:
[
{
"method": "POST",
"to": "/index/node/events?uniqueness=get_or_create",
"id": 1,
"body": {
"key": "id",
"value": "222222222",
"properties": {
"id": "222222222",
"type": "event-type"
}
}
},
{
"method": "POST",
"to": "/index/node/events",
"body": {
"uri": "{1}",
"key": "id",
"value": "222222222"
}
},
{
"method": "POST",
"to": "/index/node/events",
"body": {
"uri": "{1}",
"key": "type",
"value": "event-type"
}
} ]
And now the second one.
[
{
method: 'POST',
to: '/index/node/events?uniqueness=get_or_create',
id: 1,
body: {
key: 'id',
value: '222222222',
properties: {id: '222222222', type: 'event-type', title: 'SUPEREVENT'}
}
},
{
method: 'POST',
to: '/index/node/events',
body: {
uri: '{1}',
key: 'id',
value: '222222222'
}
},
{
method: 'POST',
to: '/index/node/events',
body: {
uri: '{1}',
key: 'type',
value: 'event-type'
}
},
{
method: 'POST',
to: '/index/node/events',
body: {
uri: '{
1
}',
key: 'title',
value: 'SUPEREVENT'
}
}
]
NOTE! that on the second request i'm adding and event title property with value SUPEREVENT. This does not get persisted nor indexed. Why? and how can I fix it?
Thank you,
Alex
From the doc:
URL Parameter uniqueness=get_or_create: Create a new node/relationship
and index it if no existing one can be found. If an existing
node/relationship is found, discard the sent data and return the
existing node/relationship.
So your second request's data will be discarded. You need to split each of your requests in two requests each, and do two batches. Each of the two batches has two instructions: first one creates the node if not present, and the second one updates the properties.

Resources