Search code examples
groovytwilio-twiml

Error in parsing String to GString


I was having this TwiML in my controller class written in groovy

"""<?xml version="1.0" encoding="UTF-8"?>
  <Response>
    <Say voice="alice">Dear customer! This  is  an automated call from X_Y_Z.com to intimate  you that the  fare for  your recently  booked  trip from  ${from},to ${to} has increased by,${fare_Difference}\$ and now the total fare is,${totalFare}\$.</Say>
    <Pause length="1"/>
    <Gather num Digits="1" action="/notify/phone/selection/${phone_Number}/${from}/${to}/${fare_Difference}/${total_Fare}" method="POST" timeout="20" >
        <Say voice="Alice" >To accept the increased fare press 1. To talk to our travel agent press 2. To repeat press 3.</Say><Pause length="3"/>
    </Gather>
  </Response>"""

Now my team lead has asked me to move the TwiML to database.

The problem here is when I'm reading it from database it is being returned as java.lang.String(We are using hibernate in DAO layer), which is causing problem as it is not evaluating the embedded values

e.g instead of subsituting value of "${from}" as "New York" it is doing nothing on it and leaving it as ${from}.

How can I achieve this?

I tried to convert it to GString, but could not achieve it.

Any help will be greatly appreciated.


Solution

  • This is a known issue and hasn't been fixed yet. A workaround is to either use a GroovyShell to evaluate the string expression or use GStringTemplateEngine. Sample code using both approaches:

    String str = '''
    <?xml version="1.0" encoding="UTF-8"?>
      <Response>
        <Say voice="alice">Dear customer! This  is  an automated call from X_Y_Z.com to intimate  you that the  fare for  your recently  booked  trip from  ${from},to ${to} has increased by,${fare_Difference}\\$ and now the total fare is,${totalFare}\\$.</Say>
        <Pause length="1"/>
        <Gather num Digits="1" action="/notify/phone/selection/${phone_Number}/${from}/${to}/${fare_Difference}/${total_Fare}" method="POST" timeout="20" >
            <Say voice="Alice" >To accept the increased fare press 1. To talk to our travel agent press 2. To repeat press 3.</Say><Pause length="3"/>
        </Gather>
      </Response>
    '''
    
    
    Map bindings = [from: 'Delhi', to: 'Mumbai', fare_Difference: '789', totalFare: '4567', phone_Number: '9876543210', total_Fare: '4567']
    
    println (new GroovyShell(new Binding(bindings)).evaluate ('"""' + str + '"""'))
    
    println new groovy.text.GStringTemplateEngine().createTemplate(str).make(bindings).writeTo(new StringWriter()).toString()
    

    One thing to note down here is if you want to skip a dollar sign then you might need to escape it using double Backslash (${fare_Difference}\\$).

    Output in each case would be:

    <?xml version="1.0" encoding="UTF-8"?>
      <Response>
        <Say voice="alice">Dear customer! This  is  an automated call from X_Y_Z.com to intimate  you that the  fare for  your recently  booked  trip from  Delhi,to Mumbai has increased by,789$ and now the total fare is,4567$.</Say>
        <Pause length="1"/>
        <Gather num Digits="1" action="/notify/phone/selection/9876543210/Delhi/Mumbai/789/4567" method="POST" timeout="20" >
            <Say voice="Alice" >To accept the increased fare press 1. To talk to our travel agent press 2. To repeat press 3.</Say><Pause length="3"/>
        </Gather>
      </Response>