Conflict between key name formatting GET vs POST (camel vs underscore)

I've been building out a backup repository for our clients configurations. I've also been using that to build templates for deploying standard items. (Queues, Outbound rules, campaigns..etc etc)..

Using the most recent version of the library - (188.0.0)
When performing GET requests keys have their words separated with an underscore (e.g. "agent_owned_callbacks" (more standard for python)

I found that using that in a template wasn't applying the settings.
When I looked at API explorer I saw that the format for keys was a little different and used camel case.
E.g. "agentOwnedCallbacks" (more standard for java script, java and related) ---

I tried to do this with one of my templates and found it worked.. ...

Great that it works.. but this is terrible that the SDK outputs one format of field, but expects to receive it in another.

Writing a function to reformat all the keys is tedious and should not be required ...

This feels like a code change has forced the python SDK to only accept the camel case..

Is there a way to force the API to accept the underscore version OR retrieve in camel case?

If not --- has someone encountered this and already written a function to get around it

Hello, the Python SDK has models that serialize to and from the API's JSON schema as documented: https://developer.genesys.cloud/devapps/api-explorer. When working with the python models, you should use the property names as they exist on the model. If you wish to inspect the JSON representation of a model, use the built-in serializer api_client.sanitize_for_serialization(...).

Hi Tim,

I've been using the models as they are returned from the queries ..
Which is not the same as the POSTS require -

Try it - run a GET any GET .. and check the naming convention..

Try to run a POST using those exact same names and it will not work.

So storing the output of a GET cannot form the basis of a template or restore function

Please excuse my ignorance here for some of this.

When you say property names as they exist on the model.. This is where I see the problem.. It is not accepting those property names.

For example when creating a queue and submitting agent owned routing rules.. I originally did it as per the model..

E.g.. my body contained

    "agent_owned_routing": {
        "enable_agent_owned_callbacks": true,
        "max_owned_callback_hours": 168,
        "max_owned_callback_delay_hours": 720
    },

With all settings as per the model.

When I issued the POST the settings did not take.

When I rewrote my template in camelcase.. e.g.


    "agentOwnedRouting": {
        "enableAgentOwnedCallbacks": true,
        "maxOwnedCallbackHours": 168,
        "maxOwnedCallbackDelayHours": 720
    },

Then it took..

So - this is why I raised the case.. This appears to be a defect.. Which I raised in Support - but they deferred me back to here.

When you point to the serialisation function - is that something I can call - and will calling that myself fix my issues .. In which case what value do I need to push for "self" (please excuse my ignorance again)

cheers
Allan

I'm not sure why you would write a JSON object like that, but I can almost guarantee you that's not what the documentation says. I haven't seen you mention what resource you're using. If you can specify what API resource you're making a request to, I can point you to the documentation for that resource so you can create your JSON object per that documentation.

Hi Tim,

So that we can be on the same page and work through to a conclusion let me summarise my experience and where I think we may be. I'm more than happy to accept that I'm doing something wrong, but I really need to understand what that is. I am coming to this with decades of Genesys experience - but only a couple of years working with self taught python coding. So please bare this in mind.

I have 2 aims - based on the same methods..

  1. Create scripts to quickly build templated configurations - in this case queues.
  2. Create scripts that can restore/build objects from backups stored as json.

I am showing the 1st aim, as I need to resolve this issue - most likely where I'm going wrong to be able to achieve the 2nd aim.

----- The process I tried ---

  1. I called the get_routiing_queues() api and stored the results as JSON objects for queues we had built using the UI.
  2. I created a template using that exact format that was returned to be able to build additional queues with the same settings
  3. I built a script, with the ability to call that template but substitiute some values (e.g. name)
  4. running the script posted to the post_routing_queues() API with the SDK using the template above.
  5. Inspecting the built objects showed me that some settings did not reflect what was in the template
  6. I worked out elements that were not saving/being configured were one's which had 2 words in the element separated by an underscore
  7. Purely on a hunch (as no documentation suggested or supported this) .. I changed the elements in my template to be camel case.. and voila they worked.

Since then

  1. you suggested I follow the formatting in the python sdk.
  2. I confirmed that I followed the element naming in the same format
  3. I included snippets from my templates for the agent_owned_routing element of the queue (non working underscore format and working camelCase format)
  4. You've suggested there is something incorrect about the formatting in my templates - but I'm not exactly sure what.

I was trying to include as much information as necessary without overloading.
But as I haven't shown enough work - I'm posting as much as I can..

Firstly the relevant parts of the python sdk to get the element naming.

Here is the screenshot from the python sdk documentation for "Queue" showing the format for those elements.

Here is the screenshot for the Agent Owned Routing subseet.

Here is an example of the saved JSON from the get_routing_queues() API for a single queue. (but formatted with indentations to make it readable and id's removed )
This is what I used to format my "body" component to send.

{
    "name": "SalesOutbound_DUAL",
    "division": {
        "name": "Home",
        "self_uri": "/api/v2/authorization/divisions/"
    },
    "description": null,
    "date_created": "2023-10-23T04:33:04.907000+00:00",
    "date_modified": "2023-10-23T22:43:36.102000+00:00",
    "modified_by": "74d0b20b-3b09-47b6-9583-091056829d02",
    "created_by": "9f73e8dd-2030-449e-80c5-ff0b1e8584c2",
    "member_count": 3,
    "user_member_count": 3,
    "joined_member_count": 3,
    "media_settings": {
        "call": {
            "enable_auto_answer": null,
            "alerting_timeout_seconds": 8,
            "service_level": {
                "percentage": 0.8,
                "duration_ms": 20000
            },
            "auto_answer_alert_tone_seconds": null,
            "manual_answer_alert_tone_seconds": null,
            "sub_type_settings": null
        },
        "callback": {
            "enable_auto_answer": null,
            "alerting_timeout_seconds": 30,
            "service_level": {
                "percentage": 0.8,
                "duration_ms": 20000
            },
            "auto_answer_alert_tone_seconds": null,
            "manual_answer_alert_tone_seconds": null,
            "sub_type_settings": null
        },
        "chat": {
            "enable_auto_answer": null,
            "alerting_timeout_seconds": 30,
            "service_level": {
                "percentage": 0.8,
                "duration_ms": 20000
            },
            "auto_answer_alert_tone_seconds": null,
            "manual_answer_alert_tone_seconds": null,
            "sub_type_settings": null
        },
        "email": {
            "enable_auto_answer": null,
            "alerting_timeout_seconds": 300,
            "service_level": {
                "percentage": 0.8,
                "duration_ms": 86400000
            },
            "auto_answer_alert_tone_seconds": null,
            "manual_answer_alert_tone_seconds": null,
            "sub_type_settings": null
        },
        "message": {
            "enable_auto_answer": null,
            "alerting_timeout_seconds": 30,
            "service_level": {
                "percentage": 0.8,
                "duration_ms": 20000
            },
            "auto_answer_alert_tone_seconds": null,
            "manual_answer_alert_tone_seconds": null,
            "sub_type_settings": null
        }
    },
    "routing_rules": [
        {
            "operator": "ANY",
            "threshold": null,
            "wait_seconds": 30.0
        }
    ],
    "conditional_group_routing": null,
    "bullseye": null,
    "scoring_method": "TimestampAndPriority",
    "acw_settings": {
        "wrapup_prompt": "OPTIONAL",
        "timeout_ms": null
    },
    "skill_evaluation_method": "ALL",
    "member_groups": null,
    "queue_flow": null,
    "email_in_queue_flow": null,
    "message_in_queue_flow": null,
    "whisper_prompt": null,
    "on_hold_prompt": null,
    "auto_answer_only": false,
    "enable_transcription": null,
    "enable_manual_assignment": null,
    "agent_owned_routing": {
        "enable_agent_owned_callbacks": true,
        "max_owned_callback_hours": 168,
        "max_owned_callback_delay_hours": 720
    },
    "direct_routing": null,
    "calling_party_name": null,
    "calling_party_number": null,
    "default_scripts": {},
    "outbound_messaging_addresses": null,
    "outbound_email_address": null,
    "peer_id": null,
    "suppress_in_queue_call_recording": true,
    "self_uri": "/api/v2/routing/queues/"
}

So that you can see how this was written. Here are the relevant functions I've used.

Where queue_list below is the return from get_routing_queues()
Which returns a list of dictionaries, each item in the list being a queue in dictionary form.

def get_queue_config(role,name=None):
    #get the current config from the source env (function returns a list with one item)
    queue_list=get_queue_details(role,name)
    queue_names=[]
    queue_number = len(queue_list)
    for i in range (0,queue_number):
         queue_names.append(queue_list[i].name)
    return queue_names,queue_list,queue_number

get_queue_details is where I actually call the API
Ignore get_token_sdk - this is a separate function I've got for retrieving the token. Similarly 'role' is a construct I've created to be able to easily refer to different environments to enable migration of a configurations from non production to production environments, so isn't particularly relevant to my question.

def get_queue_details(role,name=None):
    api_key = get_token_sdk(role)
    if name==None:
        name=""
    api_instance = PureCloudPlatformClientV2.RoutingApi(api_key)
    queue_list=[]
    pages =  api_instance.get_routing_queues(name=name).page_count
    print ("Pages = ",  pages)
    for j in range(1,pages+1):
        try: 
            page=j
            print ("Page: ",j)
            api_response=api_instance.get_routing_queues(name=name,page_number=page)
            print ("Actual api response :",api_response.to_json())
            queue_list.extend(api_response.entities)
        except ApiException as e:
            print("Exception when calling RoutingApi->get_routing_queues: %s\n" % e)
            sys.exit(0)
    print (queue_list)
    return queue_list

Finally - how I'm writing the API response to file.

def export_configs(queue_names,queue_list,queue_number):
    for i in range (0,queue_number):
        q_name=queue_names[i]
        q_filename=(path.join(repoFolder,q_name+".json")).replace(" ","_")
        #print(q_filename)
        q_json=queue_list[i].to_json()
        #print(q_json)
        with open(q_filename,"w") as outfile:
            outfile.write(q_json)

Each queue getting a separate file and for easy reference. The file name has spaces replaced with underscores...

Here is my original template file.. (note Australian/UK spelling used for elements that aren't actually POSTED or for names)

{
    "dialler": {
        "WebCallback": {
            "division": {
                "name": "Home"
            },
            "description": null,
            "media_settings": {
                "call": {
                    "enable_auto_answer": null,
                    "alerting_timeout_seconds": 8,
                    "service_level": {
                        "percentage": 0.8,
                        "duration_ms": 20000
                    },
                    "auto_answer_alert_tone_seconds": null,
                    "manual_answer_alert_tone_seconds": null,
                    "sub_type_settings": null
                },
                "callback": {
                    "enable_auto_answer": null,
                    "alerting_timeout_seconds": 30,
                    "service_level": {
                        "percentage": 0.8,
                        "duration_ms": 20000
                    },
                    "auto_answer_alert_tone_seconds": null,
                    "manual_answer_alert_tone_seconds": null,
                    "sub_type_settings": null
                },
                "chat": {
                    "enable_auto_answer": null,
                    "alerting_timeout_seconds": 30,
                    "service_level": {
                        "percentage": 0.8,
                        "duration_ms": 20000
                    },
                    "auto_answer_alert_tone_seconds": null,
                    "manual_answer_alert_tone_seconds": null,
                    "sub_type_settings": null
                },
                "email": {
                    "enable_auto_answer": null,
                    "alerting_timeout_seconds": 300,
                    "service_level": {
                        "percentage": 0.8,
                        "duration_ms": 86400000
                    },
                    "auto_answer_alert_tone_seconds": null,
                    "manual_answer_alert_tone_seconds": null,
                    "sub_type_settings": null
                },
                "message": {
                    "enable_auto_answer": null,
                    "alerting_timeout_seconds": 30,
                    "service_level": {
                        "percentage": 0.8,
                        "duration_ms": 20000
                    },
                    "auto_answer_alert_tone_seconds": null,
                    "manual_answer_alert_tone_seconds": null,
                    "sub_type_settings": null
                }
            },
            "routing_rules": [
                {
                    "operator": "ANY",
                    "threshold": null,
                    "wait_seconds": 30.0
                }
            ],
            "conditional_group_routing": null,
            "bullseye": null,
            "scoring_method": "TimestampAndPriority",
            "acw_settings": {
                "wrapup_prompt": "MANDATORY",
                "timeout_ms": null
            },
            "skill_evaluation_method": "NONE",
            "member_groups": null,
            "queue_flow": {
                "name": "Red_NextGen_Unified_InQueue_Flow"
            },
            "email_in_queue_flow": null,
            "message_in_queue_flow": null,
            "whisper_prompt": null,
            "on_hold_prompt": null,
            "auto_answer_only": false,
            "enable_transcription": true,
            "enable_manual_assignment": null,
            "agent_owned_routing": {
                "enable_agent_owned_callbacks": true,
                "max_owned_callback_hours": 1,
                "max_owned_callback_delay_hours": 2
            },
            "direct_routing": null,
            "calling_party_name": null,
            "calling_party_number": null,
            "default_scripts": {},
            "outbound_messaging_addresses": null,
            "outbound_email_address": null,
            "peer_id": null,
            "suppress_in_queue_call_recording": true
        }
    }
}

Now for the relevant code for preparing the body from the template.

def import_template():
    #import the list template from the outbound.json file
    #global  g_temp,camp_elements
    file= open ("templates/queues.json")
    json_data = json.load(file)
    #print(json_data)
    #convert to python dictionaries
    q_temp=json_data.get(q_function)
    q_template=q_temp.get(template)
    #check validity of dictionary entry 
    if type(q_temp)!=dict:
        print("The template you have requested doesn't exist in queues.json file")
        exit(2)
    # get the list part of the template 

    file.close
    return q_template

... I then add values where necessary, not all error trapping added yet ..

e.g.

def configure_queue(q_template):
    q_config=q_template
    ##get configs from template names and environment 
    division_name=q_template['division']['name']
    division_id = get_div_id(role,division_name)
    if division_id == -1:
        print ("Error: A division with the name ", division_name," doesn't exist in the environment")
    q_flow_name=q_template['queue_flow']['name']
    print(q_flow_name)
    q_flow_id=get_unique_flow_id(role,q_flow_name)
    print(q_flow_id)
    voice_script_name=q_template["default_scripts"]["CALL"]["name"]
    voice_script_id=get_unique_script_id(role,voice_script_name)
    print ("Voice Script \n Name: ",voice_script_name,"\n ID: ", voice_script_id)
    # assign configs to q_config 
    q_config["division"]["id"]=division_id
    q_config["name"]=queue_name
    q_config["default_scripts"]["CALL"]["id"]=voice_script_id
    del q_config["default_scripts"]["CALL"]["name"]
    q_config["queue_flow"]["id"]=q_flow_id
    #print(q_config)
    return q_config

The result of which gets submitted as the body via the following

def create_queue(role,body):
    api_key = get_token_sdk(role)
    api_instance = PureCloudPlatformClientV2.RoutingApi(api_key) 
    try:
    # Create a queue
        api_response = api_instance.post_routing_queues(body)
        print (api_response)
        return api_response.id
        
    except ApiException as e:
        print("Exception when calling RoutingApi->post_routing_queues: %s\n" % e)   
        sys.exit(0)

So now for the working template... I've only changed configs I'm particularly concerned with at this point so there are still many elements with the underscore naming

{
    "dialler": {
        "WebCallback": {
            "division": {
                "name": "Home"
            },
            "description": null,
            "mediaSettings": {
                "call": {
                    "enableAutoAnswer": true,
                    "alertingTimeoutSeconds": 8,
                    "serviceLevel": {
                        "percentage": 0.8,
                        "durationMs": 20000
                    },
                    "autoAnswerAlertToneSeconds": null,
                    "manualAnswerAlertToneSeconds": null,
                    "subTypeSettings": null
                },
                "callback": {
                    "enableAutoAnswer": null,
                    "alertingTimeoutSeconds": 30,
                    "serviceLevel": {
                        "percentage": 0.8,
                        "durationMs": 20000
                    },
                    "autoAnswerAlertToneSeconds": null,
                    "manualAnswerAlertToneSeconds": null,
                    "subTypeSettings": null
                },
                "chat": {
                    "enableAutoAnswer": null,
                    "alertingTimeoutSeconds": 30,
                    "serviceLevel": {
                        "percentage": 0.8,
                        "durationMs": 20000
                    },
                    "auto_answer_alert_tone_seconds": null,
                    "manual_answer_alert_tone_seconds": null,
                    "sub_type_settings": null
                },
                "email": {
                    "enableAutoAnswer": null,
                    "alertingTimeoutSeconds": 300,
                    "serviceLevel": {
                        "percentage": 0.8,
                        "durationMs": 86400000
                    },
                    "autoAnswerAlertToneSeconds": null,
                    "manualAnswerAlertToneSeconds": null,
                    "subTypeSettings": null
                },
                "message": {
                    "enableAutoAnswer": null,
                    "alertingTimeoutSeconds": 30,
                    "serviceLevel": {
                        "percentage": 0.8,
                        "durationMs": 20000
                    },
                    "autoAnswerAlertToneSeconds": null,
                    "manualAnswerAlertToneSeconds": null,
                    "subTypeSettings": null
                }
            },
            "routingRules": [
                {
                    "operator": "ANY",
                    "waitSeconds": 30.0
                }
            ],
            "conditional_group_routing": null,
            "bullseye": null,
            "scoringMethod": "TimestampAndPriority",
            "acwSettings": {
                "wrapupPrompt": "MANDATORY",
                "timeout_ms": null
            },
            "skill_evaluation_method": "NONE",
            "member_groups": null,
            "queueFlow": {
                "name": "RedEnergy_InQueue_Outbound_DUAL_V0.1"
            },
            "email_in_queue_flow": null,
            "message_in_queue_flow": null,
            "whisper_prompt": null,
            "on_hold_prompt": null,
            "auto_answer_only": false,
            "enable_transcription": true,
            "enable_manual_assignment": null,
            "agentOwnedRouting": {
                "enableAgentOwnedCallbacks": true,
                "maxOwnedCallbackHours": 168,
                "maxOwnedCallbackDelayHours": 720
            },
            "direct_routing": null,
            "calling_party_name": null,
            "calling_party_number": null,
            "defaultScripts": {
                "CALL":{
                    "name":"DefaultOutbound_RED2.1"
                }
            },
            "outbound_messaging_addresses": null,
            "outbound_email_address": null,
            "peer_id": null,
            "suppress_in_queue_call_recording": true
        }
    }
}

I've also changed the function that adds in the necessary data to match this format.

def configure_queue(q_template):
    q_config=q_template
    ##get configs from template names and environment 
    division_name=q_template['division']['name']
    division_id = get_div_id(role,division_name)
    if division_id == -1:
        print ("Error: A division with the name ", division_name," doesn't exist in the environment")
    q_flow_name=q_template['queueFlow']['name']
    print(q_flow_name)
    q_flow_id=get_unique_flow_id(role,q_flow_name)
    print(q_flow_id)
    voice_script_name=q_template["defaultScripts"]["CALL"]["name"]
    voice_script_id=get_unique_script_id(role,voice_script_name)
    print ("Voice Script \n Name: ",voice_script_name,"\n ID: ", voice_script_id)
    # assign configs to q_config 
    q_config["division"]["id"]=division_id
    q_config["name"]=queue_name
    q_config["defaultScripts"]["CALL"]["id"]=voice_script_id
    del q_config["defaultScripts"]["CALL"]["name"]
    q_config["queueFlow"]["id"]=q_flow_id
    print(json.dumps(q_config))
    return q_config

So, I'd much prefer to use the naming convention as per the sdk - but need to know what I'm doing wrong that is forcing me to use camel case.

I can't see what I may be doing wrong, but it does seem that I can't post a template in the same format that the GET requests are responding with. Hence why I suspected there may be a defect.

Lastly --

I've based the code on calling the API in my create_queue function from the API Explorer, Python SDK example

BUT maybe this is leading me down the wrong path and there is a different way I should be calling this API..

e.g. the
"create_queue_request" instead of "post_routing_queues" .. .

Probably because I am relatively new to this, it isn't clearly obvious how to use this method. Including how to send the token.

If that's the case - maybe just a clear example of how to use that method would inform me how I could use my stored templates and configs retrieved)

OKAY ---

I read my own posts and I have worked out how to use the create_queue_request by looking at the Python SDK example again..

I will post that method below as reference.

So I can close the loop for what I'm trying to achieve though I have one question.

Is there a way/function to re-format the returned object from a python sdk get method as the exact JSON schema expected by the API (camelCase)?

(As simply applying .to_json() returns the keys with the element naming in the SDK and not the JSON schema)


SO -- how to do it - using the create_queue_request and post_routing_queues methods from the SDK

#import functions 
import PureCloudPlatformClientV2
from PureCloudPlatformClientV2.models import CreateQueueRequest,AgentOwnedRouting

#get token 
api_client = PureCloudPlatformClientV2.api_client.ApiClient().get_client_credentials_token(CLIENT_ID, CLIENT_SECRET)

#initiate API instance 
api_instance=PureCloudPlatformClientV2.RoutingApi(apiclient)


#setup the body using the sdk instead of raw input 

name= "anotherskillTest"
AgentOwnedRouting.enable_agent_owned_callbacks=True
AgentOwnedRouting.max_owned_callback_delay_hours=300
AgentOwnedRouting.max_owned_callback_hours=24
CreateQueueRequest.name=name
CreateQueueRequest.description='are you kidding me'
CreateQueueRequest.agent_owned_routing=PureCloudPlatformClientV2.AgentOwnedRouting()

#apply model to variable 
body=CreateQueueRequest()

#apply body to api call via sdk method 
api_response=api_instance.post_routing_queues(body)

#print response for confirmation 
print (api_response)

Hi,

I tried to use the utils version of sanitize_for_serialization function from utils, but this didn't seem to do anything to the formatting.
I'm not sure how to use the same from the api_client.

Pretty sure this is where you were pointing me to at the start...

Cheers

Allan

Yes:

You can see where/how it's used a few lines above: https://github.com/MyPureCloud/platform-client-sdk-python/blob/master/build/PureCloudPlatformClientV2/api_client.py#L324

And you can see where/how call_api is invoked from the public function you're calling here: https://github.com/MyPureCloud/platform-client-sdk-python/blob/master/build/PureCloudPlatformClientV2/apis/routing_api.py#L4447


This function returns a JSON string. Can you share the exact output string this function gives you?

1 Like

Ok - it works ..

I was trying it on a saved template/object and that didn't work ..

I tried it on a campaign in the environment and it works perfectly ..

So I can use this to create JSON templates from existing objects and for storing configs..

role="devOutboundRed"

camp=get_campaign_details(role,'Sales_WebCallback_DUAL')

post_body = sanitize_for_serialization(camp)

print(post_body)

and here is the print

[{'id': '', 'name': 'Sales_WebCallback_DUAL', 'dateCreated': '2023-10-23T04:35:00.303000+00:00', 'dateModified': '2023-10-29T22:50:34.115000+00:00', 'version': 128, 'contactList': {'id': '', 'name': 'Sales_WebCallback_DUAL', 'selfUri': '/api/v2/outbound/contactlists/1a015e60d8fb2'}, 'queue': {'id': '0f2e8ad3d94f014', 'name': 'SalesOutbound_DUAL', 'selfUri': '/api/v2/routing/queues/4'}, 'dialingMode': 'progressive', 'script': {'id': '32f44', 'name': 'DefaultOutbound_RED', 'selfUri': '/api/v2/scripts/published/35-b'}, 'site': {'id': 'b99ef', 'name': 'Melbourne', 'selfUri': '/api/v2/telephony/providers/edges/sites/'}, 'campaignStatus': 'off', 'phoneColumns': [{'columnName': 'Phone1', 'type': 'cell'}], 'abandonRate': 5.0, 'dncLists': [], 'callableTimeSet': {'id': '4', 'name': 'WebCallBack_Default', 'selfUri': '/api/v2/outbound/callabletimesets/4d'}, 'callAnalysisResponseSet': {'id': 'c6f', 'name': 'SalesOutbound_WebCallback', 'selfUri': '/api/v2/outbound/callanalysisresponsesets/c61f'}, 'callerName': '', 'callerAddress': '0', 'outboundLineCount': 0, 'ruleSets': [{'id': '5dffe1e5bd0', 'name': 'SetCallerName_WebCallback', 'selfUri': '/api/v2/outbound/rulesets/'}, {'id': '', 'name': 'Sales_WebCallback_Testing_new', 'selfUri': '/api/v2/outbound/rulesets/'}], 'skipPreviewDisabled': False, 'previewTimeOutSeconds': 0, 'alwaysRunning': False, 'noAnswerTimeout': 30, 'priority': 5, 'contactListFilters': [], 'division': {'id': '', 'name': 'Home', 'selfUri': '/api/v2/authorization/divisions/'}, 'dynamicContactQueueingSettings': {'sort': False}, 'selfUri': '/api/v2/outbound/campaigns/5eb08dee-ab649'}]

Sorry about all the confusion -- hopefully all my examples here give others something to work with

:face_with_diagonal_mouth:

Hi Allan,

I was reading your post and it seems like you are using scripts to manage the configuration of your Genesys Cloud organization. Have you taken a look at our CX as Code terraform provider? CX as Code allows you to define in plain old text (HCL or JSON) and then deploy via Terraform. In addition, our CX as Code provider can export Genesys Config in JSON or HCL.

If you haven't taken a look at CX as Code, I suggest you look at here. You can also look at our provider documentation that shows the Genesys objects that are currently supported.

Thanks,
John Carnell
Director, Developer Engagement

Hi John,

Yes I've looked at that, but much earlier on for templating callflows using Archy.

I didn't go with that at that point, as the requirement was that callflows be editable in Architect but also allow easy changes va datatables (as opposed to archy variable substitution).. I was also instructed to ensure I had a system that could still allow the business to configure things via data tables (for callflows) or the provided objects (e.g. queue setups).. But provide an automated way to migrate from non production to production.

I will definitely re-investigate the CX as Code method. I'm interested know that Terraform has become non-gpl if you will migrate to, or support OpenTofu or another alternative..

But yes ..we do use Archy for backup storage and deployment of the callflows themselves.

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.