The diagnosis.php page below, is requested via an AJAX HTTPRequest(), and it is displayed on a div in the same calling page. The ICD's javascript resource located at https://icdcdn.who.int/embeddedct/icd11ect-1.6.1.js is defined in the same calling page.

Console information below shows that, there is a successful connection to the ICD API script. However, the API call returns error 'Invalid Token Specified';

How do I correctly integrate this API, with proper calls to the API server in php? ECT v1.6.1 - React v17.0.2 icd11ect-1.6.1.js:1 waiting for setting the last minor version icd11ect-1.6.1.js:1 autoBind: true 2icd11ect-1.6.1.js:1 waiting for setting the last minor version icd11ect-1.6.1.js:1 loading... 2icd11ect-1.6.1.js:1 waiting for setting the last minor version icd11ect-1.6.1.js:1 searchMethod set to: POST icd11ect-1.6.1.js:1 setting the last minor version: 2023-01 icd11ect-1.6.1.js:1 loading... icd11ect-1.6.1.js:1 ICDAPI Initialization Completed: true

diagnosis.php `

<?php session_start(); require('../../../conn/connection.php'); $pid = $_REQUEST['pid']; $cfid = $_REQUEST['cfid'];?>

<script>
    var mySettings = myCallbacks = null;
</script>
    
    <link rel="stylesheet" href="https://icdcdn.who.int/embeddedct/icd11ect-1.6.1.css">
    <div class="container-fluid tab-pane">
        <h3 class="mt-3 mb-3">General Diagnosis</h3>
        <hr />
        <a href="#addNewDiagnosisDiv" onclick="showDiagnosisDiv()" class="link mt-2 mb-2">Add New Diagnosis </a>
        <div class="container-fluid mt-3 mb-3" id="newDiagnosisDiv" style="display:none; border-style:solid; border-color:#ddd; border-radius:5px; padding: 10px 10px;">
            <div class="row">
                <div class="col-3">
                    <div class="form-group">
                        <select id="ICDSearchCategory" onchange="showOrHideType(this.value)">
                            <option value='Confirmed (ICD10)'> Confirmed (ICD10) </option>
                            <option value='Confirmed (Unclassified)'> Confirmed (Unclassified) </option>
                            <option value='Query (Unconfirmed)'> Query (Unconfirmed) </option>
                        </select>
                    </div>
                </div>
                <div class="col" id="showSearchType">
                    <div class="form-check-inline">
                        <label class="form-check-label"> <span class="text-danger">*</span> Thesaurus:   
                            <!--input type="radio" class="form-check-input" id="optradio" name="optradio" value="local" disabled >Local
                        </label-->
                    </div>
                    <div class="form-check-inline">
                        <label class="form-check-label">
                            <input type="radio" class="form-check-input" id="optradio" name="optradio" value="global" checked>Global
                        </label>
                    </div>
                    <div class="form-check-inline">                 
                        <input type="text" class="ctw-input" autocomplete="off" data-ctw-ino="1" placeholder="Enter a keyword to search the global ICD10 database"> 
                    </div>
                    <div class="ctw-window" data-ctw-ino="1"></div>
                    <div class="form-check-inline">
                        <a class="btn text-primary" id="btnAdd" onclick="saveDiagnosis(<?php echo $_REQUEST['cfid']; ?>,<?php echo $_REQUEST['pid']; ?>)">+ Add </a>
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-2">
                    <h5 class="text-primary"><span class="text-danger">*</span> ICD10 Code: <span class="small text-muted" id="showICD10Code"></span></h5>
                </div>
                <div class="col">
                    <h5 class="text-primary"><span class="text-danger">*</span> ICD10 Description: <span class="small text-muted" id="showICD10Desc"></span></h5>
                </div>
            </div>
        </div>
        <div class="container-fluid mt-2 mb-2" id="showDianosisTable">
            <table class="table-responsive table-striped" style="width:100%;">
                <thead class="text-center bg-secondary text-white">
                    <th style="width:5%;">Status</th> <th style="width:19%;">Description</th> <th style="width:19%;">Category</th>                              
                    <th style="width:19%;">Thesaurus Description</th> <th style="width:19%;">Updated By</th> <th style="width:19%;">Diagnosis Date</th>
                </thead>
                <tbody class="text-center">
    <?php           $cat = mysqli_query($con, "SELECT * FROM diagnosis WHERE pid='".$_REQUEST['pid']."' ") or die(mysqli_error($con)); $count = 0;
                    if(mysqli_num_rows($cat) > 0){
                        while($r = mysqli_fetch_array($cat)){ $count += 1; ?>
                            <tr>
                                <td class="text-center" style=""><button class="btn btn-danger bg-white text-danger" id="did" onclick="updateDiagnosisStatus(<?php echo $r['diagid'];?>, '<?php echo $r['status']; ?>')"> <?php echo $r['status']; ?> </button></td>
                                <td class="text-left" style=""> <?php echo $r['description']; ?></td>
                                <td class="text-left" style=""> <?php echo $r['category']; ?></td>
                                <td class="text-left" style=""> <?php echo $r['thesaurus']; ?></td>
                                <td class="text-left" style=""> <?php echo $r['diagnosedby']; ?></td>
                                <td class="text-left" style=""> <?php echo $r['diagnosisdate']; ?></td>
                            </tr>
    <?php               }
                    } ?>
                </tbody>
            </table>
        </div>
        <input type="hidden" id="mycfid" value="<?php echo $_REQUEST['cfid'];?>" /> <input type="hidden" id="mypid" value="<?php echo $_REQUEST['pid'];?>" />
        <div class="alert text-left" id="diasalert"> </div> 
    </div>
    
<script>
    mySettings = {
            // The API located at the URL below should be used only for software
            // development and testing. ICD content at this location might not
            //  be up to date or complete. For production, use the API located at
            // id.who.int with proper OAUTH authentication
                
// apiServerUrl:    "https://icd11restapi-developer-test.azurewebsites.net", apiSecured:        false,

            apiServerUrl:   "https://id.who.int", apiSecured:       true,

            enableKeyboard: true,
            popupMode:      true,
            sourceApp:      "NMSL Mosimi FPP Portal",
            language:       "en" // set the language to English
        };
        // example of an Embedded Coding Tool using the callback selectedEntityFunction 
        // for copying the code selected in an <input> element and clear the search results
        myCallbacks = {
            selectedEntityFunction: (selectedEntity) => { 
                // {"iNo":"1",
                // "uri":"http://id.who.int/icd/release/11/2023-01/mms/1439886552/unspecified",
                // "linearizationUri":"http://id.who.int/icd/release/11/2023-01/mms/1439886552/unspecified",
                // "foundationUri":"http://id.who.int/icd/entity/1439886552",
                // "code":"1F4Z",
                // "title":"Malaria, unspecified",
                // "bestMatchText":"Malaria, unspecified",
                // "selectedText":"Malaria, unspecified",
                // "searchQuery":"Malaria"}
                // paste the code into the <input>
                
                // document.getElementById('paste-selectedEntity').value = selectedEntity.code+'; '+selectedEntity.title;        
                document.getElementById('showICD10Code').innerHTML = selectedEntity.code;
                document.getElementById('showICD10Desc').innerHTML = selectedEntity.title;
                // clear the searchbox and delete the search results
                ECT.Handler.clear("1");
            },
            
            getNewTokenFunction: async () => {
                // if the embedded coding tool is working with the cloud hosted ICD-API, you need to set apiSecured=true
                // In this case the Embedded Coding Tool calls this function when it needs a new token.
                // So, your backend web application should provide updated tokens 

                const url = 'icdbackend/index.php' // we assume this backend script returns a JSON {'token': '...'} 
                const x = new XMLHttpRequest();
                try {
                    x.onreadystatechange = function(){ 
                        // console.log('State: ', this.readyState);
                        // console.log('Status: ', this.status);
                        console.log('Response: ', this.responseText);
                        if(this.readyState === 4 && this.status === 200){
                            const result = this.responseText;
                            const token = result.token;
                        }
                    }; x.open("GET", url, true); x.send();
                    // const response = await fetch(url);
                    // const result = await response.json();
                    // const token = result.token;
                    // return token; // the function return is required 
                } catch (e) {
                    console.log("Error during the request");
                }
            },
            
            searchStartedFunction: () => {
                //this callback is called when searching is started.
                console.log("Search started!");
            },
            
            searchEndedFunction: () => {
                //this callback is called when search ends.
                console.log("Search ended!");
            }
            
        };

        // configure the ECT Handler with mySettings and myCallbacks
        ECT.Handler.configure(mySettings, myCallbacks);
</script>

<script>

    var currentStatus = "none";
    function showDiagnosisDiv(){ //alert();
        if (currentStatus === 'none'){
            $("#newDiagnosisDiv").show(); currentStatus = 'block';
        }else if(currentStatus === 'block'){
            $("#newDiagnosisDiv").hide(); currentStatus = 'none';
        }
    }

    function showOrHideType(value){
        var x = new XMLHttpRequest();       
        x.onreadystatechange = function(){ 
            if(this.readyState === 4 && this.status === 200){               
                // $("#showSearchType").html(this.responseText);
            }
        }; x.open("GET", "processalldata.php?d=show ICD search type&v="+value, true); x.send(); 
    }
    
    
    function saveDiagnosis(c,p){ var cfid = $("#mycfid").val(); var pid = $("#mypid").val(); //alert(pid); 
        var searchCat = $("#ICDSearchCategory").val();
        if(searchCat === 'Confirmed (ICD10)'){
            var icd10code = $("#showICD10Code").html(); var icd10desc = $("#showICD10Desc").html();
            var description = $("#showICD10Code").html() + " - " + $("#showICD10Desc").html(); var category = searchCat; var thesaurusDesc = $("#thesaurus").val(); 
        }else if(searchCat === 'Confirmed (Unclassified)' || searchCat === 'Query (Unconfirmed)'){
            var description = $("#diagnosisKeyword").val(); var category = searchCat; var thesaurusDesc = ''; 
            var icd10code = $("#showICD10Code").html(); var icd10desc = $("#showICD10Desc").html();
        }
        // $("#diasalert").html(cfid + " - " + pid);
        var x = new XMLHttpRequest(); var f = new FormData();
        f.append("icd10code", icd10code); f.append("icd10desc", icd10desc); f.append("desc", description); f.append("cat", category); f.append("thes", thesaurusDesc);
        f.append("conName", "Consultant Name"); f.append("date", "Date of Diagnosis"); f.append("cfid", cfid); f.append("pid", pid); f.append("st", 'Diagnosis');
        x.onreadystatechange = function(){
            if(this.readyState === 4 && this.status === 200){               
                if(this.responseText.includes("This diagnosis already exists as Active.") === true){
                    var resLeft = this.responseText.split("|")[0];
                    $("#diasalert").html(resLeft); return false;
                }else{
                    $("#showDianosisTable").html(this.responseText);
                }
                
            }
        }; x.open("POST", "processalldata.php?d=save and load diagnosis", true); x.send(f); 
    }
    
    function fetchICDAPIValues(value){
        
    }
    
    function updateDiagnosisStatus(id, cStatus){ var pid = $("#mypid").val();
        if(cStatus === 'Active'){ cStatus = 'Inactive'; }else { cStatus = 'Active'; }
        var x = new XMLHttpRequest(); x.onreadystatechange = function(){
            if(this.readyState === 4 && this.status === 200){   //alert(this.responseText);
                if(this.responseText.includes("This diagnosis already exists as Active.") === true){
                    var resLeft = this.responseText.split("|")[0];
                    $("#diasalert").html(resLeft); return false;
                }else{
                    $("#showDianosisTable").html(this.responseText);
                }
                
            }
        }; x.open("GET", "processalldata.php?d=update diagnosis&cs="+cStatus+"&id="+id+"&pid="+pid, true); x.send(); 
    }
</script>

icdbackend/index.php

<?php 
    $cid = '80d4f4af-4fe7-4986-bafb-28d968659195_ed6d67ab-09b9-47aa-86a7-32d2471acd26';
    $csec = "SPLScANIWqiz/gZD0xvREB74ABS0s7yjoKAu5c3u2XA=";
    $tokenEndpoint = "https://icdaccessmanagement.who.int/connect/token";
    $clientId = "$cid";
    $clientSecret = "$csec";
    $grant_type = "client_credentials";
    $scope = "icdapi_access";

    $data = array(
        'client_id' => $clientId,
        'client_secret' => $clientSecret,
        'scope' => $scope,
        'grant_type' => $grant_type
    );

    $options = array(
        'https' => array(
            'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
            'method'  => 'POST',
            'content' => http_build_query($data)
        )
    );
    $context  = stream_context_create($options);
    $result = file_get_contents($tokenEndpoint, false, $context);
    if ($result === FALSE) { 
        $error = error_get_last();
        echo "HTTP request failed. Error was: " . $error['message'];
    } else {
        $json_array = (json_decode($result, true));
        $tken = $json_array['access_token'];

        // create HTTP context to access ICD API
        $options = array(
            'https' => array(
                'header'  => "Authorization: Bearer ".$tken."\r\n".
                             "Accept: application/json\r\n".
                             "Accept-Language: en\r\n".
                             "API-Version: v2"
            )
        );
        $context  = stream_context_create($options);
        $result = file_get_contents('https://id.who.int/icd/entity', false, $context);
        $token = array(); 
        if ($result === FALSE) { 
            $error = error_get_last();
            echo "HTTP request failed. Error was: " . $error['message'];
        } else { 
            // $token[] = $result; echo json_encode($token);
            $token = array('token' => $tken); echo json_encode($token);
        }
    }
?>

Actually, the 'invalid token specified' error emanates from this line... apiServerUrl: "https://id.who.int", apiSecured: true,

However, if I change the apiServerUrl to 'https://icd11restapi-developer-test.azurewebsites.net' and set apeSecured to true, athus: // apiServerUrl: "https://icd11restapi-developer-test.azurewebsites.net", apiSecured: false,

the API returns another type of error,

'Uncaught (in promise) Error: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received'

0

There are 0 best solutions below