-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtelegram_bot.py
More file actions
166 lines (128 loc) · 5.18 KB
/
telegram_bot.py
File metadata and controls
166 lines (128 loc) · 5.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
"""
텔레그램 봇 모듈
"""
import logging
import os
from telegram import Update, Bot
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
logger = logging.getLogger(__name__)
# 텔레그램 봇 토큰 (환경 변수에서 가져오기)
TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN", "8518155783:AAE8ZUdF2XRwXVt_dYohZFZo1rY52ZS8FgE")
# 전역 봇 인스턴스
_bot_instance: Bot = None
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""봇 시작 명령어"""
await update.message.reply_text(
"안녕하세요! 자동 매매 봇입니다.\n\n"
"사용 가능한 명령어:\n"
"/start - 봇 시작\n"
"/trade - 자동 매매 실행\n"
"/status - 현재 상태 확인"
)
async def trade_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""자동 매매 실행 명령어"""
await update.message.reply_text("자동 매매를 실행합니다...")
# 여기서 FastAPI 엔드포인트를 호출할 수 있습니다
# 예: requests.post("http://localhost:8000/api/trade/auto/ai")
await update.message.reply_text(
"✅ 자동 매매가 완료되었습니다!\n\n"
"결과:\n"
"- 모드: Paper Trade\n"
"- 실제 돈 사용: 없음"
)
async def status_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""상태 확인 명령어"""
await update.message.reply_text(
"🤖 봇 상태: 정상 작동 중\n"
"📊 모드: Paper Trade\n"
"💰 실제 결제: 비활성화"
)
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""일반 메시지 처리"""
await update.message.reply_text(
"명령어를 사용해주세요:\n"
"/start - 시작\n"
"/trade - 자동 매매\n"
"/status - 상태 확인"
)
async def send_message_to_chat(chat_id: int, message: str):
"""
특정 채팅방에 메시지 전송
Args:
chat_id: 텔레그램 채팅 ID
message: 전송할 메시지
"""
global _bot_instance
if not TELEGRAM_BOT_TOKEN:
logger.warning("텔레그램 봇 토큰이 설정되지 않았습니다.")
return False
try:
if _bot_instance is None:
_bot_instance = Bot(token=TELEGRAM_BOT_TOKEN)
await _bot_instance.send_message(chat_id=chat_id, text=message, parse_mode="HTML")
logger.info(f"텔레그램 메시지 전송 완료: chat_id={chat_id}")
return True
except Exception as e:
logger.error(f"텔레그램 메시지 전송 실패: {str(e)}")
return False
def get_bot_instance():
"""봇 인스턴스 가져오기"""
global _bot_instance
if _bot_instance is None and TELEGRAM_BOT_TOKEN:
_bot_instance = Bot(token=TELEGRAM_BOT_TOKEN)
return _bot_instance
def create_bot_application():
"""텔레그램 봇 애플리케이션 생성"""
if not TELEGRAM_BOT_TOKEN:
logger.warning("TELEGRAM_BOT_TOKEN 환경 변수가 설정되지 않았습니다.")
return None
application = Application.builder().token(TELEGRAM_BOT_TOKEN).build()
# 명령어 핸들러 등록
application.add_handler(CommandHandler("start", start))
application.add_handler(CommandHandler("trade", trade_command))
application.add_handler(CommandHandler("status", status_command))
# 일반 메시지 핸들러
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
# 전역 봇 인스턴스 설정
global _bot_instance
_bot_instance = Bot(token=TELEGRAM_BOT_TOKEN)
return application
async def start_bot():
"""봇 시작 (폴링 방식)"""
application = create_bot_application()
if application:
logger.info("텔레그램 봇 시작 중...")
await application.initialize()
await application.start()
await application.updater.start_polling()
logger.info("텔레그램 봇이 실행 중입니다.")
return application
return None
async def stop_bot(application):
"""봇 종료"""
if application:
logger.info("텔레그램 봇 종료 중...")
await application.updater.stop()
await application.stop()
await application.shutdown()
logger.info("텔레그램 봇이 종료되었습니다.")
async def run_bot():
"""봇 실행 (별도 프로세스용)"""
application = await start_bot()
if application:
try:
# 봇이 계속 실행되도록 대기
import signal
import asyncio
def signal_handler(signum, frame):
logger.info("시그널 수신 - 봇 종료 중...")
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
# 무한 대기 (Ctrl+C 또는 SIGTERM까지)
while True:
await asyncio.sleep(1)
except KeyboardInterrupt:
logger.info("키보드 인터럽트 - 봇 종료 중...")
finally:
if application:
await stop_bot(application)