Second Life Copybot
Feedback Survey script - Printable Version

+- Second Life Copybot (https://secondlifecopybot.com)
+-- Forum: SECOND LIFE PRODUCTS (https://secondlifecopybot.com/forum-1.html)
+--- Forum: SCRIPTS (https://secondlifecopybot.com/forum-1022.html)
+---- Forum: SCRIPTS (https://secondlifecopybot.com/forum-8.html)
+----- Forum: Business Scripts (https://secondlifecopybot.com/forum-44.html)
+----- Thread: Feedback Survey script (/thread-1228.html)



Feedback Survey script - YoungMoney - 03-04-2013

Code:
// Evaluation tool with multiline questions


// Setting up the evaluation tool is simple. Prepare a notecard with your questions on one line, answers on the next, alternating (see the example). You should use pipe characters | to separate answer choices. Pipes in the QUESTION will be converted into new lines so you can write multiline questions. NOTE: no line can be more than 255 characters long. Answers longer than 8 characters will not display clearly, so think about those factors in your questions and answers too!
// Example: Did you enjoy your visit to Literature Alive!
Yes|Fairly|No
//Put the script and notecard into a prim and follow the simple instructions. The card can have any name you like - but the name of the card will be sent in the email, so you can use it to be indicative of the content of the questionnaire - the questions are NOT sent in the email to save space in the script memory.


integer pointer=0;      //Where we are in the various cycles - reading notecards, asking questions etc.
list questions;         //The questions we've read in
list answers;           //The answers in raw form (still in one string per answer set)
string address;         //The email address. email is a restricted word in lsl - it's an event name.
integer listenID;       //So we can turn listeners on and off - less lag that way.
key owner;              //So I can listen to only the owner, and potentially add some admin functions off a touch (not implemented but the code is there).
integer chan;           //Channel for  the silent email registration - required in state_entry AND listen, hence a global.
string card;            //Name of the notecard you're using.
key questionnaire;      //Key of the person taking the questionnaire
string totalq;          //Total number of questions
string responses;       //The actual answers given, plus querent's name and card name.

setQuestions()          //A function - we need to access this from a couple of places, hence putting it in as a function
{
    string question=llList2String(questions, pointer);                                  //Raw question
    question=llDumpList2String(llParseString2List(question, ["|"], []), "\n");          //Swaps | for /n (new line)
    llDialog(questionnaire, question, llParseString2List(llList2String(answers, pointer), ["|"], []), -1001);   //Asks the questions in a dialog box.
}

default         //Set everything up
{
    state_entry()
    {
        llSetText("Setting up", <1.0, 1.0, 1.0>, 1.0);      //Show what we're doing.
        owner=llGetOwner();                                 //Grab the owner's key for lower down
        chan=(integer)("0x"+llGetSubString((string)owner, 0, 1));   //Set up a channel (not 0) based on the key (1-255) so there's silent entry.
        listenID=llListen(chan, "", llGetOwner(), "");              //Listen only to the owner as well.
        llOwnerSay("Please say your email address for completed surveys on /"+(string)chan+". E.G. /"+(string)chan+" example@aol.com");   //Tell them what to say
    }
    listen(integer cha, string name, key id, string msg)    //Listen event - grab their details and make sure it's all OK.
    {
        if(cha==chan)
        {
            address=msg;
            llListenRemove(listenID);                   //Tidy up the listen, just in case.
            listenID=llListen(-1001, "", owner, "");
            llDialog(owner, "The email address for results is "+msg+". Is that correct?", ["Yes", "No"], -1001);    //Check the email address is right
        } else if(cha=-1001)
        {
            if(msg=="Yes")      //Email is OK, so...
            {
                llListenRemove(listenID);
                if(llGetInventoryNumber(INVENTORY_NOTECARD)!=1) //there's not 1 notecard, so I'm not sure which one to use. Complain!
                {
                    llOwnerSay("You must put exactly one card in me with the questions and answers on it before I can set up!");    //Complain politely...
                } else                                          //There is only one, so we'll assume (however rashly) it's the right one.
                {
                    card=llGetInventoryName(INVENTORY_NOTECARD, 0); //Get the card's name
                    pointer=0;                                      //reset the pointer (this is paranoia, but it doesn't hurt)
                    llGetNotecardLine(card, pointer);               //Start reading the card (handled in the dataserver event).
                }
            } else  //They put their email address in wrong
            {  
                llResetScript();    //Well we've not really done anything. We could cycle back to ask again if we'd done more.
            }
        }
    }
    dataserver(key id, string data)     //This handles various things - this time it's reading data from a notecard.
    {
        if(data!=EOF)                   //It's real data, not the end of the file.
        {
            if(pointer%2)               //is it an odd numbered line
            {
                answers+=data;          //if so, it's an answer line
            } else
            {
                questions+=data;        //else it's even (0 first remember) - so it's a question
            }
            pointer++;                  //Advance the pointer
            llGetNotecardLine(card, pointer);   //Get the next line.
        } else                          //It IS the end of the file, so we've grabbed it all...
        {
            totalq=(string)llGetListLength(questions);  //Get the number of questions
            state ready;                                //Go into a ready state, so we can take answers.
        }
    }
    changed(integer change)
    {
        if((change & CHANGED_OWNER) || (change & CHANGED_INVENTORY))    //They've changed the contents, or the owner, so reset it - probably a new card after all.
        {
            llResetScript();
        }
    }
}

state ready             //Waiting for victims to answer questions.
{
    state_entry()
    {
        llSetText("Touch me to start the\n feedback survey\nThere are "+totalq+" questions.", <1.0, 1.0, 1.0>, 1.0);   //Tell punters what to do
    }
        touch_start(integer num)        //Process the touch
    {
        key temp=llDetectedKey(0);
        if(temp==owner)                 //No admin built in, but it's available as an option
        {
            //offer some options
            questionnaire=temp;
            state running;
        } else                          //It's a punter - start the questionnaire.
        {
            questionnaire=temp;
            state running;
        }
    }
}

state running       //We're actually asking questions
{
    state_entry()
    {
        llSetText(llKey2Name(questionnaire)+" is taking the questionnaire, please wait!", <1.0, 1.0, 1.0>, 1.0);    //Tell the world so!
        listenID=llListen(-1001, "", questionnaire, "");        //Only listen to the answers, stops spamming
        llSensorRepeat(questionnaire, "", AGENT, 60, PI, 30.0); //Keep checking they're still there - they might have got bored and wondered off, crashed etc.
        pointer=0;                                              //reset the pointer (recycling variables is good)
        setQuestions();                                         //Ask the first question (see function above)
    }
    listen(integer chan, string name, key id, string msg)       //Listen for the answers.
    {
        if(pointer==0)                                          //First answer, so say what's happening.
        {
            responses=name+"'s answers to the questionnaire on notecard "+card+".\n";
        }
        responses+="Q"+(string)(pointer+1)+": "+msg+"\n";       //Add their answer to this question to the email.
        pointer++;
        if(pointer==(integer)totalq)                            //Got to last question.
        {
            llSay(0, "Thank you for taking this questionnaire. Please wait whilst I send the results before starting.");    //Tell them they're done.
            llSetText("Sending results, please wait.\nThis should take about 20s.", <1.0, 1.0, 1.0>, 1.0);                  //Tell others they're done too, and to wait a bit
            llEmail(address, "Questionnaire answers", responses);                                                           //Send the email.
            state ready;                                                                                                    //Back to the ready state
        } else
        {
            setQuestions();                                                                                                 //Ask the next question
        }
    }
    no_sensor()                                                                                                             //The person's left, so send their partial answers
    {
        llSensorRemove();                                                                                                   //Tidy up
        llEmail(address, "Questionnaire answers", responses);                                                               //Send email
        state ready;                                                                                                        //Back to ready state
    }
}