Home Community Blog Buy Now

Misty Community Forum

Issue on Google Cloud TTS after auto-upgraded for Robot version

the Google TTS API function is not work after upgrade to the new firmware but it is work before the upgrade. Can I down grade to the previous version manually?

Hi @terence.chiu,
Which command are you using to call the Google TTS API?
If you could share the whole call without the key, it would be helpful to debug.

Herewith the code. The misty working fine by the following coding before the version upgrade, but it fail to speak after that.

// ====================================================================
// ========================== Text To Speech ==========================
// ====================================================================

// We store the text to be converted to audio in the “textToSpeak”
// global variable, and call speakTheText() function to execute TTS

function speakTheText()
// Parameters to send with request to Google TTS API.
// Feel free to change the pitch, speaking rate and gender.
// For more information see the Google TTS API developer docs:
// Method: text.synthesize  |  Cloud Text-to-Speech Documentation
var arguments = JSON.stringify({
‘input’: {
‘text’: misty.Get(“textToSpeak”)
‘voice’: {
‘languageCode’: misty.Get(“langCodeForTTS”),
‘ssmlGender’: “MALE”
‘audioConfig’: {
‘audioEncoding’: “LINEAR16”,
“effectsProfileId”: [
“pitch”: 0,
“speakingRate”: 0.91

misty.Debug("Sending Data to Google");
misty.SendExternalRequest("POST", "https://texttospeech.googleapis.com/v1beta1/text:synthesize", "Bearer", misty.Get("googleAuthToken"), arguments, false, false, null, "application/json", "_Base64In")
misty.Debug("Text sent to Google Text to Speech API");


function _Base64In(data)
misty.Debug(“Audio(base64) in from Google TTS API”);

misty.Set("playingAudio", true, false);
misty.DisplayImage("e_Love.jpg",1.0, 3000);

// If Misty is not already locked on to a human face, we use audio
// localization data to turn her head in the speaker's direction 
var angleTolook = misty.Get("speechSourceAngle") >= 0 ? misty.Get("yawLeft") * misty.Get("speechSourceAngle") / 90 : misty.Get("yawRight") * Math.abs(misty.Get("speechSourceAngle")) / 90;
if (misty.Get("findFace")) 
    misty.MoveHead(-20, 0, angleTolook, null, 1);
    misty.MoveArmDegrees((angleTolook >= 0) ? "left" : "right", 85, 60);
    misty.MoveArmDegrees((angleTolook >= 0) ? "right" : "left", -80, 60);
    misty.MoveArmDegrees((misty.Get("headYaw") >= 0) ? "left" : "right", 85, 60);
    misty.MoveArmDegrees((misty.Get("headYaw") >= 0) ? "right" : "left", -80, 60);

// Saves and plays the Base64-encoded audio data 
misty.SaveAudio("tts.wav", JSON.parse(data.Result.ResponseObject.Data).audioContent, true, true);

// Starts Misty listening to the wake word ("Hey, Misty") again
misty.DisplayImage("e_Terror2.jpg", 1.0, 3000);
misty.StartKeyPhraseRecognition(true, true, 15000);
// misty.RegisterEvent("KeyPhraseRecognized","KeyphraseRecognized", 10, false);
// misty.StartKeyPhraseRecognition();
misty.ChangeLED(255, 255, 255);
misty.Set("playingAudio", false, false);


I just want to double check that you’ve made sure that the keys that are being accessed with the misty.Get commands are still set when you’re running this. I’ve boiled down the parts that you seem to be having issues with and taken out the misty.Get portions just to show the hardcoded settings are working:

var arguments = JSON.stringify({
    'input': {
    'text': "This is a test"
    'voice': {
    'languageCode': "en-US",
    'ssmlGender': "MALE"
    'audioConfig': {
    'audioEncoding': "LINEAR16",
    "effectsProfileId": [
    "pitch": 0,
    "speakingRate": 0.91

var googleAuthToken = "<AuthToken>"

misty.SendExternalRequest("POST", "https://texttospeech.googleapis.com/v1beta1/text:synthesize", "Bearer", googleAuthToken, arguments, false, false, null, "application/json", "_Base64In")

function _Base64In(data)
    misty.Debug("Audio(base64) in from Google TTS API");

    misty.SaveAudio("tts.wav", JSON.parse(data.Result.ResponseObject.Data).audioContent, true, true);

If I set the AuthToken to a valid Access token that I got from the OAuth 2.0 playground from Google I am able to successfully call Google’s TTS service and play the audio on the robot.

Some useful tips for debugging this might be to subscribe to the SkillData websocket, when the skill calls the SendExternalRequest method that websocket will return a message with relevant information if it returned an error. For example if your misty.Get("googleAuthToken") call isn’t returning a valid OAuth2 access token you would see something like this message in the SkillData websocket:

{"data":"{\"Status\":3,\"Result\":{\"Command\":null,\"ResponseObject\":{\"Data\":\"{\\n  \\\"error\\\": {\\n    \\\"code\\\": 401,\\n    \\\"message\\\": \\\"Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.\\\",\\n    \\\"status\\\": \\\"UNAUTHENTICATED\\\"\\n  }\\n}\\n\",\"ContentType\":\"application/json\"}}}","truncated":false}

Which tells you that there was not a valid access token used. I would expect similar messages if invalid arguments are passed to the TTS API.

EDIT: In case you were expecting them to save and you are specifying to save in long term storage, make sure you follow the instructions in the Yellow Note section of Using the “Set” Command Including making sure that you have "SkillStorageLifetime" : "LongTerm" in the skill meta file, the attribute doesn’t exist by default when newly creating the meta file and must be added.

Thank you so much for your recommendation and certificated our coding without a problem. We found that the problem on our Google Cloud account billing issue, it can’t re-charge the value and caused the TTS service stopped.

The problem already got solved. Thank you!!