Here's how to hook in a Qualtrics survey

156 views
Skip to first unread message

Dave Eargle

unread,
Mar 15, 2016, 2:05:19 PM3/15/16
to PsiTurk
Hey all, I figured out how to hook a Qualtrics survey into the psiturk flow. When a Qualtrics survey ends, it sends a message to window.top. So if you've embedded the Qualtrics survey as an iframe, your psiturk exp.html is window.top. You just need to be listening for the posted message and then execute javascript to do whatever once you've detected that they've finished.

The posted message when they finish a qualtrics survey looks like this:

'QualtricsEOS|<survey_id>|<qualtrics_session_id>'

So I do something like this:

window.addEventListener('message', function(event){
        console.log(event.data);
        if (event.data) {
            if (typeof event.data === 'string') {
                q_message_array = event.data.split('|');
                if (q_message_array[0] == 'QualtricsEOS') {
                    psiTurk.recordTrialData({'phase':'postquestionnaire', 'status':'back_from_qualtrics'});
                    psiTurk.recordUnstructuredData('qualtrics_session_id', q_message_array[2]);
                }
            }
        }
        // display the 'continue' button, which takes them to the debriefing
        $('#next').show();
    })

I also pass the psiTurk uniqueId over to the qualtrics survey and set it as embedded data so that I have things linked up in both directions. Thusly: 

$('#iframe').attr('src','https://<your qualtrics url>?SID=<your survey id>&UID=' + uniqueId);

rick...@gmail.com

unread,
Jun 26, 2018, 12:02:57 PM6/26/18
to PsiTurk
Hey all,
Just raising a small issue here. I have a hybrid experiment, where two blocks of tasks are completed using psiTurk and a third block is done via Qualtrics. I'm currently just testing functionality, and most of Dave's original version works. That is, the survey loads successfully in an iFrame in my experiment, and I can navigate through it, but either Qualtrics or Chrome is not allowing message passing. So once the Qualtrics "finished" screen is reached, my next button (same syntax as Dave's below) doesn't appear, and an exception is thrown in the console (see below). I can confirm from the page source that Qualtrics takes in embedded data, as it passed "debug" to Qualtrics. It seems to be an issue with the message getting passed back to window.top.

If it is Chrome problem [I haven't tested in other browsers], it may or may not be affecting other browsers, but I suspect other browsers will eventually do similar things given the topics discussed here: https://goo.gl/rStTGz

It seems not to be a Qualtrics problem, but again, I can't tell.

Here's [an abbreviated version of] what I get from the console, I believe the DOMException is the symptom, and the messages above are likely the problem:

[Deprecation] The deviceorientation event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.

The deviceorientation events are blocked by feature policy. See https://github.com/WICG/feature-policy/blob/gh-pages/features.md#sensor-features
s.resolve.s.fulfill

DOMException: Blocked a frame with origin "https://delaware.ca1.qualtrics.com" from accessing a cross-origin frame.
at S.r.<anonymous> (https://jfe-cdn.qualtrics.com/jfe/static/dist/jfe.23b06de6252174cbd5c9.js:1:71906)
at S.r.i [as postEOSActions] (https://jfe-cdn.qualtrics.com/jfe/static/dist/vendor.4aac5340ddac8f994b7b.js:1:207704)
at S.r.postEOSActions (https://jfe-cdn.qualtrics.com/jfe/static/dist/vendor.4aac5340ddac8f994b7b.js:1:227253)
at S.r.<anonymous> (https://jfe-cdn.qualtrics.com/jfe/static/dist/jfe.23b06de6252174cbd5c9.js:1:69745)
at https://jfe-cdn.qualtrics.com/jfe/static/dist/vendor.4aac5340ddac8f994b7b.js:1:227253
at r (https://jfe-cdn.qualtrics.com/jfe/static/dist/vendor.4aac5340ddac8f994b7b.js:1:68822)
at n._callHandler (https://jfe-cdn.qualtrics.com/jfe/static/dist/vendor.4aac5340ddac8f994b7b.js:1:35955)
at n._settlePromiseFromHandler (https://jfe-cdn.qualtrics.com/jfe/static/dist/vendor.4aac5340ddac8f994b7b.js:1:36124)
at n._settlePromiseAt (https://jfe-cdn.qualtrics.com/jfe/static/dist/vendor.4aac5340ddac8f994b7b.js:1:38444)
at n._settlePromises (https://jfe-cdn.qualtrics.com/jfe/static/dist/vendor.4aac5340ddac8f994b7b.js:1:40669) "https://jfe-cdn.qualtrics.com/jfe/static/dist/jfe.23b06de6252174cbd5c9.js:1:71976"


Before I go fishing for how to deal with this, does anyone know whether this is going to be implemented in other browsers in the future? It seems solvable, but I'm not an internet security expert, so if anyone has suggestions, I'm all ears.

If I solve the problem I'll repost.

-Rick

Dave Eargle

unread,
Jun 26, 2018, 1:14:38 PM6/26/18
to rick...@gmail.com, PsiTurk
Deviceorientation messages are unrelated, and cross window messaging is supposed to work around cross origin security issues. I think the other message about cross origin is also a red herring -- i think that's just other qualtrics code that is failing but that doesn't actually matter. Can you show your message reveiving code on the psiturk side? Is qualtrics successfully posting _anything_ back to window.top? Try console.logging all received messages.


On Tue, Jun 26, 2018, 10:03 AM <rick...@gmail.com> wrote:
Hey all,
Just raising a small issue here. I have a hybrid experiment, where two blocks of tasks are completed using psiTurk and a third block is done via Qualtrics. I'm currently just testing functionality, and most of Dave's original version works. That is, the survey loads successfully in an iFrame in my experiment, and I can navigate through it, but either Qualtrics or Chrome is not allowing message passing. So once the Qualtrics "finished" screen is reached, my next button (same syntax as Dave's below) doesn't appear, and an exception is thrown in the console (see below). I can confirm from the page source that Qualtrics takes in embedded data, as it passed "debug" to Qualtrics. It seems to be an issue with the message getting passed back to window.top.

If it is Chrome problem [I haven't tested in other browsers], it may or may not be affecting other browsers, but I suspect other browsers will eventually do similar things given the topics discussed here: https://goo.gl/rStTGz

It seems not to be a Qualtrics problem, but again, I can't tell.

Here's [an abbreviated version of] what I get from the console, I believe the DOMException is the symptom, and the messages above are likely the problem:

 [Deprecation] The deviceorientation event is deprecated on insecure origins, and support will be removed in the future. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.

The deviceorientation events are blocked by feature policy. See https://github.com/WICG/feature-policy/blob/gh-pages/features.md#sensor-features
s.resolve.s.fulfill

 DOMException: Blocked a frame with origin "https://delaware.ca1.qualtrics.com" from accessing a cross-origin frame.
--
You received this message because you are subscribed to the Google Groups "PsiTurk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to psiturk+u...@googlegroups.com.
To post to this group, send email to psi...@googlegroups.com.
Visit this group at https://groups.google.com/group/psiturk.
For more options, visit https://groups.google.com/d/optout.

rick...@gmail.com

unread,
Jun 27, 2018, 10:17:52 AM6/27/18
to PsiTurk
Ok, so first, thanks Dave for being so great, and providing the template for this message listening function.

For whatever reason, the window event function was throwing those errors because my code contained a few errors (of course!)

I indeed receive the message / code and log the data (confirmed via console.log). I think my problem is, as you said, unrelated to those errors, which are now not thrown (the DOM exception). It seems to just be a problem with placement of the next button. So I'll figure it out from here.

In either case, good to know that Qualtrics still works as it should.

Cheers!
Rick

Dave Eargle

unread,
Jun 27, 2018, 10:31:11 AM6/27/18
to rick...@gmail.com, PsiTurk
 Great!

Joseph Nah

unread,
Oct 1, 2018, 1:39:58 PM10/1/18
to PsiTurk
Hi Dave,

I am wondering if you have an example code that implements qualtrics survey within the psiturk framework?

I'm trying to do the same thing as Rick below where the final experimental block is done via Qualtrics, after which the experiment would proceed to the post-questionnaire stage. I'm having trouble implementing the example you gave. I would appreciate some pointers if possible.

Dave Eargle

unread,
Oct 1, 2018, 1:40:59 PM10/1/18
to Joseph Nah, PsiTurk
In the docs

Joseph Nah

unread,
Oct 1, 2018, 1:44:06 PM10/1/18
to PsiTurk
I am aware of the example in the docs but was hoping if there were any other examples.

Dave Eargle

unread,
Oct 1, 2018, 1:59:00 PM10/1/18
to Joseph Nah, PsiTurk
Ask something more specific and I'll see how I can help, but just call new View at the bottom of the message listener to switch to a new page, just like you would within any other psiturk view.

window.addEventListener('message', function (event) {
console.log(event.data);
if (event.data) {
if (typeof event.data === 'string') {
var q_message_array = event.data.split('|');
if (q_message_array[0] == 'QualtricsEOS') {
var rt = (new Date().getTime()) - timestamp;
                    psiTurk.recordTrialData({
'phase': 'qualtrics',
'action': 'back_from_qualtrics',
                        'viewTime': rt
});
psiTurk.recordUnstructuredData('qualtrics_session_id', q_message_array[2]);
                    current_view = new WhateverYouWant();
}
}
}
})

Rick Hass

unread,
Oct 1, 2018, 7:57:44 PM10/1/18
to Dave Eargle, Joseph Nah, PsiTurk
The docs version works well. Basically you’re just using an iFrame to display qualtrics in the psiturk app environment. The rest of it is embedding the data in Qualtrics and then waiting for the message. So look up more stuff on embedding iFrames and about event listeners.

What I did was have the submit button appear on the psiturk side only after the finished survey message comes back from Qualtics.

I’m sure there are a million ways to do it but this way worked well for my recent experiment which involved both psiturk and qualtrics hosted tasks.

My code isn’t posted yet but would be happy to upload to Github. 

Rick

You received this message because you are subscribed to a topic in the Google Groups "PsiTurk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/psiturk/2xJ3Uc8feZk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to psiturk+u...@googlegroups.com.

Joseph Nah

unread,
Oct 1, 2018, 9:07:19 PM10/1/18
to PsiTurk
Yeah it turns out the majority of the problem was my lack of knowledge of jquery. Once I got that down, I was able to get it to work.

The one thing I still don't understand is how to customize the URL for each participant and would appreciate if someone could point me in the right direction.

Right now, whenever I use the URL format in the docs example, I get a broken link. I worked around this by just using the general URL and plan to cross match the survey data to the psiturk data.

Thanks,
Joe

Dave Eargle

unread,
Oct 1, 2018, 9:30:52 PM10/1/18
to Joseph Nah, PsiTurk
Post an example link that is broken for you? It's just url parameters, e.g. ? and & format, with the question mark starting immediately after your qualtrics url.

Joseph Nah

unread,
Oct 1, 2018, 9:38:04 PM10/1/18
to PsiTurk
So based on the example in the docs:

$('#iframe').attr('src','<your qualtrics url>&UID=' + uniqueId);

my url parameters looked something like this:
$('#iframe').attr('src','https://columbiangwu.co1.qualtrics.com/jfe/form/SV_3EHflgEl2JdxXaR&UID=' + uniqueId);

Looks like the docs example was missing the "?" before the "&". Now that I added it in, it works fine.
$('#iframe').attr('src','https://columbiangwu.co1.qualtrics.com/jfe/form/SV_3EHflgEl2JdxXaR?&UID=' + uniqueId);

Thanks,
Joe

Rick Hass

unread,
Oct 1, 2018, 9:38:19 PM10/1/18
to Joseph Nah, PsiTurk
I seem to remember having a problem with that and that I hadn’t gotten the link right initially, or that Qualtrics changes it’s link syntax sinc Dave wrote that code. Check qualtrics docs for how the link should end (I.e with an ampersand or question mark). It should be in the section on embedded data from a url. Make sure that is correct and that you’re adding the psiturkID part to pass to qualtrics at the correct end point of the link. I’ll try to remember to copy and paste my code here tomorrow. It was a small little issue that my eyes didn’t recognize at first.

Rick Hass

unread,
Oct 1, 2018, 9:40:32 PM10/1/18
to Joseph Nah, PsiTurk
Ah perfect! I’m glad my memory still works!

Dave Eargle

unread,
Oct 1, 2018, 9:52:47 PM10/1/18
to Rick Hass, Joseph Nah, PsiTurk
Yeah that's a mistake in the docs then. It's not qualtrics-specific -- url parameters must always start with a questionmark. Feel free to PR the docs.

Dave Eargle

unread,
Oct 1, 2018, 9:53:40 PM10/1/18
to Dave Eargle, Joseph Nah, PsiTurk, Rick Hass
And you dont need an ampersand before UID in your example. Just the questionmark.
Message has been deleted

Jeroen van Baar

unread,
Dec 17, 2018, 3:23:02 PM12/17/18
to PsiTurk
Hi all,

Thanks a lot for writing this thread. I'm currently trying to link my Qualtrics survey to my Psiturk experiment using the iFrame solution outlined here. However, I get the following error message in the console:

"Permission denied to access property \"qualtricsEndOfSurvey\" on cross-origin object"

Googling around a bit tells me that this is because my browser doesn't allow cross-site scripting. Is that right? Do you know of a way around this issue particularly when using Psiturk and Qualtrics?

Thanks a lot!

Best,

Jeroen

Dave Eargle

unread,
Dec 17, 2018, 6:29:55 PM12/17/18
to Jeroen van Baar, PsiTurk
Show your code for where you are listening for the postback message?

Jeroen van Baar

unread,
Dec 17, 2018, 6:47:03 PM12/17/18
to Dave Eargle, PsiTurk
At first I just copied the example code from readthedocs:

window.addEventListener('message', function(event){
                console.log(event.data);
                if (event.data) {
                    if (typeof event.data === 'string') {
                        q_message_array = event.data.split('|');
                        if (q_message_array[0] == 'QualtricsEOS') {
                            psiTurk.recordTrialData({'phase':'postquestionnaire', 'status':'back_from_qualtrics'});
                            psiTurk.recordUnstructuredData('qualtrics_session_id', q_message_array[2]);
                        }
                    }
                }
            })

But that would lead to the error message from my previous post. Right now, as a workaround, I’m just dumping all incoming messages into the participants database:

window.addEventListener('message', function(event){
                console.log(event.data);
                psiTurk.recordTrialData({'phase':"postquestionnaire", 'QualtricsMessage1':event.data});
                psiTurk.recordTrialData({'phase':"postquestionnaire", 'QualtricsMessage2':event.data});
                psiTurk.saveData();
            })

I’m not great with Javascript yet, e.g. I don’t fully understand how to handle the fact that Qualtrics seems to send 2 messages (‘closeQSIWindow’ and the EOS message). At first I picked up only on the first message, so now I’m storing event.data twice before calling psiTurk.saveData(). Ideally I’d listen to messages until the EOS message is passed, and only then call saveData. Any tips here would be most welcome, thanks!

--
Jeroen van Baar
Postdoctoral Research Associate

Brown University
Department of Cognitive, Linguistic & Psychological Sciences
Metcalf 149, 190 Thayer St, Providence, RI. 02912

Dave Eargle

unread,
Dec 17, 2018, 10:22:36 PM12/17/18
to Jeroen van Baar, Dave Eargle, PsiTurk
The error message doesn't make sense to me, i do not see how it could have been generated with the example code. Try it again perhaps.
Reply all
Reply to author
Forward
0 new messages