
Yap
as of version 4.0.0
Yap is an application to find meetings or someone to talk to over the phone (helpline) leveraging a BMLT root server.
The purposes of yap are :
- To be able to take the results of a BMLT root server and play it back through the telephone.
- To be able to set up routing rules for zip codes and helpline numbers with optional extension dialing.
- To be able to set up volunteer schedules and associated rules to answer calls.
- We are taking advantage of using Twilio which essentially handles all the VOIP parts. You provision a number, set up an application, and point it your PHP server.
Setup
This will require that you have an SSL certificate installed on your webserver to transit a secure connection. This is required by Twilio.
- Create a new virtual application or add the yap code to an existing folder. You can always find the latest stable version here (be sure download the yap-x-x-x.zip file and not the source code): https://github.com/bmlt-enabled/yap/releases/latest. You can also try out or help test the latest bleeding edge features by installing one of the unreleased versions. The newest version would always be the highest numbered build.
- You will need to set up a new blank MySQL database. Be sure to set up backups on your database as well. Your hosting provider may cover this more. Take note of the configuration host, database name, username and password.
- Once the application is configured visit the url where the application was installed. This will redirect you to an installer page. Fill out all the settings and when you are done copy and paste the result into a file called config.php on your server. If done correctly the database will automatically initialize and redirect you to the admin login page.
- You will need to enter your twilio_account_sid and twilio_auth_token. You can find this on your account dashboard. You can also use a different Twilio account using the admin portal under “Service Bodies”. Keep in mind that if a key or keys are set at any parent above, all child service bodies will inherit that key. In order to use a key, just specify
override_service_body_id
in your webhook with the applicable id. - Be sure to get a Google Maps API key (for google_api_key) Make sure you have “Google Maps Geocoding API” and “Google Maps Time Zone API” enabled on your credentials. This key must be separate from your BMLT key with no server restrictions, this is safe because yap never passes the key client side. Your key however, should have an IP-based restriction if possible. You can get your server IP from your hosting provider. You can login into your Google API console here: https://console.cloud.google.com/apis/. This article may be useful https://bmlt.app/google-api-key/
- You will need to enter your twilio_account_sid and twilio_auth_token. You can find this on your account dashboard. You can also use a different Twilio account using the admin portal under “Service Bodies”. Keep in mind that if a key or keys are set at any parent above, all child service bodies will inherit that key. In order to use a key, just specify
- You will need to set up a Twilio account, and do the following. Purchase a phone number (typically you would buy one for your locale, tollfree is pretty much unnecessary these days). Configure that number to point to a Webhook. It would be something like https://example.com/index.php. You can also configure SMS Gateway and Call Detail Records from this section well. Demo phone numbers have proven to have many limitations, so funding your account and buying a number will be the only known reliable path forward.
- Make a call to your number and try it out. If there is a problem the debugger in the Twilio console will let you know why. Most likely you did not setup your config.php file correctly.
- There are many ways to customize the config.php and also to set overrides. See the rest of this documentation and the page on Configuration Precedence.
Call Detail Records
Point all your phone numbersCall Status Changes Callback
Webhook in Twilio to your instance to status.php
.
You can use either HTTP GET or POST. Voice Recognition Options
It’s possible to set the expected spoken language, for recognition by setting the following variable in config.php to the culture variant. The default isen-US
, which is US English.
Use the this chart to find the code of your preference https://www.twilio.com/docs/api/twiml/gather#languagetags.
static $gather_language = "en-US";
You can also set some expected words or hints, to help the voice recognition engine along. Use the setting by separating words with commas. You can use phrases as well.
Each hint may not be more than 100 characters (including spaces). You can use up to 500 hints.
static $gather_hints = "";
Voice recognition for input gathering is turned on by default, to turn it off you can do the following. When you make this change, the prompts will say “press or say” and now respond to saying the digit response as well as pressing the digit on a phone.
static $speech_gathering = false;
Configuration Precedence
- Querystring parameters that match the name. For example if you wanted to override the title for one page you’d do the following:
index.php?title=something+here
- Session overrides. This means the entire call will use this setting.
index.php?override_title=something+here
. Twilio will respect this setting for entire during of the call. - Service body overrides from the Admin UI. These have a cascading hierarchy of precedence based off the service body above it in the hierarchy tree from your root server. Either the
override_service_body_id
(which will affect call routing) oroverride_service_body_config_id
will pull these settings into the session for use. - Config.php. Any setting is controllable from within config.php.
- Factory defaults. You can review them on your
/admin/settings.php
page.
config.php
file setting as well with additional precedence.
- Create a new file called
config_something.php
. Add whichever settings you want to override. You do not need every setting, only those you want to override. - Use the last part after the underscore in your webhook as, for example: https://your-yap-server/index.php?override_config=something.
State Province Lookup
$province_lookup
, variable to true
in the config.php
file.
static $province_lookup = true;
You can also specify a predetermined list of provinces / states. If you use this setting, then a speech gathering will be replaced with a numbered menu of states. Currently it would support up to 9 states in the list. To enable this do the following for example (the order in the list and position is the number that will be said to be pressed in the menu):
static $province_lookup = true;
static $province_lookup_list = ["North Carolina", "South Carolina"];
Province Bias
static $toll_free_province_bias
to your config.php
, and set to the two letter state or province bias.
This example: will bias to Texas.
$toll_free_province_bias = "TX"
To enable a toll number bias (meaning to override the location of the number itself), add $toll_province_bias
to your config.php
, and set to the two letter state or province bias.
Location Lookup Bias
$location_lookup_bias
in config.php.
For example say you wanted to lookup Bayonne. By default Bayonne, New Jersey would be interpreted. If you were intended for France you would set your config as the following:
static $location_lookup_bias = "country:France";
A full listing of available bias options are available here: https://developers.google.com/maps/documentation/geocoding/intro#ComponentFiltering. You can use as few or as many as you want, by separating each set with pipe “|” character.
static $custom_coding = [['location' => "Pasco County, FL", 'latitude' => "0.00", 'longitude' => "0.00"]]
If you are using the Config option in the Admin UI to override by service body, use JSON formatting instead as seen below.
[{"location": "Pasco County, FL", "latitude": "0.00", "longitude": "0.00"}]
Postal Code Lengths
static $postal_code_length = 4;
Fallback
config.php
, specify the following.
static $helpline_fallback = "1919555555";
Voice Greeting
static $en_US_greeting = "https://example.com/your-recorded-greeting.mp3"
You can also set a custom greeting for voicemail.
static $en_US_voicemail_greeting = "https://example.com/your-recorded-greeting.mp3"
These settings are overridable from within each service body call handling.
Language Options
There is a concept of language resource files. You will notice them in thelang/
folder. Please open a ticket if you would like to contribute to translating to another language.
You can also override any of the language prompts in the config.php
file.
For example, say you wanted to still use English, but change the “city or county” prompt to say, “city or suburb”. You would do the following in config.php:
static $override_city_or_county = "city or suburb";
You can see the full listing in the lang/en-US.php
which always has the full latest listing of the voice prompts.
You can also change the spoken language accent. There is a wide variety. See the Twilio documentation for more details: https://www.twilio.com/docs/voice/twiml/say#attributes-language. There are also some additional voices available here as well https://www.twilio.com/docs/voice/twiml/say/text-speech#voices.
An example would be using an Australian English Accent. Set your config.php to:
static $voice = "alice";
static $language = "en-AU";
Language Call Routing
You can also create a language selection menu upon dialing in. It will only be available for those that there are resource files for inlang/
folder. If you have some translations, please send them, so they can be merged in.
Add a new setting called, specifying the language codes for each language you want included. The order will indicate the order in which it will be played back:
static $language_selections = "en-US,pig-latin";
If you want to route calls to volunteers by language, see the section on Language in Specialized Routing.
This example will make option 1, English and option 2, pig latin.
Mixing languages and voices
Voices can be configured for every language option. For example for Spanish:
es_US_voice = "Polly.Penelope";
Custom Extensions
- Add an option to your
$digit_map_search_type
that points toSearchType::CUSTOM_EXTENSIONS
. - Add mappings in
$custom_extensions
for each extension you want to add. For example if you wanted redirect extension “365” to a specific phone number you would do the below:
static $custom_extensions = [365 => '555-555-1212'];
- Add an option for the mp3 or wav file prmpt that will play back all the choices in the custom extensions menu
$en_US_custom_extensions_greeting
(be sure to specify recordings for each language that you offer).
To test, call in dial the digit map choice and you should hear the audio file prompt playback. Enter the extension number followed by the pound sign (it might be good to inform the end-user in your prompt to press pound after they dial the appropriate extension).
Also to note is that the main menu greeting will not inform the user about the custom extensions option, so you may also want to set $en_US_greeting
to include that information.
Blocklist
static $blocklist = "";
Users
User authentication has primarily been sourced by a BMLT. You can create users outside the BMLT and use Yap’s internal user authentication. To create an admin user run the following MySQL script. Be sure to set a strong password and fill it in the variable before running this on your MySQL instance.
SET @realname = '';
SET @username = '';
SET @password = '';
INSERT INTO users (name, username, password, permissions, is_admin) VALUES (@realname, @username, SHA2(@password, 256), 0, 1);
Meeting Search Radius
Change the default meeting search radius, this can be in miles or a negative number which would set the radius at the first n results. You can change this in yourconfig.php
with the following:
static $meeting_search_radius = 30;
This would set the radius to a maximum of 30 miles.
static $meeting_search_radius = -50;
This would set the radius at the first 50 results and is the default.
More information on how the BMLT uses search radius is here: https://bmlt.app/how-auto-radius-works/
Results Counts Maximums
The default number of meeting results is 5. You can change this in yourconfig.php
with the following:
static $result_count_max = 10;
This would set to a maximum of ten (10) results.
Grace Period
This is so that yap still returns results for meetings that have already started. By default a 15 minute grace period will be applied. This can be adjusted by setting$grace_minutes
in your config.php
.
static $grace_minutes = 10;
Ignoring Certain Formats
In some cases you might want to ignore a specific format. Add the following setting with the formats you want to exclude. Separate each with a comma.
static $ignore_formats = "ASM";
Post Call Options
Making SMS results for voice calls optional
The default of the system is to send an SMS after each voice meeting result. As an option to you audience you can add the following parameter to yourconfig.php
file.
static $sms_ask = true;
static $infinite_searching = true;
Suppress Voice Results
In order to prevent voice results from being returned for meeting searches set the following setting:
static $suppress_voice_results = true;
SMS Gateway
sms-gateway.php
.
Then you can send a zip code, county or city to your phone number and get back a response.
SMS Options
SMS Summary Page
You can configure the SMS results as a summary page link using croutonjs. Set your configuration to have
static $sms_summary_page = true;
Adding Map Links
Some older handsets are not capable of rendering maps links. If you want to enable this feature add the following to your config.php
file.
static $include_map_link = true;
Adding Location Text
This feature enables you to include the name of the meeting location in search results, by default it is disabled. If you want to enable this feature add the following to your config.php
file.
static $include_location_text = true;
Adding Distance Details
This feature allow you to include the distance from the search criteria in an SMS response. You can specify either mi
or km
.
static $include_distance_details = 'mi';
static $sms_combine = true;
Custom Query
In some cases you may want use a custom BMLT query. For example, if you have a small service body you may want to ignore the day of the week concept that is the default behavior in searches. You can do this with the settingcustom_query
. This setting also supports the use of some magic variables.
For example say you want to always use the service body id for making queries, you could create the settings as follows:
static $custom_query="&services[]={SETTING_SERVICE_BODY_ID}"
Because there is a setting called service_body_id
already and assuming you had overridden it, meeting searches will now send a query to the BMLT and return accordingly.
You could have also hardcoded it if you wanted. Like any other variable, you can set this on the querystring as a session wide override.
In some cases you may need to combine this with the result_count_max
to increase the limit of how many results are returned. You may also need to use sms_ask
, as many results could be returned.
There are a couple of other stock magic variables.
{DAY}
– will use the day of today / tomorrow.{LATITUDE}
– the latitude of the lookup.{LONGITUDE}
– the longitude of the lookup.
If you do not have {LATITUDE}
or {LONGITUDE}
in your custom query, it will automatically skip the location gathering aspects of the meeting search menus and go directly to returning results.
Sorting Results
By default the results will be sorted starting with today and then moving on to the next result. If latitude and longitude are not used in the meeting query, the first meeting latitude and longitude will be the assumed timezone. If you wanted to hardcode the sorting to start with another day you could use say for Wednesday usestatic
static $meeting_result_sort = 4;
Or you can keep a more natural flow by setting it to 1 which would sort Sunday to Saturday.
Disabling Postal Code Gathering
To disable postal code lookups set your config as follows:
static $disable_postal_code_gather = true;
Mobile Check
You can configure the SMS results to check if the device is mobile and not a landline or voip before sending. If not a mobile device SMS will not be sent. Set your configuration to have
static $mobile_check = true;
Including Unpublished
If running root server 2.15.1 or greater you can include unpublished meetings.
static $include_unpublished = true;
Temporary Closures / Showing Meeting Format Details
If a meeting is marked with the TC
format then it will be excluded from results. If it marked as a Virtual Meetings as well then it will be returned by with no physical address details.
If you want the text from the format description to be returned add TC
to include_format_details
. Example:
static $include_format_details = ['TC', 'VM', 'HY'];
You can include any format here. For example if you wanted to show whether a meeting is Open or Closed you could do that by including the format code in this setting.
If you want to change the description of some of the specific formats you can change the format description for that specific language in your root server.
Virtual Meetings
If a meeting is marked asVM
or HY
with a format then you should be able to automatically have the virtual_meeting_link
and phone_meeting_number
returned in the SMS.
If you want the links (for some reason), to be said in voice responses, you can enable this with say_links
set to true
.
If you want the text from the format description to be returned add VM
or HY
to include_format_details
. Example:
static $include_format_details = ['TC', 'VM', 'HY'];
If you want to change the description of some of the specific formats you can change the format description for that specific language in your root server.
Helpline Search Radius
Change the default helpline search radius, this is in miles. You can change this in yourconfig.php
with the following:
static $helpline_search_radius = 30;
This would set the radius to a maximum of 30 miles and is the default.
Helpline Call Routing
555-555-5555|wwww700
for example after the helpline field on the BMLT Service Body Administration. In this case it’s instructing to dial 555-555-5555 and wait 4 seconds and then dial 700.
Music On Hold
- Ambient: https://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient – [license]
- Classical (default): https://twimlets.com/holdmusic?Bucket=com.twilio.music.classical – [license]
- Electronica: https://twimlets.com/holdmusic?Bucket=com.twilio.music.electronica – [license]
- Guitars: https://twimlets.com/holdmusic?Bucket=com.twilio.music.guitars – [license]
- New Age: https://twimlets.com/holdmusic?Bucket=com.twilio.music.newage – [license]
- Rock: https://twimlets.com/holdmusic?Bucket=com.twilio.music.rock – [license]
- Soft Rock: https://twimlets.com/holdmusic?Bucket=com.twilio.music.soft-rock – [license]
Tomato Helpline Routing
In some cases you might want make use of aggregated helpline information. In order use the setting:
static tomato_helpline_routing = true;
When a call comes in first a lookup will occur in Tomato to determine which root server can handle that request. If the root server matches first helpline_bmlt_root_server
if used, and then bmlt_root_server
, it will use that for the subsequent routing requests. Otherwise it will use the helpline routing field for the remote root servers in the tomato response.
Using Hidden Service Bodies For Helpline Lookups
It is possible to create a service body with an unpublished group in order to create additional routing for service bodies that may not exist in a given root server. Once those service bodies have been populated and the unpublished meetings are added, you can make use of the helpline field to route calls. You will also need to add to the config.php three additional variables. This allows yap to authenticate to the root server and retrieve the unpublished meetings. This is required as a BMLT root server by design will not return unpublished meetings in the semantic interface.
static $helpline_search_unpublished = true;
static $bmlt_username = "";
static $bmlt_password = "";
You will need to also ensure that PHP has write access to write to this folder, in order to store the authentication cookie from the BMLT root server.
NOTE: This will not work for the Tomato server, because there is no concept of authentication.
static $helpline_bmlt_root_server = "";
Checking the Call Routing
There is a very simple way to check where a could would be routed to.
curl https://example.com/yap/helpline-search.php?Digits=Turkey,NC
When configuring the TwiML app instead of pointing to index.php
point to input-method.php?Digits=2
in your webhook.
If you still want the title to display point your webhook to input-method.php?Digits=2&PlayTitle=1
.
This could useful for wiring up to a Grasshopper extension. Typically you set this as Department Extension and have your prompt instruct to press a series of keypresses.
For example, if you set this up as extension 1, from within you employee extensions you would instruct the caller to press *1 (star one) for finding meetings.
Force Helpline Routing
You can force the helpline option to go directly to a specific service body by specifying the following on your webhook in Twilio.
?override_service_body_id=x
The service body id would be found in your BMLT root server. It must exist in that root server instance to be routed correctly.
Volunteer Routing
Incompatible with Yap 1.x Volunteer Dialers, you will have reconfigure your setup.- You will need to ensure that the following
config.php
parameters are set. They should be a service body admin that will be responsible for reading and writing data back to your BMLT. This will not work with the “Server Administrator” account.
static $bmlt_username = "";
static $bmlt_password = "";
2. You will need to specify Twilio API parameters. You can find this on your account dashboard when you login into Twilio.
static $twilio_account_sid = "";
static $twilio_auth_token = "";
Head over to your admin login page. https://your-yap-instance/admin.
Login with any credentials from your BMLT server.
Go to the Service Bodies tab and click “Call Handling”. From there you should see a drop-down menu labeled “Helpline Routing” open it, make sure “Volunteers” is selected and save.
Go to Volunteers, and you should see that service body in the dropdown, and select it.
Click Add Volunteer. Fill out the Name field, and then click the “+” to expand out the rest of the details. You should be able to start populating the number and shift information. You will also have to click “Enable” in the bottom right. Once you are done, click “Save Volunteers”.
You can also sort the sequence by dragging and dropping the volunteer cards.
Go to Schedules to preview your changes. Select your service body from the dropdown, and it should render onto the calendar.
You can now test to see if things are working.
- Volunteer Routing Redirect: You do this by setting in the Service Body Call Handling the Volunteer Routing mechanism to “Volunteers Redirect” and specifying the respective Service Body Id in the “Volunteers Redirect Id” field.
- Forced Caller Id: This setting changes the outgoing display caller id.
- Call Timeout: This is the number of seconds before trying the next number for volunteer routing.
SMS Volunteer Routing
SMS
or Phone & SMS
.
The SMS trigger keyword by default is “talk”, followed by the location information. You can override this by using the sms_helpline_keyword
setting. You cannot use the word “help” or “stop” by itself as these are reserved keywords by Twilio. You could however, use a combination of words like “get help” or “need help”.
As a safety measure, if no volunteers are specified with “SMS”, but it’s enabled on the service body call handling, it will send to the primary contact number.
Voicemail
This is configured through service body call handling, through your call strategy setting.Voicemail Recordings
NEW in Yap 3.x Recordings are now available in the admin portal under “Service Bodies > Call Records” for each respective area.Voicemail Notifications to SMS
NEW in Yap 3.x You can set up any volunteer to receive voicemail notifications. Within the volunteer setting, set the dropdown Responder to “Enabled”. If you specify a Primary Contact Number, it will SMS a link to the recording that person when a voicemail is left. You can also comma separate the values if you want it to go to more than one person.Voicemail Notifications to Email
You can also optionally use email. You will have to enable this by adding an email address under the Primary Contact Email. You can optionally supply a list of comma separated emails for multiple recipients. You will also need to ensure that the following settings are in yourconfig.php
.
static $smtp_host = ''; // the smtp server
static $smtp_username = ''; // the smtp username
static $smtp_password = ''; // the smtp password
static $smtp_secure = ''; // either ssl (port 486) or more securely tls (port 587)
static $smtp_from_address = ''; // the address where the email will be sent from
static $smtp_from_name = ''; // the label name on the from address
If you need to, for some reason, to override the port here is another optional setting.
static $smtp_alt_port = ''; // enter the integer for the respective to use
If you do not receive an email, check your server logs. There should be some good information there. Also the upgrade advisor should give you some information about what might be missing as long as $smtp_host is set.
Specialized Routing
Gender Routing
Gender routing allows you to specify volunteers as Male or Female to enable callers to speak with volunteers of their gender selection.
This setting is configured from within each service body call handling.
If you want to add the option to allow callers to choose no preference for gender, add the following setting:
static $gender_no_preference = true;
Language
You can tag volunteers to zero or more languages (The default setting will be whatever the first option is in the language_selections
setting. This setting takes effect in the case that no language has been set on a volunteer). Be sure to set the list of languages you want your callers to be prompted, see Language Options for more information.
Service Body Direct Dial
If you set the config valueextension_dial = true
, you can override the default behavior of any phone number to ask for a service body ID. This will then route the call directly to that service body. Volunteer Auto Answer
By using this feature it will automatically answer the call. This can have the side effect of going to someone’s voicemail however. To enable add to your config.php:
static $volunteer_auto_answer = true;
Logging Debugging
To enable advanced debugging set in your config.php
static $debug = true;
Playback for the Just For Today Meditation
This will add an option on the main menu to press 3 to playback the Just For Today meditation.
static $jft_option = true;
Upgrading
Upgrading from Yap 1.x to Yap 2.x
You will also need to follow item #3 & #4 under Setup, to add the Twilio credentials.
You can check that everything is functioning by going to the upgrade advisor
https://your-instance/upgrade-advisor.php
Upgrading from Yap 2.x to Yap 3.x
Follow the upgrading steps here first. You will also need to follow item #8 under Setup, to add the database configuration.
You can check that everything is functioning by going to the upgrade advisor
https://your-instance/upgrade-advisor.php
If you need to re-import your data from your root server you can run the following script. This will delete any changes you have made since you upgraded.
TRUNCATE TABLE config;
DELETE FROM flags WHERE flag_name='root_server_data_migration';
Contribute
ngrok
. Grab the ngrok hostname that is generated and then use that in your Twilio settings.
You get an instant proxy to your local services to step through and debug.