wake-up-neo.com

Fehler: Es wurde keine Antwort eingestellt. Cloud-Funktionen für Aktionen in Google Assistant

Ich baue eine Assistant -App für Google Home mit Dialogflow, Cloud-Funktionen und der neuen NodeJS-Client -Bibliothek V2 für Actions bei Google. Tatsächlich bin ich dabei, meinen alten mit V1 erstellten Code nach V2 zu migrieren. 

Der Kontext 

Ich versuche, den Standort des Benutzers anhand zweier getrennter Absichten abzurufen: Request Permission (Absicht, die Berechtigungsanforderung an den Benutzer auslöst/sendet) und User Info (Absicht, die prüft, ob der Benutzer die Berechtigung erteilt hat, und gibt dann die vom Assistenten angeforderten Daten zurück, um fortzufahren. 

Die Angelegenheit 

Das Problem ist, dass derselbe Code, der auf V1 problemlos funktioniert hat, nicht auf V2 funktioniert. Also musste ich ein bisschen umgestalten. Wenn ich meine Cloud-Funktion bereitstelle, kann ich erfolgreich die Erlaubnis des Benutzers anfordern, seinen Speicherort abrufen und dann eine externe Bibliothek verwenden (geocode). Ich kann den Latlong in eine für Menschen lesbare Form konvertieren. Aber aus einigen Gründen (ich denke, es ist ein Versprechen) kann ich das Versprechen nicht auflösen und es dem Benutzer zeigen 

Der Fehler

Ich erhalte den Fehler unten: 

 enter image description here

Der Code

Unten ist mein Cloud-Funktionscode. Ich habe mehrere Versionen dieses Codes ausprobiert, wobei die Bibliothek request, https usw. verwendet wurde. Kein Glück ... Kein Glück 

    const {dialogflow, Suggestions,SimpleResponse,Permission} = require('actions-on-google')  
    const functions = require('firebase-functions'); 
    const geocoder = require('geocoder');

    const app = dialogflow({ debug: true });

    app.middleware((conv) => {
        conv.hasScreen =
            conv.surface.capabilities.has('actions.capability.SCREEN_OUTPUT');
        conv.hasAudioPlayback =
            conv.surface.capabilities.has('actions.capability.AUDIO_OUTPUT');
    });

    function requestPermission(conv) {
        conv.ask(new Permission({
            context: 'To know who and where you are',
            permissions: ['NAME','DEVICE_PRECISE_LOCATION']
        }));
    }

    function userInfo ( conv, params, granted) {

        if (!conv.arguments.get('PERMISSION')) {

            // Note: Currently, precise locaton only returns lat/lng coordinates on phones and lat/lng coordinates 
            // and a geocoded address on voice-activated speakers. 
            // Coarse location only works on voice-activated speakers.
            conv.ask(new SimpleResponse({
                speech:'Sorry, I could not find you',
                text: 'Sorry, I could not find you'
            }))
            conv.ask(new Suggestions(['Locate Me', 'Back to Menu',' Quit']))
        }

        if (conv.arguments.get('PERMISSION')) {

            const permission = conv.arguments.get('PERMISSION'); // also retrievable with explicit arguments.get
            console.log('User: ' + conv.user)
            console.log('PERMISSION: ' + permission)
            const location = conv.device.location.coordinates
            console.log('Location ' + JSON.stringify(location))

            // Reverse Geocoding
            geocoder.reverseGeocode(location.latitude,location.longitude,(err,data) => {
                if (err) {
                    console.log(err)
                }


                // console.log('geocoded: ' + JSON.stringify(data))
                console.log('geocoded: ' + JSON.stringify(data.results[0].formatted_address))
                conv.ask(new SimpleResponse({
                    speech:'You currently at ' + data.results[0].formatted_address + '. What would you like to do now?',
                    text: 'You currently at ' + data.results[0].formatted_address + '.'
                }))
                conv.ask(new Suggestions(['Back to Menu', 'Learn More', 'Quit']))

            })

        }

    }


    app.intent('Request Permission', requestPermission);
    app.intent('User Info', userInfo);

    exports.myCloudFunction = functions.https.onRequest(app);

Jede Hilfe wird sehr geschätzt. Vielen Dank

8
AllJs

Sie haben die letzte Vermutung richtig - Ihr Problem ist, dass Sie keine Versprechen verwenden.

app.intent() erwartet, dass die Handler-Funktion (in Ihrem Fall userInfo) ein Promise zurückgibt, wenn async-Aufrufe verwendet werden. (Wenn nicht, können Sie mit nichts zurückkommen.)

Normalerweise verwenden Sie etwas, das ein Versprechen zurückgibt. Dies ist jedoch in Ihrem Fall schwierig, da die Geocode-Bibliothek nicht für die Verwendung von Promises aktualisiert wurde und Sie anderen Code verwenden, der in der Funktion userInfo nichts zurückgibt.

Ein Umschreiben könnte in diesem Fall ungefähr so ​​aussehen (den Code habe ich jedoch nicht getestet). Darin teile ich die beiden Bedingungen in userInfo in zwei andere Funktionen auf, so dass eine Promise zurückgegeben werden kann.

function userInfoNotFound( conv, params, granted ){
  // Note: Currently, precise locaton only returns lat/lng coordinates on phones and lat/lng coordinates 
  // and a geocoded address on voice-activated speakers. 
  // Coarse location only works on voice-activated speakers.
  conv.ask(new SimpleResponse({
    speech:'Sorry, I could not find you',
    text: 'Sorry, I could not find you'
  }))
  conv.ask(new Suggestions(['Locate Me', 'Back to Menu',' Quit']))
}

function userInfoFound( conv, params, granted ){
  const permission = conv.arguments.get('PERMISSION'); // also retrievable with explicit arguments.get
  console.log('User: ' + conv.user)
  console.log('PERMISSION: ' + permission)
  const location = conv.device.location.coordinates
  console.log('Location ' + JSON.stringify(location))

  return new Promise( function( resolve, reject ){
    // Reverse Geocoding
    geocoder.reverseGeocode(location.latitude,location.longitude,(err,data) => {
      if (err) {
        console.log(err)
        reject( err );
      } else {
        // console.log('geocoded: ' + JSON.stringify(data))
        console.log('geocoded: ' + JSON.stringify(data.results[0].formatted_address))
        conv.ask(new SimpleResponse({
          speech:'You currently at ' + data.results[0].formatted_address + '. What would you like to do now?',
          text: 'You currently at ' + data.results[0].formatted_address + '.'
        }))
        conv.ask(new Suggestions(['Back to Menu', 'Learn More', 'Quit']))
        resolve()
      }
    })
  });

}

function userInfo ( conv, params, granted) {
  if (conv.arguments.get('PERMISSION')) {
    return userInfoFound( conv, params, granted );
  } else {
    return userInfoNotFound( conv, params, granted );
  }
}
10
Prisoner

Dank @Prisoner konnte ich es funktionieren lassen. Ich musste meine Dialogflow-Struktur oder irgendetwas nicht ändern. Alles, was ich tun musste, war, den Reverse-Geocoding-Bereich in den Vorschlag von @Prisoner zu ändern. Und es hat für mich funktioniert. 

//Reverse Geocoding

return new Promise( function( resolve, reject ){
    // Reverse Geocoding
    geocoder.reverseGeocode(location.latitude,location.longitude,(err,data) => {
      if (err) {
        console.log(err)
        reject( err );
      } else {
        // console.log('geocoded: ' + JSON.stringify(data))
        console.log('geocoded: ' + JSON.stringify(data.results[0].formatted_address))
        conv.ask(new SimpleResponse({
          speech:'You currently at ' + data.results[0].formatted_address + '. What would you like to do now?',
          text: 'You currently at ' + data.results[0].formatted_address + '.'
        }))
        conv.ask(new Suggestions(['Back to Menu', 'Learn More', 'Quit']))
        resolve()
      }
   })
});

Ich kann jetzt zu anderen Dingen übergehen! 

2
AllJs