A comprehensive Frappe app for UTM parameter generation and URL shortening with advanced analytics.
- Generate short, memorable URLs
- Custom aliases support
- Bulk URL creation
- Expiration date management
- Domain blocking for security
- Complete UTM parameter builder
- Template system for reusable campaigns
- Automatic URL generation with UTM parameters
- Auto-computed full URLs with UTM parameters
- Campaign code generation
- One-click URL copying to clipboard
- Real-time click tracking
- Device type detection (Desktop/Mobile/Tablet)
- Browser and OS identification
- Geolocation tracking (optional)
- Country-wise analytics
- Unique visitor counting
- Rate limiting
- Domain blocking
- URL validation
- Malicious URL detection
- Permission-based access control
- Frappe Framework v15+
- ERPNext v15+ (optional but recommended)
- Clone this repository to your Frappe bench apps folder:
cd frappe-bench/apps
git clone https://github.com/chinmaybhatk/utm_shortener.git
- Install the app to your site:
bench --site your-site.local install-app utm_shortener
- Run database migrations:
bench --site your-site.local migrate
-
Create the required DocTypes manually:
- UTM Campaign
- Short URL
- URL Click Log
- UTM Template
- UTM Shortener Settings (Single DocType)
-
Configure settings:
- Go to UTM Shortener Settings
- Set your base domain
- Configure rate limits
- Enable geolocation if needed
- Navigate to UTM Campaign in the desk
- Click New
- Fill in campaign details:
- Campaign Name: "Summer Sale 2025"
- UTM Source: "email"
- UTM Medium: "newsletter"
- UTM Campaign: "summer_sale_2025"
- Base URL: "https://example.com/products" (NEW)
- The Full URL with UTM Parameters will be automatically generated
- Click Copy Full URL button to copy the complete URL
- Save
- Go to Short URL in the desk
- Click New
- Enter your original URL
- Select a UTM Campaign (optional)
- Add custom alias (optional)
- Save
import requests
response = requests.post('https://yoursite.com/api/method/utm_shortener.utm_shortener.api.create_short_url', {
'original_url': 'https://example.com/product',
'utm_campaign': 'summer_sale_campaign',
'custom_alias': 'summer-sale'
})
data = response.json()
print(data['message']['short_url'])
response = requests.post('https://yoursite.com/api/method/utm_shortener.utm_shortener.doctype.utm_campaign.utm_campaign.generate_utm_url', {
'campaign_name': 'CAMP-001',
'base_url': 'https://example.com/products'
})
utm_url = response.json()['message']
print(f"Generated URL: {utm_url}")
response = requests.get('https://yoursite.com/api/method/utm_shortener.utm_shortener.api.get_url_analytics', {
'short_code': 'abc123'
})
analytics = response.json()['message']
print(f"Total clicks: {analytics['short_url']['total_clicks']}")
import json
urls = [
{"url": "https://shop.com/laptops", "alias": "laptops"},
{"url": "https://shop.com/phones", "alias": "phones"}
]
response = requests.post('https://yoursite.com/api/method/utm_shortener.utm_shortener.api.bulk_create_utm_urls', {
'campaign': 'summer_sale_campaign',
'url_list': json.dumps(urls)
})
Main campaign management with UTM parameters. Fields:
- Campaign Name (Data, Required)
- Campaign Code (Data, Auto-generated, Unique)
- UTM Source (Data, Required)
- UTM Medium (Select: email, social, cpc, etc.)
- UTM Campaign (Data, Required)
- UTM Term (Data, Optional)
- UTM Content (Data, Optional)
- Base URL (Data, Optional) - NEW
- Full URL with UTM Parameters (Small Text, Read-only, Auto-generated) - NEW
- Description (Text Editor)
- Status (Select: Active, Inactive, Completed)
- Start Date/End Date
Individual shortened URLs with tracking. Fields:
- Short Code (Data, Required, Unique, Auto-generated)
- Original URL (Long Text, Required)
- Short URL (Data, Read-only, Auto-generated)
- UTM Campaign (Link: UTM Campaign, Optional)
- Generated UTM URL (Long Text, Read-only)
- Custom Alias (Data, Optional, Unique)
- Total Clicks (Int, Default: 0, Read-only)
- Status (Select: Active, Inactive, Expired)
- Expiry Date (Date, Optional)
- Last Accessed (Datetime, Read-only)
Detailed click tracking records. Fields:
- Short URL (Link: Short URL, Required)
- Timestamp (Datetime, Default: now)
- IP Address (Data)
- User Agent (Long Text)
- Referrer URL (Long Text)
- Country (Data)
- City (Data)
- Device Type (Select: Desktop, Mobile, Tablet, Unknown)
- Browser (Data)
- Operating System (Data)
Reusable UTM parameter templates. Fields:
- Template Name (Data, Required)
- Template Code (Data, Auto-generated)
- UTM Source/Medium (Data, Required)
- UTM Campaign/Term/Content Templates (Data)
- Description (Text)
- Is Active (Check, Default: 1)
System-wide configuration. Fields:
- Base Domain (Data, Default: "short.ly")
- Use HTTPS (Check, Default: 1)
- Default Expiry Days (Int, Default: 365)
- Rate Limit Per Hour (Int, Default: 100)
- Enable Geolocation (Check)
- Geolocation API Key (Password)
- Blocked Domains (Long Text)
The app includes role-based permissions:
- UTM Manager: Full access to all features
- UTM User: Create and manage own URLs
- UTM Viewer: Read-only access to analytics
- cleanup_expired_urls: Mark expired URLs as inactive
- update_geolocation_data: Update location data for recent clicks
- reset_rate_limits: Reset user rate limiting counters
You can extend the doctypes with custom fields:
# Add custom field to UTM Campaign
custom_field = {
"dt": "UTM Campaign",
"properties": [
{
"fieldname": "budget",
"label": "Campaign Budget",
"fieldtype": "Currency"
}
]
}
- Check website route configuration in hooks.py
- Ensure the app is installed and migrated
- Verify domain settings
- Check UTM Shortener Settings
- Adjust rate_limit_per_hour value
- Verify click logs are being created
- Check browser restrictions
- Ensure proper permissions
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
# Install in development mode
bench get-app utm_shortener /path/to/local/repo
bench --site dev.local install-app utm_shortener
bench --site dev.local migrate
MIT License - see LICENSE file for details.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Frappe Framework: v15.0+
- ERPNext: v15.0+ (optional)
- Python: 3.8+
- NEW: Auto-generate full URLs with UTM parameters
- NEW: Base URL field in UTM Campaign
- NEW: One-click copy URL functionality
- NEW: Real-time URL preview
- Improved user experience
- Initial release
- Core URL shortening functionality
- UTM parameter generation
- Basic analytics
- API endpoints
- Frappe v15 compatibility
Made with β€οΈ for the Frappe community