question

litheintern avatar image
litheintern asked

iterate through facts once and restart the process after session ends

Hi everyone, I'm writing a fact skill as well using space geek template. I added a feature that once the fact is given, it will be deleted from the array and thus it will never pop up again. However, here comes the problem. It will only work once. After the element was deleted. It could never be retrieved. And thus, in later sessions I can't get any more facts. I tried to make a copy of the array and delete the elements from the copy, but yet it still won't work. Anyone has any good solutions to this? All I'm trying to do is that whenever a fact is given, it won't be given again in the same session. But it should come back if a new session starts. Below are my codes for the handleNewQuestion function: function handleNewFactRequest(response) { var COPY_FACTS= SOME_FACTS.splice(); if(COPY_FACTS.length>0){ var factIndex = Math.floor(Math.random() * COPY_FACTS.length); var fact = COPY_FACTS[factIndex]; // Create speech output var speechOutput = "Here's your random fact: " + fact + " would you like more?"; var repromptOutput = "would you like more random facts?"; COPY_FACTS.splice(factIndex, 1); response.ask(speechOutput, repromptOutput); }else{ var speechOutput = "That's all the facts we have for now."; response.tell(speechOutput); } }
alexa skills kitdebugging
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
You realize that you are deploying this to Lambda? Lambda starts up a new instance each time it is invoked. So deleting it from the array does nothing. That's a runtime change. If you want this behavior, then you are going to need to persist what facts have been heard already somewhere, like DynamoDB.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

litheintern avatar image
litheintern answered
what do you mean deleting my array does nothing? It actually does delete the elements of my array when I was running the skill. If I keep asking alexa, all the new facts given by alexa does not repeat the previous ones. So I suppose the elements are deleted. So it will eventually end up with array.length==0. So then alexa will just tell me there are no more facts and end session. What I want is that when a new session starts, all the deleted elements will come back so the skill is still good to go. Which is not the case. If I invoke the skill again, the array is still empty and thus it'll just end the session right away.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
>If I keep asking alexa, all the new facts given by alexa does not repeat the previous ones. How do you know this? How extensively have you tested? If you have a whole bunch of facts, then you wouldn't be able to tell the difference. Cut it down to just three facts. Then invoke the skill four times. Either you will find repeats, or it will exception on the 4th invocation. Even if it exceptions the 4th time, wait a few minutes, and then try again. Lambda creates a run-time instance, but it doesn't keep it around indefinitely. So even if it seems to be persisting your deletes, I think you will find once the instance times out and is reloaded, they are all back.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

litheintern avatar image
litheintern answered
I know this because I only have 5 facts. and since I have it on my developer portal, I was able to test it on a real echo. Every time it gives me a fact, and ask me whether I want more, I just say "next"(which invokes my intent again). and yes,t he orders are always random, the random index is then used to splice my original array. After it goes through all of them, it'll tell me there's no more facts. Yes, the instance eventually comes back. But last time I tested, it took more than 30 minutes. When I tested on developer portal, every session has different ID. There are any way to reset the variables as soon as a new session starts? Waiting for more than 30 minutes for them to come back is a real turn off. If you read my codes, it very straight forward. Message was edited by: litheintern Message was edited by: litheintern
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

jjaquinta avatar image
jjaquinta answered
Java Lambda functions reset in seconds. There is no good way to get perfect behavior, other than persisting to off line storage. First off, if you just delete from the array, it has two downsides. 1) it will affect all users of the skill. I.e. if you have two people using it at once, they will deplete the array jointly. 2) When Lambda resets, it will go back to the start. The user may experience two identical facts in a row depending on timing. You can solve the first problem by keeping an internal map where you map the user ID to a list of facts. When a UserID is encountered for the first time, clone the master array and stick it in the map. Then you can deplete the user specific map as you go. Another alternative is to round-robin it. Pick the starting point at random, then each time you respond with a fact increment the point modulo the size of the fact list. It means it will be as varied as possible for each users, adapts well to multiple users at once, and doesn't run out, but rather serves the oldest one first. The downside is the facts will always be presented in the same order. It all kind of depends on the profile of user you expect to get. I've done a lot of metrics on my Knock-Knock Jokes skill. The average user listens to two jokes at a time. The upper quartile is about four jokes. But, since I have hundreds of jokes, the chance of getting the same joke twice is not big enough to worry about.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

litheintern avatar image
litheintern answered
Got it. Thanks, that's really helpful.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Galactoise avatar image
Galactoise answered
The way we handle this with complibot is to store a list of all the compliments they've heard in a given session (via the sessionAttributes feature), and then if a compliment matches one they've heard, we just reroll our random selection and pick a new one. We have some logic in there to make sure we're not infinitely rerolling if someone consumes a lot of content, etc, but in general it's a pretty simple solution.
10 |5000

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.