feat: paste overflow via FlaskPaste for long replies

Add Bot.long_reply() that sends lines directly when under threshold,
or creates a FlaskPaste paste with preview + link when over. Refactor
abuseipdb, alert history, crtsh, dork, exploitdb, and subdomain
plugins to use long_reply(). Configurable paste_threshold (default: 4).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-17 22:07:31 +01:00
parent 8cabe0f8e8
commit 1836fa50af
9 changed files with 242 additions and 21 deletions

View File

@@ -142,5 +142,4 @@ async def cmd_abuse(bot, message):
return f"{addr} -- error: {exc}"
results = await asyncio.gather(*[_query(a) for a in addrs])
for line in results:
await bot.reply(message, line)
await bot.long_reply(message, list(results), label="abuse check")

View File

@@ -2012,6 +2012,7 @@ async def cmd_alert(bot, message):
return
loop = asyncio.get_running_loop()
fp = bot.registry._modules.get("flaskpaste")
history_lines = []
for row_id, backend, title, url, date, found_at, short_id, short_url in reversed(rows):
ts = found_at[:10]
title = _truncate(title) if title else "(no title)"
@@ -2033,7 +2034,8 @@ async def cmd_alert(bot, message):
line = f"[{name}/{backend}/{short_id}] ({date or ts}) {title}"
if display_url:
line += f" -- {display_url}"
await bot.reply(message, line)
history_lines.append(line)
await bot.long_reply(message, history_lines, label="history")
return
# -- info (any user, channel only) ---------------------------------------

View File

@@ -182,6 +182,4 @@ async def cmd_cert(bot, message):
await bot.reply(message, f"Querying crt.sh for {len(domains)} domain(s)...")
results = await asyncio.gather(*[analyze_domain(d) for d in domains])
for line in results:
await bot.reply(message, line)
await bot.long_reply(message, list(results), label="certs")

View File

@@ -67,8 +67,9 @@ async def cmd_dork(bot, message):
subcmd = parts[1].lower()
if subcmd == "list":
lines = [f" {k:<10} {desc}" for k, (_, desc) in sorted(_DORKS.items())]
await bot.reply(message, "Dork categories:\n" + "\n".join(lines))
lines = ["Dork categories:"]
lines.extend(f" {k:<10} {desc}" for k, (_, desc) in sorted(_DORKS.items()))
await bot.long_reply(message, lines, label="dork categories")
return
if len(parts) < 3:

View File

@@ -158,10 +158,10 @@ async def cmd_exploitdb(bot, message):
if not matches:
await bot.reply(message, f"No exploits matching '{term}'")
return
for entry in matches[:_MAX_RESULTS]:
await bot.reply(message, _format_entry(entry))
lines = [_format_entry(e) for e in matches[:_MAX_RESULTS]]
if len(matches) > _MAX_RESULTS:
await bot.reply(message, f"({len(matches)} total, showing {_MAX_RESULTS})")
lines.append(f"({len(matches)} total, showing {_MAX_RESULTS})")
await bot.long_reply(message, lines, label="exploits")
return
if sub.lower() == "cve":
@@ -177,10 +177,10 @@ async def cmd_exploitdb(bot, message):
if not matches:
await bot.reply(message, f"No exploits for {cve_id}")
return
for entry in matches[:_MAX_RESULTS]:
await bot.reply(message, _format_entry(entry))
lines = [_format_entry(e) for e in matches[:_MAX_RESULTS]]
if len(matches) > _MAX_RESULTS:
await bot.reply(message, f"({len(matches)} total, showing {_MAX_RESULTS})")
lines.append(f"({len(matches)} total, showing {_MAX_RESULTS})")
await bot.long_reply(message, lines, label="exploits")
return
# Direct ID lookup
@@ -209,7 +209,7 @@ async def cmd_exploitdb(bot, message):
if not matches:
await bot.reply(message, f"No exploits matching '{term}'")
return
for entry in matches[:_MAX_RESULTS]:
await bot.reply(message, _format_entry(entry))
lines = [_format_entry(e) for e in matches[:_MAX_RESULTS]]
if len(matches) > _MAX_RESULTS:
await bot.reply(message, f"({len(matches)} total, showing {_MAX_RESULTS})")
lines.append(f"({len(matches)} total, showing {_MAX_RESULTS})")
await bot.long_reply(message, lines, label="exploits")

View File

@@ -153,8 +153,7 @@ async def cmd_subdomain(bot, message):
total = len(sorted_subs)
shown = sorted_subs[:_MAX_RESULTS]
for fqdn, ips in shown:
await bot.reply(message, f" {fqdn} -> {', '.join(ips)}")
lines = [f" {fqdn} -> {', '.join(ips)}" for fqdn, ips in shown]
suffix = f" ({total - _MAX_RESULTS} more)" if total > _MAX_RESULTS else ""
await bot.reply(message, f"{domain}: {total} subdomains found{suffix}")
lines.append(f"{domain}: {total} subdomains found{suffix}")
await bot.long_reply(message, lines, label="subdomains")