Home > Net >  Twilio Studio RegEx in "Split Based On..." Widget
Twilio Studio RegEx in "Split Based On..." Widget

Time:10-01

I'm still in my trial phase with Twilio and working on putting together a "flow" in Studio to handle my use-case properly. So far, all of the basic, plain-text steps in my flow seem to be working exactly as expected, but I'm having problems figuring out how to handle incoming media/attachments the way I want. I readily admit and acknowledge that what I've put together may not be the most effective solution, but it's what I've come up with based on the research I've done so far.

First, here is the basic breakdown of the desired steps in my flow:


  1. I have a separate application that connects to the Twilio REST API to initiate the flow's execution. It passes a couple of parameters into the flow's flow.data namespace for inclusion in various messages sent to the end-user as a part of the flow.
    Private Async Sub StartFlow(ByVal Recipient As String)
        Try
            Dim RefNum As String = GenerateReferenceNumber(8)
            Dim NoticeParameters As New Dictionary(Of String, Object) From {
                {"ref_num", RefNum},
                {"contact_num", "(800) 555-1234"},
                {"client_name", "Caliente Client"}
            }
    
            TwilioClient.Init(SID, Token)
    
            Dim FlowExecution = Await ExecutionResource.CreateAsync(parameters:=NoticeParameters,
                                                                    [to]:=New PhoneNumber(Recipient),
                                                                    from:=MyTwilioNumber,
                                                                    pathFlowSid:=NoticeFlowSID)
    
        Catch ex As Exception
    
        End Try
    End Sub
    
  2. The first step in the flow's execution is to initialize a variable in the flow.variables namespace named current_response with a value of EMPTY.
  3. The flow's next step is to send our initial SMS contact to the end-user via a Send & Wait For Reply widget called "Notice".
  4. When a reply is received from the user, the flow.variables.current_response value is updated by a Set Variables widget:
    • If the value of widgets.Notice.inbound.MediaUrl0 is not NULL, the flow.variables.current_response value is set to the URL value from that property.
    • If the value of widgets.Notice.inbound.MediaUrl0 is NULL, the flow.variables.current_response value is set to the value of the widgets.Notice.inbound.Body property instead.
  5. After setting the current_response variable's value, that variable is passed on to a Split Based On... widget (named "Response_Received") that tests the flow.variables.current_response with the following Regular Expression to determine whether or not the value is a URL:
    [(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\ ~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\ .~#?&//=]*)
    
    • If the value is not a URL, the flow should pass execution on to the next Split Based On... widget (named "Other_Response") to handle certain plain-text replies with a pre-defined set of responses.
    • If the value is a URL, it should pass execution to a Make HTTP Request widget that will POST to my MVC controller to log the incoming file.
  6. Depending on the end-user's reply, the Other_Response widget will then pass execution on to another Send & Wait For Reply widget that can update the flow.variables.current_response property with that widget's inbound.MediaUrl0 or inbound.Body via another Set Variables widget if they continue the conversation.
  7. After updating the current_response variable, flow execution returns to the "Response_Received" widget with the new value (see #5).

The idea is that, if the user initially responds with something like HELP, I want to be able to send them a message with additional details about the reason we reached out to them in the first place, then allow them to send us the specific information (file) we're requesting while still retaining the values I populated into the flow from my in-house application - most specifically, a unique reference number I've generated for the contact. Even if it takes them a couple of tries, as long as the execution is valid, I want any reply within that execution to have the capability of processing an incoming file based on those same values.

In my tests, I've been able to get all of the simple, plain-text responses to work as I've designed:

  • I reply to the flow's initial message with one of the pre-defined messages and the flow returns the correct response and waits.
  • I reply to that message with another of the pre-defined messages and the flow again returns the appropriate response and waits.
  • I reply to that message with a plain-text message that isn't defined as a valid response and the flow correctly returns a message stating, "I'm sorry. I didn't recognize your response. Please try again."

However, if I reply to the flow's initial message with a file as I expect to have our end-users doing (I've used PDF and PNG files in my testing so far), I still get the message stating, "I'm sorry. I didn't recognize your response. Please try again." This message is not defined in the path from the split designated for replies with a URL.

Based on the results, I can only assume that there's something "wrong" with the RegEx logic that's not actually matching the URL as it should. I've Twilio Studio Flow

I am continuing to work with the Twilio Support team as well to determine if there's an actual "problem" here, or if I'm simply doing it wrong (a distinct possibility). There very well may be more effective/efficient ways to achieve my goals but, in the absence of a "generic" option to validate any incoming widget (e.g., widgets.previous_widget.inbound.MediaUrl0), this is the best solution I've been able to find so far.

The main reason I'm posting my question here is not only to try and find a solution that fits my specific needs, but also to document the troubleshooting process and hopefully help anyone else who's just beginning to work with Studio and needs to implement some "complex" business rules.


UPDATE - Alternative Solution Found

So, after talking it through with Twilio Support, we still weren't able to figure out why the above method doesn't work, but we were able to determine that the current best course of action is to add a series of Split Based On... widgets into the flow at each point where I currently just have the Set Variables widgets. While it significantly increases the overall complexity of the flow itself, this method eliminates the need to use the RegEx matching I had to identify incoming URLs.

Even so, once I was finally able to properly articulate why I was trying to make this work, the representative with whom I spoke agreed that it should work and is going to continue testing and investigating the issue. In the meantime, I'm going to update my flow to add all of the extra widgets I need for my logic, but I'd still like to find out if there's some reason I'm overlooking why this is failing.

CodePudding user response:

Based on my conversations with the Twilio Support team, it seems that, for whatever reason, the RegEx method I had implemented will not work. I wasn't able to get a specific reason why it fails, but it appears to be a technical limitation somewhere within Studio. In this case, to achieve my specific goals, there are basically two alternatives:

  1. As I described in the UPDATE in the OP, I can use Split Based On... widgets at each Send & Wait For Reply point that test whether the MediaUrl0 value is empty, then use a pair of Set Variables widgets - one for text-only replies and one for replies with attachments - to pass the value(s) on to the appropriate next step in the flow. Use "Split Based On..." widget
  2. Instead of using a RegEx match to test the value of my current_response variable, I can use the Starts With test to see if the current_response begins with "my" Twilio API URL (https://api.twilio.com/2010-04-01/Accounts/[ACCOUNT SID]/Messages). Use "Starts With" condition

Obviously, the former method requires a bit more complexity - several additional widgets to direct the flow to the appropriate next widget - but is less dependent on the actual value of the Twilio API URL. The only "problem" with the latter method would be that if the API version (2010-04-01) changes, I would need to update each point in my flow where it's used to reference the new version.

At this time, I've opted for the former solution and have tested the flow several times to ensure that it all seems to be working correctly. After a few "false starts", I've been able to get through the entire process with all of the correct responses and operations. Simple text replies send back the appropriate response while sending a file pushes the information over to my MVC controller for further processing.


One totally tangential side note: Because the MediaUrl0 value "masks" the original file name and strips the file extension, I needed a way to determine what kind of file was being sent. In a "regular" SMS interaction using Twilio's Programmable Messaging tools, there's a MediaContentType0 property. This value is not a selectable option in the Studio flow editor. I was able to retrieve the value of this property by manually typing it into the appropriate fields (widgets.[WIDGET_NAME].inbound.MediaContentType0), so it seems that any value that is available in the current JSON should be accessible through Studio. You just have to know what you're looking for because it isn't "documented". I hope this all helps someone else looking to implement their own Studio flow.

  • Related