본문 바로가기
Computer/Etc

chatgpt와 함께 telegram-bot 개발하기(가계부 봇) 2

by hexists 2023. 7. 5.

 

chatgpt와 함께 telegram-bot 개발하기(가계부 봇) 1

chatgpt와 함께 telegram-bot 개발하기(가계부 봇) 2(현재글)

chatgpt와 함께 telegram-bot 개발하기(가계부 봇) 3


1편에 이어 chatgpt와 함께 telegram-bot을 개발했던 내용을 정리한다.

여기서는 실제 코드를 함께 남겨본다.

 

1. 기능 구상

먼저 필요한 기능은 아주 단순하다.

"한주의 예산을 입력하고, 지출을 입력하면 예산에서 지출을 빼주고 잔액을 알려준다"

여기서 필요한 기능은

 

1. 예산 입력

2. 지출 입력

3. 잔액 확인

 

이렇게 3가지 기능을 생각했다.

 

2. chatgpt에 최대한 자세히 프롬프트를 입력한다.

telegram 봇을 만들거야. 봇은 가계부 봇이야. 봇에서 지원하는 기능은 '예산 등록', '지출 기록', '잔액 확인'이야. 구현하는 코드를 python으로 작성해줘.

(이렇게 정리하다보니 그렇게 자세한 프롬프트는 아닌 것 같다.)

 

chatgpt는 위 프롬프트에 대해 이렇게 답을 했다.

물론이죠! Python을 사용하여 Telegram 가계부 봇을 구현해드릴 수 있습니다. Telegram Bot API를 사용하여 봇을 만들고 SQLite 데이터베이스를 사용하여 예산, 지출 및 잔액 정보를 저장할 수 있습니다. 아래에 코드 예시를 제시하겠습니다.

먼저, 필요한 패키지를 설치해야 합니다. Python `python-telegram-bot` 패키지를 사용하여 Telegram Bot API와 상호 작용할 수 있습니다. SQLite 데이터베이스에 액세스하기 위해 `sqlite3` 패키지를 사용합니다.

```python
import sqlite3
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters

# Telegram Bot API 토큰을 입력하세요.
TOKEN = 'YOUR_TELEGRAM_BOT_TOKEN'

# 데이터베이스 연결 및 커서 생성
conn = sqlite3.connect('expenses.db')
cursor = conn.cursor()

# expenses 테이블 생성
cursor.execute('''CREATE TABLE IF NOT EXISTS expenses
                  (id INTEGER PRIMARY KEY AUTOINCREMENT,
                   amount REAL,
                   category TEXT,
                   description TEXT)''')
conn.commit()

def start(update, context):
    """봇 시작 시 환영 메시지를 보내줍니다."""
    context.bot.send_message(chat_id=update.effective_chat.id, text="가계부 봇입니다. 사용 가능한 명령어: /예산, /지출, /잔액")

def budget(update, context):
    """예산 등록 명령어를 처리합니다."""
    budget_amount = float(context.args[0])
    cursor.execute("INSERT INTO expenses (amount, category, description) VALUES (?, '예산', '예산 등록')",
                   (budget_amount,))
    conn.commit()
    context.bot.send_message(chat_id=update.effective_chat.id, text=f"예산 {budget_amount}이 등록되었습니다.")

def spend(update, context):
    """지출 기록 명령어를 처리합니다."""
    amount = float(context.args[0])
    category = context.args[1]
    description = ' '.join(context.args[2:])
    cursor.execute("INSERT INTO expenses (amount, category, description) VALUES (?, ?, ?)",
                   (amount, category, description))
    conn.commit()
    context.bot.send_message(chat_id=update.effective_chat.id, text=f"지출 {amount}({category})이 기록되었습니다.")

def balance(update, context):
    """잔액 확인 명령어를 처리합니다."""
    cursor.execute("SELECT SUM(amount) FROM expenses")
    total_expenses = cursor.fetchone()[0]
    if total_expenses is None:
        total_expenses = 0
    cursor.execute("SELECT SUM(amount) FROM expenses WHERE category = '예산'")
    total_budget = cursor.fetchone()[0]
    if total_budget is None:
        total_budget = 0
    remaining_budget = total_budget - total_expenses
    context.bot.send_message(chat_id=update.effective_chat.id, text=f"잔액: {remaining_budget}")

def error(update, context):
    """오류 발생 시 메시지를 출력합니다."""
    print(f"오류 발생: {context.error}")

def main():
    """메인 함수"""
    updater = Updater(TOKEN, use_context=True)
   

 dispatcher = updater.dispatcher

    # 명령어 처리기 등록
    dispatcher.add_handler(CommandHandler('start', start))
    dispatcher.add_handler(CommandHandler('예산', budget))
    dispatcher.add_handler(CommandHandler('지출', spend))
    dispatcher.add_handler(CommandHandler('잔액', balance))

    # 오류 처리기 등록
    dispatcher.add_error_handler(error)

    # 봇 시작
    updater.start_polling()
    updater.idle()

if __name__ == '__main__':
    main()
```

위의 코드를 실행하면 Telegram Bot API를 사용하여 가계부 봇을 시작할 수 있습니다. 봇을 시작한 후에는 `/예산`, `/지출`, `/잔액`과 같은 명령어를 사용하여 예산을 등록하고 지출을 기록하며 잔액을 확인할 수 있습니다. 데이터는 SQLite 데이터베이스에 저장되며, `expenses.db`라는 파일에 저장됩니다.

실행하기 전에 코드에서 `YOUR_TELEGRAM_BOT_TOKEN`을 실제로 발급받은 봇의 토큰으로 대체해야 합니다. 봇의 토큰을 얻으려면 Telegram의 BotFather를 통해 봇을 만들고 토큰을 받아야 합니다.

또한, 코드를 실행하기 전에 `python-telegram-bot` 패키지를 설치해야 합니다. 다음과 같이 명령어를 사용하여 패키지를 설치할 수 있습니다.

```
pip install python-telegram-bot
```

이제 위의 코드를 실행하면 Telegram 가계부 봇이 작동하고, 예산 등록, 지출 기록 및 잔액 확인 기능을 사용할 수 있게 됩니다.

 

3. 실제 코드를 작성하고 테스트하기

chatgpt가 알려준 코드를 복사해서 실행했다.

 

일단, chatgpt에서 알려준 코드를 실행전에 botfather에서 newbot을 만들고, token을 발급 받아야 한다.

이 부분은 chatgpt에 물어보기 전에 필요하다는 것을 알고 있어서 미리 검색을 통해 정보를 얻고 token을 발급 받았다.

(https://spica910.tistory.com/172 이 블로그 글의 도움을 받았다.)

 

token을 입력하고 코드를 실행하면 바로 오류가 발생한다.

Traceback (most recent call last):
  File "/Users/daniellee/Develop/telegram_bot/test.py", line 81, in <module>
    main()
  File "/Users/daniellee/Develop/telegram_bot/test.py", line 69, in main
    dispatcher.add_handler(CommandHandler('예산', budget))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/daniellee/Develop/telegram_bot/.venv/lib/python3.11/site-packages/telegram/ext/commandhandler.py", line 163, in __init__
    raise ValueError('Command is not a valid bot command')
ValueError: Command is not a valid bot command

 

검색을 해보니 telegram의 command는 영어만 가능하다고 한다.

command를 영어로 적당히 고치면 잘 실행된다.

 

두번째로 잔액을 조회할 때 0으로 나온다.

코드를 확인해보니 def balance()의 sql에 오류가 있다.

def balance(update, context):
    """잔액 확인 명령어를 처리합니다."""
    cursor.execute("SELECT SUM(amount) FROM expenses")
    total_expenses = cursor.fetchone()[0]
    if total_expenses is None:
        total_expenses = 0
    cursor.execute("SELECT SUM(amount) FROM expenses WHERE category = '예산'")
    total_budget = cursor.fetchone()[0]
    if total_budget is None:
        total_budget = 0
    remaining_budget = total_budget - total_expenses
    context.bot.send_message(chat_id=update.effective_chat.id, text=f"잔액: {remaining_budget}")

위 코드를 보면, total_expenses의 sql에 모든 테이블의 결과를 sum하고, total_budget의 sql에서는 '예산'의 결과만 sum에서 빼준다.

이렇게 하면 total_expenses에 '예산'이 포함되서 결과가 잘못 출력됐다.

total_expenses의 sql 조건문에 category != '예산'을 포함해서 수정한다.

 

이렇게하면 기본 기능 구현은 완료됐다.

 

3편에서 계속 이어간다.