A HIPAA-compliant, omnichannel patient communication module for OpenEMR using the Sinch Conversations API.
- π± Multi-Channel Messaging: SMS, WhatsApp, RCS, MMS, Viber - all through a unified API
- π HIPAA-Compliant: Approved message templates with no PHI in SMS
- β Consent Management: Track patient opt-ins and honor opt-out requests
- π€ Keyword Handling: Automatic HELP/STOP/START response system
- π
Appointment Features:
- High-compliance appointment reminders (portal links only)
- Telehealth appointment links
- Missed appointment follow-up
- Pre-visit instructions
- π¬ Portal Notifications:
- New secure message alerts
- Test results available notifications
- π° Billing Communications:
- Statement ready notifications
- Balance due reminders (no amounts in SMS)
- π₯ Wellness & Prevention:
- Annual wellness visit reminders
- Public health campaigns (flu shots, screenings)
- π’ Operational Messages:
- Office closure alerts
- Emergency updates
- π Post-Visit Surveys: Patient feedback collection
- π Polling Architecture: No webhooks needed - simple local development
- OpenEMR 7.0.0 or later
- PHP 8.2 or later
- MySQL 5.7 or later / MariaDB 10.2 or later
- Sinch Conversations API account with BAA (see Legal Requirements below)
OpenEMR does not automatically drop module tables on uninstall. If you need to reinstall the module cleanly:
# Option 1: Via Docker (if using Docker environment)
docker compose exec -T mysql mariadb -uroot -proot openemr < cleanup.sql
# Option 2: Via phpMyAdmin or MySQL client
# Connect to your OpenEMR database and run cleanup.sqlThis will drop all module tables and allow a clean reinstallation.
-
Navigate to your OpenEMR installation directory
-
Install the module via Composer:
composer require opencoreemr/oce-module-sinch-conversations
-
Log into OpenEMR as an administrator
-
Navigate to Administration > Modules > Manage Modules
-
Find "OpenCoreEMR Sinch Conversations" in the list and click Register
-
Click Install
-
Click Enable
- Download the latest release
- Extract to
interface/modules/custom_modules/oce-module-sinch-conversations(relative to your OpenEMR root directory) - Follow steps 3-7 from the Composer installation
-
Navigate to Administration > Globals > OpenCoreEMR Sinch Conversations Module
-
Configure the following settings:
- Sinch Project ID: Your Sinch project ID
- Sinch App ID: Your Sinch app ID
- API Key: Your Sinch API key (will be encrypted)
- API Secret: Your Sinch API secret (will be encrypted)
- API Region: Select your preferred region (default: 'us')
- Default Channel: SMS, WhatsApp, or RCS
- Clinic Name: Your clinic name (appears in all messages)
- Clinic Phone: Your main clinic phone number
-
Save the settings
-
Test the connection using the "Test API Connection" button
CRITICAL: Patients must opt in before receiving any messages.
Methods for collecting consent:
- Patient Portal: Add opt-in checkbox during portal registration
- In-Person: Collect consent on intake forms
- Web Form: Dedicated consent form on clinic website
When a patient opts in, the system will automatically send the required confirmation:
Example Clinic: You have successfully opted-in to receive alerts from
Example Clinic. Msg&Data rates may apply. Msg freq varies. Reply HELP for help.
Reply STOP to unsubscribe at any time.
Messages are sent automatically based on triggers:
- Appointment Reminder: Sent 24 hours before appointment (configurable)
- Telehealth Link: Sent 15 minutes before telehealth appointment
- Test Results: When results are finalized in OpenEMR
- New Portal Message: When provider sends secure message
- Missed Appointment: When patient marked as no-show
Or manually from the module interface:
- Navigate to Modules > Sinch Conversations
- Click Send Message
- Select patient
- Choose template
- Preview and send
For announcements to multiple patients:
- Navigate to Modules > Sinch Conversations
- Click Batch Messages
- Select patient cohort (all patients, age range, etc.)
- Choose template (office closure, wellness campaign, etc.)
- Preview and schedule/send
- Navigate to Modules > Sinch Conversations
- View inbox with all conversations
- Click Refresh to check for new patient replies
- Click conversation to view full thread
- Reply to patient messages
The system automatically handles patient keyword responses:
| Keyword | Action | Response |
|---|---|---|
| STOP | Opt-out patient | "You have been unsubscribed from our text notifications..." |
| START | Re-subscribe patient | "You have been re-subscribed to text notifications..." |
| HELP | Provide assistance | "Text notifications from {{ clinic_name }}. For assistance, call..." |
Supported opt-out keywords: STOP, STOPALL, UNSUBSCRIBE, CANCEL, END, QUIT Supported opt-in keywords: START, UNSTOP, SUBSCRIBE
IMPORTANT: This module uses the Sinch Conversations API to send text messages to patients. You MUST have a Business Associate Agreement (BAA) with Sinch before using this module in production with patient data.
OpenCoreEMR has a BAA with Sinch and has received compliance approval for the message templates included in this module.
If you are not using this module through OpenCoreEMR, you must:
- β Execute your own BAA with Sinch before sending any patient messages
- β Submit your message templates to Sinch for compliance review
- β Obtain approval before using templates in production
- β Maintain proper consent records for all patients
To establish a BAA with Sinch:
- OpenCoreEMR Customers: Contact support@opencoreemr.com
- Other Organizations: Contact Sinch at https://www.sinch.com/contact/
Before sending any SMS messages, you MUST:
You must obtain prior express written consent from patients before sending any text messages. This consent must:
- β Be in writing (electronic or paper)
- β Clearly state the patient agrees to receive text messages
- β Include the phone number where they'll receive messages
- β Specify the types of messages they'll receive (appointments, billing, etc.)
- β State that message and data rates may apply
- β Include opt-out instructions
Example Consent Language:
I consent to receive text message notifications from [Clinic Name] at the phone number provided above. I understand that these messages may include appointment reminders, test result notifications, billing reminders, and other healthcare-related communications. I understand that message and data rates may apply, and message frequency varies. I can opt out at any time by replying STOP.
You must maintain records of:
- β Patient signature or electronic agreement
- β Date of consent
- β Phone number provided
- β Types of messages agreed to
- β Method of consent (web form, in-person, etc.)
Standard SMS is not encrypted. You must NEVER include Protected Health Information such as:
- β Diagnoses
- β Treatment details
- β Specific test results
- β Medication names
- β Account balances (amounts)
- β Specific appointment reasons
Instead: Use the approved templates that direct patients to the secure patient portal.
β Good: "Your test results are available. Log in to view: [portal link]" β Bad: "Your cholesterol test came back at 245 mg/dL"
- β Process STOP keywords within seconds
- β Confirm opt-out with confirmation message
- β Never send marketing messages to opted-out patients
- β May still send critical transactional messages (e.g., appointment cancellations)
Every message must start with your clinic name:
β Good: "Example Clinic: Your appointment is tomorrow..." β Bad: "Your appointment is tomorrow..."
Every message must include opt-out instructions:
β Required: "Reply STOP to opt-out"
When a patient first opts in, you MUST send this confirmation message:
{{ clinic_name }}: You have successfully opted-in to receive alerts from
{{ clinic_name }}. Msg&Data rates may apply. Msg freq varies. Reply HELP
for help. Reply STOP to unsubscribe at any time.
This message is required by carriers (CTIA) and the TCPA. The system sends it automatically when a patient opts in.
All message templates included in this module have been reviewed and approved by Sinch for use by OpenCoreEMR under our BAA. These templates are:
- β HIPAA-compliant (when used with proper consent)
- β TCPA-compliant
- β Carrier-compliant (CTIA guidelines)
Template Categories:
- Initial Opt-In Confirmation (required)
- Appointment Reminders (high-compliance version)
- Telehealth Appointment Links
- Missed Appointment Follow-Up
- Pre-Visit Instructions
- Portal Notifications (new messages, test results)
- Billing Reminders (statement ready, balance due)
- Preventive Care / Wellness Reminders
- Public Health Announcements (flu shots, etc.)
- Office Closure / Emergency Updates
- Post-Visit Feedback Surveys
If you create custom templates, you MUST submit them to Sinch for compliance review before using them in production.
See TEMPLATE-IMPLEMENTATION-PLAN.md for complete template details.
Best practices for send times:
- β 8 AM - 9 PM local time (patient's timezone)
- β Avoid late night or early morning messages
- β Exception: Emergency/urgent notifications (office closures, safety alerts)
This open-source software is provided "AS IS" without warranty of any kind, express or implied. You are solely responsible for ensuring your use of this module complies with:
- HIPAA Privacy and Security Rules
- TCPA (Telephone Consumer Protection Act)
- State-specific privacy laws (e.g., California CMIA, Texas HB300)
- Carrier regulations (CTIA Best Practices)
- Any other applicable laws and regulations
STRONGLY RECOMMENDED: Consult with legal counsel experienced in healthcare compliance before deploying this module in a production environment.
- π Encrypted Credentials: API keys encrypted using OpenEMR's CryptoGen
- π TLS/SSL: All API communications use TLS 1.2+
- π Audit Logging: All messages logged for compliance
- β Access Control: OpenEMR ACL integration
- π‘οΈ CSRF Protection: All forms protected against CSRF attacks
- π Patient Consent: Verified before every message send
This module uses a polling architecture instead of webhooks:
Benefits:
- β Simple local development (no ngrok needed)
- β Works identically locally and in production
- β User-controlled refresh (click "Refresh" button)
- β Easier testing and debugging
- β No external dependencies
How it works:
- Provider clicks "Refresh" or loads inbox
- Module polls Sinch API for new messages
- Stores new messages in local database
- Displays updated inbox
See POLLING-ARCHITECTURE.md for detailed implementation.
This module includes a Taskfile for common development tasks:
# Install Task (if not already installed)
# macOS
brew install go-task
# Linux
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin
# Show all available tasks
task --list
# Quick start
task setup # Complete setup (install, prebuild, start)
task dev:start # Start Docker environment
task dev:port # Get OpenEMR URL
task module:cleanup # Clean database for reinstall
task check # Run all code quality checksCommon tasks:
task dev:start- Start Docker environmenttask dev:logs- View live logstask dev:port- Get OpenEMR access URLtask module:cleanup- Drop tables for clean reinstalltask db:shell- Access databasetask check- Run pre-commit checkstask --list- See all available tasks
Quick setup for local module development:
# 1. Clone and install dependencies
git clone https://github.com/opencoreemr/oce-module-sinch-conversations.git
cd oce-module-sinch-conversations
composer install
# 2. Pre-build OpenEMR (optional but recommended - saves 5-10 min)
cd vendor/openemr/openemr
composer install --no-dev
npm install --legacy-peer-deps && npm run build
cd ../../..
# 3. Start Docker environment
docker compose up -d --wait
# 4. Get the port and open in browser
docker compose port openemr 80
# Visit http://localhost:PORT and login with admin/passAll local changes are immediately reflected - no rebuild needed! See docker/README.md for details.
# View live logs from OpenEMR container
docker compose logs -f openemr
# View MySQL logs
docker compose logs -f mysql
# Check container status
docker compose ps
# Execute commands in running OpenEMR container
docker compose exec openemr bash
docker compose exec openemr php -v
# Access MariaDB database
docker compose exec mysql mariadb -h mysql -uroot -proot openemr
# Stop environment (keeps data)
docker compose down
# Stop and remove all data (fresh start)
docker compose down -v
# Restart a specific service
docker compose restart openemr
# View phpMyAdmin (get port first)
docker compose port phpmyadmin 80
# Visit http://localhost:PORTNote: We use docker compose exec to run commands in already-running containers:
- Fast execution (no container startup overhead)
- No entrypoint conflicts
- Works with running services
Container won't start:
# Check logs for errors
docker compose logs openemr
# Remove everything and start fresh
docker compose down -v
docker compose up -d --waitOpenEMR installer keeps running:
# The installer creates a sites/default/sqlconf.php file
# If this file exists, installer is complete
docker compose exec openemr ls -la /var/www/localhost/htdocs/openemr/sites/default/sqlconf.phpChanges not showing up:
# PHP changes should be instant (OPCACHE_OFF=1)
# If not, restart Apache:
docker compose restart openemrDatabase issues:
# Access database directly
docker compose exec mysql mariadb -uroot -proot openemr
# View module tables
docker compose exec mysql mariadb -uroot -proot -e "SHOW TABLES LIKE 'oce_sinch%'" openemr
# Export database
docker compose exec mysql mariadb-dump -uroot -proot openemr > backup.sql
# Import database
docker compose exec -T mysql mariadb -uroot -proot openemr < backup.sqlPort conflicts:
# If port 80 is already in use, Docker will assign a random port
# Find the assigned port:
docker compose port openemr 80
# Or specify a custom port in compose.yml:
# ports:
# - "8080:80" # Use localhost:8080Installing module in OpenEMR:
- Access OpenEMR at
http://localhost:PORT - Login as admin/pass
- Navigate to Administration > Modules > Manage Modules
- Find "oce-module-sinch-conversations" and click Register
- Click Install then Enable
Testing module changes:
- Edit any PHP/Twig file in your local directory
- Refresh browser - changes appear immediately
- No container rebuild needed!
Running tests inside container:
# Access container shell
docker compose exec openemr bash
# Inside container, navigate to module directory
cd /var/www/localhost/htdocs/openemr/interface/modules/custom_modules/oce-module-sinch-conversations
# Run pre-commit checks (includes syntax check, PHPCS, PHPStan, etc.)
pre-commit run -a
# Run individual checks if needed
composer phpcs # Code style
composer phpstan # Static analysisDebugging:
# View Apache error logs
docker compose logs -f openemr | grep -i error
# View PHP errors from log files
docker compose exec openemr tail -f /var/log/apache2/error.log60-70% of this module can be developed without any PHI:
- β API integration layer
- β Template system
- β Keyword handlers (HELP/STOP)
- β UI framework (with mock data)
- β Database schema
- β Polling service
- β Testing (with synthetic data)
Testing without patient data:
- Send test messages to your own phone number
- Use Sinch test/sandbox environment
- Mock data in UI: "Jane Doe", "+15555551234"
See PHI-ANALYSIS.md for complete development approach.
# Run all code quality checks
pre-commit run -a
# This runs:
# - PHP syntax check
# - PHP_CodeSniffer (PSR-12)
# - PHPStan (level 8)
# - Rector
# - Composer Require CheckerThis module follows OpenEMR's modern architecture:
- Controllers in
src/Controller/handle HTTP requests - Services in
src/Service/contain business logic - Twig templates in
templates/for all HTML - Symfony HTTP Foundation for Request/Response
- Custom exceptions for error handling
- QueryUtils for all database operations
See CLAUDE.md for complete architecture guide.
TEMPLATE-IMPLEMENTATION-PLAN.md- Complete template guidePOLLING-ARCHITECTURE.md- Polling implementation detailsPHI-ANALYSIS.md- PHI-free development approachcopilot-breakdown.md- Feature roadmap and implementation phasesCLAUDE.md- Module architecture patterns
For support with this module:
- Email: support@opencoreemr.com
- Phone: Contact your account representative
For Sinch BAA or compliance questions:
- Email: support@opencoreemr.com
For technical issues with this module:
For Sinch BAA or compliance:
- Sinch Contact: https://www.sinch.com/contact/
For legal/compliance advice:
- Consult your own legal counsel
This is a complex project with strict compliance requirements. Contributions should:
- β
Follow OpenEMR module architecture patterns (see
CLAUDE.md) - β Pass all pre-commit checks (PHPCS, PHPStan, Rector)
- β Include proper error handling with custom exceptions
- β Use Symfony Request/Response objects
- β Use QueryUtils for all database operations
- β Include comprehensive tests
- β Never include PHI in test data
- β Document all API integrations
Before submitting a PR:
- Run
pre-commit run -aand fix all issues - Test with Sinch sandbox/test environment
- Update documentation if adding features
- Ensure no PHI in code, comments, or commits
GNU General Public License v3.0 or later
Developed by OpenCoreEMR Inc
- Website: https://opencoreemr.com
- Email: info@opencoreemr.com
This module is designed to help healthcare organizations communicate with patients via text messaging in a HIPAA-compliant manner. However, the ultimate responsibility for compliance rests with the organization using this software.
You must:
- β Have appropriate legal agreements in place (BAA with Sinch)
- β Obtain and document patient consent
- β Train staff on proper usage
- β Monitor for compliance
- β Consult with legal counsel
OpenCoreEMR Inc provides this software "as is" and makes no warranties regarding compliance with any laws or regulations.