| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.gdata.health">
- <title>Using Google Health</title>
- <para>
- The Google Health Data <acronym>API</acronym> is designed to enable developers to do two
- things:
- <itemizedlist>
- <listitem>
- <para>
- 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.
- </para>
- </listitem>
- <listitem>
- <para>
- 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
- <acronym>XML</acronym> 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.
- </para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- There are three main feeds, each of which requires authentication. Unlike other Google Data
- <acronym>API</acronym>s, each Google Health feed has a limited set of
- <acronym>HTTP</acronym> 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
- <ulink
- url="http://code.google.com/apis/health/reference.html#Authentication">http://code.google.com/apis/health/reference.html#Authentication</ulink>.
- <itemizedlist>
- <listitem>
- <para>
- <firstterm>Profile Feed</firstterm>
- use the profile feed to query a user's health profile for specific information.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>Register Feed</firstterm>
- use the register feed to reconcile new CCR data into a profile.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>Profile List Feed</firstterm> 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.
- </para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- See <ulink
- url="http://code.google.com/apis/health/">http://code.google.com/apis/health</ulink>
- for more information about the Google Health <acronym>API</acronym>.
- </para>
- <sect2 id="zend.gdata.health.connect">
- <title>Connect To The Health Service</title>
- <para>
- The Google Health <acronym>API</acronym>, like all Google Data <acronym>API</acronym>s,
- is based off of the Atom Publishing Protocol (APP), an <acronym>XML</acronym> based
- format for managing web-based resources. Traffic between a client and the Google Health
- servers occurs over <acronym>HTTP</acronym> and allows for authenticated connections.
- </para>
- <para>
- Before any transactions can occur, a connection needs to be made. Creating a connection
- to the Health servers involves two steps: creating an <acronym>HTTP</acronym> client and
- binding a <classname>Zend_Gdata_Health</classname> service instance to that client.
- </para>
- <sect3 id="zend.gdata.health.connect.authentication">
- <title>Authentication</title>
- <para>
- The Google Health <acronym>API</acronym> allows programmatic access to a user's
- Health profile. There are three authentication schemes that are supported by Google
- Health:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <firstterm>ClientLogin</firstterm> 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.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>AuthSub</firstterm> 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
- <acronym>API</acronym> must be digitally signed.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>OAuth</firstterm> is an alternative to AuthSub. Although this
- authentication scheme is not discussed in this document, more information
- can be found in the <ulink
- url="http://code.google.com/apis/health/developers_guide_protocol.html#OAuth">Health
- Data <acronym>API</acronym> Developer's Guide</ulink>.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- See <ulink
- url="http://code.google.com/apis/gdata/auth.html">Authentication Overview in the
- Google Data <acronym>API</acronym> documentation</ulink> for more
- information on each authentication method.
- </para>
- </sect3>
- <sect3 id="zend.gdata.health.connect.service">
- <title>Create A Health Service Instance</title>
- <para>
- In order to interact with Google Health, the client library provides the
- <classname>Zend_Gdata_Health</classname> 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 <acronym>API</acronym>.
- </para>
- <para>
- Once you've decided on an authentication scheme, the next step is to create an
- instance of <classname>Zend_Gdata_Health</classname>. This class should be passed an
- instance of <classname>Zend_Gdata_HttpClient</classname>. This provides an interface
- for AuthSub/OAuth and ClientLogin to create a special authenticated
- <acronym>HTTP</acronym> client.
- </para>
- <para>
- To test against the H9 Developer's (/h9) instead of Google Health (/health), the
- <classname>Zend_Gdata_Health</classname> constructor takes an optional third
- argument for you to specify the H9 service name 'weaver'.
- </para>
- <para>
- The example below shows how to create a Health service class using ClientLogin
- authentication:
- </para>
- <programlisting language="php"><![CDATA[
- // 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);
- ]]></programlisting>
- <para>
- 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 <acronym>API</acronym>s, it is required that all
- requests from your application be digitally signed.
- </para>
- <programlisting language="php"><![CDATA[
- /*
- * Retrieve the current URL so that the AuthSub server knows where to
- * redirect the user after authentication is complete.
- */
- function getCurrentUrl() {
- $phpRequestUri = htmlentities(substr($_SERVER['REQUEST_URI'],
- 0,
- strcspn($_SERVER['REQUEST_URI'],
- "\n\r")),
- ENT_QUOTES);
- if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') {
- $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 <-
- session_start();
- $client = setupClient(@$_GET['token']);
- // Create an instance of the Health service
- $userH9Sandbox = false;
- $healthService = new Zend_Gdata_Health($client,
- 'googleInc-MyTestAppName-v1.0',
- $userH9Sandbox);
- ]]></programlisting>
- <para>
- NOTE: the remainder of this document will assume you are using AuthSub for
- authentication.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.gdata.health.profilefeed">
- <title>Profile Feed</title>
- <para>
- To query the user's profile feed, make sure your initial AuthSub token was requested
- with the <property>permission</property> parameter set to <emphasis>1</emphasis>. The
- process of extracting data from the profile requires two steps, sending a query and
- iterating through the resulting feed.
- </para>
- <sect3 id="zend.gdata.health.profilefeed.query">
- <title>Send a Structured Query</title>
- <para>
- You can send structured queries to retrieve specific records from a user's profile.
- </para>
- <para>
- When retrieving the profile using the Health <acronym>API</acronym>, specifically
- constructed query <acronym>URL</acronym>s are used to describe what (CCR) data
- should be returned. The <classname>Zend_Gdata_Health_Query</classname> class helps
- simplify this task by automatically constructing a query <acronym>URL</acronym>
- based on the parameters you set.
- </para>
- <sect4 id="zend.gdata.health.profilefeed.query.construct">
- <title>Query The Feed</title>
- <para>
- To execute a query against the profile feed, invoke a new instance of an
- <classname>Zend_Gdata_Health_Query</classname> and call the service's
- <methodname>getHealthProfileFeed()</methodname> method:
- </para>
- <programlisting language="php"><![CDATA[
- $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);
- ]]></programlisting>
- <para>
- Using <methodname>setDigest("true")</methodname> returns all of user's CCR data
- in a single Atom <emphasis><entry></emphasis>.
- </para>
- <para>
- The <methodname>setCategory()</methodname> helper can be passed an additional
- parameter to return more specific CCR information. For example, to return just
- the medication Lipitor, use
- <methodname>setCategory("medication", "Lipitor")</methodname>. The same
- methodology can be applied to other categories such as conditions, allergies,
- lab results, etc.
- </para>
- <para>
- A full list of supported query parameters is available in the <ulink
- url="http://code.google.com/apis/health/reference.html#Parameters">query
- parameters section</ulink> of the Health <acronym>API</acronym> Reference
- Guide.
- </para>
- </sect4>
- </sect3>
- <sect3 id="zend.gdata.health.profilefeed.iterate">
- <title>Iterate Through The Profile Entries</title>
- <para>
- Each Google Health entry contains CCR data, however, using the
- <property>digest</property> query parameter and setting is to
- <constant>TRUE</constant> will consolidate all of the CCR elements
- (that match your query) into a single Atom <emphasis><entry></emphasis>.
- </para>
- <para>
- To retrieve the full CCR information from an entry, make a call to the
- <classname>Zend_Gdata_Health_ProfileEntry</classname> class's
- <methodname>getCcr()</methodname> method. That returns a
- <classname>Zend_Gdata_Health_Extension_CCR</classname>:
- </para>
- <programlisting language="php"><![CDATA[
- $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>";
- }
- }
- ]]></programlisting>
- <para>
- Here, the <methodname>getCcr()</methodname> 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
- <methodname>getCATEGORYNAME()</methodname>, where <constant>CATEGORYNAME</constant>
- is a supported Google Health category. See the <ulink
- url="http://code.google.com/apis/health/reference.html#CatQueries">Google Health
- reference Guide</ulink> for the possible categories.
- </para>
- <para>
- 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:
- </para>
- <programlisting language="php"><![CDATA[
- $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>";
- }
- ]]></programlisting>
- </sect3>
- </sect2>
- <sect2 id="zend.gdata.health.profilelist">
- <title>Profile List Feed</title>
- <para>NOTE: This feed is only available when using ClientLogin</para>
- <para>
- 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 <emphasis><content></emphasis> and
- the profile name in the <emphasis><title></emphasis> element.
- </para>
- <sect3 id="zend.gdata.health.profilelist.query">
- <title>Query The Feed</title>
- <para>
- To execute a query against the profile list feed, call the service's
- <methodname>getHealthProfileListFeed()</methodname> method:
- </para>
- <programlisting language="php"><![CDATA[
- $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>';
- }
- ]]></programlisting>
- <para>
- Once you've determined which profile to use, call
- <methodname>setProfileID()</methodname> with the profileID as an argument. This will
- restrict subsequent <acronym>API</acronym> requests to be against that particular
- profile:
- </para>
- <programlisting language="php"><![CDATA[
- // 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>';
- ]]></programlisting>
- </sect3>
- </sect2>
- <sect2 id="zend.gdata.health.notice">
- <title>Sending Notices to the Register Feed</title>
- <para>
- 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 <acronym>XHTML</acronym>
- 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.
- </para>
- <sect3 id="zend.gdata.health.notice.send">
- <title>Sending a notice</title>
- <para>
- Notices can be sent by using the <methodname>sendHealthNotice()</methodname> method
- for the Health service:
- </para>
- <programlisting language="php"><![CDATA[
- $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);
- ]]></programlisting>
- </sect3>
- </sect2>
- </sect1>
|