Question

Photo of Aaron Hackett

1

Twilio phone calls

Has anyone succeeded in using Twilio for a roaming phone #?  Similar to the sms reply feature where you can assign the number to a person, but for a phone call... I would love this! We could have one on call # for all our pastors. 

  • Photo of Michael Garrison

    2

    Aaron- with lots of help from Tyler Schrock in the Slack community, I figured out a way to do what you are (maybe) looking for. At least, it works until such time as voice routing is added to Rock natively or with a plugin.

    I've set up a demo on rock.rocksolidchurchdemo.com and linked to the appropriate pages below. This solution is for a complex situation, where the on call pastor changes on a schedule:

     

    1) Start by creating a new content channel type (Admin tools -> CMS Configuration -> Content Channel Types). At http://rock.rocksolidchurchdemo.com/page/1307 I called it a "Person Scheduler" channel type. Set the date range type to "Single Date" and include time. Disable priority and then create an Item Attribute called "Scheduled Person" that's a "Person" field type. Show it in the grid. Save the attribute definition and then save the channel type.

     

    2) Next you'll create a new content channel (Admin tools -> CMS Configuration -> Content Channels). at http://rock.rocksolidchurchdemo.com/page/1309 I called it "On-call pastor". Set it to "Type" of "Person scheduler" (which we just created). Enable RSS. Save.

     

    3) Now you can add the pastors to the schedule- go into the "On call pastor" content channel and add a new item. The Title doesn't matter for our use- you can set it to the person's name, the day of the week, or even leave it blank. The content, likewise, can be left blank. Just set the time to the beginning of the person's on-call rotation and select them in the "Scheduled Person" attribute. Save. Repeat for as many people as you need. Each person's rotation lasts until the next person's starts. at http://rock.rocksolidchurchdemo.com/page/1310?ContentChannelId=1002 you can see I set up one for Monday (in the past), today (Tuesday) and also Wednesday and Thursday this week, so you can see that it's only giving us today's person.

    MAKE SURE THAT WHOMEVER YOU ASSIGN TO ANY OF THESE POSTS HAS A MOBILE NUMBER LISTED IN ROCK. Otherwise Twilio is going to attempt to forward to an empty phone number, which in the best case, simply won't work.

     

    3b) Take a look at the URL for this page- see at the end where it says "ContentChannelId=1002"? Take note of that number, whatever it is on your installation. 

     

    4) Finally, we need to create the XML template that Rock will use to output Twiml. Go to "Defined Types" (Admin tools -> General Settings -> Defined Types) and go into the "Lava Templates". Add a new template. At http://rock.rocksolidchurchdemo.com/page/119?definedTypeId=48 I called it "Scheduled Person Twiml". Set the MIME type to "text/xml". Here's the template:

    <?xml version="1.0" encoding="UTF-8"?>
    <Response>
    {% for item in Items %}
      <Dial timeout="20" action="/forward?Dial=true">{{ item | Attribute:'ScheduledPerson','Object' | PhoneNumber:'Mobile' }}</Dial>
    {% endfor %}
    </Response>

     Save. Now hover over the defined value (the template name) and a tooltip will pop up, indicating the ID of the template you just defined. At the above link, you'll see it's 5648. Make note of this number.

     

    5) Let's see it work! Visit http://rock.rocksolidchurchdemo.com/GetChannelFeed.ashx?ChannelId=1002&Count=1&TemplateId=5648 . You can see here where to replace the 1002 with the ContentChannelId that we took note of in step 3b, and the TemplateId that we took note of in step 4. "Count=1" means it will only return the most recent (but not future) "posts". Which, here, means "the post identifying the CURRENT on-call person".

     

    6) It works! Cool. So now feed that URL to Twilio (webhook HTTP GET method) for the voice endpoint on that phone number and you're good to go! Twilio will be directed to forward any voice calls to the number specified in that file, specifically the mobile number of whoever the currently-assigned person is. And (bonus) you can use a Content Channel block on your internal homepage so that staff can see who is currently on-call. Etc =)

     

    ------------------------------------------

    Note: this method won't work for scheduling rotations for SMS- since your pastor will need to be able to reply to the person who sent them a text, but the text will actually be coming FROM your twilio number, you need Rock's native Twilio endpoint to do a lookup and provide the code at the end of the message so that replies actually get delivered.

    ------------------------------------------

    Alternative: Since this doesn't work for scheduling SMS recipients, but that didn't seem to be an issue with you, perhaps your "on call" pastor doesn't change very often. In that case, there's no need to actually create a schedule. Just create a template that has exactly the output you wish to be returned to Twilio. Then you can use ANY (valid rss-enabled) channelID and this alternate static templateid to have it output exactly what you type in as an XML file. See http://rock.rocksolidchurchdemo.com/GetChannelFeed.ashx?ChannelId=3&TemplateId=5649 and the "Static Twiml" lava template at http://rock.rocksolidchurchdemo.com/page/119?definedTypeId=48 to see that the actual output has nothing to do with the channel's content (which in this case is simply the built-in "blog" channel.

    Of course, this alternative doesn't do anything that the twimlet doesn't do, so the twimlet is probably still a clearer way to set the number if it doesn't have to be scheduled out...

  • Photo of Michael Garrison

    0

    Aaron, let me start by saying I'm not sure how Rock handles phone calls- perhaps what you're looking for is possible natively in some way and someone else might have that answer.


    But I know that you can set up different endpoints within Twilio's interface for SMS (which should be set to [yourrockaddress.com]/Webhooks/Twilio.ashx) versus the endpoint for voice. So rather than setting that endpoint for the voice method, you COULD use one of their twimlets (such as http://twimlets.com/forward?PhoneNumber=555-555-1234& ) as your endpoint for voice traffic to set the phone number of the pastor who was presently "on call". Interestingly you can set the CallerId to be your twilio number so that they can set a custom ringtone for all "on call" calls.


    Alternately for regular rotations (and depending on your current website- I don't know how to do this in Rock because I don't know how to generate a custom XML file using Rock), you can set up a page on your website that uses either programming logic (an array storing day or the week and the corresponding pastor's phone number) or scheduled posts, etc, to output an XML file in the same format as the twimlets link I posted above. That way you wouldn't have to manually update the number in Twilio's interface every time the "on call" duty changed to a new person.


    Check out Twilio's documentation and twimlets.com for more information on all of the possibilities available.


    I hope that helps, but almost as much I hope someone else chimes in here knowing how to do this with Rock ;-)

  • Photo of Aaron Hackett

    0

    I figured out the twimlet. That's a good alternative. I'd love to see us able to do this within rock.  
  • Photo of Aaron Hackett

    0

    Michael, This is super great! 

    I put this in Twilio as a "voice" Webhook HTTP Post. Is that correct? I'm getting a response "An application error has occurred". Is that possibly because ROCK renders the phone as (123) 456-7890 rather than 1-123-456-7890?

    I absolutely love this solution... it is exactly what I was looking for. 

    • Aaron Hackett

      I forgot to mention... the error in Twilio is 12100 (document parse error) Attached is readout of the debug console.


      Error - 12100


      Document parse failure


      Twilio was unable to parse the provided XML Document.
      Your TwiML document must be a valid XML Document, or Twilio will not be able to read your document. You can debug XML parsing errors by getting the response body in the debugger, and then using an online validation tool like the W3C Validation Service.
      Possible Causes


      There is a leading space, or an empty line, before the XML type header (i.e. <?xml version="1.0" encoding="UTF-8"?>)
      The root <Response> element is missing
      There is an unclosed element
      There is an unquoted attribute
      There is an improperly nested element
      Possible Solutions


      Make sure there is no extra space or line at the beginning of the file before the type header
      Make sure your root element is <Response>
      XML is case sensitive, make sure your start and end elements match case. (Twilio elements begin with a capital letter)
      Make sure characters such as < > and & are escaped properly, as &lt; &gt; and &amp;.
      Request Inspector


      POSThttp://www.thehousechurch.tv/GetChannelFeed.ashx2016-08-10 09:00:16 UTC
      Request
      Response
      Headers
      BodyShow Raw
      Invalid request type.

    • Michael Garrison

      Try a GET request instead of POST... Rock is using the parameters in the URL so it expects a GET request and may be choking when passed parameters like the source phone number through POST. We don't actually have to pass anything to Rock, so hopefully it will just ignore what it doesn't need in the URL.


      I checked on the twimlet generator and it doesn't get rid of parentheses, so I don't think that's the issue...


      You could give me your TemplateId and ChannelId if you want me to verify the XML, but it's pretty basic, I imagine you can check it yourself ;-)

    • Aaron Hackett

      Just tried this. HTTP GET worked excellently! I am so excited to have this working. Thank you so much for your response and help. This is great! Blessings!

    • Michael Garrison

      So glad to hear it- I did just try submitting a POST request to the demo I set up and it returned "Invalid Request Type". Which explains the error. So yep, it's gotta be GET all the way. I'll update the answer accordingly.