Hi Matt,
This is a fun one.
If we want to have a "call and response" knock-knock joke, we need to break the joke up. Rather than pausing, we'll ask for the punchline of the joke in a separate command. Here's one way to do it:
Command 1 (We say "knock knock"):
.
a. Scrape the website.
b. Capture all the jokes on the page using a regular expression.
c. Choose a random match from the jokes and respond aloud with the first part of the joke (the knock knock "name").
d. Add this name and its corresponding punchline to a payload XML file. The name is the phrase and the punchline is stored as the value.
e. Now we rebuild this command group, so that VC will be able to understand us when we say our follow-up knock knock response.
Command 2 (We say "{PF.1} who?")
a. VC just needs to read out {1} -- the punchline.
<?xml version="1.0" encoding="utf-16"?>
<!--VoxCommando 2.2.3.5-->
<commandGroup open="True" name="Knock knock call and answer" enabled="True" prefix="" priority="0" requiredProcess="" description="">
<command id="291" name="Knock knock" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="60" loop="False" loopDelay="0" loopMax="0" description="Decode.HTML decodes wonky html characters. I save a random "who" name and its matching punchline into a payloadXML. Then we rebuild the command group, otherwise VC won't be able to listen for the new phrase we just added to the payloadXML.">
<action>
<cmdType>PayloadXML.Clear</cmdType>
<params>
<param>payloads\knockjokes.xml</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Scrape</cmdType>
<params>
<param>https://www.jokesbykids.com/knock-knock/page/{Rnd.1.90}/</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Tools.Decode.HTML</cmdType>
<params>
<param>{LastResult}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.ShowText</cmdType>
<params>
<param>Knock knock ...</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.RegEx</cmdType>
<params>
<param><p>.*?/>.*?/>(.*?).<.*?<div\sclass="punch_line">(.*?)</div></div></param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Results.SetVar</cmdType>
<params>
<param>jokenum</param>
<param>{Rnd.1.{#m}}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>PayloadXML.AddPair</cmdType>
<params>
<param>payloads\knockjokes.xml</param>
<param>{Match.{var.jokenum}.2}</param>
<param>{Match.{var.jokenum}.1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>TTS.Speak</cmdType>
<params>
<param>{Match.{var.jokenum}.1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.AddText</cmdType>
<params>
<param>{Match.{var.jokenum}.1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>Group.Rebuild</cmdType>
<params>
<param>Knock knock call and answer</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<phrase>Knock knock</phrase>
</command>
<command id="292" name="{1} who?" enabled="true" alwaysOn="False" confirm="False" requiredConfidence="0" loop="False" loopDelay="0" loopMax="0" description="">
<action>
<cmdType>TTS.Speak</cmdType>
<params>
<param>{1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<action>
<cmdType>OSD.ShowText</cmdType>
<params>
<param>{1}</param>
</params>
<cmdRepeat>1</cmdRepeat>
</action>
<payloadFromXML phraseOnly="False" use2partPhrase="False" phraseConnector="by" Phrase2wildcard="anyone" optional="False">payloads\knockjokes.xml</payloadFromXML>
<phrase>who</phrase>
</command>
</commandGroup>
I added a few other tweaks as well.
1. The page
https://www.jokesbykids.com/knock-knock/ only has 6 jokes on it, and unless kids add new jokes to it, these jokes will get stale for us quickly. But there are apparently 96 pages of knock knock jokes.
I changed the URL to this instead:
https://www.jokesbykids.com/knock-knock/page/{Rnd.1.90}/
2. You wanted to retrieve a random joke from the page. We need that random number to be the same for both {Match.#.1} and {Match.#.2}. I added an action that stores a random number between 1 and {#M} as a variable. (I called it "jokenum".) Then I use that value in order to choose a random match.
As always, there are different ways to handle the challenge. My approach is one but maybe others will have other suggestions.
Thanks for posting!