fhir-iva-integration
Example integration to https://fhir.epic.com/
Introduction
This repository provides and example integration to EPIC using the Epic on FHIR Sandbox. To use this example, you will need to create an account and Build an app run the APIs.
FHIR App
This integration example requires you to build an App that allow the SMART Backend Services (Backend OAUTH 2.0) workflow to obtain an access token.
To use this integration, you will need to create a public and private key as described in the section Creating a Public Private Key Pair for JWT Signature and upload public key file to the FHIR Application and the Private Key to the fhirSettings global variable.
When configuring the FHIR App, please make sure to:
- Select Backend System as the Application Audience
- Select the APIs you wish to use. NOTE: Only DSTU2 APIs have been tested
- Use the Non-Production Client ID in the fhirSettings Global Variable
- Upload your publickey509.pem file to *Sandbox JWT Signing Public Key
- Select DSTU2 for SMART on FHIR Version. Other versions have not been tested
- The rest should be optional for the Sandbox and not required for this example
IVA Studio
Global Variables
Add both fhirInterface as a Function and fhirSettings as an Object to Global Variables.
fhirInterface currently as one function getToken that first checks REDIS for an unexpired token, then create one using the JWT method described by FHIR's documentation.
Because this is just an example, limited error handling and no Token refresh protocols have been implemented.
fhirSettings
Open the file fhirSettings and add your private key.
NOTE: Remember, because this is a JSON Object, new lines from the private key will need to be replaced with '\n'.
This is not recommended for a production environment.
The file should look something like this when complete.
{
"base_url" : "https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR",
"token_url" : "https://fhir.epic.com/interconnect-fhir-oauth/oauth2/token",
"jwt" : {
"uuid_namespace" : "30e3078d-59fe-4151-8571-304c87580209",
"client_id" : "66eaeb38-c5f7-41cb-8cd3-791efacf25e5",
"privateKey" : "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEA45nS5ecQak+ewzLOCkWnvwp+cjw1NiZOLV1aX+DGxDkuEX3h\ndQLAYT+bQ+MFojqPQErxnp3kFR+uLQSfQ3tkBL3v4H07hLnV/oZQ5d1CCoCfNVQS\nI3FyN0jr/qPMrqrih+QVouA01GvupShSGrrBYks204lCmHE0VWnvP/+BKDdlEeD5\n1uuDXKpDdE4tQh52y92YhDEoSmw9q6RW2IFKMeaQt3h4nOLVkMNcMyLWaspqmbCE\nTpduwVseY19QV8bNQiy6JaWp3AiVL2+M9VjEr5i2DFMRfQVSPOElCzDlwXZ4LFyk\nOMvPYyECnly7TCiGWcenR/iCjdmgFsrUZKbbqQIDAQABAoIBAHbktQnJ8YZHf1zi\nnkU5a85dMf6EuxtFWVNTT9GD/vEkGY+jnXHddReX/YiyABBl3M0uGRfNzQbH3NnB\nb1z2CSJ9AeDYKo5D8aibC4l4UnZgCEr4Vt1S9uIwYq9La7HWrK1mFXNXAeHxW+HE\ntVcnNbweJE7Ohg5SHI993jAlTZfuk6jqbRFQiOsdSAWcXAYDOeGNHJW/OEmcHa1v\n+vFA8eOjRo8fgxDWgOASdHlWfe4oY3BgKvIlFxtnO7bbqfE9+66lZ+VZMSBivWKZ\nspW1jgJCMZY+s5HNAj74aTV273N2Dd5UA/B3au/8yihHWG1DCuvIJgBhlyuebymA\n0mbnBu0CgYEA+vqR1/6sUbjvIe0Q5hKIzgmQTB5JBhMdVhN9jjkWbzmmHg14X8bx\nMnyomOOOYMs2BL/XnnYELdvLXbNsdfn3z7YLnRRWJYz5BeZKo0cziJ1qAU/GQivl\n+yUQDMWAI+tOCRO2eWU4H5pfWinYgb/Fjnk1e6WU1EEUJI4oE6nC5MsCgYEA6CeF\nKph4579OrjM5aEeOa+v/cHbWen3sw8tYuX5YIUsceJkwnlr7vdgwxfWjWHpQ1vA7\nJTHpTiiU9NBYyIw3RJTCC45+nZB0Wozco6Iimscggceupd8ewbAtk/hAAjWXp7y5\n6+PrqLrML4KGqEJS3CDyOx/NKFW3vXkJjq8FJtsCgYEA5rCQg7fsDkXtUALGqKNa\nqf+yabTgrDu/mFHb83FXxK55mWAKSAblxuE8WyO2yBOhOGZZu6aAmuJPoHX+eMZl\n2L9dF2oM8QEOGDUgX8pffPAr8r6v3jzZbKoZgZO7/8gWd1NuQ1EdcDcF9CtIfaKW\n5SlWVqvRC/QxnpQoFELTCFcCgYEA5HPfi6c3c3bDCpHF8GRaNsGqQRXwweGhWJuG\n2CMIvtqXTeYR/gMysANLG8M51xum6ZzF1zhiilNNIgzVEaVJzedFfPHgj1VT6rer\neCtZOk6yIoRJzVjff2LLt00YUBRFBP+nRgaoJQaNYENmF7YMrCqPtLb6wLJ5ea7e\nRNbejvkCgYEA1nMBDVtFbGyfWtmBB12ip5Xj76DhMvjsTc72cE8aKlDPHMYg7t2B\nSaeks8I20f+yRBWBQW9VdyAflTfZBCSM1fdFGj1M14bTr+ikNT4TNdBmXDbS//3t\nlOoomQDl08DhtkH/wSZrwJKgnNVCSPT+fLZzbTcmrsGkv6FdRthPjFY=\n-----END RSA PRIVATE KEY-----"
},
"patient_id" : "T81lum-5p6QvDR7l6hv7lfE52bAbA2ylWBnv9CZEzNb0B"
}
Proxy Scripts
An example proxy script has been provided to test our a Patient.READ(DSTU2) API Call. Ideally, you should work this into your Conversation Flows using the Call API Widget
(async () => {
try {
const token = await fhirInterface().getToken();
let config = {
method: "get",
url: `${fhirSettings.base_url}/DSTU2/Patient/${fhirSettings.patient_id}`,
headers: {
"Accept" : "application/json",
"Authorization" : `${token.token_type} ${token.access_token}`
}
};
const result = await axios(config);
res.json(result.data);
} catch (err) {
if( err.response ){
res.status(err.response.status).json(err.response.data);
} else {
res.status(400).json(JSON.stringify(err));
}
}
})();
You can call this Proxy Script using the follow cUrl command on the Proxy end point for your workspace and you should get some patient details back. For example,
curl --location 'https://router.ivastudio.verint.live/ProxyScript/run/661554664677144c0e1e71d5/current/fhirPatientRead'
