deep-jade
deep-jade2y ago

Google Directions API - timetable information public transportation

Hi guys, I would like to create a timetable information via Google Maps using VF. Which Google API do I need to use (is it the Directions API) How can I correctly integrate the API into Voiceflow? The Voiceflow user should enter the stop where he would like to get on and then enter the stop where he would like to get off. He also needs to be able to enter the date and time of his trip. After entering this data, Google's timetable information should display the appropriate route in Voiceflow, both as text and as a map. Is something like that possible? I look forward to your input and thank you in advance for your help!
No description
16 Replies
NiKo | Voiceflow
Yes, this is be doable using Google APIs but you will also need custom components in the react chat to render that in the Chat widget or a dedicated integration if you're thinking of implementing this for another channel. As an example, here a simple demo generating the instructions from the Google Directions API response and render it using a JS Step and the Text Step with markdown. jsonData is your Google Directions response from an API Step, then use the {directions} variable in a text step.
const directionsData = jsonData

let timelineMarkdown = "";
const steps = directionsData.routes[0].legs.flatMap(leg => leg.steps);

steps.forEach((step, index) => {
const icon = getIcon(step.maneuver);
const instruction = step.html_instructions
.replace(/<b>/g, '**')
.replace(/<\/b>/g, '**')
.replace(/<wbr\/>/g, ' ');
const distance = step.distance.text;
const duration = step.duration.text;

const stepMarkdown = `#### ${icon} **${instruction}**
- **Distance:** ${distance}
- **Duration:** ${duration}
\n ---
`;
timelineMarkdown += stepMarkdown;
});

function getIcon(instruction) {
if (instruction.toLowerCase().includes('-left')) {
return '⬅️';
} else if (instruction.toLowerCase().includes('-right')) {
return '➡️';
} else if (instruction.toLowerCase().includes('continue')) {
return '➡️';
} else if (instruction.toLowerCase().includes('merge')) {
return '⬆️';
} else {
return 'ℹ️';
}
}

directions = `
<div style="font-size: small;">

# Directions

${timelineMarkdown}

</div>
`;
const directionsData = jsonData

let timelineMarkdown = "";
const steps = directionsData.routes[0].legs.flatMap(leg => leg.steps);

steps.forEach((step, index) => {
const icon = getIcon(step.maneuver);
const instruction = step.html_instructions
.replace(/<b>/g, '**')
.replace(/<\/b>/g, '**')
.replace(/<wbr\/>/g, ' ');
const distance = step.distance.text;
const duration = step.duration.text;

const stepMarkdown = `#### ${icon} **${instruction}**
- **Distance:** ${distance}
- **Duration:** ${duration}
\n ---
`;
timelineMarkdown += stepMarkdown;
});

function getIcon(instruction) {
if (instruction.toLowerCase().includes('-left')) {
return '⬅️';
} else if (instruction.toLowerCase().includes('-right')) {
return '➡️';
} else if (instruction.toLowerCase().includes('continue')) {
return '➡️';
} else if (instruction.toLowerCase().includes('merge')) {
return '⬆️';
} else {
return 'ℹ️';
}
}

directions = `
<div style="font-size: small;">

# Directions

${timelineMarkdown}

</div>
`;
You can also use Functions for this.
No description
KimLooo
KimLooo2y ago
Great post format @MoveMentor 👏 thanks for posting
deep-jade
deep-jadeOP2y ago
Thank you NiKo, but as I am a newbie to VF, I need more help, sry! So, I was able to make an API call to the Google directions API so far, this is the response:
deep-jade
deep-jadeOP2y ago
deep-jade
deep-jadeOP2y ago
So, in this API JSON answer, I have a origin (including its place ID) and a destination (also including its place ID). Now I would like to show the direction from origin to destination in an embadded map including the mode as "transit". How can I integrate my JSON answer into a map? Thank you so much for your first answer 🙂
NiKo | Voiceflow
The Google Static Maps API does not support specifying the mode of transportation (such as transit) directly in the URL for the map image but you can use the overview_polyline from the API response to generate an image. https://maps.googleapis.com/maps/api/staticmap?size=600x300&maptype=roadmap&path=enc:${overviewPolyline}&markers=color:green%7Clabel:S%7C${startLocation.lat},${startLocation.lng}&markers=color:red%7Clabel:D%7C${endLocation.lat},${endLocation.lng}&key=${apiKey} A code example to parse your API response and generate instructions + a link to the map: {APIResponse} is the variable you map the response from the API step {instructions} and {mapUrl} the variables you will use to store the value extracted from the API response in your code. Example:
const response = APIResponse // Your variable with the API response

// Extract start and end locations
const startLocation = response.routes[0].legs[0].start_location;
const endLocation = response.routes[0].legs[0].end_location;
const overviewPolyline = response.routes[0].overview_polyline.points;

// Create a Google Static Map URL
const apiKey = 'YOUR GOOGLE MAP API KEY';
mapUrl = `https://maps.googleapis.com/maps/api/staticmap?size=600x300&maptype=roadmap&path=enc:${overviewPolyline}&markers=color:green%7Clabel:S%7C${startLocation.lat},${startLocation.lng}&markers=color:red%7Clabel:D%7C${endLocation.lat},${endLocation.lng}&key=${apiKey}`;

// Generate instructions
const steps = response.routes[0].legs[0].steps;
instructions = steps.map((step, index) => {
const instructionText = step.html_instructions.replace(/<[^>]*>/g, ''); // Remove HTML tags
return `Step ${index + 1}: ${instructionText} (${step.distance.text})`;
}).join('\n');
const response = APIResponse // Your variable with the API response

// Extract start and end locations
const startLocation = response.routes[0].legs[0].start_location;
const endLocation = response.routes[0].legs[0].end_location;
const overviewPolyline = response.routes[0].overview_polyline.points;

// Create a Google Static Map URL
const apiKey = 'YOUR GOOGLE MAP API KEY';
mapUrl = `https://maps.googleapis.com/maps/api/staticmap?size=600x300&maptype=roadmap&path=enc:${overviewPolyline}&markers=color:green%7Clabel:S%7C${startLocation.lat},${startLocation.lng}&markers=color:red%7Clabel:D%7C${endLocation.lat},${endLocation.lng}&key=${apiKey}`;

// Generate instructions
const steps = response.routes[0].legs[0].steps;
instructions = steps.map((step, index) => {
const instructionText = step.html_instructions.replace(/<[^>]*>/g, ''); // Remove HTML tags
return `Step ${index + 1}: ${instructionText} (${step.distance.text})`;
}).join('\n');
No description
NiKo | Voiceflow
If instead, you want to use embedded map, then you will have to populate a variable with something like:
<iframe width="220" height="250" style="border:0" loading="lazy" allowfullscreen src="https://www.google.com/maps/embed/v1/directions?key=APIKEY&origin=51.2543161,7.1501153&destination=51.2703534,7.1949765&mode=transit">
</iframe>
<iframe width="220" height="250" style="border:0" loading="lazy" allowfullscreen src="https://www.google.com/maps/embed/v1/directions?key=APIKEY&origin=51.2543161,7.1501153&destination=51.2703534,7.1949765&mode=transit">
</iframe>
and use it in a Text step (this will not render in the Test tool for security reasons, only on the Chat widget).
No description
deep-jade
deep-jadeOP2y ago
NiKo, amazing, thank you so much for your answer. I would like to use the embedded map as you have shown here in your example. I was working with place ID instead of Lat & Lng. But with place ID it doesn't work. So I think I have to use Lat & Lng, do I? Otherwise would it be possible that you share your example here?
deep-jade
deep-jadeOP2y ago
So if I'm using the place-ID there is no direction shown...
No description
deep-jade
deep-jadeOP2y ago
how can I fetch the lng and lat from the API call?
deep-jade
deep-jadeOP2y ago
this link on the right hand side doesnt work
No description
deep-jade
deep-jadeOP2y ago
but I fixed the problem with the lat & lng, now I can fetch lat and lng from the api call
deep-jade
deep-jadeOP2y ago
this works perfectly!
No description
deep-jade
deep-jadeOP2y ago
but as I wrote before, how can I implement the lat & lng into the embadded map? thank you so much for helping me in advance and sorry, one more question: what "lat" and "lng" do I need from the API call? Do I need it from "routes" or from the "start_address" and "end_address"? Here is my JSON API Call:
deep-jade
deep-jadeOP2y ago

Did you find this page helpful?