Need a bit of Alexa-to-Jovo advice

amazon-alexa

#1

Alexa has some native support for a few questions about the recording currently playing – among the MusicRecording intents, it has phrases that should get routed to the active skill’s Amazon.SearchAction handling. (See https://developer.amazon.com/en-US/docs/alexa/custom-skills/musicrecording-intents.html)

I’m not clear on what would need to be done in Jovo to catch and respond to those queries.

My attempts to guess the appropriate incantations in the app.js/handler.js haven’t yet succeeded.

Developers: Should this be doable with Jovo, and if so what’s the trick?

(I can implement equivalent queries directly in my skill, but then I would have to explicitly Ask the skill to get them routed appropriately, rather than just being able to say “Echo, who’s the performer?” I’ll do that if I must, but I’d rather have the skill’s behavior be more like other music skills. Though admittedly said skills are probably tied a lot deeper into Amazon’s presumed data structures for music catalogs.)


#2

I haven’t used these intents yet, but from the requests in the documentation, it seems like they are typical intent strings that would need to be added as intent handlers, e.g.

'AMAZON.SearchAction<[email protected][producer]>'() {
  // ...
}

What happens if you try this? Could you also send a full request JSON that you receive in your skill if you test a query like this?


#3

Ah. I’m still having trouble wrapping my head around quoted strings as “function” names; I was expecting that I could define AMAZON.SearchAction and treat the rest as parameter types. I’ll try it that way.

Query for “Who performs this song” when the skill is in stopped mode:

{
   "version": "1.0",
   "session": {
      "new": true,
      "sessionId": "amzn1.echo-api.session.55690c28-4052-4500-a7ff-a9642cdd65ba",
      "application": {
         "applicationId": "amzn1.ask.skill.c952aa96-df06-4cbf-a9a9-46b7b4113871"
      },
      "attributes": {},
      "user": {
         "userId": "amzn1.ask.account.AFG4ORA6CUUX3VDUDSGGSO6KTYNN6Y6TN7SNYYBOGRFEVEJNFFXJWPLLRSVAA7Z64XO7JBXSBGXGQDPCFBLPFEGHBJYPCA4RDB4JIV3ISLQ5SL4EHTFIFYZJCLWPBB7KY44M5B6NFBNIYBLRW6FDM2SS4YTNJJA2G7ILVFPHPZMCT3OWKCNJUHI2LMGYOWUEZWKWRH3ALTUIAEY"
      }
   },
   "context": {
      "AudioPlayer": {
         "offsetInMilliseconds": 1461816,
         "token": "null",
         "playerActivity": "STOPPED"
      },
      "Extensions": {
         "available": {}
      },
      "System": {
         "application": {
            "applicationId": "amzn1.ask.skill.c952aa96-df06-4cbf-a9a9-46b7b4113871"
         },
         "user": {
            "userId": "amzn1.ask.account.AFG4ORA6CUUX3VDUDSGGSO6KTYNN6Y6TN7SNYYBOGRFEVEJNFFXJWPLLRSVAA7Z64XO7JBXSBGXGQDPCFBLPFEGHBJYPCA4RDB4JIV3ISLQ5SL4EHTFIFYZJCLWPBB7KY44M5B6NFBNIYBLRW6FDM2SS4YTNJJA2G7ILVFPHPZMCT3OWKCNJUHI2LMGYOWUEZWKWRH3ALTUIAEY"
         },
         "device": {
            "deviceId": "amzn1.ask.device.AG73RQEX4T2TCJ4WYDKYHCXAFRGNWAHK4QSIZDKARG52EN4FCWAQVVG4GYZDJUIPV66HCV6QUYTNVZMVTIX56DGZ3SSXLV2ZEI4AG5LH2SADPGHSPGQIR72Y4SMXY2AVWJCDQ4CSCY57SV54H7MT5ZBPTN4A",
            "supportedInterfaces": {
               "AudioPlayer": {}
            }
         },
         "apiEndpoint": "https://api.amazonalexa.com",
         "apiAccessToken": "(...elided...)",
         "unit": {
            "unitId": "amzn1.ask.unit.AG4K633PFRTQ46UOUMDB3ULGNHTYA4PWMDYLVQ3P7WRZ6V6IWKHIKXBPU2766EC5UPF6GXONHQN7A5RRTV5KOHTGIFF4NE5HOBLFPFGDAXE3IGYAZBW6L4R6SXK4EJQYEY"
         }
      }
   },
   "request": {
      "type": "IntentRequest",
      "requestId": "amzn1.echo-api.request.2d23e065-9a13-444a-bf4f-a01241bf7411",
      "locale": "en-US",
      "timestamp": "2021-10-12T13:34:59Z",
      "intent": {
         "name": "AMAZON.SearchAction<[email protected][byArtist.musicGroupMember]>",
         "confirmationStatus": "NONE",
         "slots": {
            "object.byArtist.musicGroupMember.type": {
               "name": "object.byArtist.musicGroupMember.type",
               "value": "performed",
               "confirmationStatus": "NONE",
               "source": "USER",
               "slotValue": {
                  "type": "Simple",
                  "value": "performed"
               }
            }
         }
      }
   }
}

#4

Trying it that way, during build the Google Action phase tells me

 »   Error: There was a problem:
 »
 »   [ERR] ENOENT: no such file or directory, open
 »   'C:\Users\keshlam\jovo\new-sounds-on-demand\platforms\googleAction\dialogf
 »   low\intents\AMAZON.SearchAction<[email protected][byArtist]>.json'

Moving these into the Alexa-specific portion of the model file (and changing the empty “phrases” to be called “samples”) changed the error message; now alexaSkill deploy is telling me

 »   [ERR] smapiUpdateInteractionModel:Server cannot process the request due to
 »    a client error e.g. the input interaction model is invalid.

So I’m not sure how to express this in the Jovo model such that it will be correctly generated into the platform-specific grammars, even just the Amazon one. Any hints?


#5

Can you show how you’ve done it?


#6

I’ve done a bit of flailing around, but the most recent attempt was as follows. Apologies for the variation in indentation seen here; probably a tabs vs. spaces issue.

  "alexa": {
    "interactionModel": {
        "languageModel": {
            "intents": [
                {
                    "name": "AMAZON.StopIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.PauseIntent",
                    "samples": []
                },
                {
                    "name": "AMAZON.CancelIntent",
                    "samples": []
                },
		    {
			"name": "AMAZON.SearchAction<[email protected][byArtist]>",
			"samples": []
		    },
		    {
			"name": "AMAZON.SearchAction<[email protected][byArtist.musicGroupMember]>",
			"samples": []
		    },
		    {
			"name": "AMAZON.SearchAction<[email protected][duration]>",
			"samples": []

		    }, 
		    {
			"name": "AMAZON.SearchAction<[email protected][inAlbum]>",
			"samples": []

		    }, 
		    {
			"name": "AMAZON.SearchAction<[email protected][producer]>",
			"samples": []
		    } 

            ]
        }
    }

The problem might be that the Amazon implied samples are conflicting with explicit phrases elsewhere in my model, but it’d be nice to have that tell me something more explicit/useful…


#7

The examples in the official Alexa docs don’t have samples: https://developer.amazon.com/en-US/docs/alexa/custom-skills/musicrecording-intents.html#intent-signature

One idea is to add the intents in the Alexa Developer Console and use jovo get alexaSkill to retrieve the model. You can then look at the files in the platforms folder to see how they differ from what you had before.


#8

Well, on the JSON side, adding the intents via the console creates the entries

        {
            "name": "AMAZON.SearchAction<[email protected][byArtist.musicGroupMember]>",
            "samples": []
        },
        {
            "name": "AMAZON.SearchAction<[email protected][byArtist]>",
            "samples": []
        },
        {
            "name": "AMAZON.SearchAction<[email protected][duration]>",
            "samples": []
        },
        {
            "name": "AMAZON.SearchAction<[email protected][inAlbum]>",
            "samples": []
        },
        {
            "name": "AMAZON.SearchAction<[email protected][producer]>",
            "samples": []
        }

… which is what the docs suggested we should use for this set. Of course they don’t put stubs into the Javascript code since we didn’t let them generate that.

Pasted the above into the Alexa-specific portion of my model (after CancelIntent) and tested (using a renamed copy of the project, of course). Created entries in app.js with the long names, quoted as you suggested. This time it seems happier. Not sure what I did differently, other than copypasting those names to make Darned Sure I didn’t mistype them.

Well, at least there’ll be an example on git soon for others to look at so they don’t make my mistake, whatever it was…

QUESTION: I just noticed that in index.js (which I’d never had to edit), you have a section called IntentMap, which appears to associate AMAZON.Whatever with WhateverIntent. Could/should that be updated so I could use more meaningful intent names in app.js?


#9

Unfortunately it looks like the ability to say “Alexa, who’s playing this song” as a non-prefixed command (without specifying “ask myskillname”) either isn’t available for apps that haven’t received special permission to accept non-prefixed commands … or there’s something else I need to do to tell the system that we are capable of responding to these queries.

I seem to remember that there is a “can you process this” handshake for at least some operations; I’ll go diving back into the Alexa apps to try to find documentation for that and see if it’s relevant.

But at least I should now accept all the Alexa-standardized phrasings of these requests that other Alexa apps do. It’s a step forward-ish.

Pushed what I’ve got so far to Git, even if it does currently just respond with a polite version of “I’m sorry, Dave. I can’t do that.”


#10

Does Jovo automatically provide default canHandle() processing for Alexa (https://developer.amazon.com/en-US/docs/alexa/custom-skills/handle-requests-sent-by-alexa.html#handle-intents)? I haven’t seen a canHandle() method in your examples… and I’m not certain what effect not having it has, especially on non-prefixed requests.


#11

The docs say that this feature is still in preview, so this might be it

canHandle is specific for the official ASK SDK, which uses a different approach than Jovo. In v4, we offer something in-between, which we hope brings together the best of both worlds: https://v4.jovo.tech/docs/handlers#handler-routing-and-the-handle-decorator


#12

Ok; at some point I need to look into migrating to v4.

The reason I’m asking is that I think (but am not sure) that canHandle may be part of how Alexa decides where to direct prefixless “who is the performer” queries, and I’m still trying to figure out how to make that work as smoothly as default routing of stop and resume do. Or if that’s even possible without having the special permissions from Amazon needed to petition for prefixless command handling.

Learning three or more intersecting “languages” at once is sometimes more interesting than I would prefer…