Automatically export Google Sheets to your SFTP server daily or hourly.
A WordPress plugin that receives Google Sheets exports via API and uploads them to any SFTP server. Useful for automated inventory feeds, data syncs, and backups.
- ✅ Easy Setup – Configure everything from WordPress admin
- ✅ Secure API – Auto-generated API keys protect your endpoint
- ✅ Flexible Scheduling – Daily or hourly exports
- ✅ Filename Options – Dated filenames or overwrite mode
- ✅ Multiple Formats – Export as CSV or XLSX
- ✅ Activity Logs – Track all uploads and errors
- ✅ Pre-built Script – Copy-paste Google Apps Script included
- ✅ No paid services required – Uses Google Apps Script and your SFTP server
Google Sheet → Apps Script (scheduled) → HTTP POST → WordPress Plugin → SFTP Server
- Google Apps Script exports your sheet on a schedule
- Sends the file to your WordPress site via REST API
- The plugin receives the file and uploads it to your SFTP server
- Download the latest release ZIP
- Go to Plugins → Add New → Upload Plugin
- Upload the ZIP and activate
- Download/clone this repository
- Copy the
sftp-sync-for-google-sheetsfolder to/wp-content/plugins/ - Activate via Plugins menu
- Go to Settings → SFTP Sync
- You'll see your auto-generated API Key and Endpoint URL at the top
Fill in your SFTP server details:
| Field | Description | Example |
|---|---|---|
| SFTP Host | Server IP or hostname | sftp.example.com or 123.45.67.89 |
| SFTP Port | Usually 22 or custom | 22 or 15492 |
| Username | SFTP username | myuser |
| Password | SFTP password | mypassword |
| Remote Path | Destination folder (must end with /) |
/uploads/ or /www/feeds/ |
Click Save Settings.
Click Test SFTP Connection to verify your credentials work.
Common errors:
- "Could not connect" → Check host and port
- "Authentication failed" → Check username and password
- "No SFTP library available" → See SFTP Library Requirements
| Setting | Options | Description |
|---|---|---|
| Schedule | Daily / Hourly | How often to export |
| Daily Export Hour | 00:00 - 23:00 | Time of day (your timezone) |
| Filename Mode | Dated / Overwrite | New file each time or replace |
| Base Filename | Any name | e.g., inventory, products |
| Export Format | CSV / XLSX | File format |
Filename examples:
- Dated:
inventory_2026-01-07_140000.csv - Overwrite:
inventory.csv
Click Save Settings.
- Open your Google Sheet
- Go to Extensions → Apps Script
- Delete any existing code
- Go back to your WordPress plugin settings
- Click "Show Google Apps Script Code"
- Copy the entire code (it's pre-configured with your settings)
- Paste into the Apps Script editor
- Press Ctrl+S to save
- Name your project (e.g., "SFTP Export")
- In Apps Script, make sure
exportAndUploadis selected in the function dropdown - Click Run
- Authorize the script when prompted:
- Click "Review Permissions"
- Choose your Google account
- Click "Advanced" → "Go to [project name] (unsafe)"
- Click "Allow"
- Check the execution log for success message
- Verify the file appears on your SFTP server
- In the function dropdown, select
setupTrigger - Click Run
- The trigger is now active!
To verify: Click the clock icon (⏰) in the left sidebar to see your trigger.
The settings (schedule, filename mode, format, etc.) are embedded in the generated Apps Script. If you change settings in WordPress:
- Save the new settings
- Click "Show Google Apps Script Code"
- Copy the new code
- Paste into Google Apps Script (replacing the old code)
- Save
- Run
setupTriggeragain if you changed the schedule
Cause: SFTP settings not saved in WordPress.
Fix:
- Go to Settings → SFTP Sync
- Enter all SFTP credentials
- Click Save Settings
Cause: API key mismatch between Apps Script and WordPress.
Fix:
- Go to Settings → SFTP Sync
- Copy the API Key shown at the top
- In Google Apps Script, update
CONFIG.API_KEYwith the new key - Or re-copy the entire Apps Script code (recommended)
Cause: Wrong SFTP credentials.
Fix:
- Double-check username and password
- Verify the host and port are correct
- Test with an SFTP client (FileZilla, WinSCP) first
- Check if your password has special characters that might need escaping
Note: Passwords with special characters like +, @, ! should work, but verify they're entered correctly.
Cause: Neither ssh2 PHP extension nor phpseclib is installed.
Fix (Option 1 - phpseclib):
cd /path/to/wp-content/plugins/sftp-sync-for-google-sheets
composer require phpseclib/phpseclib:~3.0Fix (Option 2): Contact your host to enable the ssh2 PHP extension.
Cause: Network/firewall issue or wrong host/port.
Fix:
- Verify the host IP/hostname is correct
- Verify the port number
- Check if your server's firewall allows outbound connections on that port
- Try connecting from your server via command line:
ssh -p PORT user@host
Cause: Remote path doesn't exist or no write permission.
Fix:
- Verify the remote path exists on the SFTP server
- Check write permissions on that directory
- Make sure the path ends with
/
Symptoms: Trigger is set but exports don't happen.
Fix:
- Check Apps Script executions: Extensions → Apps Script → Executions
- Look for failed executions and error messages
- Re-run
setupTriggerto recreate the trigger - Make sure you authorized all permissions
If you suspect your API key is compromised:
- Go to Settings → SFTP Sync
- Click Regenerate next to the API Key
- Important: Re-copy the Apps Script code to your Google Sheet
- The old API key will stop working immediately
The plugin tries these methods in order:
- ssh2 PHP extension (fastest, if available)
- phpseclib3 (recommended fallback)
- phpseclib 2.x (legacy support)
Most managed WordPress hosts (including Kinsta) have phpseclib available or allow installing it via Composer.
| Resource | Daily Limit |
|---|---|
| URL Fetch calls | 20,000 |
| Script runtime | 6 min per execution |
| Triggers | 20 per user |
These limits are very generous for typical use cases.
- Keep your API key secret – Don't share it publicly
- Use HTTPS – Your WordPress site should use SSL
- Regenerate keys periodically – If you suspect a leak
- Monitor logs – Check the plugin logs for unauthorized attempts
Each Google Sheet can have its own Apps Script pointing to the same WordPress endpoint. Just use different base filenames.
You can create multiple Apps Scripts in the same sheet, each pointing to a different WordPress endpoint.
- WordPress.org initial release
- Improved code quality based on plugin review feedback
- Moved log storage to wp-content/uploads for better security
- Updated WordPress compatibility to 6.9
- Renamed plugin to "SFTP Sync for Google Sheets" for WordPress.org compliance
- Fixed all escaping issues (using esc_html_e, esc_html__ throughout)
- Fixed input sanitization for $_SERVER variables
- Updated text domain to sftp-sync-for-google-sheets
- Removed promotional language from descriptions
- Removed hidden files (
.htaccess,.gitignore) from distribution for WordPress.org plugin directory compliance - Logs directory now protected by
index.phponly
- Fixed: CSV export now uses Google's native CSV export URL instead of manual CSV building
- Fixed: WP All Import not recognizing CSV column headers
- CSV output is now identical to Google Sheets "File > Download > CSV"
- Updated generated Google Apps Script code
- Updated WordPress compatibility to 6.9
- Security: Improved password encryption using AES-256-CBC with WordPress salts
- Security: Added rate limiting (60 requests/minute) to prevent API abuse
- Added
composer.jsonfor easier phpseclib dependency management - Added
index.phpsecurity files to prevent directory listing - Updated WordPress compatibility to 6.7
- Added Export Settings section in admin
- New schedule options: Daily or Hourly
- New filename mode: Dated (unique files) or Overwrite (same file each time)
- Configurable base filename and export format (CSV/XLSX)
- Apps Script now auto-configured with plugin settings
- Improved SFTP error messages for debugging
- Initial release
- SFTP upload via ssh2 or phpseclib
- REST API endpoint for receiving files
- Admin settings page
- Activity logging
- Google Apps Script generator
Olivier Bigras
Website: https://olivierbigras.com
GPL v2 or later - https://www.gnu.org/licenses/gpl-2.0.html