Analytics or Clinic Reports

Hi all,

We are wondering what analytics or reports are available for things like visits/day/provider etc. We see an ad for a dashboard on the homepage but can not find where to obtain that data for our clinic. We have roughly 200 licenses and are looking to manage data.

Thanks!

1 Like

We were working on this before COVID-19 hit. I do have a bash script that could function as “api documentation” if you have a technical person on your team they could poll our API every once in a while and collect some high-level usage data:


# Must be clinic owner or admin
EMAIL=''
PASSWORD=''


function extract_token_id () {
  TOKEN_ID=$(echo "$1" | python -c "import json, sys; data = json.load(sys.stdin); print data['id'];")
  echo "$TOKEN_ID"
}


TOKEN_OBJECT=$(curl -sS 'https://api.doxy.me/api/users/login' -X POST -H 'Content-Type: application/x-www-form-urlencoded' -d "email=$EMAIL&password=$PASSWORD")
TOKEN_ID=$(extract_token_id $TOKEN_OBJECT)

echo "Access token:"
# echo $TOKEN_ID

SESSION_HISTORY=$(curl -sS 'https://api.doxy.me/api/sessions/exportClinic' -X GET -H "Authorization: $TOKEN_ID" -H 'Accept: application/json, text/plain, */*' )

# echo "Sessions:"
echo $SESSION_HISTORY```
3 Likes

Awesome! Great to know there’s an API!

Hi Dylan,

We were able to connect the API successfully, https://api.doxy.me/api/sessions/exportClinic, but I guess this is not the API Documentation. Is the API Endpoint different to fetch the documentation?

Dylan, does this API provide any info about the Star Rating/feedback for the clinic? It would be nice to use that info as a feedback loop for our organization.

I got this working, but it took a bit… First thing for people to know is that the bash script provided is written with python 2 in mind, not python 3. Second lesson learned is that the script only handles simple passwords, not passwords with crazy special characters in them. Third lesson is that the end result of this script is a json dataset, which must then be converted to something more useful like a .csv file; had to do that in another python script, below:

json_to_csv.py:
import csv, json, sys
if sys.argv[1] is not None and sys.argv[2] is not None:
fileInput = sys.argv[1]
fileOutput = sys.argv[2]
inputFile = open(fileInput) #open json file
outputFile = open(fileOutput, ‘wb’) #load csv file
data = json.load(inputFile) #load json content
inputFile.close() #close the input file
output = csv.writer(outputFile) #create a csv.write
output.writerow(data[0].keys()) # header row
for row in data:
output.writerow(row.values()) #values row

so, our bash script (saved as GetDoxyLog.sh) now looks like this:
# Must be clinic owner or admin
EMAIL=‘putyouremailhere@domain.com’
PASSWORD=‘putyourpasswordhere’

function extract_token_id () {
  TOKEN_ID=$(echo "$1" | python -c "import json, sys; data = json.load(sys.stdin); print data['id'];")
  echo "$TOKEN_ID"
}


TOKEN_OBJECT=$(curl -sS 'https://api.doxy.me/api/users/login' -X POST -H 'Content-Type: application/x-www-form-urlencoded' -d "email=$EMAIL&password=$PASSWORD")
TOKEN_ID=$(extract_token_id $TOKEN_OBJECT)

echo "Access token:"
# echo $TOKEN_ID

SESSION_HISTORY=$(curl -sS 'https://api.doxy.me/api/sessions/exportClinic' -X GET -H "Authorization: $TOKEN_ID" -H 'Accept: application/json, text/plain, */*' )

# echo "Sessions:"
echo $SESSION_HISTORY > doxyLog.json

python json_to_csv.py doxyLog.json doxyLog.csv

So, now we just run GetDoxyLog.sh, and very quickly we have a DoxyLog.csv file ready for import into a database.

I hope this is a bit more helpful!

Is there an API call that allows us to list the listing of users? This way we can see not only who IS using it (with the Export Clinic Sessions call you already showed us), but then we could see the listing of users to know who ISN’T using the system.

ProspiraIT,

Thanks for posting the csv script. Ive went ahead and cleaned up the file formatting and made them work for both Python 2 and Python 3.

OSX/Linux:

export-doxy-sessions-json.sh

#! /bin/bash

# 1. Must be executed from Linux or Mac, with Python 2/3
# 2. Must be clinic owner or admin
# 3. Must set EMAIL env variable, ex. `export EMAIL=[email address]`
# 4. Must set PASSWORD env variable, ex. `export PASSWORD=[admin password]` 
# 5. This script is purely a demonstration of the current API, and it should not be considered stable

function extract_token_id () {
  TOKEN_ID=$(echo "$1" | python -c "from __future__ import print_function; import json,sys; data=json.load(sys.stdin); print(data['id']);");
  echo "$TOKEN_ID"
}

# 
TOKEN_OBJECT=$(curl -sS 'https://api.doxy.me/api/users/login' -X POST -H 'Content-Type: application/x-www-form-urlencoded' -d "email=${EMAIL}&password=${PASSWORD}")
TOKEN_ID=$(extract_token_id $TOKEN_OBJECT)

SESSION_HISTORY=$(curl -sS 'https://api.doxy.me/api/sessions/exportClinic' -X GET -H "Authorization: $TOKEN_ID" -H 'Accept: application/json, text/plain, */*' )

echo $SESSION_HISTORY

doxy-sessions-json-to-csv.py:

from __future__ import print_function
import csv, json, sys

if len(sys.argv) != 3:
    print("arg 1: .json sessions input filename")
    print("arg 2: .csv sessions output filename")
    sys.exit(0)

with open(sys.argv[1], 'r') as in_file:
    json_data = json.load(in_file)

with open(sys.argv[2], 'w') as out_file:
    csv_writer = csv.writer(out_file)
    csv_writer.writerow(json_data[0].keys())
    for row in json_data:
        csv_writer.writerow(row.values())

Windows:

export_clinic_sessions.ps1:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$email = Read-Host 'Doxy.me admin account email'
$password = Read-Host 'Doxy.me admin account password'

$Body = @{
    email = $email
    password = $password
}

$LoginResponse = Invoke-WebRequest -URI "https://api.doxy.me/api/users/login" -UseBasicParsing -Body $Body -Method 'POST'
$LoginJSON = $LoginResponse.Content | ConvertFrom-Json
$AuthTokenId = $LoginJSON.id

$SessionsResponse = Invoke-WebRequest -URI "https://api.doxy.me/api/sessions/exportClinic" -UseBasicParsing -Method 'GET' -Headers @{'Accept' = 'application/json'; 'Authorization' = $AuthTokenId}
$SessionsJSON = $SessionsResponse.Content
$SessionsJSON | Out-File -FilePath .\clinic-sessions.json

Windows Instructions:

  1. Download this file: export_clinic_sessions.txt (747 Bytes) (same contents as code above)
  2. Go to the “Downloads” folder, and change the file name from “export_clinic_sessions” to “export_clinic_sessions.ps1” (File type option: All files)
  3. Right-click the file, and select Run with PowerShell (How to start PowerShell)
  4. Follow the instructions when prompted
  5. A file named “clinic-sessions.json” will be in the Downloads folder.
  6. For a .csv file, please use a JSON to CSV converter

These tasks should be more easily available in the UI in the future. For now, the API should be fully accessible with code. Thanks again for the handy script. Please post any idea you have here in the Discussion area or the Feature Request area!

3 Likes

For listing users, a simple list of first name, last name, email, status (member, owner, admin, disabled), created date, and deleted date (if possible) is all that’s needed. This could then be compared with the existing session log API so we can see not only who IS using the licenses but also who ISN’T. That way, we can reach out to those who aren’t and see what we can do to get them using this awesome facility. This is also helpful in allocating costs internally: I’d use the name/email fields to marry the listing to our HR roster so I can indicate what departments they’re with. I could use the created/deleted dates to factor the doxy user license costs, too, at a daily rate. I’m currently maintaining a list like this manually, but I worry that my manual list will get out of date and my reports will lose value over time. Much better to have an API so I can automate the table update daily.

Is there a plan to make this accessible to all customers (including those without a programming staff)?

2 Likes

Yes, we will hopefully make something like an “Export Sessions” button somewhere for account owners. Unfortunately, I cannot comment on a timeline for new features during this month. Our developers are working on several improvements that we hope to release soon!

2 Likes

@ProspiraIT,

Thanks for posting here. I can certainly take a look later this week to see any possibilities for a solution. The API will likely come first, then we will try to make better documentation and menu options after that. Once again, I cant comment on timelines.

1 Like

Was just looking into this for our clinical staff, thanks for all the tips.

Like @ProspiraIT … wondering if there are any other APIs ready beyond the session info ( I couldn’t find reference to any others)? Even for beta testing? @mrboots ?

Anyhow, I like Bash as much as the next guy, but seems like it’s mostly being used to get to curl? Thought I’d try an all python solution. Could be shorter, but left some error checking and debug statements in there. Feel free to clone somebody else’s json-to-csv example, if that is what you’re looking for.

from __future__ import print_function 
import json, requests  

# acknowledgement: https://community.microstrategy.com/s/article/Sample-REST-API-in-Python-Authentication?language=en_US
                        
api_login = 'user@example.com'
api_password = 'secretpassword123'
base_url = 'https://api.doxy.me/api/'

def login(base_url,api_login,api_password):
    #print("Getting Doxy Auth Token...")
    data_get = {'email': api_login,'password': api_password}
    r = requests.post(base_url+'users/login', data=data_get)
        
    if r.ok:
        content = r.json()
        authToken = content['id']
        cookies = dict(r.cookies)
        return authToken, cookies 
    else:             
        print("HTTP %i - %s, Message %s" % (r.status_code, r.reason, r.text))
                      
def get_sessions(base_url, auth_token, cookies):  
    #print("Getting Doxy sessions...")
    header_gs = {'Authorization': auth_token, 'Accept': 'application/json, text/plain, */*'}
    r = requests.get(base_url + "sessions/exportClinic", headers=header_gs, cookies=cookies)
    if r.ok:
        #print("Authenticated...")
        return r.json()
    else:
        print("HTTP %i - %s, Message %s" % (r.status_code, r.reason, r.text))

def export_sessions(sessions_json):
    # do whatever you like here...  convert to CSV, import to a DB, etc
    print("Exporting all the JSON data")
    print(json.dumps(sessions_json))

def main():
    auth_token, cookies = login(base_url,api_login,api_password)
    sessions_json = get_sessions(base_url, auth_token, cookies)
    export_sessions(sessions_json)

main()
2 Likes

The website shows access to “Analytics” -
https://doxy.me/enterprise

Is this possible and how?

3 Likes

@LukeJ thanks for the first post! This sorta stuff is not really a solution long-term, and I don’t want anyone to think that we expect doctors and clinics to be programmers for gathering this data. Bash and Python here are just for the short term while we handle many other areas of the platform over the coming weeks. Please use this page strictly for reference if you have the motivation to get a head start on some of the API features. I’ll try to post some other endpoints we have, and how to use them soon.

@larrypavlock , I apologize for these info pages. We should probably update them to set better expectations for our customers.

1 Like

Thanks for sharing the API bash/python script.
I tend to work in Perl, so I re-wrote the script in Perl using the Mojo::UserAgent module
This will work cross-platform, prompts for clinic username and password

use strict;
use warnings;
use 5.10.0;
use Mojo::UserAgent;
use Data::Dumper;

#Some variable declaration
my $urlsession = "https://api.doxy.me/api/sessions/exportClinic";
my $urllogin = "https://api.doxy.me/api/users/login";
my ($name, $pw);
my $ua = Mojo::UserAgent->new;
$ua = $ua->inactivity_timeout(30);
	
#Interactive Input for email address and password
print "Enter your login name: ";
$name = <STDIN>;
chomp $name;
print "Enter your password: ";
$pw = <STDIN>;
chomp $pw;
my $q = {
    "email" => $name,
    "password" => $pw,
};

#Get token for API credential
my $l = $ua->post( $urllogin => { 'Content-Type' => 'application/x-www-form-urlencoded' } => form => $q)->res->json;
my $token = $l->{'id'};
#say "Token is $token";

#Use token for API request for clinic info
my $ua2 = Mojo::UserAgent->new;
$ua2->on(start => sub {
    my ($ua, $tx) = @_;
    $tx->req->headers->authorization($token);
});
my $s = $ua2->get( $urlsession => { 'Content-Type' => 'application/json', "Accept" => "application/json, text/plain, */*" } )->res->json;

#Print out array of hashes
say Dumper($s);
3 Likes

@svdk, nice Perl script! I have no practice with Perl myself, but it looks beautiful, commented and everything.

I’d like to make sure everyone is aware that we have a discussion area for feature requests here: Feature Requests - Doxy.me User Community

This area really helps us prioritize requests from the users directly. We know that Doxy.me users want more features, and we really appreciate feedback on how we should approach new updates. I’ve heard some great ideas for the API so far, and I want to make sure the conversation continues. Thanks!

1 Like

Hi. Very much a novice at this. Can anyone help with the following output? I have entered the clinic admin email and password into the file.

Roberts-MacBook-Air:~ ers$ sh /Users/ers/Desktop/doxy2.sh 
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 290, in load
    **kw)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Invalid control character at: line 1 column 57 (char 56)
{"error":{"name":"Error","status":401,"message":"Authorization Required","statusCode":401,"code":"AUTHORIZATION_REQUIRED"}}
Roberts-MacBook-Air:~ ers$