IMPORTANT: This project is not HIPAA compliant. However, "the HHS Office for Civil Rights (OCR) will not impose penalties for noncompliance with regulatory requirements under the HIPAA Rules against covered health care providers or their business associates in connection with the good faith use of online or web-based scheduling applications for the scheduling of individual appointments for COVID-19 vaccinations during the COVID-19 nationwide public health emergency".
This project is a free lightweight mobile-friendly web tool for registering, scheduling, notifying, managing, and filing reports for mass vaccination efforts such as the COVID-19 vaccination. It attempts to provide a digital workflow reducing the burden of manual paperwork and processes for small/medium vaccination clinics that may not have the IT infrastructure to build thier own tools. Centralized infrastructure can be challenging to access, use, adapt and may not account for onsite workflows. As vaccination distribution grows, these tools hope to help smaller clinics operate more efficiently allowing more vacinations per staff. As technology or transportion limited individuals become a larger percentage of the target population, staff responsiblies will only increase taking time away from administering vaccinations.
This tool only requires a free Google account to host the project using Google Sheets as the database, Google Drive to store images, and Gmail for messaging. All of the data is stored in (and most of the configuration can be done by editting) a Google Sheet. This means the data is easily edittable and exportable to other EMR systems. It is built using App Script to automatically create web forms/pages for creating, displaying, and updating data in the spreadsheet. Photos of ID cards can be captured using a mobile phone camera, stored in Google Drive, and associated with patient records.
If Google Cloud Vision Services are enabled on your host account, it can also perform text recognition on insurance cards for much faster (and less error prone) check-in process. The VisionAPI service is free for the first 1000 queries/month, with a modest cost for additional queries/month.
You can play with a early prototype instance of the tool. It is under VERY active development.
This section is very much work in progress.
This in an App Script project that runs on Google Docs. Hosting an instance requires a free Google Account. You can reuse an account you have. However, this account will be the administrator with full privileges to the data and scripts. This app will request edit permissions for Drive, Spreadsheets, and Gmail. If you are not comfortable with that, you may want to create a separate account for hosting this project.
Reminder: This project is not HIPAA compliant. It is provided in hopes in may be useful where that is not required. Do not share the Google account creditials with anyone you would not trust to delete or copy the patient information safely.
The (optional, but recommended) steps below use a Chrome extension to help synchronize code with Github. These instructions assume you are using the Google Chrome Browser. The App Script IDE does not sync changes between browsers in real-time. Open browser windows on other computers can hold onto an old state of the project. If you resume editting on an old browser state, you will overwrite any new edits. Syncing to Github is recommended for keeping multiple editors in sync.
'https://drive.google.com/drive/folders/1zOu5qg7VCP4tz1BFyZJDSwGGZmAyflal'
. Your project folder ID is: '1zOu5qg7VCP4tz1BFyZJDSwGGZmAyflal'
. You will need this later.'https://docs.google.com/spreadsheets/d/163XoWSUqz2MjaMewZEi0hxOEpDFdJgfgfR2SL_0NDco/edit#gid=0'
. Your spreadsheet ID is: '163XoWSUqz2MjaMewZEi0hxOEpDFdJgfgfR2SL_0NDco'
. You will need this later.config.gs
, and you will need to modify 'YOUR_SPREADSHEET_ID'
and 'YOUR_PROJECT_FOLDER_ID'
to be the long string of characters from the previous steps to tell this project what files/directory to use for the project.Code.gs
, and press run. In a moment, it will say Authorization Required. Click review permissions. Select your host account. It will warn you that "Google hasn't verified this app." Since this is a custom app of which you are now the developer, this is correct. You are approving this to make modifications to files in your Google Drive. Click Advanced and Go to name_of_your_app. It will list the edit rights that the application needs to your files (Google Drive, Google Sheets, Gmail, external Vision service, etc) then hit Allow.run from editor complete
in the Execution Log. This means everything went correctly. If it says Lost connection
, try running it again."Inital Test"
. Under configuration > Web app, select Execute as Me to enable access your account data. Set Who has access to be Only myself while you are testing. Then hit Deploy.Name: Vaccine Registration App (Or any name)
From the drop down click "Create Credentials" and click OAuth Client ID.
Application type: "Desktop app"
Name: "Vaccine Registration App" (or any name you want)
Copy your Client ID and Client Secret into the file login.service.gs
Replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with your pasted ID (within the double quotes).
It should be a long string of letters "abcdefg12345679".
Make sure to click save after you update the config.gs.
If you leave the OAuth dashboard page that has the ID you can always go back and click your app to find it.
It will be under "OAuth 2.0 Client IDs" section in the same Credentials section from step 2.
You can click into the application to get your client secret.
For more information about Google Cloud API:
Creating and Managing Projects: https://cloud.google.com/resource-manager/docs/creating-managing-projects
This tool uses Docusign for eSignatures, which contains an audit trail in case a signature is challenged. This is a level of safety desired by many businesses. However, Docusign is a paid service. If a free option is required (where you assume the risk if the signature is challenged), please file a bug and we can look into supporting that option.
This configruation uses the JWT Grant Authorization to allow the web app to act on behalf of a Docusign account holder to request eSignatures without the authorized user to be present at the time of request. This allows the Vaccine tool to request signatures anytime. To configure the web app to use Docusign in this mode, you will have to create authorization keys and copy them to your config.gs
file.
Create (or login into) your Docusign Developer Account. NOTE: This is only tested on a developer account which allows free testing. I have not checked what would change for a billed account yet, but I assume these key are also available in the non-developer account UI.
Goto menu item My Apps & Keys
If you do not already have an application key you would like to use, click on Add an App and Integration Key. Enter a new app name like "VaccineTool"
Copy the shown "Integration Key" for your new application and set var DOCUSIGN_INTEGRATION_KEY = 'YOUR_INTEGRATION_KEY
in config.gs
Click "Add Secret Key". Copy the shown key to var DOCUSIGN_SECRET_KEY = 'YOUR_SECRET_KEY'
in config.gs
Click "Generate RSA key". A pop up will appear showing your new Public and Private Key. Copy your public key to var DOCUSIGN_PUBLIC_KEY = 'YOUR_PUBLIC_KEY'
in config.gs
and copy your private key to var DOCUSIGN_RSA_PRIVATE_KEY = 'YOUR_RSA_PRIVATE_KEY'
in config.gs
. You must include all the data including the ------
. You will also have to manually add \n\
to the end of each line to make AppScript happy with the string that spans multiple lines.
Unfortunately, the DOCUSIGN_RSA_PRIVATE_KEY
generated is not compatible with AppScript, and has to be converted to a non-RSA PRIVATE_KEY. To do this, follow this help article. You may need to install a terminal/command-line tool called openssl
. You can search on Google for "how to install openssl on ..." your platform (e.g. Windows, Max, Linux). Once you generate the non-RSA version of your Docusign private key, copy the private key to var DOCUSIGN_PRIVATE_KEY = 'YOUR_PRIVATE_KEY'
in config.gs
. Be sure to include the ------
and you will also have to manually add \n\
to the end of each line to make AppScript happy with the string that takes multiple lines. For example:
var DOCUSIGN_PRIVATE_KEY = '-----BEGIN PRIVATE KEY-----\n\
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5akfQ5s4+nx0E\n\
o5JTY3fNkBK1epJKyeRHKQTtpOg2NTygvj+c7J+F6tfjO0EvCj7OZuiJcAWfQnae\n\
QJzLh8LHMvGwVycLaYCM9VP49dUJYuSxP1bQbEsUbSlK2CgzZoUu984gyNqv4Jzj\n\
Qzxi/Z7elwP22epSTouzDM9V0+opFv+qEdImQJqB63Bg7JsZA3PQQZgkhFq6rWz1\n\
uhLVIHtDHOxR3ce9fHaxbghWdCmKVLdAUMMppqvSK8AplGZO6XamATIE11ybyC72\n\
...
RKeSDV1pUliCJBWfsza5jlTs9PW3vDStqd+eh0I7q+/im7UTZLOgvdxrart4XoG\n\
fKyqVnZ+lQQEEZM3RNEY3oAc6UBrY0wqEn11SsvxZUjLZSfcG9mGgUaHk7kpYGFR\n\
p02MS34YFBLDIT5CwCjGaob9mAuvob0/n940RDsCgYB6AhQ/svaWUK8DFdFMrZrj\n\
AFWtRhH++kqJu4F9gfkzDQUnfzSiXGxDGi+Xs0+ECzgq1IknmfuDZKOVynA2Tj6H\n\
8pF6kfBskPtDDV5MA7+ZekwuzeZxl3NZuTuWwZWHF/TIPLDlm7WIfiXn6MWvNfx/\n\
3GxOXnRQ05WJbWlz6J3+Cg==\n\
-----END PRIVATE KEY-----';
In the Docusign website, add a new Redirect URI: https://localhost:3000/auth/docusign/callback
.
Click "Save" to finalize your changes.
Now we need to grant consent for this Web App to use the Docusign account on behalf of an authorized user using JWT Grant Authorization. To do this, you need to create a URL of this format replacing DOCUSIGN_INTEGRATION_KEY
with your intergation key from before.
https://account-d.docusign.com/oauth/auth?response_type=code&scope=signature%20impersonation&client_id=DOCUSIGN_INTEGRATION_KEY&redirect_uri=https://localhost:3000/auth/docusign/callback
Paste this URL into a new browser window. It will take you to Docusign and ask you to login. This should be the account that you want the webapp to request eSignatures with. After you grant the requested permissions, it will take you to an error page saying "This site can’t be reached". You can ignore this error. You only neeed to complete the approval steps earlier.
On the Docusign Website, click on "Templates". This is the empty version of your PDF consent form that the app can use as a template. Create (or upload) your template. Docusign offers many ways of creating templates with many features. Please refer to thier documentation on how to configure a template.
Create a "Role" for the template called "Patient". Hit "Next". Set the signature location on the PDF, then "Save and Close" to finish the template.
Once you've created your template you should see it in the list. Click on the name to look at the details. If you already have a template you would like to use, you can use that instead. Just be sure that template includes a "Role" named "Patient".
On the page showing the details of the template, in the URL you will see something like https://appdemo.docusign.com/templates/details/e61c36b6-cca8-44df-97d3-2f1abe3504dc
. Your templateID is the string of letters at the end, in this example: e61c36b6-cca8-44df-97d3-2f1abe3504dc
. Copy this to var DOCUSIGN_TEMPLATE_ID = 'YOUR_TEMPLATE_ID'
in config.gs
Goto https://admindemo.docusign.com/users, and click on your user name.
Find your API Username (or UserID) and copy to var DOCUSIGN_API_USERNAME = 'YOUR_API_USERNAME'
in config.gs
. It should look something like 6ddaf671-512f-448b-98bb-c9f123416de5
Once these variables are all defined in config.gs
, refresh your tool and instead of a spinning wait screen during the registration process, it should redirect you to a docusign flow requesting a signature. After the signature is complete, if will send the patient a PDF copy of the consent form, upload a PDF copy to your Google Drive, and redirect the patient to the Appointment selection page.
docusign.service.gs
, in the toolbar next to Debug, select testDocusignAPI
from the drop down menu, then hit Run. If all is well, the Execution Log should end with pass.The developer account watermarks the PDF with "Developer Demo" in red. To remove this, you will have to perform this setup with a paid Docusign account, and change the OAUTH_HOST
in docusign.service.gs
from account-d.docusign.com
to account.docusign.com
in config.gs
, and as well as redo the consent process again with this in the URL. (TODO: move this from docusign.service.gs
to config.gs
and perhaps create a helper function/page?)