forked from aviaryan/voice-transcribe-summarize-telegram-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbot.py
165 lines (138 loc) · 6.47 KB
/
bot.py
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 os
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
from groq import Groq
import tempfile
from dotenv import load_dotenv
load_dotenv()
# List of authorized user IDs
AUTHORIZED_USERS = [95165304] # Add more user IDs as needed
# Initialize Groq client
groq_client = Groq(api_key=os.getenv("GROQ_API_KEY"))
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Send a message when the command /start is issued."""
print(f"Received start command from user: {update.effective_user.id}")
user_name = update.effective_user.first_name
try:
await update.message.reply_text(
f"👋 Hi {user_name}! I'm a Voice Note Summarizer Bot.\n\n"
"You can:\n"
"1. Forward me voice messages\n"
"2. Send me direct voice recordings\n\n"
"I'll transcribe them and provide you with both the transcription and a summary!"
)
print(f"Sent welcome message to user: {update.effective_user.id}")
except Exception as e:
print(f"Error in start handler: {str(e)}")
async def handle_voice(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle voice messages and voice notes."""
try:
# Check user authorization
if update.effective_user.id not in AUTHORIZED_USERS:
await update.message.reply_text("⛔ Sorry, you are not authorized to use this bot. Contact @aviaryan.")
return
# Send initial status
status_message = await update.message.reply_text("🎵 Processing your voice note...")
# Get voice file
voice_file = await update.message.voice.get_file()
# Download the voice file to a temporary location
with tempfile.NamedTemporaryFile(suffix='.ogg', delete=False) as temp_file:
await voice_file.download_to_drive(temp_file.name)
temp_path = temp_file.name
# Transcribe using Whisper via Groq
transcription = await transcribe_audio(temp_path)
# Generate summary using LLama 3 via Groq
summary = await generate_summary(transcription)
# Split and send transcription if it's too long
if len(transcription) > 3000: # Leave room for summary and formatting
await status_message.edit_text("📝 *Transcription (Part 1):*", parse_mode='Markdown')
# Split transcription into chunks of 4000 characters
chunk_size = 4000
transcription_chunks = [transcription[i:i + chunk_size]
for i in range(0, len(transcription), chunk_size)]
# Send transcription chunks
for i, chunk in enumerate(transcription_chunks, 1):
await update.message.reply_text(
f"*Transcription (Part {i}):*\n{chunk}",
parse_mode='Markdown'
)
# Send summary separately
await update.message.reply_text(
"📌 *Summary:*\n"
f"{summary}",
parse_mode='Markdown'
)
else:
# Send everything in one message if it's short enough
await status_message.edit_text(
"📝 *Transcription:*\n"
f"{transcription}\n\n"
"📌 *Summary:*\n"
f"{summary}",
parse_mode='Markdown'
)
# Cleanup temporary file
os.unlink(temp_path)
except Exception as e:
await update.message.reply_text(f"❌ Sorry, an error occurred: {str(e)}")
async def transcribe_audio(file_path: str) -> str:
"""Transcribe audio using Whisper via Groq API."""
with open(file_path, "rb") as file:
transcription = groq_client.audio.transcriptions.create(
file=(file_path, file.read()), # Required audio file
model="distil-whisper-large-v3-en", # Required model to use for transcription
# ^ using cheapest model to manage costs (https://groq.com/pricing/)
# prompt="Specify context or spelling", # Optional
# response_format="json", # Optional
# temperature=0.0 # Optional
)
return transcription.text.strip()
async def generate_summary(text: str) -> str:
"""Generate a summary using LLama 3 via Groq API."""
completion = groq_client.chat.completions.create(
model="llama-3.3-70b-versatile", # Replace with actual Groq LLama 3 model name
messages=[
{"role": "system", "content": "Generate a concise summary of the following text:"},
{"role": "user", "content": text}
],
max_completion_tokens=32768,
)
return completion.choices[0].message.content
async def handle_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Handle text messages and generate summaries."""
try:
# Check user authorization
if update.effective_user.id not in AUTHORIZED_USERS:
await update.message.reply_text("⛔ Sorry, you are not authorized to use this bot. Contact @aviaryan.")
return
# Send initial status
status_message = await update.message.reply_text("📝 Generating summary...")
# Get the text message
text = update.message.text
# Generate summary using LLama 3 via Groq
summary = await generate_summary(text)
# Send the summary
await status_message.edit_text(
"📌 *Summary:*\n"
f"{summary}",
parse_mode='Markdown'
)
except Exception as e:
await update.message.reply_text(f"❌ Sorry, an error occurred: {str(e)}")
async def error_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Log Errors caused by Updates."""
print(f"Update {update} caused error {context.error}")
# Initialize bot application
"""Create and configure the bot application."""
application = (
Application.builder()
.token(os.getenv("TELEGRAM_BOT_TOKEN"))
.build()
)
# Add handlers
application.add_handler(CommandHandler("start", start))
application.add_handler(MessageHandler(filters.VOICE, handle_voice))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_text)) # Add text message handler
application.add_error_handler(error_handler)
if __name__ == '__main__':
application.run_polling(allowed_updates=Update.ALL_TYPES, drop_pending_updates=True)