Saturday, January 14, 2017

Powershell: Retrieving Qualtrics Survey Results Starter Script

Retrieving survey results from Qualtrics is less convenient than ever with the Qualtrics v3 API! 

Don't get me wrong, it's great that you can call a REST API to retrieve results from your survey. The inconvenient part is having to make three different API calls to get the results and ending up with a file that needs to be unzipped before you can work with it.

Thankfully, with PowerShell, this is a fairly straightforward task. Although there are many examples on how to do this using other programming languages, I was unable to find one using PowerShell, so I'm providing the script below as a starter script for your own purposes. You can easily add to this script if you need to export results in a different format (I only tested the below using "json" and "xml" as arguments) or wish to retrieve only a subset of responses or questions.

All of the information needed to create your API calls is nicely documented on the Qualtrics API site.


function Get-Qualtrics-Response-Export {
    param(
        [string] $organizationId,
        [string] $dataCenterId,
        [string] $apiToken,
        [string] $format,
        [string] $surveyId,
        [string] $outFile
        )

    $hostName = "{0}{1}qualtrics.com" -f "$organizationId.".TrimStart('.'), "$dataCenterId.".TrimStart('.')

    # ---------------------------------------------------------------------------- #
    #
    # XML - Create Response Export - Starts an export for a survey in XML format
    # https://api.qualtrics.com/docs/xml
    # https://api.qualtrics.com/docs/response-exports
    #
    # ---------------------------------------------------------------------------- #
    
    $url = "https://$hostName/API/v3/responseexports"
    
    $requestHeaders = @{}
    #$requestHeaders.Add("Accept", "*/*")
    $requestHeaders.Add("X-API-TOKEN", "$apiToken")
    $requestHeaders.Add("accept-encoding", "gzip, deflate")

    $requestData = @{
            format = "$format"
            surveyId = "$surveyId"
            includedQuestionIds = @()
            useLabels = $true
        }

    $body = (ConvertTo-Json $requestData)

    $response = Invoke-RestMethod -Method Post -Uri $url -ContentType "application/json" -Headers $requestHeaders -Body $body 
    $responseExportId = $response.result.id

    write-host "Response Export ID: $responseExportId"
    write-host
    
    # ---------------------------------------------------------------------------- #
    #
    # Get Response Export Progress - Retrieve the status of a response export
    # https://api.qualtrics.com/docs/get-response-export-progress
    #
    # ---------------------------------------------------------------------------- #

    $requestData = $null
    $body = (ConvertTo-Json $requestData)
    $percentComplete = 0
    $status = ""

    while($percentComplete -lt 100)
    {
        $response = Invoke-RestMethod -Method Get -Uri "$url/$responseExportId" -ContentType "application/json" -Headers $requestHeaders -Body $body 

        $status = $response.result.status

        if($status -eq "failed" -or $status -eq "cancelled")
        {
            # If you receive a status of cancelled or failed, please go back and regenerate a responseExportId 
            # for your desired export format - JSON, CSV, CSV 2013, XML, SPSS - and try this request again.
            write-host $response.result.info.reason
            write-host $response.result.info.nextStep
            break
        }

        $percentComplete = $response.result.percentComplete
        write-host "Response Export Progress: $percentComplete%"
    }

    # ---------------------------------------------------------------------------- #
    #
    # Get Response Export File - Retrieve the response export file after the export is complete
    # https://api.qualtrics.com/docs/get-response-export-file
    #
    # ---------------------------------------------------------------------------- #

    if($percentComplete -eq 100)
    {
        $response = Invoke-RestMethod -Method Get -Uri "$url/$responseExportId/file" -ContentType "application/json" -Headers $requestHeaders -Body $body -OutFile $outFile
        
        if(test-path $outFile)
        {
            $destination = split-path -path $outFile
            Expand-ZIP-File -zipFile $outFile -destination $destination
        }
    }
}

function Expand-ZIP-File($zipFile, $destination)
{
    $shell = new-object -com Shell.Application
    $zip = $Shell.NameSpace($zipFile)

    foreach($item in $zip.items())
    {
        $Shell.NameSpace($destination).CopyHere($item, 0x14)
    }
}

clear

<#
Your hostname should have one of the following formats:
    yourorganizationid.yourdatacenterid.qualtrics.com
    yourdatacenterid.qualtrics.com
    yourorganizationid.qualtrics.com
#>

$organizationId = "Your Organization ID (if exists)"
$dataCenterId = "Your Data Center ID (if exists)"
$apiToken = "Your API Token"
$format = "xml"
$surveyId = "Your Survey ID"
$outFile = "c:\ken\qualtrics\data\temp.zip"

#Get-Qualtrics-Response-Export -organizationId $organizationId -dataCenter $dataCenterId -apiToken $apiToken -format $format -surveyId $surveyId -outFile $outFile