Create a weather voice assistant in React
In this tutorial we are going to create a simple React app that will use the speechSynthesis API to speak the current temperature in the city we type in.
Prerequisites
- Signup for a key at rapidapi
- Can create a new React App. I recommend Create React App or heading to codesandbox.io (Note there is no real dependency on using react for this application, this is just the framework I am most comfortable with.)
Firstly we will create the UI for the page. (For simplicity only basic styling will be done here.)
<div className="wrapper">
<div>
<p>Type in a city to see the current weather.</p>
<input id="city" type="text" />
<button
onClick={() => speakTheWeather(document.getElementById("city").value)}
>
search
</button>
</div>
</div>
))}
Now we will create a function called speakTheWeather
that will use SpeechSynthesisUtterance
to tell us the weather.
const speakTheWeather = (city) => {
let msg = new SpeechSynthesisUtterance();
const voices = window.speechSynthesis.getVoices();
msg.voice = voices[0];
msg.text = "Tell me the weather";
speechSynthesis.speak(msg);
};
So far when we type a city and click search our assistant will say Tell me the weather. There is a lot of configuration you can do with the voice including pitch,lang,rate,voice,volume
and the results from these configurations can vary from browser/device. See the MDN Website for more details.
Now we will extend our function to tell us the weather so we will fetch the weather from the specified city as shown below. Note we will store our API details in another file, the value of the WEATHER_API
is https://community-open-weather-map.p.rapidapi.com/weather?units=metric
.
In the below code if we type in a city that the api has a result for we will hear our browser say eg The current TEMPERATURE for London is 25 degrees. If we input a value it can't find it will say unable to get the TEMPERATURE for ...
const speakTheWeather = (city) => {
let msg = new SpeechSynthesisUtterance();
const voices = window.speechSynthesis.getVoices();
msg.voice = voices[0];
fetch(`${WEATHER_API}&q=${city}`, {
headers: {
"X-RapidAPI-Key": WEATHER_API_KEY,
},
})
.then(function (response) {
return response.json();
})
.then(function (myJson) {
msg.text = `The current TEMPERATURE for ${city} is ${myJson.main.temp} degrees`;
speechSynthesis.speak(msg);
})
.catch(function (err) {
msg.text = `unable to get the TEMPERATURE for ${city}`;
speechSynthesis.speak(msg);
});
};
And there we have it our browser now speaks tells us the Temperature for the city we type in. We will add one more change to the code and add in a sessionStorage
layer to the code so that we only call the api once for each city in each session.
const speakTheWeather = (city) => {
let msg = new SpeechSynthesisUtterance();
const voices = window.speechSynthesis.getVoices();
msg.voice = voices[0];
if (sessionStorage[city] !== undefined) {
msg.text = `The current TEMPERATURE for ${city} is ${sessionStorage[city]} degrees`;
speechSynthesis.speak(msg);
} else {
fetch(`${WEATHER_API}&q=${city}`, {
headers: {
"X-RapidAPI-Key": WEATHER_API_KEY,
},
})
.then(function (response) {
return response.json();
})
.then(function (myJson) {
sessionStorage[city] = myJson.main.temp;
msg.text = `The current TEMPERATURE for ${city} is ${myJson.main.temp} degrees`;
speechSynthesis.speak(msg);
})
.catch(function (err) {
msg.text = `unable to get the TEMPERATURE for ${city}`;
speechSynthesis.speak(msg);
});
}
};
Now you have the power to use the speechSynthesis
api how are you going to incorporate it into your app?
See working example on codesandbox