New A4 monitoring script + updated A1→A2 webhook with Live Campaign indicator.
NEW SCRIPT: a4_webhook_monitor.py
- Monitors campaigns with status A4
- Sends webhook when A4 campaigns found
- A4 = Campaign NOT going live
- Webhook payload includes: "live_campaign": "NO"
A4 WEBHOOK PAYLOAD:
{
"campaign_id": "abc123...",
"campaign_number": "C000000078",
"campaign_name": "Campaign Name",
"status": "A4",
"live_campaign": "NO", ← NEW FIELD!
"timestamp": 1234567890,
"message": "Campaign marked A4 - Not going live"
}
A1→A2 WEBHOOK UPDATE:
Added "live_campaign": "YES" to existing webhook
- A1→A2 campaigns ARE going live
- Webhook now includes live campaign indicator
A1→A2 WEBHOOK PAYLOAD (UPDATED):
{
"campaign_id": "abc123...",
"campaign_number": "C000000078",
"campaign_name": "Campaign Name",
"old_status": "A1",
"new_status": "A2",
"live_campaign": "YES", ← NEW FIELD!
"asset_count": 5,
"processed_assets": [...],
"timestamp": 1234567890
}
EMAIL NOTIFICATION:
NEW: a4_webhook_sent template
- Gray theme for A4 status
- Shows "Live Campaign: NO" prominently
- Lists webhook URL and payload details
USAGE:
Default (OAuth2):
python scripts/a4_webhook_monitor.py
With mTLS:
python scripts/a4_webhook_monitor.py --auth-pfx
CRON SCHEDULE (same as other workflows):
*/5 * * * * cd ~/Python-Version && venv/bin/python scripts/a4_webhook_monitor.py >> logs/cron_a4.log 2>&1
WORKFLOW SUMMARY:
- A1→A2: Webhook with "live_campaign": "YES" (going live)
- A4: Webhook with "live_campaign": "NO" (not going live)
- A5→A6: No webhook (rework workflow)
- B1→B2: No webhook (global masters)
Changes:
- NEW: scripts/a4_webhook_monitor.py (200 lines)
- EDIT: scripts/a1_to_a2_download.py (added live_campaign: YES)
- EDIT: scripts/shared/notifier.py (added a4_webhook_sent template)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
211 lines
6.7 KiB
Python
Executable file
211 lines
6.7 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""
|
|
A4 Webhook Monitor
|
|
Monitors campaigns with status A4 and sends webhook notification
|
|
A4 status indicates campaign is not going live
|
|
Sends webhook with "Live Campaign": "NO"
|
|
Compatible with Python 3.6+
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
import time
|
|
import logging
|
|
import argparse
|
|
|
|
# Add shared library to path
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
|
|
|
from shared.config_loader import load_config
|
|
from shared.dam_client import DAMClient
|
|
from shared.database import Database
|
|
from shared.notifier import Notifier
|
|
|
|
# Setup logging with rotation
|
|
from logging.handlers import RotatingFileHandler
|
|
|
|
# Create logs directory if it doesn't exist
|
|
os.makedirs('logs', exist_ok=True)
|
|
os.makedirs('logs/backup', exist_ok=True)
|
|
|
|
# Configure logging with rotation
|
|
log_handler = RotatingFileHandler(
|
|
'logs/a4_webhook.log',
|
|
maxBytes=10*1024*1024, # 10MB per file
|
|
backupCount=28 # Keep 28 rotated files (approximately 1 month)
|
|
)
|
|
log_handler.setLevel(logging.INFO)
|
|
log_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
|
|
|
|
console_handler = logging.StreamHandler()
|
|
console_handler.setLevel(logging.INFO)
|
|
console_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
handlers=[log_handler, console_handler]
|
|
)
|
|
|
|
logger = logging.getLogger('A4Webhook')
|
|
|
|
def process_campaign(campaign, dam, db, notifier, config):
|
|
"""
|
|
Process A4 campaign - send webhook notification
|
|
|
|
Returns:
|
|
dict with success boolean
|
|
"""
|
|
campaign_id = campaign['asset_id']
|
|
campaign_name = campaign['campaign_name']
|
|
campaign_number = campaign.get('campaign_id', 'N/A')
|
|
|
|
logger.info("=" * 60)
|
|
logger.info("Processing A4 campaign: {} ({})".format(campaign_name, campaign_number))
|
|
logger.info("=" * 60)
|
|
|
|
try:
|
|
# Check if webhook is enabled
|
|
if not config['webhooks']['campaign_status_update']['enabled']:
|
|
logger.info("Webhook disabled in config - skipping")
|
|
return {'success': True, 'webhook_sent': False}
|
|
|
|
webhook_url = config['webhooks']['campaign_status_update']['url']
|
|
|
|
# Build webhook payload
|
|
payload = {
|
|
'campaign_id': campaign_id,
|
|
'campaign_number': campaign_number,
|
|
'campaign_name': campaign_name,
|
|
'status': 'A4',
|
|
'live_campaign': 'NO', # A4 = Not going live
|
|
'timestamp': int(time.time()),
|
|
'message': 'Campaign marked A4 - Not going live'
|
|
}
|
|
|
|
logger.info("Sending webhook for A4 campaign...")
|
|
logger.info(" Campaign: {} ({})".format(campaign_name, campaign_number))
|
|
logger.info(" Status: A4")
|
|
logger.info(" Live Campaign: NO")
|
|
logger.info(" Webhook URL: {}".format(webhook_url))
|
|
|
|
# Send webhook
|
|
webhook_result = notifier.send_webhook(
|
|
url=webhook_url,
|
|
payload=payload
|
|
)
|
|
|
|
if webhook_result:
|
|
logger.info("✓ Webhook sent successfully")
|
|
|
|
# Send email notification
|
|
notifier.send_email(
|
|
template_name='a4_webhook_sent',
|
|
recipients=config['notifications']['recipients']['success'],
|
|
data={
|
|
'campaign_name': campaign_name,
|
|
'campaign_id': campaign_id,
|
|
'campaign_number': campaign_number,
|
|
'webhook_url': webhook_url
|
|
}
|
|
)
|
|
|
|
return {'success': True, 'webhook_sent': True}
|
|
else:
|
|
logger.error("✗ Webhook send failed")
|
|
return {'success': False, 'webhook_sent': False}
|
|
|
|
except Exception as e:
|
|
logger.error("Campaign processing failed: {}".format(str(e)))
|
|
return {'success': False, 'webhook_sent': False}
|
|
|
|
def main():
|
|
"""Main polling loop"""
|
|
# Parse command-line arguments
|
|
parser = argparse.ArgumentParser(description='Ferrero A4 Webhook Monitor')
|
|
parser.add_argument('--auth-pfx', action='store_true',
|
|
help='Use mTLS certificate authentication instead of OAuth2')
|
|
args = parser.parse_args()
|
|
|
|
logger.info("=" * 60)
|
|
logger.info("Ferrero A4 Webhook Monitor Starting")
|
|
if args.auth_pfx:
|
|
logger.info("Authentication: mTLS Certificate (--auth-pfx)")
|
|
else:
|
|
logger.info("Authentication: OAuth2 (default)")
|
|
logger.info("=" * 60)
|
|
|
|
# Load configuration
|
|
config = load_config('config/config.yaml')
|
|
|
|
# Initialize clients
|
|
dam = DAMClient(config, use_mtls=args.auth_pfx)
|
|
db = Database(config)
|
|
notifier = Notifier(config)
|
|
|
|
# Test connections
|
|
logger.info("Testing connections...")
|
|
if not dam.test_connection():
|
|
logger.error("DAM connection failed - exiting")
|
|
sys.exit(1)
|
|
|
|
if not db.test_connection():
|
|
logger.error("Database connection failed - exiting")
|
|
sys.exit(1)
|
|
|
|
logger.info("All connections OK")
|
|
logger.info("")
|
|
|
|
# SINGLE RUN MODE - Process ONE campaign and exit
|
|
# Cron will run this script every 5 minutes, processing one campaign at a time
|
|
try:
|
|
logger.info("Searching for A4 campaigns...")
|
|
|
|
# Search for campaigns with status A4
|
|
campaigns = dam.search_campaigns(status='A4')
|
|
|
|
if not campaigns:
|
|
logger.info("No A4 campaigns found - exiting")
|
|
db.close()
|
|
sys.exit(0)
|
|
|
|
# Process ONLY THE FIRST campaign
|
|
campaign = campaigns[0]
|
|
logger.info("Found {} A4 campaigns - processing first one only".format(len(campaigns)))
|
|
logger.info("")
|
|
|
|
result = process_campaign(campaign, dam, db, notifier, config)
|
|
|
|
if result['success'] and result.get('webhook_sent'):
|
|
logger.info("")
|
|
logger.info("=" * 60)
|
|
logger.info("✓ A4 webhook sent successfully")
|
|
logger.info(" Campaign: {}".format(campaign['campaign_name']))
|
|
logger.info(" Live Campaign: NO")
|
|
logger.info("=" * 60)
|
|
db.close()
|
|
sys.exit(0)
|
|
else:
|
|
logger.warning("")
|
|
logger.warning("=" * 60)
|
|
logger.warning("✗ A4 webhook processing incomplete")
|
|
logger.warning("=" * 60)
|
|
db.close()
|
|
sys.exit(1)
|
|
|
|
except Exception as e:
|
|
logger.critical("Script error: {}".format(str(e)))
|
|
# Send critical error notification
|
|
notifier.send_email(
|
|
template_name='upload_failed',
|
|
recipients=config['notifications']['recipients']['critical'],
|
|
data={
|
|
'filename': 'A4 Webhook Script',
|
|
'tracking_id': 'N/A',
|
|
'error': str(e)
|
|
}
|
|
)
|
|
db.close()
|
|
sys.exit(1)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|