#!/usr/bin/env python3
"""
Discord bot for #remora channel - analyzes links in real-time
Posts summaries, adds to Tududi inbox, maintains JSON history
"""
import discord
import os
import json
import re
import requests
from datetime import datetime
from pathlib import Path
from dotenv import load_dotenv
# Load .env file
load_dotenv()
# Config
CHANNEL_ID = 1467557082583535729
TRACKER_FILE = Path(__file__).parent / "tracker.json"
TUDUDI_API_URL = os.getenv("TUDUDI_API_URL", "https://todo.dilain.com/api/v1")
TUDUDI_API_KEY = os.getenv("TUDUDI_API_KEY")
GATEWAY_URL = os.getenv("OPENCLAW_GATEWAY", "http://127.0.0.1:18789")
GATEWAY_TOKEN = os.getenv("OPENCLAW_GATEWAY_TOKEN")
# Load or init tracker
def load_tracker():
if TRACKER_FILE.exists():
with open(TRACKER_FILE) as f:
return json.load(f)
return {
"channel_id": CHANNEL_ID,
"processed_message_ids": [],
"links": []
}
def save_tracker(data):
with open(TRACKER_FILE, "w") as f:
json.dump(data, f, indent=2)
# Detect links in text
def extract_urls(text):
url_pattern = r'https?://[^\s<>"{}|\\^`\[\]]+'
return re.findall(url_pattern, text)
# Fetch and analyze URL
def analyze_url(url):
"""Fetch URL and create summary"""
try:
print(f" š„ Fetching: {url}")
response = requests.get(url, timeout=5, headers={
'User-Agent': 'Mozilla/5.0'
})
content = response.text[:2000] # First 2k chars
# Extract title
title_match = re.search(r'
]*>([^<]+)', content, re.IGNORECASE)
title = title_match.group(1).strip() if title_match else url.split('/')[-1]
# Simple content type detection
link_type = "webpage"
if "github.com" in url:
link_type = "GitHub"
elif "reddit.com" in url:
link_type = "Reddit"
elif "youtube.com" in url or "youtu.be" in url:
link_type = "YouTube"
elif "tiktok.com" in url:
link_type = "TikTok"
elif "twitter.com" in url or "x.com" in url:
link_type = "Twitter/X"
return {
"title": title,
"type": link_type,
"status": "ok"
}
except Exception as e:
print(f" ā Error fetching: {e}")
return {
"title": "Couldn't fetch",
"type": "unknown",
"status": "error",
"error": str(e)
}
# Send to Tududi inbox
def add_to_tududi(title, url, link_type):
"""Add to Tududi inbox with summary"""
try:
if not TUDUDI_API_KEY:
print(" ā ļø TUDUDI_API_KEY not set")
return False
content = f"š {link_type}: {title}\nš {url}"
response = requests.post(
f"{TUDUDI_API_URL}/inbox",
headers={
"Authorization": f"Bearer {TUDUDI_API_KEY}",
"Content-Type": "application/json"
},
json={"content": content},
timeout=5
)
if response.status_code == 200:
print(f" ā
Added to Tududi: {title}")
return True
else:
print(f" ā ļø Tududi error: {response.status_code}")
return False
except Exception as e:
print(f" ā Tududi error: {e}")
return False
# Discord bot
intents = discord.Intents.default()
intents.message_content = True
class LinkAnalyzerBot(discord.Client):
async def on_ready(self):
print(f"ā
Bot logged in as {self.user}")
print(f"š Watching channel #remora ({CHANNEL_ID})")
async def on_message(self, message):
# Ignore bot's own messages
if message.author == self.user:
return
# Only process #remora channel
if message.channel.id != CHANNEL_ID:
return
# Check for URLs
urls = extract_urls(message.content)
if not urls:
return
# Skip if already processed
tracker = load_tracker()
if message.id in tracker["processed_message_ids"]:
return
print(f"š New link from {message.author}: {message.content}")
# Process each URL
for url in urls:
print(f" Processing: {url}")
# Analyze
analysis = analyze_url(url)
# Add to Tududi
add_to_tududi(analysis["title"], url, analysis["type"])
# Prepare response
summary = f"š **{analysis['type']}**: {analysis['title']}"
if analysis["status"] == "error":
summary += f"\nā ļø {analysis['error']}"
# Post summary in channel
await message.reply(summary, mention_author=False)
# Add to tracker
tracker["links"].append({
"url": url,
"title": analysis["title"],
"type": analysis["type"],
"author": str(message.author),
"message_id": message.id,
"date": datetime.now().isoformat(),
"tududi": True
})
# Update processed IDs
tracker["processed_message_ids"].append(message.id)
save_tracker(tracker)
# Main
if __name__ == "__main__":
token = os.getenv("DISCORD_BOT_TOKEN")
if not token:
print("ā DISCORD_BOT_TOKEN not set!")
print("Set it: export DISCORD_BOT_TOKEN='your_token'")
exit(1)
bot = LinkAnalyzerBot(intents=intents)
bot.run(token)