├── Dockerfile
├── Makefile
├── README.md
├── docker-compose.yml
├── main.py
└── requirements.txt
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.8-buster
2 |
3 | RUN apt-get update
4 |
5 | COPY requirements.txt /requirements.txt
6 | COPY main.py /main.py
7 |
8 | RUN apt-get clean
9 |
10 | RUN pip install --upgrade pip
11 |
12 | RUN pip install -r requirements.txt
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | do1:
2 | apt-get update
3 |
4 | apt-get install -y docker.io
5 |
6 | apt-get install curl git bzip2 -y
7 |
8 | curl https://pyenv.run | bash
9 | do2:
10 | pyenv install miniconda3-3.9-4.12.0
11 |
12 | pyenv global miniconda3-3.9-4.12.0
13 |
14 | pip install docker-compose
15 | dcup:
16 | docker-compose up -d --build
17 | dcdown:
18 | docker-compose down
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Python-ChatGPT-TelegramBot-Docker
2 | # 一個Python ChatGPT TelegramBot快速建置平台。
3 |
4 |
5 | ### [English](https://github.com/pyfbsdk59/Python-ChatGPT-TelegramBot-Docker/blob/main/README_en.md)
6 | ### [日本語](https://github.com/pyfbsdk59/Python-ChatGPT-TelegramBot-Docker/blob/main/README_jp.md)
7 |
8 |
9 | #### 1. 初次上傳專案到github,請多包涵。初版沒有設置另外的.env檔案和環境變數。之後會改正。
10 |
11 |
12 | #### 2. 本專案參考了以下前輩的方案改成製作,只針對剛學習Python或Docker的朋友來佈置TelegramBot在VPS上:
13 |
14 | https://github.com/howarder3/GPT-Linebot-python-flask-on-vercel
15 | https://github.com/n3d1117/chatgpt-telegram-bot
16 |
17 | #### 3. 可使用任何VPS建制,例如DigitalOcean, Linode或是vultr。 用ssh連入主機,輸入帳密後,
18 |
19 | ---
20 | # 環境建制(先建制了Makefile)
21 |
22 | ### Step 1: 輸入以下指令(建制docker和pyenv環境)
23 |
24 | make do1
25 |
26 |
27 | ### Step 2: 輸入以下多行的指令。一個一個複製貼上輸入。(一共有7個指令)
28 |
29 | echo 'export LC_ALL=C.UTF-8' >> ~/.bashrc
30 |
31 | echo 'export LANG=C.UTF-8' >> ~/.bashrc
32 |
33 | echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
34 |
35 | echo 'export PATH="$PYENV_ROOT/shims:$PATH"' >> ~/.bashrc
36 |
37 | echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
38 |
39 | echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bashrc
40 |
41 | exec $SHELL
42 |
43 |
44 | ### Step 3: 輸入以下指令 (建制python環境且安裝docker-compose)
45 |
46 | make do2
47 |
48 |
49 | ### Step 4: 輸入 cd ~ ,到主目錄,輸入以下指令下載本專案。
50 |
51 | git clone https://github.com/pyfbsdk59/Python-ChatGPT-TelegramBot-Docker.git
52 |
53 |
54 | ### Step 5: 輸入以下指令進入本專案目錄(已建制Makefile)。
55 |
56 | cd Python-ChatGPT-TelegramBot-Docker
57 |
58 |
59 | ### Step 6a: 輸入以下指令,開始建制本專案的容器,完成後會有1個container(記得先用nano指令修改main.py的OEPNAI api key的部分,還有加入自己的TelegramBot token和自己的TG帳號的id。)
60 |
61 | make dcup
62 |
63 | ### Step 6b: 也可以不用設置Docker就直接執行,請輸入以下指令,但要先有Python環境。
64 |
65 | python main.py &
66 |
67 | ------
68 | ### 創建Telegram機器人和取得token,請參考:
69 | https://ithelp.ithome.com.tw/articles/10245264
70 | https://tcsky.cc/tips-01-telegram-chatbot/
71 |
72 | ### 取得自己的Telegram user id,加入機器人,取得。請參考:
73 | https://telegram.me/getidsbot
74 | https://blog.csdn.net/qq_40394269/article/details/124832889
75 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 |
4 | services:
5 | pyChatGPT_TGbot:
6 | build: ./
7 | volumes:
8 | - ./app:/app
9 |
10 |
11 | command: python main.py &
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import os
3 |
4 |
5 | import telegram.constants
6 | from telegram import Update
7 | from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, MessageHandler, filters
8 | import openai
9 |
10 | openai.api_key = "" #加入你的OPENAI的api key #Please add your OPENAI api key between "".
11 |
12 |
13 | chat_language = "zh" #os.getenv("INIT_LANGUAGE", default = "zh")
14 |
15 | MSG_LIST_LIMIT = 20 #int(os.getenv("MSG_LIST_LIMIT", default = 20))
16 | LANGUAGE_TABLE = {
17 | "zh": "哈囉!",
18 | "en": "Hello!"
19 | }
20 |
21 |
22 | class Prompts:
23 | def __init__(self):
24 | self.msg_list = []
25 | self.msg_list.append(f"AI:{LANGUAGE_TABLE[chat_language]}")
26 |
27 | def add_msg(self, new_msg):
28 | if len(self.msg_list) >= MSG_LIST_LIMIT:
29 | self.remove_msg()
30 | self.msg_list.append(new_msg)
31 |
32 | def remove_msg(self):
33 | self.msg_list.pop(0)
34 |
35 | def generate_prompt(self):
36 | return '\n'.join(self.msg_list)
37 |
38 | class ChatGPT:
39 | def __init__(self):
40 | self.prompt = Prompts()
41 | self.model = "text-davinci-003" #os.getenv("OPENAI_MODEL", default = "text-davinci-003")
42 | self.temperature = 0.9 #float(os.getenv("OPENAI_TEMPERATURE", default = 0))
43 | self.frequency_penalty = 0 #float(os.getenv("OPENAI_FREQUENCY_PENALTY", default = 0))
44 | self.presence_penalty = 0.6 #float(os.getenv("OPENAI_PRESENCE_PENALTY", default = 0.6))
45 | self.max_tokens = 240 #int(os.getenv("OPENAI_MAX_TOKENS", default = 240))
46 |
47 | def get_response(self):
48 | response = openai.Completion.create(
49 | model=self.model,
50 | prompt=self.prompt.generate_prompt(),
51 | temperature=self.temperature,
52 | frequency_penalty=self.frequency_penalty,
53 | presence_penalty=self.presence_penalty,
54 | max_tokens=self.max_tokens
55 | )
56 |
57 | print("AI回答內容:")
58 | print(response['choices'][0]['text'].strip())
59 |
60 | print("AI原始回覆資料內容:")
61 | print(response)
62 |
63 | return response['choices'][0]['text'].strip()
64 |
65 | def add_msg(self, text):
66 | self.prompt.add_msg(text)
67 |
68 |
69 | class ChatGPT3TelegramBot:
70 |
71 | def __init__(self):
72 | self.chatgpt = ChatGPT()
73 |
74 | # Help menu
75 | async def help(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
76 | await update.message.reply_text("/start - Start the bot\n/reset - Reset conversation\n/help - Help menu")
77 |
78 | # Start the bot
79 | async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
80 | if not self.is_allowed(update):
81 | logging.info(f'User {update.message.from_user.name} is not allowed to start the bot')
82 | return
83 |
84 | logging.info('Bot started')
85 | await context.bot.send_message(chat_id=update.effective_chat.id, text="I'm a Chat-GPT3 Bot, please talk to me!")
86 |
87 | # Reset the conversation
88 | async def reset(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
89 | if not self.is_allowed(update):
90 | logging.info(f'User {update.message.from_user.name} is not allowed to reset the bot')
91 | return
92 |
93 | logging.info('Resetting the conversation...')
94 | #
95 | await context.bot.send_message(chat_id=update.effective_chat.id, text="Done!")
96 |
97 | # Refresh session
98 | async def refresh(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
99 | if not self.is_allowed(update):
100 | logging.info(f'User {update.message.from_user.name} is not allowed to refresh the session')
101 | return
102 |
103 | logging.info('Refreshing session...')
104 | #
105 | await context.bot.send_message(chat_id=update.effective_chat.id, text="Done!")
106 |
107 |
108 |
109 | # React to messages
110 | async def prompt(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
111 | if not self.is_allowed(update):
112 | logging.info(f'User {update.message.from_user.name} is not allowed to use the bot')
113 | return
114 |
115 | logging.info(f'New message received from user {update.message.from_user.name}')
116 | await context.bot.send_chat_action(chat_id=update.effective_chat.id, action=telegram.constants.ChatAction.TYPING)
117 |
118 | ai_reply_response = self.get_chatgpt_response(update.message.text)
119 |
120 |
121 | await context.bot.send_message(
122 | chat_id=update.effective_chat.id,
123 | reply_to_message_id=update.message.message_id,
124 | text= ai_reply_response, #AI回答的內容
125 | #text=response["message"], #原始程式
126 | parse_mode=telegram.constants.ParseMode.MARKDOWN
127 | )
128 |
129 | def get_chatgpt_response(self, user_message) -> dict:
130 | try:
131 |
132 | #user_message #接收人類問題的字詞變數
133 | self.chatgpt.prompt.add_msg(f"HUMAN:{user_message}?\n")
134 | response = self.chatgpt.get_response() #ChatGPT產生的回答
135 |
136 | print("AI回答內容2:")
137 | print(response)
138 |
139 | return response
140 |
141 | except ValueError as e:
142 | logging.info(f'Error: {e}')
143 | return {"message": "I'm having some trouble talking to you, please try again later."}
144 |
145 | async def error_handler(self, update: object, context: ContextTypes.DEFAULT_TYPE) -> None:
146 | logging.debug(f'Exception while handling an update: {context.error}')
147 |
148 | def is_allowed(self, update: Update) -> bool:
149 |
150 | allowed_chats= "" #引號中填入允許通話的Telegram id #Please add your Telegram id between "".
151 |
152 | return str(update.message.from_user.id) in allowed_chats #self.config['allowed_chats']
153 |
154 | def run(self):
155 | #以下引號中填入你的TGBot的token #Please add your TelegramBot token between "" below.
156 | application = ApplicationBuilder().token("").build()
157 |
158 | application.add_handler(CommandHandler('start', self.start))
159 | application.add_handler(CommandHandler('reset', self.reset))
160 | application.add_handler(CommandHandler('help', self.help))
161 | application.add_handler(CommandHandler('refresh', self.refresh))
162 | application.add_handler(MessageHandler(filters.TEXT & (~filters.COMMAND), self.prompt))
163 |
164 | application.add_error_handler(self.error_handler)
165 |
166 | application.run_polling()
167 | #####################################################################
168 |
169 | def main():
170 | logging.basicConfig(
171 | format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
172 | level=logging.INFO
173 | )
174 |
175 | telegram_bot = ChatGPT3TelegramBot()
176 |
177 |
178 | telegram_bot.run()
179 |
180 |
181 |
182 | if __name__ == '__main__':
183 | main()
184 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | python-telegram-bot==20.0a6
2 | openai
3 |
4 |
5 |
--------------------------------------------------------------------------------