!7 cmodule GThingsLister > DynPrintLog { // standard fields for a Gazelle module S globalID = aGlobalID(); bool active = true; // custom fields for this module S ruleID = 'invcwuqfdjvuloyv; // take fulfillments from there S varName = "toes"; LS thingsSaid = syncList(); LS thingsNotYetSaid; // TODO: remove module on cleanup start { if (thingsNotYetSaid == null) { thingsNotYetSaid = syncList(); //addAll(thingsNotYetSaid, "frogs", "shoes"); addNotNulls(thingsNotYetSaid, map(dm_gazelle_fulfillmentsForRule_imported(ruleID), fulfillment -> mapGet(fulfillment.varMap(), varName))); } } S giveMeOne() { if (empty(thingsNotYetSaid)) { dm_gazelle_stopThisModule(); ret "I don't know any more body parts..."; } S s = removeRandom(thingsNotYetSaid); thingsSaid.add(s); ret s + "!"; } S answer(S s) { if (!active) null; if "done|stop|gazelle stop|stop gazelle|thanks|thanks gazelle" { dm_gazelle_stopThisModule(); ret "OK"; } if "ok|cool|yes|good|next one please" ret giveMeOne(); null; } S initialAnswer(O... _) { S s = "Hello! I list things that are not actually body parts (it's just a demo).\n"; if (empty(thingsNotYetSaid)) { s += "Sadly, I don't know any body parts"; dm_gazelle_stopThisModule(); } else s += "Here is one: " + giveMeOne(); ret s; } }