Testing for out of hours call forwarding - twilio

I need to get a call forwarding number in place so that outside of uk office hours all incoming calls redirect to our out of hours service.
I've written this which returns a $status = 'closed';
<?php
// set the timezone
date_default_timezone_set ('Europe/London');
function checkDateValue($val, $args) {
if (($val) >= $args['min'] && ($val) <= $args['max'] ) :
return true;
else :
return false;
endif ;
}
// set min and max valuesfor hours, minutes and seconds - format HH:MM:SS
$hours = array(
'min' => '09:00:00',
'max' => '17:30:00'
);
// set min and max values bwtween 0 nd 6. 0 = sunday
$days = array(
'min' => 1,
'max' => 5
);
// store current time
$currentTime = time();
// test if the current time is in opening hours or is a weekday
$status = 'open';
if (checkDateValue(date('H:i:s', $currentTime), $hours) === false || checkDateValue(date('w', $currentTime), $days) === false) {
$status = 'closed';
}
I'm wondering if there is anything in the the php-sdk or in twiml that can handle conditional dialing based on detecting the time of day and day of the week and that also accounts for current callers timezone.
Thanks.

Twilio developer evangelist here.
There's nothing within Twilio's PHP SDK or TwiML that will do this time detection for you, you will need to write your own method (as you have done) to detect the current time and then use that to return different TwiML to perform the in hours or out of hours response.
So, you could add to your current script something like:
use Twilio\TwiML;
$response = new TwiML;
if ($status == 'closed') {
$response->say("Sorry, the office is closed right now");
} else {
$response->dial($officePhone);
}
echo $response;
I'm not sure why you would need to account for the current caller's time zone, your UK hours won't change if someone calls from France. Perhaps you could comment or update your question with a bit more detail. Otherwise, hope this helps.

Related

Is my Twilio function correct for routing a call based on day of week and time of day?

I'm trying to route calls to different agents based on time of day using Twilio Studio referencing the following function and wondering if it's correct? I'm not a programmer, so this is adapted from Need help creating a Time Gate in Twilio Function
// Time of Day Routing
// Useful for IVR logic, for Example in Studio, to determine which path to route to
// Add moment-timezone 0.5.31 as a dependency under Functions Global Config, Dependencies
const moment = require('moment-timezone');
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.VoiceResponse();
function businessHours() {
// My timezone East Coast (other choices: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
const now = moment().tz('America/Denver');
// Weekday Check using moment().isoWeekday()
// Monday = 1, Tuesday = 2 ... Sunday = 7
if(now.isoWeekday() == 1 || 3 || 5 /* Check for Normal Work Week Monday - Friday */) {
//Work Hours Check, 9 am to 5pm (17:00 24 hour Time)
if((now.hour() >= 8 && now.hour() < 9:30) || (now.hour() >= 12 && now.hour() < 17) /* 24h basis */) {
return true
}
}
if(now.isoWeekday() == 2 /* Check for Normal Work Week Monday - Friday */) {
//Work Hours Check, 9 am to 5pm (17:00 24 hour Time)
if((now.hour() >= 8:30 && now.hour() < 11) /* 24h basis */) {
return true
}
}
if(now.isoWeekday() == 4 /* Check for Normal Work Week Monday - Friday */) {
//Work Hours Check, 9 am to 5pm (17:00 24 hour Time)
if((now.hour() >= 8 && now.hour() < 10:30) || (now.hour() >= 15 && now.hour() < 17) /* 24h basis */) {
return true
}
}
// Outside of business hours, return false
return false
};
const isOpen = businessHours();
if (isOpen) {
twiml.say("Business is Open");
} else {
twiml.say("Business is Closed");
}
callback(null, twiml);
};
Twilio developer evangelist here.
Stack Overflow is not the best place to ask "is this correct?". It's much better to come with an actual problem that you have and a description of the things you have tried to fix that problem. It's also hard to answer "is this correct?" if we don't know the outcome you actually want.
However, I can see one issue with the code above and that is dealing with working hours that fall outside of just on the hour tests.
now.hour() will return a whole number that is the current hour. You cannot compare this to 9:30 for example. Instead, we have to look at both the hours and the minutes,
In your first conditional hour check you have:
if((now.hour() >= 8 && now.hour() < 9:30) || (now.hour() >= 12 && now.hour() < 17) /* 24h basis */) {
return true
}
In words, you seem to be going for: If the time is between 8am and 9:30am or the time is between 12pm and 5pm then return true.
To cope with the time 9:30 we have to check that the time is between 8am and 10am and if it is some number of minutes past 9, that number of minutes is not more than 30. Just to cut down the code we are looking at, the issues is this predicate:
(now.hour() >= 8 && now.hour() < 9:30)
We could replace this with:
((now.hour() >= 8 && now.hour() < 9) || (now.hour() == 9 && now.minute() < 30))
This now tests that the hour is more than or equal to 8 and less than 9 OR that the hour is equal to 9 and the minutes are less than 30.
Since "greater than or equal to 8 and less than 9" is effectively the same as "equal to 8" we could shorten this to:
(now.hour() === 8 || (now.hour() == 9 && now.minute() < 30))
But you will want to use the full version when you want to fix further comparisons, like between 8:30 and 11 or between 8 and 10:30.
Hopefully this gives you a good idea of how to approach all your time comparisons.

Check what Date Format user uses

How can I check within my Rails app what datetime format the user currently uses as his default?
I have this method:
def local_date(date, am_pm = false)
unless am_pm
date&.localtime&.strftime('(%d.%m.%Y, %H:%M)')
else
date&.localtime&.strftime('(%d.%m.%Y, %I:%M %p)')
end
end
I need to set am_pm accordingly to users local machines datetime format WITHOUT relying on the :locale parameter as not everyone who speaks english uses am/pm
This is achievable in Rails only with the help of a bit of client side JavaScript code. The client side code would detect whether the user is using 24 hours time format or 12 hours time format, and then store that information of a cookie.
Your server side code should then read that information from the cookie and set your time format accordingly.
Add this to your app/assets/javascript/application.js file.
function getCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
var date = new Date(Date.UTC(2012, 11, 12, 3, 0, 0));
var dateString = date.toLocaleTimeString();
//apparently toLocaleTimeString() has a bug in Chrome. toString() however returns 12/24 hour formats. If one of two contains AM/PM execute 12 hour coding.
if (dateString.match(/am|pm/i) || date.toString().match(/am|pm/i) )
{
//12 hour clock
//check if we are already rendering in 12 hours format
if(getCookie("time_format") != "twelve")
{
document.cookie = "time_format=twelve";
/***
Now force the browser to reload current page from server.
Since we had set the the cookie, the server will now render
all pages in 12 hours format
****/
location.reload(true).
}
}
else
{
//24 hour clock
document.cookie = "time_format=twenty_four";
}
In your ApplicationController
class SomeController < ApplicationController
around_faction :set_time_format
def set_time_format
if cookie[:time_format]=="twelve"
#Set your desired time format string with 12 hour style
else
#default
#Set your desired time format string with 24 hour style
end
end
end

Twilio Function - Using Moment for Open Office Hours

Hi Im trying to get this working properly. I'd like the open time to be set between 14:00 UTC and 22:00 UTC. But it doesn't seem to work.
When I call the function url I get a return of "open" when I call it outside of the open times.
Can anyone help me with this? Thanks.
exports.handler = function(context, event, callback) {
const moment = require('moment');
let callerId = event.Caller; // || "+1-000-000-0000"; // default caller ID
let twiml = new Twilio.twiml.VoiceResponse();
if ((moment().hour() >= 14 || moment().hour() < 22) && moment().isoWeekday() <= 5) {
twiml.say("Open");
} else {
twiml.say("Closed");
}
twiml.redirect("http://twimlets.com/voicemail?Email=eeemail#email.com&Message=Please%20leave%20a%20message.&Transcribe=true");
callback(null, twiml);
};
Your code sample you have the hour 17 not 14, anyway, this thing:
(moment().hour() >= 17 || moment().hour() < 22)
will always return true, change it to:
(moment().hour() >= 17 && moment().hour() < 22)
to get the time between 5 PM and 10 PM

Timestamp pattern

Let's assume I have the following reminder timestamp
local reminder_timestamp = "2013-12-13T00:00:00+01:00"
And I'm using the below function to return time in UTC
local function makeTimeStamp(dateString)
local pattern = "(%d+)%-(%d+)%-(%d+)%a(%d+)%:(%d+)%:([%d%.]+)([Z%p])(%d%d)%:?(%d%d)"
local year, month, day, hour, minute, seconds, tzoffset, offsethour, offsetmin = dateString:match(pattern)
local timestamp = os.time( {year=year, month=month, day=day, hour=hour, min=minute, sec=seconds} )
local offset = 0
if ( tzoffset ) then
if ( tzoffset == "+" or tzoffset == "-" ) then -- we have a timezone!
offset = offsethour * 60 + offsetmin
if ( tzoffset == "-" ) then
offset = offset * -1
end
timestamp = timestamp + offset
end
end
return timestamp
end
What should be the pattern above to match the reminder timestamp I mentioned earlier?
You need to use Lua's string parsing capabilities. Try a few of the techniques mentioned in the following, and if you still have issues, post specifically what is not working:
Question about splitting string and saving in several variables
Question about extracting data from a string, very similar to yours (although problem domain is GPS coordinates instead of date/time)
Question about how to do pattern matching in Lua, several good examples and links to docs
Here is the answer and the function actually works fine
pattern = "(%d+)%-(%d+)%-(%d+)%a(%d+)%:(%d+)%:([%d%.]+)([Z%p])(%d%d)%:?(%d%d)"
reminder_timestamp = "2013-12-23T08:00:00+01:00"
local year, month, day, hour, minute, seconds, tzoffset, offsethour, offsetmin = reminder_timestamp:match(pattern)
Resource: http://www.lua.org/manual/5.1/manual.html#5.4.1

time/date calculations

I have a database of users and each user has its own timezone settings.
For example, user A has GMT-05:00 , user B has GMT+1:00 , etc
I am trying to display the correct current date/time for this users using the simplest way I can find. I got to this code, which although it looks good (imho), it displays a positive difference (+5 hours) instead of negative (minus 5 hours).
Script below:
<?php
// below two lines -- info that I normally take from DB
$row['callstart'] = "1362067791"; // unixtimestamp
$userInfo['timezone'] = 'GMT-5';
echo date('Y-m-d H:i:s',$row['callstart'])."\n"; // original hour
$date = date('Y-m-d H:i:s',$row['callstart']);
$date = new DateTime($date,new DateTimeZone('GMT'));
$date->setTimezone(new DateTimeZone($userInfo['timezone']));
$row['callstart'] = $date->format('Y-m-d H:i:s');
echo $row['callstart']; // converted to GMT-5 hour
?>
Results below:
root#ssw238:/tmp# php /work/yy.php
2013-02-28 16:09:51 // that's the current GMT hour/date
2013-02-28 21:09:51 // should actually be 11:09:51 instead of 21:09:51
root#ssw238:/tmp#
Any idea where and what I am doing wrong?
This is when common sense works against us... From Wikipedia
In order to conform with the POSIX style, those zone names beginning with "Etc/GMT" have their sign reversed from what most people expect. In this style, zones west of GMT have a positive sign and those east have a negative sign in their name (e.g "Etc/GMT-14" is 14 hours ahead/east of GMT.)
So the solution is
// below two lines -- info that I normally take from DB
$row['callstart'] = "1362067791"; // unixtimestamp
// reversed the sign
$userInfo['timezone'] = 'GMT+5';
echo date('Y-m-d H:i:s',$row['callstart'])."\n"; // original hour
$date = date('Y-m-d H:i:s',$row['callstart']);
$date = new DateTime($date,new DateTimeZone('GMT'));
$date->setTimezone(new DateTimeZone($userInfo['timezone']));
$row['callstart'] = $date->format('Y-m-d H:i:s');
echo $row['callstart']; // converted to GMT-5 hour
hmmm ... i rather youse this
<?php
$row['callstart'] = "1362067791";
$userInfo['timezone'] = 'GMT-5';
$orginal =date('Y-m-d H:i:s',$row['callstart']);
echo $orginal;
echo '<br/>';
$newdate=date('Y-m-d H:i:s',($orginal + strtotime(substr($userInfo['timezone'] ,3).'hours')));
echo $newdate
?>
2013-02-28 17:09:51
2013-02-28 13:22:36

Resources