SUSI.AI Chromebot has almost all sorts of reply that SUSI.AI Server can generate. But it still missed the Map Type response that was generated by the SUSI.AI Server.
This blog explains how the map type response was added to the chromebot.
Brief Introduction
The original issue was planned by Manish Devgan and Mohit Sharma as an advanced task for Google Code-In 2017. The link to which can be found here: #157
For a long time the issue remained untouched and after GCI got over I assigned the issue to myself as it was a priority issue since MAP type was a major response from the SUSI.AI Server.
How was Map Type response added?
There were a lot of things to be taken in mind before starting working on this issue.
- Changing code scheme during GCI and other PRs
- API Response from the SUSI.AI Server
- Understanding the new codebase that got altered during GCI-17
- Doing it quick
I will go through all the steps in detail
Changing Code Scheme
The code was altered numerous times with the addition of a number of pull requests during GCI-17 and there were no docstrings for any functions and methods. So I had to figure them out in order to start working on the map type response.
API Response from the SUSI.AI Server
To understand the JSON that server sent, I went to SUSI.AI API and did a simple search for
“Where is Berlin?” and the response generated is given below.
( Since the JSON is very big I am only posting the relevant data for this issue )
"actions": [ { "type": "answer", "language": "en", "expression": "Berlin (, German: [bɛɐ̯ˈliːn] ( listen)) is the capital and the largest city of Germany as well as one of its 16 constituent states." }, { "type": "anchor", "link": "https://www.openstreetmap.org/#map=13/52.52436820069531/13.41053001275776", "text": "Here is a map", "language": "en" }, { "type": "map", "latitude": "52.52436820069531", "longitude": "13.41053001275776", "zoom": "13", "language": "en" } ] |
Here we see and understand that “actions” is an Array of JSONs and the third part has “type” as “map”. This is the relevant information that we require for generating the map-type response.
The important variables in this context are: “latitude” and “longitude”.
Understanding the Codebase
Now I had to figure out the new pattern of adding response types to the SUSI.AI Chromebot.
After having a talk with @ms10398 I figured out the route map.
The above image shows the correct flow of Javascript Code that generated the response. After this, I was good to go and start my work.
Adding the Map-Type Response
To start with I chose “LEAFLET.JS” as the Javascript Library that will be used to create maps.
- So I added the LEAFLET.JS to the JS folder.
- Now changes were made to the “index.html” file
<link rel=”stylesheet” href=”https://unpkg.com/leaflet@1.3.1/dist/leaflet.css” /> http://âjs/leaflet.jsâ |
Appropriate CSS was added along with a link to leaflet.js was added.
- Adding CSS to the “mapClass”
.mapClass{ height : 200px; width : 200px; } |
- Generating Maps with dynamic IDs
This part was where I applied brain, as to add the map to any div we required the div to have a proper and unique ID and so a way to generate unique IDs for div without using any external source was to be thought of.
I came with idea of using timestamp, as it will always be unique.
var timeStamp = new Date.now().toString();
|
Then I created the “composeMapReply()” function.
function composeReplyMap(response, action){ var newDiv = messages.childNodes[messages.childElementCount]; var mapDiv = document.createElement(“div”); var mapDivId = Date.now().toString(); mapDiv.setAttribute(“id”, mapDivId); mapDiv.setAttribute(“class”, “mapClass”); newDiv.appendChild(mapDiv); messages.appendChild(newDiv); var newMap = L.map(mapDivId).setView([Number(action.latitude), Number(action.longitude)], 13); L.tileLayer(“https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}”,{ /* This part contains the data for api call. */ }).addTo(newMap); response.isMap = true; response.newMap = mapDiv; return response } |
The complete code can be found: here
At last after adding so many snippets of code we were able to generate the Map-Type response for SUSI.AI Chromebot
GIF
A gif showing the Map-Type response in action.
Resources
- Learn about LEAFLET.JS : leafletjs.com/
- Javascript setAttribute() : https://www.w3schools.com/jsref/met_element_setattribute.asp
- Link to SUSI.AI API : https://api.susi.ai
- Learn more about Date.now() in Javascript : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now
- Convert strings to Numbers in Javascript : https://www.w3schools.com/jsref/jsref_number.asp
- Learn how to interpret JSON : https://www.w3schools.com/js/js_json_intro.asp
- Issue for the same : https://github.com/fossasia/susi_chromebot/issues/157
- Pull Request for the same : https://github.com/fossasia/susi_chromebot/pull/287