Valence API D2L/Brightspace API calls from WordPress Site

942 views Asked by At

I'm new to the Valence API and D2L(Brightspace) and I'm currently having issues with sending API Requests through my WordPress Enrollment form. Below are some steps as to what I am trying to achieve:

  1. A Student Signs up/enrolls in a course through an enrollment form on my WordPress site
  2. The enrollment passes the new student information to the Valence API doAPIRequest function in sample.js
  3. The Ajax call in sample.js contains an action called 'example_wordpress_action' which is defined in functions.php. This is where the API requests are made.
  4. The main problem is that when I try to use a post request, there is always a 400 Bad Request returned. However, I am able to apply a GET/ whoami request with out any issues. Is there a chance that the issues are with the way the user information is being entered?

Below is a copy of the format that is being used to send the created users information (The RoldId is being used on the D2L site and I am using method 'POST' and API request of '/d2l/api/lp/1.4/users/'):

{
  "OrgDefinedId": "SBoateng",
  "FirstName": "Samuel",
  "MiddleName": "",
  "LastName": "Boateng",
  "ExternalEmail": "[email protected]",
  "UserName": "SBoateng",
  "RoleId": 103,
  "IsActive": true,
  "SendCreationEmail": false
}

This is what is returned from the request:

Unexpected non-JSON response from the server: 
Array
(
    [headers] => Array
        (
            [cache-control] => private
            [content-length] => 0
            [server] => Microsoft-IIS/7.5
            [x-powered-by] => ASP.NET
            [x-xss-protection] => 0
            [date] => Tue, 23 Jun 2015 18:35:05 GMT
            [connection] => close
        )

    [body] => 
    [response] => Array
        (
            [code] => 400
            [message] => Bad request
        )

    [cookies] => Array
        (
        )

    [filename] => 
)
2

There are 2 answers

3
Viktor Haag On

According to the documentation for the create-user route, a 400 status code as a response indicates one of two things: you've provided invalid data for your new user record somehow, or the back-end service was (for some reason) unable to create the new user record (very rare, but it does happen). In the second of those cases, you'd get a more detailed message in the error description indicating the failure to create. As you didn't get this, the most likely reason is one of these:

  • You're not sending what you think you're sending; it's somehow badly formatted.

  • You're providing an invalid RoleId -- it was valid in the environment you tested under, but in the production environment, that RoleId doesn't exist. This happens sometimes, but in this case, I suspect not. To verify, try fetching back the RoleId by Id first, and view those results.

  • You're providing a UserNamethat already exists in the system: this property is the ID you use to identify yourself when you log in to the Brightspace system, so it has to be unique. Occasionally clients will find that the "temporary test" UserName they're using already exists in their back-end service, for whatever reason, and this can cause surprising failures. You can try validating by fetching back a user by that UserName first to validate you don't already have a record for that user.

0
massi On

I have since been able to solve this issue with some help. below is the code that I used, in case there are others who come across this in the future.

  1. excerpt PHP where the form is kept:

                            <input class="required textInput" id="name_first" name="name_first"  size="35" maxlength="255" placeholder= "First Name"  type="text" value="<?php echo $_SESSION["student_profile"]["name_first"]; ?>" required />
                            <label class="required_lables" for="name_first"><em></em></label>
    
                            <!--  Middle Initial  -->
                            <label for="name_middle"><em></em></label>
                            <input class="textInput optional" id="name_middle" name="name_middle" size="35" maxlength="255" placeholder= "Middle Name (optional)" type="text" value="<?php echo $_SESSION["student_profile"]["name_middle"]; ?>" />
    
                            <!--  Last Name  -->
                            <input class="required textInput" id="name_last" name="name_last"  size="35" maxlength="255" placeholder= "Last Name" type="text" value="<?php echo $_SESSION["student_profile"]["name_last"]; ?>" required/>
                            <label class="required_lables" for="name_last"><em></em></label>
    
  2. Form submission page. The Ajax call is made in here:

    $_SESSION['student_profile'] = $_POST;

    $first_name=$_SESSION['student_profile']['name_first'];

    $middle_name =$_SESSION['student_profile']['middle_name '];

    $last_name =$_SESSION['student_profile']['last_name '];

    $email =$_SESSION['student_profile']['email '];

    echo '<script>';
    echo 'var data = {"OrgDefinedId": "'. $orgDefinedId .'",  "FirstName": "'. $first_name .'",  "MiddleName": "'. $middle_name .'",  "LastName": "'. $last_name .'",  "ExternalEmail": "'. $email .'",  "UserName": "'. $uName .'",  "RoleId": 103,  "IsActive": true,  "SendCreationEmail": false};';
    echo 'var type = "CREATE";';
    echo 'window.$vars = {dataField : data};';
    echo 'window.$vartype = {typeField : type};';
    echo 'doAPIRequest();';//direction to js file with the ajax call
    echo '</script>';
    
    ?>
    
  3. Ajax that is used in wordpress: The action used is called example_wordpress_action and it is defined in functions.php

    function doAPIRequest() {
     var host = "myHostSite.com";
     var port = "443";
     var scheme = "https";
     var req = "/d2l/api/lp/1.4/users/";
     var method =  "POST";
     var typeAPI = window.$vartype.typeField;
     var ajaxurl = "/wp-admin/admin-ajax.php";  
     var data = window.$vars.dataField;     
     var userName = window.$varsUname.useNameField;
     var anon = "";
     var appId = myAppID;
     var appKey = myAppKey;
            $.ajax({
                url: ajaxurl,
                data: {
                    action : 'example_wordpress_action',
                    host: host,
                    port: port,
                    scheme: scheme,
                    anon: anon,
                    apiRequest: req,
                    typeapp: typeAPI,
                    apiMethod: method,
                    appUser: userName,
                    data: data,
                    appId: appId,
                    appKey: appKey
                },
                success: function(data) {
                    var output;
                    if(data == '') {
                        output = 'Success!';
                        return;
                    } else {
                        try {
                            output = JSON.stringify(JSON.parse(data), null, 4);
                        } catch(e) {
                            output = "Unexpected non-JSON response from the server: " + data;
                        }
                    }
                },
                error: function(jqXHR, textStatus, errorThrown) {               
                },
            });
    

    }

  4. Funcions.php where the request is made using wp_remote_request:

function example_wordpress_action_function() {

    $host = $_GET['host'];
    $port = $_GET['port'];
    $scheme = $_GET['scheme'];
    $data = $_GET['data'];
    $apiMethod = $_GET['apiMethod'];
    $appId = $_GET['appId'];
    $appKey = $_GET['appKey'];
    $appRequest = $_GET['apiRequest'];
    $appUserName = $_GET['appUser'];

    $data_string = json_encode($data);

    $userId = $myUserId;
    $userKey = $myUserKey;

    $authContextFactory = new D2LAppContextFactory();
    $authContext = $authContextFactory->createSecurityContext($appId, $appKey);
    $hostSpec = new D2LHostSpec($host, $port, $scheme);
    $opContext = $authContext->createUserContextFromHostSpec($hostSpec, $userId, $userKey);

    $uri = $opContext->createAuthenticatedUri($appRequest, $apiMethod);
    $headers = array( 'authorization' => 'basic ', 'accept' => 'application/json', 'content-type' => 'application/json', 'content-length' => strlen( $data_string ) ); 
    $post = array( 'method' => $apiMethod, 'headers' => $headers, 'body' => $data_string );
    $createResponses = wp_remote_request($uri, $post);
    die();
}
add_action( 'wp_ajax_example_wordpress_action', 'example_wordpress_action_function' );
add_action("wp_ajax_nopriv_example_wordpress_action", "example_wordpress_action_function");