Unable to use transferToVoicemail task actions with Archy

Hi there,
I am trying to use the transferToVoicemail in a task and Archy will not validate. Here is the transferToVoicemail as I am trying to use it (in the below example, Task.voicemailQueue is a queueVariable):

- transferToVoicemail:

                                                name: Transfer to VM

                                                destination:

                                                    queue:

                                                        targetQueue:

                                                            exp: "Task.voicemailQueue"

Archy errors out the following:

  • ERROR! ArchSession.startWithClientIdAndSecret - Caught unhandled exception during callback function execution. Ending session. Exception info: - Parameter 'expressionText' in 'ArchValueGroup.setExpression' is invalid. Reason: ERROR! you cannot assign the expression text 'Task.voicemailQueue' because this value [IsOutput:false, CanBeExpression:true, CanBeLiteral:true, CanBeNoValue:false, CanBeVariable:false, isReadable:false, isWritable:false] is not writable.

Of course the same directly in Architect works just fine.

Can somebody help, it is holding me back pretty badly right now.

Hi Aurelien,

We're having some trouble reproducing the behavior you detailed, so I have a few questions for you. What type of call flow are you doing this in? How is the queue variable being created? Are you able to share more of your transferToVoicemail action YAML, and potentially more of your flow? If you're uncomfortable posting it in public, you could DM it to me as well.

Thanks,
Scott

Hi Scott,
Thanks for looking into this. More than happy to share more of the flow, and I will send you a link to the actual file in DM.
Things to note. This is part of some shared logic so the opening tag for the file is "common". Also, the flow this shared logic is used in is inboundCall.

Here is an excerpt:

handleOOB.yaml

common:

    tasks:

        ## HANDLE OOB / HOLIDAY ##

        ## This task's purpose is to handle a call in OOB / Holiday scenario

        ## inputs: 

        ##     - Flow.calltype -> the queue to handle

        ## outputs:

        ##     

        - task:

            name: Handle OOB

            refId: handleOOB

            variables:

                - stringVariable:

                    name: Task.oob_action

                - stringVariable:

                    name: Task.oob_message

                - stringVariable:

                    name: Task.holiday_message

                - stringVariable:

                    name: Task.voicemail

                - stringVariable:

                    name: Task.external_number

                - stringVariable:

                    name: Task.datatable_errorType

                - stringVariable:

                    name: Task.datatable_errorMessage

                - queueVariable:

                    name: Task.voicemailQueue

            actions:
            ...
                               - findQueue:

                                                findName:

                                                    exp: Flow.queue

                                                findResult:

                                                    var: Task.voicemailQueue

                                                outputs:

                                                    notFound:

                                                        actions:

                                                            - updateData:

                                                                name: Set Failure Message

                                                                statements:

                                                                    - string:

                                                                        value:

                                                                            lit: '[Deliver To Queue / Find Queue]'

                                                                        variable: Flow.failureStep

                                                                    - string:

                                                                        value:

                                                                            lit: 'Delivery queue not found.'

                                                                        variable: Flow.failureMessage

                                                            - jumpToTask:

                                                                name: Handle Queue Not Found Failure

                                                                targetTaskRef: /inboundCall/tasks/task[handleFailure]

                                            - transferToVoicemail:

                                                name: Transfer to VM

                                                refId: tfVm

                                                destination:

                                                    queue:

                                                        targetQueue:

                                                            exp: Task.voicemailQueue

                                                        callbackNumber:

                                                            exp: 'ToPhoneNumber(Call.ANI)'

                                                        voicemailGreeting:

                                                            audio:

                                                                exp: 'ToAudioBlank(0)'

This shared logic is injected in the inboundCall like the following and it then referenced where it needs to be used by /inboundCall/tasks/task[handleOOB]:

inboundCall:
    ....   
    tasks:
        ....
        # Inject common task: Handle OOB
        - refArray: ../shared/handleOOB.yaml#/common/tasks

Goes without saying that it works perfectly as long as I am not using a transferToVoicemail action.
Hope you can help :slight_smile:

Hi Scott,
sorry I am unsure of how to DM you? I don't think I have the relevant privileges to do so.

Is the content of the above reply enough for you to help out?
FYI, I tried to do the simplest of YAML file to see if that would work, and it doesn't:

inboundCall:
    name: Test Transfer VM
    defaultLanguage: en-au
    settingsActionDefaults:
        callBridge:
            processingPrompt:
                noValue: true
        callData:
            processingPrompt:
                noValue: true
    initialGreeting:
        exp: ToAudioBlank(0)
    startUpRef: ./tasks/task[tfVm]
    variables:
        - queueVariable:
            name: Flow.voicemailQueue
    tasks:
        - task:
            name: Transfer to VM
            refId: tfVm
            actions:
                - transferToVoicemail:
                    name: Transfer to VM
                    destination:
                        queue:
                            targetQueue:
                                exp: Flow.voicemailQueue
                            callbackNumber:
                                exp: "ToPhoneNumber(Call.ANI)"
                            voicemailGreeting:
                                audio:
                                    exp: "ToAudioBlank(0)"

Archy gives me the same error:
- ERROR! ArchSession.startWithClientIdAndSecret - Caught unhandled exception during callback function execution. Ending session. Exception info: - Parameter 'expressionText' in 'ArchValueGroup.setExpression' is invalid. Reason: ERROR! you cannot assign the expression text 'Flow.voicemailQueue' because this value [IsOutput:false, CanBeExpression:true, CanBeLiteral:true, CanBeNoValue:false, CanBeVariable:false, isReadable:false, isWritable:false] is not writable.

I am really confused. A transferToAcd works fine, with the targetQueue element being of the same type of the one in transferToVoicemail.

Help :slight_smile:

Alternatively, I am curious to see how you did try to replicate the issue to see if that would work on my side?

Hi Aurelien_Plancque,

We found a bug in Archy with how the transferToVoicemail action handles expressions on the targetQueue property, and we have a fix incoming. It will be included in the next version of Archy, which we hope to have out by sometime next week. Thanks for finding the issue!

Thanks,
Jon

Hi Jon,
great news. Happy to help. Looking forward the next version then. Would you be able to post back here once the new version is released?

Hi Aurelien_Plancque,

Yeah, I'll post in this topic once this new version has been released!

Thanks,
Jon

Hi Aurelien_Plancque,

The latest version of Archy is now available and can be upgraded using the command archy version latestPublished.

Thanks,
Jon

Thanks Jon. I think this release introduced a bigger defect though. I believe that Archy is now very confused when I insert shared logic by doing the following:

  • actions:

                                          - updateData:
    
                                              name: Update End Reason
    
                                              statements:
    
                                                  - string:
    
                                                      value:
    
                                                          lit: '{{end_reason_oob_default}}'
    
                                                      variable: Flow.endReason
    
                                          # Inject common action: Set End Reason
    
                                          - refArray: ./commonTasks.yaml#/common/tasks/task[setEndReason]/actions
    

I am doing a lot of these. It builds fine with 1.0.0. Building the same set of YAML files with 1.1.0 gives me a random:

example of build 1:

pre-processor - duplicate reference id of '__archy_setParticipantData_103__' was found within the YAML file. Please verify that all reference ids are unique within the array '/inboundCall/tasks/task[handleOOB]/actions/switch[__archy_switch_127__]/evaluate/firstMatch/string/cases/case/actions'.
    Path: '/inboundCall/tasks/task[handleOOB]/actions/switch[__archy_switch_127__]/evaluate/firstMatch/string/cases/case/actions'
    Property name: 'refId'

If I build multiple times, the error specifies a different path (which is why I believe Archy get confused about the auto generated refId). I specifically thinks it is happening if you use the same shared logic twice in the same YAML.
Here is the full YAML for reference:

common:

    tasks:

        ## HANDLE OOB / HOLIDAY ##

        ## This task's purpose is to handle a call in OOB / Holiday scenario

        ## inputs: 

        ##     - Flow.calltype -> the queue to handle

        ## outputs:

        ##     

        - task:

            name: Handle OOB

            refId: handleOOB

            variables:

                - stringVariable:

                    name: Task.oob_action

                - stringVariable:

                    name: Task.oob_message

                - stringVariable:

                    name: Task.holiday_message

                - stringVariable:

                    name: Task.voicemail

                - stringVariable:

                    name: Task.external_number

                - stringVariable:

                    name: Task.datatable_errorType

                - stringVariable:

                    name: Task.datatable_errorMessage

                - queueVariable:

                    name: Task.voicemailQueue

            actions:

                - dataTableLookup:

                    name: DT - Lookup Queue OOB Configuration

                    lookupValue:

                        exp: Flow.calltype

                    dataTable:

                        Calltype OOB:

                            failureOutputs:

                                errorType: 

                                    var: Task.datatable_errorType

                                errorMessage: 

                                    var: Task.datatable_errorMessage

                            foundOutputs:

                                oob_action:

                                    var: Task.oob_action

                                oob_message:

                                    var: Task.oob_message

                                holiday_action:

                                    var: Task.holiday_action

                                holiday_message:

                                    var: Task.holiday_message

                                voicemail:

                                    var: Task.voicemail

                                external_number:

                                    var: Task.external_number

                    outputs:

                        notFound:

                            actions:

                                - updateData:

                                    name: Set Failure Message

                                    statements:

                                        - string:

                                            value:

                                                lit: '[Handle OOB / Lookup OOB Configuration]'

                                            variable:

                                                Flow.failureStep

                                        - string:

                                            value:

                                                exp: 'Append("Configuration not found for queue ", Flow.queue, " in DT Queue OOB")'

                                            variable: Flow.failureMessage

                                - jumpToTask:

                                    name: Handle Transfer to ACD Failure

                                    targetTaskRef: /inboundCall/tasks/task[handleFailure]

                        failure:

                            actions:

                                - updateData:

                                    name: Set Failure Message

                                    statements:

                                        - string:

                                            value:

                                                lit: '[Handle OOB / Lookup OOB Configuration]'

                                            variable:

                                                Flow.failureStep

                                        - string:

                                            value:

                                                exp: 'Append("Error while looking up Data Table: Calltype OOB", " - message: ", Task.datatable_errorMessage)'

                                            variable: Flow.failureMessage

                                - jumpToTask:

                                    name: Handle Transfer to ACD Failure

                                    targetTaskRef: /inboundCall/tasks/task[handleFailure]

                - setParticipantData:

                    name: Set OOB Reason

                    attributes:

                        - attribute:

                            name: 

                                lit: 'OOB Reason'

                            value:

                                exp: Flow.ivr_state

                - decision:

                    name: Closed or Holiday

                    condition:

                        exp: Flow.ivr_state == "closed"

                    outputs:

                        yes:

                            actions:

                                - playAudio:

                                    audio:

                                        exp: ToAudioTTS(Task.oob_message)

                        no:

                            actions:

                                - playAudio:

                                    audio:

                                        exp: ToAudioTTS(Task.holiday_message)

                - switch:

                    name: Evaluate Task.oob_action

                    evaluate:

                        firstMatch:

                            string:

                                value:

                                    exp: Task.oob_action

                                cases:

                                    - case:

                                        value:

                                            lit: 'voicemail'

                                        actions:

                                            - updateData:

                                                name: Update End Reason

                                                statements:

                                                    - string:

                                                        value:

                                                            lit: '{{end_reason_oob_voicemail}}'

                                                        variable: Flow.endReason

                                            # Inject common action: Set End Reason

                                            - refArray: ./commonTasks.yaml#/common/tasks/task[setEndReason]/actions

                                            - findQueue:

                                                findName:

                                                    exp: Flow.queue

                                                findResult:

                                                    var: Task.voicemailQueue

                                                outputs:

                                                    notFound:

                                                        actions:

                                                            - updateData:

                                                                name: Set Failure Message

                                                                statements:

                                                                    - string:

                                                                        value:

                                                                            lit: '[Deliver To Queue / Find Queue]'

                                                                        variable: Flow.failureStep

                                                                    - string:

                                                                        value:

                                                                            lit: 'Delivery queue not found.'

                                                                        variable: Flow.failureMessage

                                                            - jumpToTask:

                                                                name: Handle Queue Not Found Failure

                                                                targetTaskRef: /inboundCall/tasks/task[handleFailure]

                                            

                                            # - transferToVoicemail:

                                            #     name: Transfer to VM

                                            #     refId: tfVm

                                            #     destination:

                                            #         queue:

                                            #             targetQueue:

                                            #                 exp: Task.voicemailQueue

                                            #             callbackNumber:

                                            #                 exp: 'ToPhoneNumber(Call.ANI)'

                                            #             voicemailGreeting:

                                            #                 audio:

                                            #                     exp: 'ToAudioBlank(0)'

                                    - case:

                                        value:

                                            lit: 'transfer'

                                        actions:

                                            - updateData:

                                                name: Update End Reason

                                                statements:

                                                    - string:

                                                        value:

                                                            lit: '{{end_reason_oob_external}}'

                                                        variable: Flow.endReason

                                            # Inject common action: Set End Reason

                                            - refArray: ./commonTasks.yaml#/common/tasks/task[setEndReason]/actions

                                            - transferToNumber:

                                                name: Transfer To External

                                                targetNumber:

                                                    exp: Task.external_number

                                                failureOutputs:

                                                    errorMessage:

                                                        var: Flow.failureMessage

                                                outputs:

                                                    failure:

                                                        actions:

                                                            - updateData:

                                                                name: Set Failure Message

                                                                statements:

                                                                    - string:

                                                                        value:

                                                                            lit: '[Handle OOB - Transfer To External]'

                                                                        variable: Flow.failureStep

                                                                    - string:

                                                                        value:

                                                                            exp: Flow.failureMessage

                                                                        variable: Flow.failureMessage

                                                            - jumpToTask:

                                                                name: Handle Transfer Failure

                                                                targetTaskRef: /inboundCall/tasks/task[handleFailure]

                                    - case:

                                        value:

                                            lit: 'menu'

                                        actions:

                                            - updateData:

                                                statements:

                                                    - string:

                                                        value:

                                                            lit: '-1'

                                                        variable: Flow.lastDtmf

                                                    - string:

                                                        value:

                                                            exp: 'Append(Flow.calltype, "_oob_root")'

                                                        variable: Flow.currentMenu

                                            - jumpToTask:

                                                name: Dynamic Menu

                                                targetTaskRef: /inboundCall/tasks/task[handleMenu]

                                    - case:

                                        value:

                                            lit: 'disconnect'

                                        actions:

                                            - updateData:

                                                name: Update End Reason

                                                statements:

                                                    - string:

                                                        value:

                                                            lit: '{{end_reason_oob_disconnect}}'

                                                        variable: Flow.endReason

                                            # Inject common action: Set End Reason

                                            - refArray: ./commonTasks.yaml#/common/tasks/task[setEndReason]/actions

                                default:

                                    - actions:

                                        - updateData:

                                            name: Update End Reason

                                            statements:

                                                - string:

                                                    value:

                                                        lit: '{{end_reason_oob_default}}'

                                                    variable: Flow.endReason

                                        # Inject common action: Set End Reason

                                        - refArray: ./commonTasks.yaml#/common/tasks/task[setEndReason]/actions

                - disconnect:

                      none: true

Again, this builds just fine with 1.0.0.

edit: to clarify, I am not setting the refId manually in the shared logic. Looking at the changelog I think there is indeed a change that would explain the failure. However, I am still trying to figure out why I can't use the same shared logic multiple times in the same array. I can work around this, but it is going to make the flow a bit more complicated for no reasons at all. I thought not actively setting the refId and let Archy generate it would suffice but (as Archy would generate the refId at injection time).

edit2: confirming that with 1.0.0, the same refId appears multiple times in that scenario. Does it means that I cannot use the same logic multiple times within the same array now? Pretty limiting. I think Archy should generate unique refId (especially when refId are not actively set in the YAML), that would sort the issue (e.g. if the refId is not set, generate it with a unique key).

Hi there,
Any updates ? I really think that not being able to use shared logic multiple times in the same array defeats the purpose of having shared logic (especially when the developer leaves the refId to be auto-generated, e.g. will never expect to reference specifically the refId so no ambiguity).

I really love Archy for all the goodness it opens up BTW :slight_smile:

Hi Aurelien_Plancque,

We took a look into this issue that you had reported and found a few items of note:

First one: using a refArray is actually not currently supported within a common YAML file. Archy currently throws an error if, inside a common file, you reference another external common file via ref. Archy should have also been throwing an error when, inside a common file, you reference another common file similarly via refArray, but this error was not being thrown. In the next release of Archy, an error will be thrown and the processing ended if you do this. We are currently not supporting that due to the complexity of embedding multiple YAML from multiple levels of referencing and also because of the possibilities of introducing an infinite loop during Archy's processing.

Secondly, the issue that you had actually reported where Archy was throwing an error due to duplicate refIds actually is a bug that we are fixing. It turned out that during the YAML embedding of a Switch action, the reference path to the objects in each switch case would generate internally as identical strings, and as a result, Archy would error out saying that there are duplicate IDs (due to the identical paths across cases). This will be fixed with the next Archy release. Thanks for reporting that issue!

Thanks,
Jon

Thanks @jon.vansteen.
I am saddened by the first point. I understand the complexity and the possibility of introducing infinite loops, but isn't this the responsibility of the developer to make sure such a loop is not created?
I mean, ultimately, Archy is designed to build complex flows using complex logic. Removing the ability to use refArray in common is going to hurt big time.
Is it reasonable to ask that you guys reconsider?

edit: I might have overreacted. If in a common, I have a tasks array, and use refArray in one of the tasks, this should still work right?

For the actual bug, thanks for fixing it. Any ideas when the release will happen?

Kind regards,

Aurelien

Aurelien_Plancque,

Thanks again for your feedback and reporting these Archy issues. Unfortunately, the ability to embed external YAML inside of a common file was not yet up to our standards where we felt comfortable releasing it as a feature just yet. We do greatly appreciate your input on it and will absolutely take it into account as we plan the future roadmap for Archy.

In regards to the edit in your most recent post about using a refArray in common, it still sounds like that may not work if I am understanding it correctly. Are you saying you want to reference an array of tasks that exists within the same common file? That's not currently supported, but allowing a ref or refArray to embed YAML from within the same common file is something that we can also look into supporting in a future release.

Currently, the only time that you can use a ref or refArray property is in the main YAML file (i.e. your flow YAML file). So if you built out your task within your flow YAML you could then use the refArray property to embed any common YAML.

We are also looking to get a new version released in the next couple of days with a fix for the duplicate refIds issue.

Thanks again,
Jon

Hi Jon,
Not exactly. The structure is more like:

  • commonA.yaml
  • commonB.yaml

I want to be able to reference an array from commonA.yaml in commonB.yaml. So if I am reading this correctly, I thin it will work properly.
Can't wait for the next release to try it out.

I am developing fairly complex flows that use a lot of what the platform has to offer which is why I think I am finding all these bugs :slight_smile:

Let me know once it is released, I will let you know how it goes.

Thanks a lot for your time, I really appreciate it.

Aurelien

Hi Aurelien_Plancque,

Thanks again for using Archy and reporting these issues! The latest version of Archy (1.2.0) should be available soon and you can follow the upgrade pattern from before to get on the latest version using archy version latestPublished.

Thanks,
Jon

Hi @jon.vansteen,
Thanks.

Here we go:

you cannot have the external reference 'refArray: ./commonTasks.yaml#/common/tasks/task[setCurrentTask]/actions' inside of the externally referenced YAML file 'C:\Users\axpla1\Apps\Archy\archyHome\dev\shared\deliverToQueue.yaml'. For example, if file A references something in file B, file B cannot reference something in file C.
    Path: '/inboundCall/tasks/refArray/task[deliverToQueue]/actions/refArray'
    Property name: 'refArray' 

Is there a way for me to send you files so you can have a look at what I am trying to achieve here, and maybe switch to DM (because this is getting really use-case specific)? This is really taking away the main purpose of Archy which in my opinion is to develop logic than can be re-used across callflows.

edit:
I am still getting the following too:

pre-processor - duplicate reference id of '__archy_getParticipantData_39__' was found within the YAML file. Please verify that all reference ids are unique within the array ''.
    Path: '/inboundCall/tasks/task[deliverToQueue]/actions'
    Property name: 'refId'

Using the same shared logic multiple times in the same YAML is still causing issue. In my scenario, in the same inboundCall/tasks/task[xxxx], I use the same shared logic 5 times, this results in the above error because Archy seems to auto-generate the same refId every time.
This can be easily replicated by following the steps as an example:

  1. create an inboundCall.yaml document with a tasks array containing 1 task with refId: startup (make this the startup task)
  2. create a common.yaml document with a tasks array and a single task with refId: testShared and a setParticipantData task action with no refId.
  3. in /inboundCall/tasks/task[startup]/actions, insert - refArray: ./common.yaml/tasks/task[testShared]/actions multiple times
    The above will have the pre-processor auto-generate the refId for /common/tasks/task[testShared]/actions/setParticipantData to the same value everywhere it is used. This is a bug I believe.

Kindly

Aurelien

Hi Aurelien_Plancque,

Thanks for reporting another issue around the duplicate refId error! I will take a look at that soon, and also thank you for providing the instructions on how to reproduce it.

So if you would wish to DM me, you can click on my name and hit "message". I believe that you can only send JSON/image files, but I think you could try changing the extension on your yaml files to .json and then send them to me via the message.

edit: Actually yaml/yml files are now supported to send over the dev forum messages so you should be able to attach those files and DM them to me.

Thanks,
Jon

Hi again Aurelien_Plancque,

Thanks again for reporting the issue! I've identified the problem around the duplicate refIds error and am working on a fix for it now. I'm hoping to get a new build of Archy out with it by early next week at the latest.

Thanks,
Jon

Hey @jon.vansteen,
Any updates on the fix?

Thanks again for picking that one up in such a timely manner :slight_smile:

Hi Aurelien_Plancque,

Looking to get this fix out either today or tomorrow! I can post back here when the new version has been released.

Thanks,
Jon