3

I want to create a new custom field on a custom object on SalesForce.

The custom field type shall be of type 'picklist' (non-global) with a predefined set of values.

I want to use the Salesforce tooling REST API, calling from python via simple-salesforce package.

I can already create a field of type 'Text' successfully - however I'm failing to create a 'picklist'-type field with some initial picklist values. Does anyone know which exact meta information is required to create a picklist field?

Details:

I am using simple-salesforce package to connect to my Salesforce instance

import simple_salesforce

sf = simple_salesforce.Salesforce(
  'username': 'myusername@mysforg.nowhere',
  'password': 'mypersonalpassword',
  'security_token': 'mysecuritytoken',
  'domain': 'test'  # I am running on a sandbox
)

The following REST API call can be used to create custom fields

url = 'tooling/sobjects/CustomField/'
object_api_name = 'MyCustomObject__c'
field_api_name = 'MyNewCustomField__c'

d_meta = {...to be defined...}  # see below

d_payload = {
    'FullName':'%s.%s' % (object_api_name, field_api_name),
    'Metadata':d_meta,
}
  
result = sf.restful(url, method='POST', json=d_payload)

I successfully created a new custom field of type 'Text' on my custom object using the following meta data

# WORKING: Meta input for custom field type 'Text'
d_meta = {
  'type': 'Text',
  'inlineHelpText': 'inline HelpText',
  'label': 'Text Field Test',
  'length': 255,
  'required': True
}

For a custom field of type 'picklist' however I simply cannot figure out which input values are required to define the picklist values. From analyzing the meta data of an existing picklist field, I found the meta info 'picklistValues' present with a list of dictionaries of picklist values with following information.

# NOT WORKING: Meta input for custom field type 'picklist' and 'picklistValues' metaData
d_meta = {
    'type': 'picklist',
    'label': 'PicklistFieldTest',
    'picklistValues':  [
        {
            'defaultValue': False,
            'active': True,
            'label': 'TestValue1',
            'value': 'TestValue1'
        },{
            'defaultValue': False,
            'active': True,
            'label': 'TestValue2',
            'value': 'TestValue2'
        }
    ]
}

This however gives me the error

SalesforceMalformedRequest:
Malformed request https://mysforg.my.salesforce.com/services/data/v42.0/tooling/sobjects/CustomField/.
Response content: [{
'message': 'Cannot deserialize instance of complexvalue from VALUE_STRING value picklist or request may be missing a required field at [line:1, column:15]',
'errorCode': 'JSON_PARSER_ERROR'
}]

Alternative using another synatx I found online using meta information on 'valueSet' doesn't succeed either

# NOT WORKING: Meta input for custom field type 'picklist' and 'valueSet' metaData
d_meta = {
    'type': 'picklist',
    'label': 'PicklistFieldTest',
    'valueSet': {
        'valueSetDefinition': {        
            'value': [
                {
                    'default': False,
                    'isActive': True,
                    'label': 'TestValue1',
                    'valueName': 'TestValue1'
                },{
                    'default': False,
                    'isActive': True,
                    'label': 'TestValue2',
                    'valueName': 'TestValue2'
                }
            ],
            'sorted': True
        }
    }    
}

Any clou which meta data information is required to create picklist field?

1 Answer 1

2

After searching and testing two days, finally posting here and searching on I now found the working solution.

So the following code connects to Salesforce Org and adds a new custom field MyNewCustomField__c to an existing custom object MyCustomObject__c as type Picklist with name/label MyNewCustomField with two picklist entries with values TestLabel<i> and API name TestFullName<i>.

import simple_salesforce

# connect to Salesforce
sf = simple_salesforce.Salesforce(
  'username': 'myusername@mysforg.nowhere',
  'password': 'mypersonalpassword',
  'security_token': 'mysecuritytoken',
  'domain': 'test'  # I am running on a sandbox
)

# ingestion setup
url = 'tooling/sobjects/CustomField/'
object_api_name = 'MyCustomObject__c'
field_api_name = 'MyNewCustomField__c'

# meta data for MyNewCustomField
d_meta = {
    'label': 'MyNewCustomField',
    'required': True,
    'type': 'Picklist',
    'inlineHelpText': 'Inline Helptext',  
    'valueSet': {
        'restricted': True,
        'valueSetDefinition': {
            'sorted': False,

            # picklist entries
            'value': [        
                {
                    'fullName': 'TestFullName1',
                    'default': True,
                    'label': 'TestLabel1'
                },{
                    'fullName': 'TestFullName2',
                    'default': False,
                    'label': 'TestLabel2'
                }
            ]
        }
    }
}

# build payload
d_payload = {
    'FullName':'%s.%s' % (object_api_name, field_api_name),
    'Metadata':d_meta,
}

# execute POST request
result = sf.restful(url, method='POST', json=d_payload)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.