python3.7

import logging
import boto3
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ApplicationBuilder, CommandHandler, CallbackQueryHandler, MessageHandler, filters, ContextTypes

# 初始化 Boto3 Route 53 客户端
route53_client = boto3.client('route53')

# 日志配置
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

# 设定操作密码
PASSWORD = "793653"  # 密码设置

# 全局变量,用于保存当前操作和参数
current_action = None
action_args = None

# 创建 DNS 记录
async def create_record(update: Update, context: ContextTypes.DEFAULT_TYPE):
    global action_args
    if action_args is None or len(action_args) < 4:
        await update.message.reply_text("创建记录时出错: 参数不足。请使用以下格式:\n/create <zone_id> <record_name> <record_type> <record_value>")
        return
    
    try:
        zone_id = action_args[0]
        record_name = action_args[1]
        record_type = action_args[2]
        record_value = action_args[3]

        response = route53_client.change_resource_record_sets(
            HostedZoneId=zone_id,
            ChangeBatch={
                'Comment': f'创建 {record_type} 记录',
                'Changes': [
                    {
                        'Action': 'UPSERT',
                        'ResourceRecordSet': {
                            'Name': record_name,
                            'Type': record_type,
                            'TTL': 300,
                            'ResourceRecords': [{'Value': value.strip()} for value in record_value.split(',')]
                        }
                    }
                ]
            }
        )
        await update.message.reply_text(f"{record_type} 记录已创建: {record_name} -> {record_value}")
    except Exception as e:
        await update.message.reply_text(f"创建记录时出错: {str(e)}")

# 删除 DNS 记录
async def delete_record(update: Update, context: ContextTypes.DEFAULT_TYPE):
    global action_args
    if action_args is None or len(action_args) < 4:
        await update.message.reply_text("删除记录时出错: 参数不足。请使用以下格式:\n/delete <zone_id> <record_name> <record_type> <record_value>")
        return
    
    try:
        zone_id = action_args[0]
        record_name = action_args[1]
        record_type = action_args[2]
        record_value = action_args[3]

        response = route53_client.list_resource_record_sets(
            HostedZoneId=zone_id,
            StartRecordName=record_name,
            StartRecordType=record_type,
            MaxItems="1"
        )

        if 'ResourceRecordSets' in response and response['ResourceRecordSets']:
            record_set = response['ResourceRecordSets'][0]
            if record_set['Name'] == record_name + '.' and record_set['Type'] == record_type:
                route53_client.change_resource_record_sets(
                    HostedZoneId=zone_id,
                    ChangeBatch={
                        'Comment': f'删除 {record_type} 记录',
                        'Changes': [
                            {
                                'Action': 'DELETE',
                                'ResourceRecordSet': {
                                    'Name': record_name,
                                    'Type': record_type,
                                    'TTL': record_set['TTL'],
                                    'ResourceRecords': [{'Value': record_value}]
                                }
                            }
                        ]
                    }
                )
                await update.message.reply_text(f"{record_type} 记录 {record_name} -> {record_value} 已删除")
            else:
                await update.message.reply_text(f"未找到匹配的 {record_type} 记录")
        else:
            await update.message.reply_text(f"未找到 {record_type} 记录 {record_name}")
    except Exception as e:
        await update.message.reply_text(f"删除记录时出错: {str(e)}")

# 密码验证函数
async def request_password(update: Update, context: ContextTypes.DEFAULT_TYPE):
    global current_action
    await update.message.reply_text("请输入密码:")
    return

async def verify_password(update: Update, context: ContextTypes.DEFAULT_TYPE):
    global current_action, action_args
    user_password = update.message.text
    if user_password == PASSWORD:
        # 删除用户输入的密码消息
        await update.message.delete()
        await update.message.reply_text("密码正确,继续操作。")

        # 执行当前操作
        if current_action == 'list_hosted_zones':
            await list_hosted_zones(update, context)
        elif current_action == 'filter_hosted_zones':
            await update.message.reply_text('请使用命令 /filter 关键字 来筛选托管域')
        elif current_action == 'create_record':
            await create_record(update, context)
        elif current_action == 'delete_record':
            await delete_record(update, context)
        current_action = None  # 重置当前操作
        action_args = None  # 清空保存的参数
    else:
        await update.message.reply_text("密码错误,请重新输入。")

# 处理创建 DNS 记录的命令
async def handle_create(update: Update, context: ContextTypes.DEFAULT_TYPE):
    global current_action, action_args
    if len(context.args) < 4:
        await update.message.reply_text("请使用以下格式创建记录:\n/create <zone_id> <record_name> <record_type> <record_value>")
        return
    # 保存操作和参数
    current_action = 'create_record'
    action_args = context.args  # 保存用户输入的参数
    await request_password(update, context)  # 请求密码验证

# 处理删除 DNS 记录的命令
async def handle_delete(update: Update, context: ContextTypes.DEFAULT_TYPE):
    global current_action, action_args
    if len(context.args) < 4:
        await update.message.reply_text("请使用以下格式删除记录:\n/delete <zone_id> <record_name> <record_type> <record_value>")
        return
    # 保存操作和参数
    current_action = 'delete_record'
    action_args = context.args  # 保存用户输入的参数
    await request_password(update, context)  # 请求密码验证

# 创建主菜单
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    keyboard = [
        [
            InlineKeyboardButton("列出托管域", callback_data='list_hosted_zones'),
            InlineKeyboardButton("筛选托管域", callback_data='filter_hosted_zones'),
        ],
        [
            InlineKeyboardButton("创建 DNS 记录", callback_data='create_record'),
            InlineKeyboardButton("删除 DNS 记录", callback_data='delete_record')
        ]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    await update.message.reply_text('选择操作:', reply_markup=reply_markup)

# 列出所有托管区域
async def list_hosted_zones(update: Update, context: ContextTypes.DEFAULT_TYPE):
    try:
        response = route53_client.list_hosted_zones()
        hosted_zones = "\n".join([f"ID: {zone['Id']}, 域名: {zone['Name']}" for zone in response['HostedZones']])
        await update.message.reply_text(f"托管的域列表:\n{hosted_zones}")
    except Exception as e:
        await update.message.reply_text(f"列出托管域时出错: {str(e)}")

# 处理用户选择
async def button(update: Update, context: ContextTypes.DEFAULT_TYPE):
    global current_action
    query = update.callback_query
    await query.answer()

    current_action = query.data  # 记录当前操作
    # 请求密码
    await query.message.reply_text('请输入密码:')

# 错误处理
def error(update, context):
    logger.warning(f'Update "{update}" caused error "{context.error}"')

if __name__ == '__main__':
    # 使用从 BotFather 获取的 Token 初始化 Bot
    token = "7539903054:AAEwC6_dMwXbM-oXlMJrif7jhc1mLUB3ZjA"
    
    application = ApplicationBuilder().token(token).build()

    # 添加处理命令
    application.add_handler(CommandHandler('start', start))
    application.add_handler(CallbackQueryHandler(button))
    application.add_handler(CommandHandler('create', handle_create))  # 处理 /create 命令
    application.add_handler(CommandHandler('delete', handle_delete))  # 处理 /delete 命令
    application.add_handler(MessageHandler(filters.TEXT, verify_password))

    # 启动 Bot
    application.run_polling()