Korean ISPs use SNI-based DPI (not DNS hijacking) to block sites. TCP DNS queries to ISP servers from Cloudflare Workers returned real IPs even for blocked domains. Now uses Globalping eyeball probes (KT, LG U+) to detect ECONNRESET on HTTPS — the signature of SNI-based blocking. Verified: pornhub.com correctly detected as blocked by Korea Telecom. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
537 lines
12 KiB
TypeScript
537 lines
12 KiB
TypeScript
// ============================================
|
|
// Environment
|
|
// ============================================
|
|
|
|
export interface Env {
|
|
DB: D1Database;
|
|
AI: Ai;
|
|
BOT_TOKEN: string;
|
|
WEBHOOK_SECRET: string;
|
|
OPENAI_API_KEY?: string;
|
|
ADMIN_TELEGRAM_IDS?: string;
|
|
ENVIRONMENT?: string;
|
|
// Financial
|
|
DEPOSIT_BANK_NAME?: string;
|
|
DEPOSIT_BANK_ACCOUNT?: string;
|
|
DEPOSIT_BANK_HOLDER?: string;
|
|
// API URLs
|
|
OPENAI_API_BASE?: string;
|
|
NAMECHEAP_API_URL?: string;
|
|
WHOIS_API_URL?: string;
|
|
CLOUD_ORCHESTRATOR_URL?: string;
|
|
CLOUD_ORCHESTRATOR?: Fetcher;
|
|
// Kroki
|
|
KROKI_URL?: string;
|
|
// Queues
|
|
WORK_QUEUE?: Queue;
|
|
// KV Namespaces
|
|
RATE_LIMIT_KV: KVNamespace;
|
|
SESSION_KV: KVNamespace;
|
|
CACHE_KV: KVNamespace;
|
|
// R2
|
|
R2_BUCKET: R2Bucket;
|
|
// Vectorize
|
|
VECTORIZE?: VectorizeIndex;
|
|
}
|
|
|
|
// ============================================
|
|
// Telegram Types
|
|
// ============================================
|
|
|
|
export interface TelegramUpdate {
|
|
update_id: number;
|
|
message?: TelegramMessage;
|
|
callback_query?: CallbackQuery;
|
|
}
|
|
|
|
export interface CallbackQuery {
|
|
id: string;
|
|
from: TelegramUser;
|
|
message?: TelegramMessage;
|
|
chat_instance: string;
|
|
data?: string;
|
|
}
|
|
|
|
export interface TelegramMessage {
|
|
message_id: number;
|
|
from: TelegramUser;
|
|
chat: TelegramChat;
|
|
date: number;
|
|
text?: string;
|
|
}
|
|
|
|
export interface TelegramUser {
|
|
id: number;
|
|
is_bot: boolean;
|
|
first_name: string;
|
|
last_name?: string;
|
|
username?: string;
|
|
language_code?: string;
|
|
}
|
|
|
|
export interface TelegramChat {
|
|
id: number;
|
|
type: string;
|
|
}
|
|
|
|
// ============================================
|
|
// OpenAI Types (Function Calling)
|
|
// ============================================
|
|
|
|
export interface OpenAIToolCall {
|
|
id: string;
|
|
type: 'function';
|
|
function: {
|
|
name: string;
|
|
arguments: string;
|
|
};
|
|
}
|
|
|
|
export interface OpenAIMessage {
|
|
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
content: string | null;
|
|
tool_calls?: OpenAIToolCall[];
|
|
tool_call_id?: string;
|
|
name?: string;
|
|
}
|
|
|
|
export interface OpenAIChoice {
|
|
message: OpenAIMessage;
|
|
finish_reason: string;
|
|
}
|
|
|
|
export interface OpenAIAPIResponse {
|
|
choices: OpenAIChoice[];
|
|
}
|
|
|
|
export interface ToolDefinition {
|
|
type: 'function';
|
|
function: {
|
|
name: string;
|
|
description: string;
|
|
parameters: {
|
|
type: 'object';
|
|
properties: Record<string, unknown>;
|
|
required?: string[];
|
|
};
|
|
};
|
|
}
|
|
|
|
// ============================================
|
|
// Workers AI Types (Fallback)
|
|
// ============================================
|
|
|
|
export type WorkersAIModel =
|
|
| "@cf/meta/llama-3.1-8b-instruct"
|
|
| "@cf/meta/llama-3.2-3b-instruct";
|
|
|
|
export interface WorkersAIMessage {
|
|
role: "system" | "user" | "assistant";
|
|
content: string;
|
|
}
|
|
|
|
// ============================================
|
|
// User & Auth Types
|
|
// ============================================
|
|
|
|
export type UserRole = 'admin' | 'user';
|
|
|
|
export interface User {
|
|
id: number;
|
|
telegram_id: string;
|
|
username: string | null;
|
|
first_name: string | null;
|
|
role: UserRole;
|
|
language_code: string;
|
|
context_limit: number;
|
|
last_active_at: string | null;
|
|
is_blocked: number;
|
|
blocked_reason: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
// ============================================
|
|
// Financial Types
|
|
// ============================================
|
|
|
|
export interface Wallet {
|
|
id: number;
|
|
user_id: number;
|
|
balance: number;
|
|
currency: string;
|
|
version: number;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
export type TransactionType = 'deposit' | 'withdrawal' | 'refund' | 'charge';
|
|
export type TransactionStatus = 'pending' | 'confirmed' | 'rejected' | 'cancelled';
|
|
|
|
export interface Transaction {
|
|
id: number;
|
|
user_id: number;
|
|
type: TransactionType;
|
|
amount: number;
|
|
status: TransactionStatus;
|
|
depositor_name: string | null;
|
|
depositor_name_prefix: string | null;
|
|
description: string | null;
|
|
reference_type: string | null;
|
|
reference_id: number | null;
|
|
confirmed_by: number | null;
|
|
confirmed_at: string | null;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface BankNotification {
|
|
bankName: string;
|
|
depositorName: string;
|
|
amount: number;
|
|
balanceAfter?: number;
|
|
transactionTime?: Date;
|
|
rawMessage: string;
|
|
}
|
|
|
|
// ============================================
|
|
// Asset Types
|
|
// ============================================
|
|
|
|
export type DomainStatus = 'active' | 'expired' | 'pending' | 'suspended';
|
|
|
|
export interface Domain {
|
|
id: number;
|
|
user_id: number;
|
|
domain: string;
|
|
status: DomainStatus;
|
|
registrar: string | null;
|
|
nameservers: string | null;
|
|
auto_renew: number;
|
|
expiry_date: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
export type ServerStatus = 'pending' | 'provisioning' | 'running' | 'stopped' | 'terminated' | 'failed';
|
|
|
|
export interface Server {
|
|
id: number;
|
|
user_id: number;
|
|
provider: string;
|
|
instance_id: string | null;
|
|
label: string | null;
|
|
ip_address: string | null;
|
|
region: string | null;
|
|
spec_label: string | null;
|
|
monthly_price: number | null;
|
|
status: ServerStatus;
|
|
image: string | null;
|
|
provisioned_at: string | null;
|
|
terminated_at: string | null;
|
|
expires_at: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
export interface DdosService {
|
|
id: number;
|
|
user_id: number;
|
|
target: string;
|
|
protection_level: 'basic' | 'standard' | 'premium';
|
|
status: 'active' | 'inactive' | 'suspended';
|
|
provider: string | null;
|
|
monthly_price: number | null;
|
|
expiry_date: string | null;
|
|
}
|
|
|
|
export interface VpnService {
|
|
id: number;
|
|
user_id: number;
|
|
protocol: 'wireguard' | 'openvpn' | 'ipsec';
|
|
status: 'active' | 'inactive' | 'suspended';
|
|
endpoint: string | null;
|
|
monthly_price: number | null;
|
|
expiry_date: string | null;
|
|
}
|
|
|
|
// ============================================
|
|
// Support Types
|
|
// ============================================
|
|
|
|
export interface Feedback {
|
|
id: number;
|
|
user_id: number;
|
|
session_type: string;
|
|
rating: number;
|
|
comment: string | null;
|
|
created_at: string;
|
|
}
|
|
|
|
export type PendingActionStatus = 'pending' | 'approved' | 'rejected' | 'executed' | 'failed';
|
|
|
|
export interface PendingAction {
|
|
id: number;
|
|
user_id: number;
|
|
action_type: string;
|
|
target: string;
|
|
params: string;
|
|
status: PendingActionStatus;
|
|
approved_by: number | null;
|
|
created_at: string;
|
|
executed_at: string | null;
|
|
}
|
|
|
|
export interface AuditLog {
|
|
id: number;
|
|
actor_id: number | null;
|
|
action: string;
|
|
resource_type: string;
|
|
resource_id: string | null;
|
|
details: string | null;
|
|
result: 'success' | 'failure';
|
|
request_id: string | null;
|
|
created_at: string;
|
|
}
|
|
|
|
export interface KnowledgeArticle {
|
|
id: number;
|
|
category: string;
|
|
title: string;
|
|
content: string;
|
|
tags: string | null;
|
|
language: string;
|
|
is_active: number;
|
|
embedding_indexed: number;
|
|
embedding_indexed_at: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
// ============================================
|
|
// Agent Session Types
|
|
// ============================================
|
|
|
|
export type OnboardingSessionStatus = 'greeting' | 'gathering' | 'suggesting' | 'completed';
|
|
|
|
export interface OnboardingSession {
|
|
user_id: string;
|
|
status: OnboardingSessionStatus;
|
|
collected_info: {
|
|
purpose?: string;
|
|
requirements?: string;
|
|
budget?: string;
|
|
tech_stack?: string[];
|
|
};
|
|
messages: Array<{ role: 'user' | 'assistant'; content: string }>;
|
|
created_at: number;
|
|
updated_at: number;
|
|
expires_at: number;
|
|
}
|
|
|
|
export type TroubleshootSessionStatus = 'gathering' | 'diagnosing' | 'suggesting' | 'escalated' | 'completed';
|
|
|
|
export interface TroubleshootSession {
|
|
user_id: string;
|
|
status: TroubleshootSessionStatus;
|
|
collected_info: {
|
|
category?: string;
|
|
symptoms?: string;
|
|
environment?: string;
|
|
errorMessage?: string;
|
|
affected_service?: string;
|
|
};
|
|
messages: Array<{ role: 'user' | 'assistant'; content: string }>;
|
|
escalation_count: number;
|
|
created_at: number;
|
|
updated_at: number;
|
|
expires_at: number;
|
|
}
|
|
|
|
export type AssetSessionStatus = 'idle' | 'viewing' | 'managing' | 'completed';
|
|
|
|
export interface AssetSession {
|
|
user_id: string;
|
|
status: AssetSessionStatus;
|
|
collected_info: Record<string, unknown>;
|
|
messages: Array<{ role: 'user' | 'assistant'; content: string }>;
|
|
created_at: number;
|
|
updated_at: number;
|
|
expires_at: number;
|
|
}
|
|
|
|
export type BillingSessionStatus = 'collecting_amount' | 'collecting_name' | 'confirming' | 'completed';
|
|
|
|
export interface BillingSession {
|
|
user_id: string;
|
|
status: BillingSessionStatus;
|
|
collected_info: {
|
|
amount?: number;
|
|
depositor_name?: string;
|
|
};
|
|
messages: Array<{ role: 'user' | 'assistant'; content: string }>;
|
|
created_at: number;
|
|
updated_at: number;
|
|
expires_at: number;
|
|
}
|
|
|
|
// ============================================
|
|
// Tool Argument Types
|
|
// ============================================
|
|
|
|
export interface ManageDomainArgs {
|
|
action: 'check' | 'whois' | 'list' | 'info' | 'set_ns' | 'price';
|
|
domain?: string;
|
|
nameservers?: string[];
|
|
tld?: string;
|
|
}
|
|
|
|
export interface ManageWalletArgs {
|
|
action: 'balance' | 'account' | 'request' | 'history' | 'cancel';
|
|
depositor_name?: string;
|
|
amount?: number;
|
|
transaction_id?: number;
|
|
limit?: number;
|
|
}
|
|
|
|
export interface ManageServerArgs {
|
|
action: 'list' | 'info' | 'start' | 'stop' | 'reboot';
|
|
server_id?: number;
|
|
}
|
|
|
|
export interface CheckServiceArgs {
|
|
action: 'status' | 'list';
|
|
service_type?: 'ddos' | 'vpn' | 'all';
|
|
service_id?: number;
|
|
}
|
|
|
|
|
|
export interface AdminArgs {
|
|
action: 'block_user' | 'unblock_user' | 'set_role' | 'broadcast' | 'confirm_deposit' | 'reject_deposit' | 'list_pending';
|
|
target_user_id?: string;
|
|
role?: UserRole;
|
|
message?: string;
|
|
transaction_id?: number;
|
|
reason?: string;
|
|
}
|
|
|
|
export interface ApproveActionArgs {
|
|
action_id: number;
|
|
approve: boolean;
|
|
reason?: string;
|
|
}
|
|
|
|
// ============================================
|
|
// Network Diagnostic Types
|
|
// ============================================
|
|
|
|
export interface DnsRecord {
|
|
type: string;
|
|
value: string;
|
|
ttl?: number;
|
|
}
|
|
|
|
export interface DnsResolverResult {
|
|
resolver: string;
|
|
ip: string;
|
|
records: DnsRecord[];
|
|
responseTimeMs: number;
|
|
error?: string;
|
|
}
|
|
|
|
export interface IspDnsBlockResult {
|
|
isp: string;
|
|
serverIp: string;
|
|
resolvedIps: string[];
|
|
blocked: boolean;
|
|
blockReason?: string;
|
|
responseTimeMs: number;
|
|
error?: string;
|
|
}
|
|
|
|
export interface HttpCheckResult {
|
|
url: string;
|
|
statusCode?: number;
|
|
responseTimeMs: number;
|
|
redirectUrl?: string;
|
|
error?: string;
|
|
}
|
|
|
|
export interface TcpCheckResult {
|
|
host: string;
|
|
port: number;
|
|
connected: boolean;
|
|
responseTimeMs: number;
|
|
error?: string;
|
|
}
|
|
|
|
export interface GlobalpingProbeResult {
|
|
city: string;
|
|
network: string;
|
|
asn: number;
|
|
isEyeball?: boolean;
|
|
blocked?: boolean;
|
|
blockReason?: string;
|
|
ping?: {
|
|
min: number;
|
|
avg: number;
|
|
max: number;
|
|
loss: number;
|
|
};
|
|
http?: {
|
|
statusCode: number;
|
|
totalMs: number;
|
|
dnsMs: number;
|
|
tcpMs: number;
|
|
tlsMs: number;
|
|
firstByteMs: number;
|
|
};
|
|
error?: string;
|
|
}
|
|
|
|
export interface NetworkDiagnosticReport {
|
|
domain: string;
|
|
timestamp: string;
|
|
dns: DnsResolverResult[];
|
|
http: HttpCheckResult[];
|
|
tcp: TcpCheckResult[];
|
|
koreaProbes: GlobalpingProbeResult[];
|
|
summary: string[];
|
|
}
|
|
|
|
// ============================================
|
|
// Inline Keyboard Data
|
|
// ============================================
|
|
|
|
export interface FeedbackKeyboardData {
|
|
type: 'feedback';
|
|
session_type: string;
|
|
rating: number;
|
|
}
|
|
|
|
export interface ActionApprovalKeyboardData {
|
|
type: 'action_approval';
|
|
action_id: number;
|
|
approve: boolean;
|
|
}
|
|
|
|
export interface EscalationKeyboardData {
|
|
type: 'escalation';
|
|
session_id: string;
|
|
action: 'accept' | 'reject';
|
|
}
|
|
|
|
export type KeyboardCallbackData =
|
|
| FeedbackKeyboardData
|
|
| ActionApprovalKeyboardData
|
|
| EscalationKeyboardData;
|
|
|
|
// ============================================
|
|
// Request Context
|
|
// ============================================
|
|
|
|
export interface RequestContext {
|
|
requestId: string;
|
|
userId?: string;
|
|
startTime: number;
|
|
}
|