I have a Hubspot chatbot on my website which asks customers to enter a departure date. They enter it in dd/mm/yyyy format and it saves to a custom date picker property. However, when the departure date response is saved to the custom property, it saves in a US format (mm/dd/yyyy), For example, if I entered 08/06/23 in the chatbot, it saves as 06/08/23, and this doesn't work for our UK based sales team.
We did try re-formatting the date via a "format data" action in a workflow and changing the date format to a %m/%d/%Y date format but the workflow would mistakenly reformat the date to mm/dd/yyyy if the day element of the departure date was 13 or greater, resulting in incorrect dates. For example, if I entered 28/06/23, it saved as 28/06/23 in the custom property, but then the re-formatting workflow changed it to 06/28/23.
I have spoken to Hubspot's strategic support about this and they said "So our chatbot in the second case is dynamically adjusting to the fact that the date provided cannot fit a MM/DD/YYYY format when the first number is greater than 12. Based on my understanding, we can't alter the chatflow's date format default *yet*, but it does adapt when forced to view a date in a European format." They suggested using a custom code to re-format the date. However, I'm not a developer and don't have access to one.
Is anyone able to help me with the custom code I would require to re-format the dates only where the day element is 12 or less?
I think I have this solved! Long story short, it's probably best to save the date provided by the user as a string, and then convert that string into the date as desired using code actions.
Here I have provided ways to do that both within the chat bot, which allows you to have users confirm that the date entered is correct; and in a workflow, which allows you to get the final date value for use elsewhere in your system.
Let me know if any of this needs clarifying!
The Chatbot
This shows a rough outline of the bot itself - key parts are as follows:
Question that saves the date response as a string to a field on the contact
Code Snippet that reformats the date and displays it back to the user
Question that confirms whether the date value returned is correct.
If/then outcomes on the question that allow the user to go back to the first Question if they entered the wrong date
Code Snippet
The code snippet below (most up to date version is the text, the screenshot just shows roughly what it should look like) does the following:
Gets the datestring value that was entered by the user
Splits it by "/" and/or "-"
Takes the three resulting values, and creates a dd/mm/yyyy date from them.
Displays that date in UK format
If there's an error (incorrect entry), returns an error message to the user
exports.main = (event, callback) => {
//get the date string that the user input
try {
const customDateString = event.session.properties.CONTACT['customdatestring'].value.trim();
//split the date string on all "/" or "-"
var customDateArray = customDateString.split(/\/|-/);
//if the year was input as only the last two digits, add the '20' to make sure it parses right
if (customDateArray[2].length == 2) {customDateArray[2] = '20'+customDateArray[2]}
//create a new date, using the first value as the day, second value as the month (it's minus one because the index for months starts at 0), and the third value as the year. Indexes in javascript start at 0, so 'value 1' is index 0.
var correctDate = new Date(customDateArray[2], (parseInt(customDateArray[1]) - 1), customDateArray[0].padStart(2, '0'))
//output the date formatted so that your UK readers will see it as they expect
const messageDate = correctDate.toLocaleDateString('en-GB');
//format the message the bot will send
const outputMessage = 'I understood that date as: ' + messageDate;
const responseJson = {
//this is the message the bot sends
botMessage: outputMessage,
//the bot does not expect a response
responseExpectd: false
}
//send the message
callback(responseJson);
}
catch (err) {
const errorMessage = "Incorrect date value entered";
const responseJson = {
//this is the message the bot sends
botMessage: errorMessage,
//the bot does not expect a response
responseExpectd: false
}
//send the message
callback(responseJson);
}
};
Example:
This is what it looks like when working!
Workflow
The workflow shown below takes the datestring, and converts it (correctly) into a hubspot date value.
Steps:
Trigger step: make sure you have this set to re-enrol on "customdatestring is known"
Custom code
inputs the customdatestring
outputs 'outputdate' as a number - this is important
the outputDate value has to be floored to remove the irrelevant time values
Format date
take the outputDate variable from the code, and add 0 days to it, outputing as date and copy into your destination date field, in this case customdatefield
exports.main = async (event, callback) => {
/*****
Use inputs to get data from any action in your workflow and use it in your code instead of having to use the HubSpot API.
*****/
const customDateString = event.inputFields['customdatestring'];
console.log(customDateString, typeof(customDateString));
var customDateArray = customDateString.split(/\/|-/);
if (customDateArray[2].length == 2) {customDateArray[2] = '20'+customDateArray[2]}
var correctDate = new Date(customDateArray[2], customDateArray[1], customDateArray[0])
const outputDate = Math.floor(correctDate.getTime());
/*****
Use the callback function to output data that can be used in later actions in your workflow.
*****/
callback({
outputFields: {
outputDate: outputDate
}
});
}
I'm happy to help with custom code if that is what is needed, but honestly the response from support makes no sense here. If you're saving this in a date picker field, it's being saved as a number of miliseconds since January 1, 1970 00:00:00.
Can you confirm that you have your settings as below? I suspect what's actually happening is that it's saving it correctly as the miliseconds value, and your reformatting is actually changing the underlying date to be wrong so that it appears correct.
If this isn't the issue, I'm happy to continue helping.
Additionally to the request to see an example of greater than 13 in the day value; if you can do the following as a test that would be great!
Take this code snippet and insert it into a brand new workflow in your HubSpot environment (as a custom code action). What it's going to do is show us the UNIX timecode value that HubSpot is saving the date as. You insert the text of the code below into the code box in the workflow editor.
You'll also need to make sure that the highlighted red box has the name of your date field in it, but that the field to the right of it (that says customdatefield) in the screenshot) still says customdatefield.
Once you have it set up as below, click the "Test" dropdown and then select a contact with this field filled out as you've shown (for best results, testing on both a "day is greater than 13" and "day is less than 13" would be optimal).
Once you've selected an appropriate contact, hit the "Test" button, and then copy the number that it outputs and share it back here. That data is just the date value - if you have any security concerns with this, you can see that we're not inputting a Secret (this is what would let the HubSpot API pull data from your system) and the only property you're including is the date field we're examining. With this code as is, it's not at all possible for me or anyone else reading this to use the data you'd be sharing for anything except reading that date value.
Oh, you are absolutely right that's bizarre. I'm working out a lil code snippet for you to use here, but can you also show me an example from the chatbot where the day value is greater than 13? Seeing how it then inserts that into the property will help a lot.
I think I have this solved! Long story short, it's probably best to save the date provided by the user as a string, and then convert that string into the date as desired using code actions.
Here I have provided ways to do that both within the chat bot, which allows you to have users confirm that the date entered is correct; and in a workflow, which allows you to get the final date value for use elsewhere in your system.
Let me know if any of this needs clarifying!
The Chatbot
This shows a rough outline of the bot itself - key parts are as follows:
Question that saves the date response as a string to a field on the contact
Code Snippet that reformats the date and displays it back to the user
Question that confirms whether the date value returned is correct.
If/then outcomes on the question that allow the user to go back to the first Question if they entered the wrong date
Code Snippet
The code snippet below (most up to date version is the text, the screenshot just shows roughly what it should look like) does the following:
Gets the datestring value that was entered by the user
Splits it by "/" and/or "-"
Takes the three resulting values, and creates a dd/mm/yyyy date from them.
Displays that date in UK format
If there's an error (incorrect entry), returns an error message to the user
exports.main = (event, callback) => {
//get the date string that the user input
try {
const customDateString = event.session.properties.CONTACT['customdatestring'].value.trim();
//split the date string on all "/" or "-"
var customDateArray = customDateString.split(/\/|-/);
//if the year was input as only the last two digits, add the '20' to make sure it parses right
if (customDateArray[2].length == 2) {customDateArray[2] = '20'+customDateArray[2]}
//create a new date, using the first value as the day, second value as the month (it's minus one because the index for months starts at 0), and the third value as the year. Indexes in javascript start at 0, so 'value 1' is index 0.
var correctDate = new Date(customDateArray[2], (parseInt(customDateArray[1]) - 1), customDateArray[0].padStart(2, '0'))
//output the date formatted so that your UK readers will see it as they expect
const messageDate = correctDate.toLocaleDateString('en-GB');
//format the message the bot will send
const outputMessage = 'I understood that date as: ' + messageDate;
const responseJson = {
//this is the message the bot sends
botMessage: outputMessage,
//the bot does not expect a response
responseExpectd: false
}
//send the message
callback(responseJson);
}
catch (err) {
const errorMessage = "Incorrect date value entered";
const responseJson = {
//this is the message the bot sends
botMessage: errorMessage,
//the bot does not expect a response
responseExpectd: false
}
//send the message
callback(responseJson);
}
};
Example:
This is what it looks like when working!
Workflow
The workflow shown below takes the datestring, and converts it (correctly) into a hubspot date value.
Steps:
Trigger step: make sure you have this set to re-enrol on "customdatestring is known"
Custom code
inputs the customdatestring
outputs 'outputdate' as a number - this is important
the outputDate value has to be floored to remove the irrelevant time values
Format date
take the outputDate variable from the code, and add 0 days to it, outputing as date and copy into your destination date field, in this case customdatefield
exports.main = async (event, callback) => {
/*****
Use inputs to get data from any action in your workflow and use it in your code instead of having to use the HubSpot API.
*****/
const customDateString = event.inputFields['customdatestring'];
console.log(customDateString, typeof(customDateString));
var customDateArray = customDateString.split(/\/|-/);
if (customDateArray[2].length == 2) {customDateArray[2] = '20'+customDateArray[2]}
var correctDate = new Date(customDateArray[2], customDateArray[1], customDateArray[0])
const outputDate = Math.floor(correctDate.getTime());
/*****
Use the callback function to output data that can be used in later actions in your workflow.
*****/
callback({
outputFields: {
outputDate: outputDate
}
});
}
One question I have, if they enter a date in the incorrect format and receive the error message, is there a way to force them to re-enter the date automatically, rather than giving them an option? For example, I can still type in something like "June or July", which prompts the error message, but they can still click "yes" to continue, which then causes the webhook code to fail.
exports.main = (event, callback) => {
//get the date string that the user input
try {
const customDateString = event.session.properties.CONTACT['customdatestring'].value.trim();
//split the date string on all "/" or "-"
var customDateArray = customDateString.split(/\/|-/);
//if the year was input as only the last two digits, add the '20' to make sure it parses right
if (customDateArray[2].length == 2) {customDateArray[2] = '20'+customDateArray[2]}
//create a new date, using the first value as the day, second value as the month (it's minus one because the index for months starts at 0), and the third value as the year. Indexes in javascript start at 0, so 'value 1' is index 0.
var correctDate = new Date(customDateArray[2], (parseInt(customDateArray[1]) - 1), customDateArray[0].padStart(2, '0'))
//output the date formatted so that your UK readers will see it as they expect
const messageDate = correctDate.toLocaleDateString('en-GB');
//format the message the bot will send
const outputMessage = 'I understood that date as: ' + messageDate;
const responseJson = {
//this is the message the bot sends
botMessage: outputMessage,
//the bot does not expect a response
responseExpectd: false
}
//send the message
callback(responseJson);
}
catch (err) {
const errorMessage = "Incorrect date value entered";
const responseJson = {
//this is the message the bot sends
botMessage: errorMessage,
//the bot does not expect a response
responseExpectd: false,
//make sure that the name here in the quotes is the name of the question where you originally asked for the departure date
nextModuleNickname: "Departure Date Question"
}
//send the message
callback(responseJson);
}
};
By using the "nextModuleNickname" option in the callback response, you can force it to go back to the departure date question and evaluate again. Just make sure you've set an internal name for that question, and replace "Departure Date Question" with your name for it.