A local dashboard tool for converting localized Word documents into CMS-ready template packages.
"As a user, I want to upload a ZIP folder of localized content and images into the dashboard, and download 3 separate ZIPs ready for CMS import: one for OMS templates, one for SMS templates, and one for Terms & Conditions."
Before: Content team manually copies content from Word docs into CMS for each language and template variant. Takes ~1 month per offer type.
After: Upload ZIP + images, configure offer metadata, download 3 CMS-ready packages. Takes ~5 minutes.
- π Upload localized content - ZIP containing Word documents
- πΌοΈ Upload images - For OMS/CRS templates
- βοΈ Configure offer - Task type, reward type, send conditions, variants
- π§ Custom types - Add new task/reward types on the fly
- ποΈ Preview content - Verify extracted content before generating
- π₯ Download 3 packages - SMS, OMS (with images), TC - all CMS-ready
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. UPLOAD β
β βββ ZIP with Word docs ({LANG}_{OfferName}.docx) β
β βββ Images (PNG, JPG, etc.) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β 2. CONFIGURE (sidebar) β
β βββ Task Type (or custom) β
β βββ Reward Type (or custom) β
β βββ Send Conditions β
β βββ Template Variants (A-F) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β 3. PREVIEW β
β βββ SMS templates per language β
β βββ OMS templates per language β
β βββ T&Cs β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β 4. DOWNLOAD β
β βββ π¦ CampaignWizardSmsTemplate.zip β
β βββ π¦ CampaignWizardOmsTemplate.zip (+ images) β
β βββ π¦ CampaignWizardTCTemplate.zip β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ZIP file containing Word documents with naming: {LANGUAGE}_{OfferName}.docx
Example:
Bet&Get_CashFreespin.zip
βββ Sett. Bet & Cash Free Spins -- 1550/
βββ EN_bet_on_sb_get_CFS.docx
βββ BR_bet_on_sb_get_CFS.docx
βββ ARG_bet_on_sb_get_CFS.docx
βββ ...
The parser expects these sections (identified by headings):
| Section | Content |
|---|---|
| MY OFFERS | Headline, Sub-headline, Task, Reward |
| LAUNCH OMS | Template A/B/C: Title, Body, CTA |
| REMINDER OMS | Template A/B/C: Title, Body, CTA |
| SMS | Template A-F: Body |
| T&Cs/SIGNIFICANT TERMS | SignificantTerms, TermsAndConditions |
Three CMS-compatible ZIP packages:
MultiMCmsExport_CampaignWizardSmsTemplate_{date}_common_common_all.zipMultiMCmsExport_CampaignWizardOmsTemplate_{date}_common_common_all.zipMultiMCmsExport_CampaignWizardTCTemplate_{date}_common_common_all.zip
SMS & TC Structure:
Common/
βββ ContentTypeList.txt
βββ DocumentTypeList.txt
βββ CampaignWizard{Type}Template/
βββ en/
β βββ ContentList.xml
β βββ DocumentList.xml
βββ br/
βββ ...
OMS Structure (includes images):
Common/
βββ ContentTypeList.txt
βββ DocumentTypeList.txt
βββ CampaignWizardOmsTemplate/
βββ files/ β Uploaded images
β βββ banner.png
β βββ promo.jpg
βββ en/
β βββ ContentList.xml
β βββ DocumentList.xml
βββ ...
# Navigate to tool directory
cd tools/cms-template-generator
# Create virtual environment (recommended)
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Mac/Linux
# Install dependencies
pip install -r requirements.txt# Start the dashboard
streamlit run app.pyThe app will open in your browser at http://localhost:8501
Single-replica requirement: The OAuth PKCE flow stores state in process memory. The app must run as a single replica β do not scale horizontally without replacing the in-memory PKCE cache with a shared store. This is enforced in
manifest.yaml(replicas: 1).
Build the image:
docker build -t crm-templates-handler .Run with your local secrets mounted (recommended for local testing):
docker run --rm -p 8501:8080 \
-v "$(pwd)/.streamlit/secrets.toml:/app/.streamlit/secrets.toml:ro" \
crm-templates-handlerOpen http://localhost:8501.
Note: Streamlit logs port
8080(the internal container port) in the console β ignore it. The app is always accessible on the host port you mapped,8501in the command above.
OAuth configuration is resolved automatically from
oauth_config.pybased on the active environment (ENVIRONMENTenv var injected by bego, orAPP_ENVfor direct Docker builds). TheOAUTH_*environment variables shown in older docs are not supported β do not pass them todocker run. To use different OAuth settings, updateoauth_config.pydirectly.
-
Configure Offer (sidebar)
- Select Task Type (or "β Custom..." for new types)
- Select Reward Type (or "β Custom..." for new types)
- Choose Send Conditions (NotOptedIn, JoinedCampaign, etc.)
- Select Template Variants (A, B, C, D, E, F)
-
Upload Content
- Upload ZIP file with Word documents
- Upload images for OMS/CRS templates (optional)
- Review the parsed document summary
-
Preview
- See uploaded images
- Select a language to inspect extracted content
- Verify SMS, OMS, and T&C content
-
Generate & Download
- Review configuration summary
- Click "Generate CMS Packages"
- Download 3 packages:
- π¦ SMS Package
- π¦ OMS Package (includes images)
- π¦ TC Package
-
Import to CMS
- Upload each package to CMS admin interface
| Input (Word) | CMS Code(s) | Notes |
|---|---|---|
| EN | en | Base English |
| EN_PE | en-pe | English (Peru) |
| ARG | es-ar-ba, es-ar-ca, es-ar-co | All Argentina regions |
| BR | br | Brazilian Portuguese |
| GR | el | Greek (different code!) |
| ET | et | Estonian |
| RU_ET | ru-ee | Russian (Estonia) |
| ... | ... | See config.py for full list |
Edit config.py to:
- Add/modify language mappings
- Update task types and reward types
- Adjust template variants
- Change CMS metadata defaults
- Ensure ZIP contains .docx files (not .doc)
- Check for nested folders in the ZIP
- Verify Word document has expected section headings (SMS, LAUNCH OMS, etc.)
- Check for typos in section headers
- Ensure all required fields have content
- Check for special characters that need escaping
| File | Purpose |
|---|---|
app.py |
Streamlit dashboard UI |
config.py |
Configuration (languages, types, metadata) |
word_parser.py |
Word document parsing logic |
xml_generator.py |
CMS XML generation |
requirements.txt |
Python dependencies |
- CSV input support (alternative to Word docs)
- Validation rules (SMS character limits, required fields)
- Direct CMS API integration (skip ZIP download)
- Template diff viewer (compare with existing CMS content)
- Batch processing (multiple offer types at once)