Using Google Health
The Google Health Data API is designed to enable developers to do two
things:
-
Read a user's Google Health profile or query for medical records that match
particular criteria and then use the results to provide personalized
functionality based on the data.
-
Add new medical records to a user's profile by including CCR data when sending a
notice to a user's profile. Note: The CCR data is stored as an
XML blob within the <atom> entry. The library does not
provide direct accessors to the object model but it does have helpers for
extracting specific fields.
There are three main feeds, each of which requires authentication. Unlike other Google Data
APIs, each Google Health feed has a limited set of
HTTP operations you can perform on it, depending on which authentication
method you are using (ClientLogin or AuthSub/OAuth). For a list of permitted operations, see
» http://code.google.com/apis/health/reference.html#Authentication.
-
Profile Feed
use the profile feed to query a user's health profile for specific information.
-
Register Feed
use the register feed to reconcile new CCR data into a profile.
-
Profile List Feed the profile list feed should be used to
determine which of the user's Health profiles to interact with. This feed is only
available when using ClientLogin.
See » http://code.google.com/apis/health
for more information about the Google Health API.
Connect To The Health Service
The Google Health API, like all Google Data APIs,
is based off of the Atom Publishing Protocol (APP), an XML based
format for managing web-based resources. Traffic between a client and the Google Health
servers occurs over HTTP and allows for authenticated connections.
Before any transactions can occur, a connection needs to be made. Creating a connection
to the Health servers involves two steps: creating an HTTP client and
binding a Zend_Gdata_Health service instance to that client.
Authentication
The Google Health API allows programmatic access to a user's
Health profile. There are three authentication schemes that are supported by Google
Health:
-
ClientLogin provides direct username/password
authentication to the Health servers. Since this method requires that users
provide your application with their password, this authentication scheme is
only recommended for installed/desktop applications.
-
AuthSub allows a user to authorize the sharing of
their private data. This provides the same level of convenience as
ClientLogin but without the security risk, making it an ideal choice for
web-based applications. For Google Health, AuthSub must be used in
registered and secure mode--meaning that all requests to the
API must be digitally signed.
-
OAuth is an alternative to AuthSub. Although this
authentication scheme is not discussed in this document, more information
can be found in the » Health
Data API Developer's Guide.
See » Authentication Overview in the
Google Data API documentation for more
information on each authentication method.
Create A Health Service Instance
In order to interact with Google Health, the client library provides the
Zend_Gdata_Health service class. This class provides a common
interface to the Google Data and Atom Publishing Protocol models and assists in
marshaling requests to and from the Health API.
Once you've decided on an authentication scheme, the next step is to create an
instance of Zend_Gdata_Health. This class should be passed an
instance of Zend_Gdata_HttpClient. This provides an interface
for AuthSub/OAuth and ClientLogin to create a special authenticated
HTTP client.
To test against the H9 Developer's (/h9) instead of Google Health (/health), the
Zend_Gdata_Health constructor takes an optional third
argument for you to specify the H9 service name 'weaver'.
The example below shows how to create a Health service class using ClientLogin
authentication:
// Parameters for ClientLogin authentication
$healthServiceName = Zend_Gdata_Health::HEALTH_SERVICE_NAME;
//$h9ServiceName = Zend_Gdata_Health::H9_SANDBOX_SERVICE_NAME;
$user = "user@gmail.com";
$pass = "pa$$w0rd";
// Create an authenticated HTTP client
$client = Zend_Gdata_ClientLogin::getHttpClient($user,
$pass,
$healthServiceName);
// Create an instance of the Health service
$service = new Zend_Gdata_Health($client);
A Health service using AuthSub can be created in a similar, though slightly more
lengthy fashion. AuthSub is the recommend interface to communicate with Google
Health because each token is directly linked to a specific profile in the user's
account. Unlike other Google Data APIs, it is required that all
requests from your application be digitally signed.
/*
* Retrieve the current URL so that the AuthSub server knows where to
* redirect the user after authentication is complete.
*/
function getCurrentUrl() {
0,
"\n\r")),
ENT_QUOTES);
$protocol = 'https://';
} else {
$protocol = 'http://';
}
$host = $_SERVER['HTTP_HOST'];
if ($_SERVER['SERVER_PORT'] != '' &&
(($protocol == 'http://' && $_SERVER['SERVER_PORT'] != '80') ||
($protocol == 'https://' && $_SERVER['SERVER_PORT'] != '443'))) {
$port = ':' . $_SERVER['SERVER_PORT'];
} else {
$port = '';
}
return $protocol . $host . $port . $phpRequestUri;
}
/*
* Redirect a user to AuthSub if they do not have a valid session token.
* If they're coming back from AuthSub with a single-use token, instantiate
* a new HTTP client and exchange the token for a long-lived session token
* instead.
*/
function setupClient($singleUseToken = null) {
$client = null;
// Fetch a new AuthSub token?
if (!$singleUseToken) {
$next = getCurrentUrl();
$scope = 'https://www.google.com/health/feeds';
$authSubHandler = 'https://www.google.com/health/authsub';
$secure = 1;
$session = 1;
$authSubURL = Zend_Gdata_AuthSub::getAuthSubTokenUri($next,
$scope,
$secure,
$session,
$authSubHandler);
// 1 - allows posting notices && allows reading profile data
$permission = 1;
$authSubURL .= '&permission=' . $permission;
echo '<a href="' . $authSubURL . '">Your Google Health Account</a>';
} else {
$client = new Zend_Gdata_HttpClient();
// This sets your private key to be used to sign subsequent requests
$client->setAuthSubPrivateKeyFile('/path/to/your/rsa_private_key.pem',
null,
true);
$sessionToken =
Zend_Gdata_AuthSub:: getAuthSubSessionToken(trim($singleUseToken),
$client);
// Set the long-lived session token for subsequent requests
$client->setAuthSubToken($sessionToken);
}
return $client;
}
// -> Script execution begins here <-
$client = setupClient(@$_GET['token']);
// Create an instance of the Health service
$userH9Sandbox = false;
$healthService = new Zend_Gdata_Health($client,
'googleInc-MyTestAppName-v1.0',
$userH9Sandbox);
NOTE: the remainder of this document will assume you are using AuthSub for
authentication.
Profile Feed
To query the user's profile feed, make sure your initial AuthSub token was requested
with the permission parameter set to 1. The
process of extracting data from the profile requires two steps, sending a query and
iterating through the resulting feed.
Send a Structured Query
You can send structured queries to retrieve specific records from a user's profile.
When retrieving the profile using the Health API, specifically
constructed query URLs are used to describe what (CCR) data
should be returned. The Zend_Gdata_Health_Query class helps
simplify this task by automatically constructing a query URL
based on the parameters you set.
Query The Feed
To execute a query against the profile feed, invoke a new instance of an
Zend_Gdata_Health_Query and call the service's
getHealthProfileFeed() method:
$healthService = new Zend_Gdata_Health($client);
// example query for the top 10 medications with 2 items each
$query = new Zend_Gdata_Health_Query();
$query->setDigest("true");
$query->setGrouped("true");
$query->setMaxResultsGroup(10);
$query->setMaxResultsInGroup(2);
$query->setCategory("medication");
$profileFeed = $healthService->getHealthProfileFeed($query);
Using setDigest("true") returns all of user's CCR data
in a single Atom <entry>.
The setCategory() helper can be passed an additional
parameter to return more specific CCR information. For example, to return just
the medication Lipitor, use
setCategory("medication", "Lipitor"). The same
methodology can be applied to other categories such as conditions, allergies,
lab results, etc.
A full list of supported query parameters is available in the » query
parameters section of the Health API Reference
Guide.
Iterate Through The Profile Entries
Each Google Health entry contains CCR data, however, using the
digest query parameter and setting is to
TRUE will consolidate all of the CCR elements
(that match your query) into a single Atom <entry>.
To retrieve the full CCR information from an entry, make a call to the
Zend_Gdata_Health_ProfileEntry class's
getCcr() method. That returns a
Zend_Gdata_Health_Extension_CCR:
$entries = $profileFeed->getEntries();
foreach ($entries as $entry) {
$medications = $entry->getCcr()->getMedications();
//$conditions = $entry->getCcr()->getConditions();
//$immunizations = $entry->getCcr()->getImmunizations();
// print the CCR xml (this will just be the entry's medications)
foreach ($medications as $med) {
$xmlStr = $med->ownerDocument->saveXML($med);
echo "<pre>" . $xmlStr . "</pre>";
}
}
Here, the getCcr() method is used in conjunction with a
magic helper to drill down and extract just the medication data from the entry's
CCR. The formentioned magic helper takes the form
getCATEGORYNAME(), where CATEGORYNAME
is a supported Google Health category. See the » Google Health
reference Guide for the possible categories.
To be more efficient, you can also use category queries to only return the necessary
CCR from the Google Health servers. Then, iterate through those results:
$query = new Zend_Gdata_Health_Query();
$query->setDigest("true");
$query->setCategory("condition");
$profileFeed = $healthService->getHealthProfileFeed($query);
// Since the query contained digest=true, only one Atom entry is returned
$entry = $profileFeed->entry[0];
$conditions = $entry->getCcr()->getConditions();
// print the CCR xml (this will just be the profile's conditions)
foreach ($conditions as $cond) {
$xmlStr = $cond->ownerDocument->saveXML($cond);
echo "<pre>" . $xmlStr . "</pre>";
}
Profile List Feed
NOTE: This feed is only available when using ClientLogin
Since ClientLogin requires a profile ID with each of its feeds, applications will likely
want to query this feed first in order to select the appropriate profile. The profile
list feed returns Atom entries corresponding each profile in the user's Google Health
account. The profile ID is returned in the Atom <content> and
the profile name in the <title> element.
Query The Feed
To execute a query against the profile list feed, call the service's
getHealthProfileListFeed() method:
$client = Zend_Gdata_ClientLogin::getHttpClient('user@gmail.com',
'pa$$word',
'health');
$healthService = new Zend_Gdata_Health($client);
$feed = $healthService->getHealthProfileListFeed();
// print each profile's name and id
$entries = $feed->getEntries();
foreach ($entries as $entry) {
echo '<p>Profile name: ' . $entry-> getProfileName() . '<br>';
echo 'profile ID: ' . $entry-> getProfileID() . '</p>';
}
Once you've determined which profile to use, call
setProfileID() with the profileID as an argument. This will
restrict subsequent API requests to be against that particular
profile:
// use the first profile
$profileID = $feed->entry[0]->getProfileID();
$healthService->setProfileID($profileID);
$profileFeed = $healthService->getHealthProfileFeed();
$profileID = $healthService->getProfileID();
echo '<p><b>Queried profileID</b>: ' . $profileID . '</p>';
Sending Notices to the Register Feed
Individual posts to the register feed are known as notices. Notice are sent from
third-party applications to inform the user of a new event. With AuthSub/OAuth, notices
are the single means by which your application can add new CCR information into a user's
profile. Notices can contain plain text (including certain XHTML
elements), a CCR document, or both. As an example, notices might be sent to remind users
to pick up a prescription, or they might contain lab results in the CCR format.
Sending a notice
Notices can be sent by using the sendHealthNotice() method
for the Health service:
$healthService = new Zend_Gdata_Health($client);
$subject = "Title of your notice goes here";
$body = "Notice body can contain <b>html</b> entities";
$ccr = '<ContinuityOfCareRecord xmlns="urn:astm-org:CCR">
<Body>
<Problems>
<Problem>
<DateTime>
<Type><Text>Start date</Text></Type>
<ExactDateTime>2007-04-04T07:00:00Z</ExactDateTime>
</DateTime>
<Description>
<Text>Aortic valve disorders</Text>
<Code>
<Value>410.10</Value>
<CodingSystem>ICD9</CodingSystem>
<Version>2004</Version>
</Code>
</Description>
<Status><Text>Active</Text></Status>
</Problem>
</Problems>
</Body>
</ContinuityOfCareRecord>';
$responseEntry = $healthService->sendHealthNotice($subject,
$body,
"html",
$ccr);
|
|