- Changed getUserSession to getAdminSession for all contact message endpoints - Admin panel now properly authenticates and displays contact messages - Fixed list, mark-read, and delete operations
Shopify AI App Builder
An AI-powered platform for building complete, production-ready Shopify apps. Describe your app idea in plain English and let AI build it for you.
✅ Deploying to Portainer? The container now automatically fixes the "unexpected character \u200e" error! Environment variables are sanitized on startup. See the Quick Fix Guide for more details.
Features
- 🤖 AI-Powered Development - Describe your Shopify app and watch it being built in real-time
- 📦 Complete Apps - Get production-ready apps with proper structure, API integrations, and more
- ⚡ OpenCode Integration - Built on SST OpenCode for reliable code generation
- 📤 Easy Export - Download as ZIP or push directly to GitHub
- 🔧 Full Terminal Access - Make manual adjustments through the web terminal
- ☁️ Docker Ready - Deploy anywhere with the included Docker configuration
Quick Start
Prerequisites
- Docker and Docker Compose installed
- (Optional) GitHub Personal Access Token for version control
- (Optional) Dodo Payments API key for payment integration
- (Optional) Google OAuth credentials for authentication
1. Clone and Configure
# Clone the repository
git clone https://github.com/southseact-3d/shopify-ai.git
cd shopify-ai
# Copy environment template
cp .env.example .env
# Edit .env with your configuration (optional)
2. Build and Run
# Build the Docker image
docker compose build
# Start the service
docker compose up -d
3. Access the Application
- Homepage: http://localhost:4000
- App Builder: http://localhost:4000/builder
- Terminal: http://localhost:4001
Architecture
┌─────────────────────────────────────────────────────┐
│ Docker Container │
│ │
│ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Port 4000 │ │ Port 4001 │ │
│ │ Web App UI │ │ ttyd Terminal │ │
│ │ (Node.js) │ │ (PowerShell) │ │
│ └──────────────┘ └──────────────────────┘ │
│ │ │ │
│ └────────┬───────────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ OpenCode │ │
│ │ AI Assistant │ │
│ └─────────────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ /home/web/data│ │
│ │ (Workspace) │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────┘
Configuration
Environment Variables
Payment setup: see the Dodo Payments guide in dodo.md.
| Variable | Description | Default |
|---|---|---|
CHAT_PORT |
Web UI port | 4000 |
ACCESS_PASSWORD |
Terminal password protection (leave empty for none) | - |
GITHUB_PAT |
GitHub Personal Access Token | - |
GITHUB_USERNAME |
GitHub username | - |
GITHUB_CLIENT_ID |
GitHub OAuth app client ID | - |
GITHUB_CLIENT_SECRET |
GitHub OAuth app client secret | - |
OPENROUTER_API_KEY |
OpenRouter API key used for planning mode | - |
OPENROUTER_API_URL |
OpenRouter API endpoint for planning | https://openrouter.ai/api/v1/chat/completions |
OPENROUTER_MODEL_PRIMARY |
Primary OpenRouter model for planning conversations | anthropic/claude-3.5-sonnet (fallback order) |
OPENROUTER_MODEL_BACKUP_1 |
Backup OpenRouter model #1 | openai/gpt-4o-mini (fallback order) |
OPENROUTER_MODEL_BACKUP_2 |
Backup OpenRouter model #2 | mistralai/mistral-large-latest (fallback order) |
OPENROUTER_MODEL_BACKUP_3 |
Backup OpenRouter model #3 | google/gemini-flash-1.5 (fallback order) |
OPENROUTER_DEFAULT_MODEL |
Final fallback model if none of the above resolve | openai/gpt-4o-mini |
OPENROUTER_PLAN_PROMPT_PATH |
Optional path to override the OpenRouter planning prompt file | chat/public/openrouter-plan-prompt.txt |
OPENROUTER_FALLBACK_MODELS |
Comma-separated additional fallback models for planning | - |
OLLAMA_API_URL |
Ollama self-hosted API URL for planning (e.g., http://localhost:11434) |
- |
OLLAMA_API_KEY |
Ollama API key for self-hosted instances (optional) | - |
DODO_PAYMENTS_API_KEY |
Dodo Payments API key | - |
DODO_PAYMENTS_ENV |
Dodo Payments environment (test or live) |
test |
DODO_TOPUP_PRODUCT_FREE |
Dodo product ID for the Free/Starter top-up | - |
DODO_TOPUP_PRODUCT_PLUS |
Dodo product ID for the Plus top-up | - |
DODO_TOPUP_PRODUCT_PRO |
Dodo product ID for the Pro top-up | - |
DODO_TOPUP_TOKENS_FREE |
Token credits for the Free/Starter top-up | 500000 |
DODO_TOPUP_TOKENS_PLUS |
Token credits for the Plus top-up | 1000000 |
DODO_TOPUP_TOKENS_PRO |
Token credits for the Pro top-up | 1000000 |
DODO_MIN_AMOUNT |
Minimum charge (in minor units) to enforce with discounts | 50 |
GOOGLE_CLIENT_ID |
Google OAuth client ID | - |
GOOGLE_CLIENT_SECRET |
Google OAuth secret | - |
PUBLIC_BASE_URL |
Optional base URL override for OAuth redirects | - |
SESSION_SECRET |
Session encryption key | - |
ADMIN_USER |
Admin username for the /admin dashboard |
admin |
ADMIN_PASSWORD |
Admin password for the /admin dashboard |
- |
ADMIN_SESSION_TTL_MS |
Admin session timeout in milliseconds | 86400000 (24h) |
COOKIE_SECURE |
Set to 1 to enable secure cookies (requires HTTPS) |
0 |
SMTP_HOST |
SMTP host for transactional emails | - |
SMTP_PORT |
SMTP port | 587 |
SMTP_SECURE |
Set to 1 to force TLS/SSL (usually port 465) |
0 |
SMTP_USER |
SMTP username | - |
SMTP_PASS |
SMTP password | - |
SMTP_FROM |
From email address for verification/reset emails | - |
EMAIL_VERIFICATION_TTL_MS |
How long verification links remain valid | 86400000 (24h) |
PASSWORD_RESET_TTL_MS |
How long password reset links remain valid | 3600000 (1h) |
⚠️ Emails (verification and password reset) are sent as branded HTML messages matching the app design. For images/assets to render correctly in emails, set
PUBLIC_BASE_URLto your site URL (e.g.https://app.example.com). IfPUBLIC_BASE_URLis not set, assets fallback to relative paths.
The planning prompt sent to OpenRouter can be edited at chat/public/openrouter-plan-prompt.txt (or by pointing OPENROUTER_PLAN_PROMPT_PATH to a different file).
Password Protection
To enable password protection for the terminal:
# In .env file
ACCESS_PASSWORD=your_secure_password
This will require authentication for the terminal (port 4001) with:
- Username:
user - Password:
<your_secure_password>
OAuth Sign-In Setup (Google + GitHub)
- Set redirect URLs
- Google:
https://your-domain.com/auth/google/callback - GitHub:
https://your-domain.com/auth/github/callback - For local testing use
http://localhost:4000/auth/<provider>/callback
- Google:
- Create credentials
- Google: In Cloud Console → APIs & Services → Credentials → OAuth Client ID (Web). Add the redirect URL above.
- GitHub: Go to https://github.com/settings/developers → OAuth Apps → New OAuth App. Set the callback URL above.
- Configure environment
- Add
GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRETto.env,docker-compose.yml, or your stack. - If the app is behind a reverse proxy, set
PUBLIC_BASE_URL(e.g.,https://app.example.com) so callback URLs are generated correctly.
- Add
- Restart the service to apply the new credentials.
Building Shopify Apps
Using Templates
The builder includes quick-start templates for common Shopify apps:
- Product Recommendation Engine - Suggest products based on customer behavior
- Bulk Image Optimizer - Optimize product images in bulk
- Custom Shipping Rules - Create advanced shipping logic
- Discount Manager - Manage complex discount campaigns
Custom Apps
Simply describe what you want in the chat input:
Build a Shopify app that shows product recommendations based on
customer purchase history. Include an admin dashboard with analytics
and a theme app extension to display recommendations on the storefront.
The AI will:
- Create a complete app structure with necessary configuration
- Set up API integrations and webhooks
- Build the admin UI for the merchant
- Create storefront components or theme app extensions
- Generate documentation and setup instructions
Exporting Your App
- Click "Download as ZIP" in the sidebar
- Or push directly to GitHub using the version control panel
- The app is ready to deploy to Vercel, Railway, or any Node.js host
Deployment
Docker Compose (Recommended)
docker compose up -d
Portainer Stack
Use the included stack-portainer.yml for Portainer deployment.
📖 See PORTAINER.md for detailed deployment guide and troubleshooting.
Quick start:
- Go to Portainer → Stacks → Add Stack
- Upload or paste
stack-portainer.yml - Set environment variables
- Important: Manually type variable names and values - don't copy-paste to avoid invisible Unicode characters
- See PORTAINER.md for detailed instructions
- Deploy
Production Recommendations
- Use a reverse proxy (NGINX, Traefik, Caddy) for HTTPS
- Set strong
ACCESS_PASSWORDfor terminal authentication - Configure proper firewall rules
- Use Docker secrets for sensitive values
Development
Project Structure
shopify-ai/
├── chat/ # Web application
│ ├── server.js # Express server
│ └── public/ # Frontend files
│ ├── homepage.html # Landing page
│ ├── builder.html # App builder UI
│ ├── styles.css # Shared styles
│ └── app.js # Frontend JavaScript
├── scripts/ # Utility scripts
│ ├── entrypoint.sh # Container startup
│ └── healthcheck.sh # Health monitoring
├── profile/ # PowerShell profile
├── Dockerfile # Container definition
├── docker-compose.yml # Local development
└── stack-portainer.yml # Production deployment
Running Locally (Development)
cd chat
npm install
npm start
Troubleshooting
Portainer Deployment Error: "unexpected character \u200e"
If you see this error when deploying to Portainer:
Failed to deploy a stack: unable to get the environment from the env file:
failed to read /data/compose/42/stack.env: line 8: unexpected character "\u200e"
in variable name "ADMIN_USER\u200e=user"
This is caused by invisible Unicode characters (like U+200E Left-to-Right Mark) in your environment variables. This typically happens when copying and pasting from certain text editors or web pages.
Solution:
-
Option A - Use the cleanup script:
# Clean your .env file ./scripts/clean-env.sh .env -
Option B - Manually recreate the variables:
- In Portainer's environment variables editor, manually type (don't copy-paste) the variable names
- Or export the environment variables to a file, clean it, and re-import
-
Option C - Download a clean template:
# Use the clean .env.example as a starting point cp .env.example .env
OpenCode Not Working
# Inside the terminal, verify OpenCode is installed
opencode --version
# Check the OpenCode installation
ls -la /root/.opencode/
Port Already in Use
# Check what's using the port
lsof -i :4000
lsof -i :4001
# Or change ports in docker-compose.yml
Container Health Issues
# Check container logs
docker compose logs -f
# Check health status
docker compose ps
Security Notes
- This service exposes a web terminal - always use
ACCESS_PASSWORDin production - Never commit
.envfiles or secrets to version control - Use HTTPS in production with a reverse proxy
- Rotate credentials regularly
License
ISC
Support
For issues and feature requests, please open a GitHub issue.