import asyncio import random import httpx import os from datetime import datetime, timedelta, timezone from ai_engine import engine from jarvis_links import get_link, get_random_template SUPABASE_URL_ENV = os.environ.get("SUPABASE_URL", "") SUPABASE_KEY_ENV = os.environ.get("SUPABASE_KEY", "") or os.environ.get("SUPABASE_ANON_KEY", "") SUPABASE_HEADERS = { "apikey": SUPABASE_KEY_ENV, "Authorization": f"Bearer {SUPABASE_KEY_ENV}", "Content-Type": "application/json", "Prefer": "return=representation" } # ============================================================ # HELPER: Auto-push ke Pinterest queue # ============================================================ async def push_to_pinterest(title: str, description: str, niche: str, affiliate_link: str = "", tags: list = None): """Auto-push konten ke Pinterest queue di Supabase""" if not SUPABASE_URL_ENV or not SUPABASE_KEY_ENV: return None try: scheduled_at = (datetime.now(timezone.utc) + timedelta(hours=random.randint(1, 6))).isoformat() payload = { "title": title[:100], "description": description[:500], "affiliate_link": affiliate_link or None, "niche": niche, "tags": tags or [], "image_prompt": f"Pinterest pin about {title}, vertical 1000x1500px, professional colorful modern design, text overlay, eye-catching", "status": "pending", "scheduled_at": scheduled_at } async with httpx.AsyncClient(timeout=10) as client: r = await client.post( f"{SUPABASE_URL_ENV}/rest/v1/pinterest_content_queue", headers=SUPABASE_HEADERS, json=payload ) if r.status_code < 400: print(f"šŸ“Œ Pinterest queue: {title[:40]}") return r.json() except Exception as e: print(f"āš ļø Pinterest push failed: {e}") return None # ============================================================ # MODULES # ============================================================ class TrendHijacker: name = "TrendHijacker" icon = "šŸ”„" TREND_SEEDS = [ "website gratis 2025", "cara bikin toko online", "hosting murah Indonesia", "bisnis online modal kecil", "tips freelancer Indonesia", "kerja remote dari rumah", "jualan online shopee tips", "produk viral shopee", "diskon shopee hari ini", "cara daftar affiliate hostinger", "passive income dari blog", "cara membuat website professional", "hosting terbaik untuk wordpress", ] async def run(self, custom_topic=None, **kwargs): topic = custom_topic or random.choice(self.TREND_SEEDS) hostinger_link = get_link("hostinger") shopee_link = get_link("shopee") prompt = f"""Kamu adalah content strategist viral Indonesia. Topik trending: "{topic}" Buat 3 ide konten viral untuk promosi affiliate. Link affiliate yang WAJIB dimasukkan natural di setiap konten: - Hostinger: {hostinger_link} - Shopee: {shopee_link} Format setiap ide: JUDUL | PLATFORM | HOOK | KONTEN (200 kata, embed link natural) | CTA | HASHTAG (5) Bahasa Indonesia casual, tidak hard-selling.""" result = await engine.think(prompt) return { "module": self.name, "topic": topic, "timestamp": datetime.now().isoformat(), "output": result["response"], "provider": result["provider"] } class ViralPredictor: name = "ViralPredictor" icon = "šŸ“Š" async def run(self, content="contoh konten affiliate", **kwargs): prompt = f"""Analisa potensi viral konten ini di Indonesia: KONTEN: {content} Berikan: VIRAL SCORE (0-100) | PLATFORM TERBAIK | KEKUATAN | KELEMAHAN | REKOMENDASI Bahasa Indonesia.""" result = await engine.think(prompt) return { "module": self.name, "timestamp": datetime.now().isoformat(), "output": result["response"], "provider": result["provider"] } class GhostNetwork: name = "GhostNetwork" icon = "šŸ‘»" async def run(self, content="konten affiliate default", **kwargs): hostinger_link = get_link("hostinger") shopee_link = get_link("shopee") prompt = f"""Adaptasi konten ini untuk 6 platform: KONTEN: {content} Link affiliate WAJIB diembed natural di setiap platform: - Hostinger: {hostinger_link} - Shopee: {shopee_link} Format per platform: PLATFORM | KONTEN ADAPTASI | HASHTAG | JAM POSTING OPTIMAL WIB Platform: Instagram, TikTok, Twitter/X, Facebook, WhatsApp, Telegram""" result = await engine.think(prompt) return { "module": self.name, "timestamp": datetime.now().isoformat(), "output": result["response"], "provider": result["provider"] } class Scout: name = "Scout" icon = "šŸ”" async def run(self, target="hostinger competitor indonesia", **kwargs): prompt = f"""Riset mendalam: "{target}" Berikan: OVERVIEW | PAIN POINTS | KOMPETITOR | PELUANG | KEYWORDS (10) | CONTENT IDEAS (5) Fokus pasar Indonesia.""" result = await engine.think(prompt) return { "module": self.name, "target": target, "timestamp": datetime.now().isoformat(), "output": result["response"], "provider": result["provider"] } class Writer: name = "Writer" icon = "āœļø" CONTENT_TYPES = { "hostinger": { "link": None, # diisi dari get_link() "keywords": ["web hosting", "hosting murah", "buat website", "domain hosting", "hostinger review"], "tags": ["webhosting", "hostinger", "buatwebsite", "hostingmurah", "affiliatemarketing"] }, "shopee": { "link": None, "keywords": ["shopee", "belanja online", "promo shopee", "diskon", "flash sale"], "tags": ["shopee", "belanjaonline", "promoshopee", "diskon", "flashsale"] } } async def run(self, topic="hosting murah", content_type="artikel_blog", platform="hostinger", auto_pinterest=True, **kwargs): link = get_link(platform, short=False) # pakai full link untuk affiliate tracking link_short = get_link(platform, short=True) conf = self.CONTENT_TYPES.get(platform, self.CONTENT_TYPES["hostinger"]) keywords = ", ".join(conf["keywords"]) prompt = f"""Kamu adalah content writer SEO & affiliate marketing Indonesia profesional. TUGAS: Tulis {content_type} berkualitas tinggi tentang "{topic}" PLATFORM AFFILIATE: {platform.upper()} LINK AFFILIATE: {link} LINK SHORT: {link_short} KEYWORDS TARGET: {keywords} INSTRUKSI WAJIB: 1. Link affiliate {link} HARUS muncul minimal 3x secara natural dalam konten 2. Jangan pernah tulis konten tanpa link affiliate 3. Gunakan anchor text bervariasi (misalnya: "klik di sini", "coba Hostinger sekarang", "daftar sekarang") 4. Buat konten minimal 500 kata, SEO-friendly 5. Tambahkan CTA yang kuat di awal, tengah, dan akhir artikel 6. Bahasa Indonesia casual tapi profesional 7. Format: JUDUL SEO | META DESCRIPTION | ISI ARTIKEL LENGKAP | CTA AKHIR | TAGS (5) Mulai sekarang, tulis kontennya:""" result = await engine.think(prompt) output = result["response"] # Auto-push ke Pinterest queue jika enabled if auto_pinterest and SUPABASE_URL_ENV: # Extract judul dari output (baris pertama) first_line = output.split('\n')[0].replace('JUDUL SEO:', '').replace('JUDUL:', '').strip() title = first_line[:100] if first_line else f"{topic} - {platform.title()}" # Buat deskripsi Pinterest dari meta description atau awal artikel desc_lines = [l for l in output.split('\n') if l.strip() and 'META' not in l.upper()] description = ' '.join(desc_lines[1:3])[:500] if len(desc_lines) > 1 else output[:300] asyncio.create_task(push_to_pinterest( title=title, description=f"{description}\n\nšŸ‘‰ {link_short}", niche=platform, affiliate_link=link_short, tags=conf["tags"] )) return { "module": self.name, "topic": topic, "platform": platform, "affiliate_link": link, "timestamp": datetime.now().isoformat(), "output": output, "provider": result["provider"] } class Publisher: name = "Publisher" icon = "šŸ“¢" async def run(self, content="konten affiliate", **kwargs): hostinger_link = get_link("hostinger") shopee_link = get_link("shopee") prompt = f"""Buat jadwal publishing 7 hari untuk konten: {content[:500]} Link affiliate yang WAJIB ada di setiap post: - Hostinger: {hostinger_link} - Shopee: {shopee_link} Format tabel: HARI | PLATFORM | JAM WIB | TIPE KONTEN | LINK AFFILIATE | CATATAN Tambahkan checklist sebelum posting dan tips optimalkan CTR.""" result = await engine.think(prompt) return { "module": self.name, "timestamp": datetime.now().isoformat(), "output": result["response"], "provider": result["provider"] } class Analyst: name = "Analyst" icon = "šŸ“ˆ" async def run(self, metrics=None, **kwargs): metrics_str = str(metrics) if metrics else "Belum ada data. Buat rekomendasi KPI awal untuk affiliate marketing Hostinger dan Shopee Indonesia." prompt = f"""Analisa performa affiliate marketing: DATA: {metrics_str} Berikan: OVERVIEW | TOP PERFORMING | UNDERPERFORMING | INSIGHT | 5 LANGKAH OPTIMASI | TARGET MINGGU DEPAN Fokus pada konversi affiliate Hostinger (target $60-100/sale) dan Shopee (2-10%/sale).""" result = await engine.think(prompt) return { "module": self.name, "timestamp": datetime.now().isoformat(), "output": result["response"], "provider": result["provider"] } class ShopeePromoter: name = "ShopeePromoter" icon = "šŸ›’" async def run(self, product_link="", product_name="", price="", **kwargs): if not product_link: return { "module": self.name, "timestamp": datetime.now().isoformat(), "output": "āŒ Link produk kosong. Masukkan link affiliate Shopee kamu.", "provider": "none" } prompt = f"""Kamu adalah copywriter viral Indonesia spesialis Shopee affiliate. PRODUK: {product_name if product_name else 'produk Shopee'} HARGA: {price if price else 'cek di link'} LINK AFFILIATE: {product_link} Buat 5 variasi konten promosi viral dengan LINK {product_link} diembed di SETIAP variasi: 1. CAPTION INSTAGRAM (max 150 kata, hashtag 10-15, casual) 2. THREAD TWITTER/X (3 tweet, hook kuat di tweet pertama) 3. STATUS WHATSAPP (singkat, personal, tidak terkesan iklan) 4. CAPTION TIKTOK (energik, trending, CTA kuat) 5. PESAN TELEGRAM BLAST (detail produk + urgensi) WAJIB: Link {product_link} harus ada di setiap variasi, embed natural. Bahasa Indonesia casual, tambah emojis.""" result = await engine.think(prompt) # Auto-push ke Pinterest juga if SUPABASE_URL_ENV and product_name: asyncio.create_task(push_to_pinterest( title=f"Promo {product_name} di Shopee - Harga Terbaik!", description=f"Dapatkan {product_name} dengan harga terbaik di Shopee! {price if price else ''} Klik untuk beli šŸ‘‰ {product_link}", niche="general", affiliate_link=product_link, tags=["shopee", "belanjashopee", "promoshopee", "diskon", "murah"] )) return { "module": self.name, "product_link": product_link, "product_name": product_name, "timestamp": datetime.now().isoformat(), "output": result["response"], "provider": result["provider"] } class PinterestWriter: """Module khusus generate konten Pinterest dengan affiliate link""" name = "PinterestWriter" icon = "šŸ“Œ" TOPICS = { "hostinger": [ "best web hosting Indonesia 2025", "cara buat website dengan Hostinger", "Hostinger review jujur 2025", "hosting murah terpercaya", "cara daftar Hostinger step by step", "WordPress hosting terbaik", ], "general": [ "cara dapat passive income dari blog", "tips affiliate marketing pemula", "bisnis online modal kecil 2025", "cara monetisasi website", "kerja dari rumah tips produktif", ] } async def run(self, niche="both", count=3, **kwargs): results = [] niches = ["hostinger", "general"] if niche == "both" else [niche] for i in range(count): selected_niche = random.choice(niches) topic = random.choice(self.TOPICS.get(selected_niche, self.TOPICS["general"])) link = get_link("hostinger") if selected_niche == "hostinger" else "" prompt = f"""Create Pinterest pin content: Topic: "{topic}" {f'Affiliate link to include: {link}' if link else ''} Reply in JSON only (no markdown): {{"title":"catchy title max 100 chars","description":"engaging 200-400 chars with keywords and link if provided","tags":["tag1","tag2","tag3","tag4","tag5"],"image_prompt":"detailed prompt for Pinterest vertical image 1000x1500px"}}""" result = await engine.think(prompt) try: import json, re clean = re.sub(r'```json\n?|```\n?', '', result["response"]).strip() parsed = json.loads(clean) await push_to_pinterest( title=parsed["title"], description=parsed["description"], niche=selected_niche, affiliate_link=link, tags=parsed.get("tags", []) ) results.append({"success": True, "title": parsed["title"], "niche": selected_niche}) except Exception as e: results.append({"success": False, "topic": topic, "error": str(e)}) success = sum(1 for r in results if r.get("success")) output = f"āœ… {success}/{count} konten Pinterest berhasil masuk queue!\n\n" for r in results: if r.get("success"): output += f"šŸ“Œ {r['title']} ({r['niche']})\n" else: output += f"āŒ Error: {r.get('error', 'unknown')}\n" return { "module": self.name, "timestamp": datetime.now().isoformat(), "output": output, "provider": "multi", "results": results } # ============================================================ # REGISTER ALL MODULES # ============================================================ MODULES = { "trend": TrendHijacker(), "viral": ViralPredictor(), "ghost": GhostNetwork(), "scout": Scout(), "writer": Writer(), "publisher": Publisher(), "analyst": Analyst(), "shopee": ShopeePromoter(), "pinterest": PinterestWriter(), } async def run_module(module_name: str, **kwargs) -> dict: if module_name not in MODULES: return {"error": f"Module '{module_name}' not found"} return await MODULES[module_name].run(**kwargs)