Search code examples
asterisk

Using Cut with multiple delimeter


I have a small problem. I have a variableCTI_VARIABLES with this content:

cti_CallDirection=1@;cti_ContractNumber=00202417@;cti_TransferVDN=48195@;cti_IvrButton=1

Each different variable within this variable is marked “@;” separated by . I’m trying to separate them with the CUT() function. But it only returns the first one, because it accepts a single character as an argument. How can I do it when I want to separate by two characters?

Here is my dialplan code

exten => addheader,1,NoOp(CTI_VARIABLES: ${CTI_VARIABLES})
same => n,GotoIf($["${CTI_VARIABLES}" = ""]?noVariables)
same => n,Set(TOTAL_VARS=${FIELDQTY(CTI_VARIABLES,@\;)})
same => n,Set(COUNTER=1)
same => n,While($[${COUNTER} <= ${TOTAL_VARS}])
same => n,Set(CURRENT_VAR=${CUT(CTI_VARIABLES,@\;,${COUNTER})})
same => n,Set(VAR_NAME=${CUT(CURRENT_VAR,\=,1)})
same => n,Set(VAR_VALUE=${CUT(CURRENT_VAR,\=,2)})
same => n,Set(PJSIP_HEADER(add,${VAR_NAME})=${VAR_VALUE})
same => n,NoOp(${VAR_NAME}: ${VAR_VALUE})
same => n,Set(COUNTER=$[${COUNTER}+1])
same => n,EndWhile
same => n(noVariables),NoOp(No CTI Variables Set)

I also tried using the FIELDQTY() function with no luck:

TOTAL_VARS=${FIELDQTY(CTI_VARIABLES,\@\;)}
TOTAL_VARS=${FIELDQTY(CTI_VARIABLES,@;)}

Solution

  • Why you ever may need count something for this simple task?

    So. Let me give you "the asterisk way":

    ; noop actually not needed, because MSet will show you all variables
    exten => addheader,1,NoOp(CTI_VARIABLES: ${CTI_VARIABLES})
    
    same => n,Set(MVAR=${STRREPLACE(CTI_VARIABLES,@;,\,)}); replace all @; to comma
    same => n,MSet(${MVAR}); put all names/vars on channel
    ; actually if you know variable names, you not need all below
    ; same=>n,Dumpchan();uncomment this if you want to see result.
    
    same => n(loop),ExecIf($[ "${MVAR}" == "" ]?Return()); exit
    same => n,Set(VAR=${CUT(MVAR,\,,1)}); get next one
    same => n,Set(MVAR=${CUT(MVAR,\,,2-)}); put from second back in string
    ; at this moment VAR has variable name and MVAR have other pairs without ${VAR}=${${VAR}}
    same => n,Set(VAR_NAME=${CUT(VAR,=,1)}); get only name
    
    same => n,Set(PJSIP_HEADER(add,${VAR_NAME})=${${VAR_NAME}); catch it from channel and put in header
    same => n,Goto(loop); next one
    

    Thats ALL

    Short tips WHY all those are working.

    MSet syntax is like this

    [Syntax]
    MSet(name1=value1[,name2=value2[,...]])
    

    And it will set all variables in one command

    if you are using

     ${${VAR}}
    

    asterisk will take value of variable VAR and put value of variable with that name.

    If cut have no delimiter, and you asking for second param, it return empty string.

    So ACTUALLY perfect way is return all info you need from your CURL request or AGI or whatever source of those variables in format like this

    cti_CallDirection=1,cti_ContractNumber=00202417,cti_TransferVDN=48195,cti_IvrButton=1
    

    After that make single MSet and put READABLE dialplan for headers.