seawolf2357 commited on
Commit
bece13e
ยท
verified ยท
1 Parent(s): 3426e70

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +50 -7
app.py CHANGED
@@ -5,6 +5,9 @@ import re
5
  import asyncio
6
  from huggingface_hub import InferenceClient
7
  from googleapiclient.discovery import build
 
 
 
8
  from youtube_transcript_api import YouTubeTranscriptApi
9
  from youtube_transcript_api.formatters import TextFormatter
10
  from dotenv import load_dotenv
@@ -25,9 +28,28 @@ intents.guild_messages = True
25
  # ์ถ”๋ก  API ํด๋ผ์ด์–ธํŠธ ์„ค์ •
26
  hf_client = InferenceClient("CohereForAI/c4ai-command-r-plus", token=os.getenv("HF_TOKEN"))
27
 
28
- # YouTube API ํ‚ค ์„ค์ •
29
  YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY")
30
- youtube_service = build('youtube', 'v3', developerKey=YOUTUBE_API_KEY)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  # ํŠน์ • ์ฑ„๋„ ID
33
  SPECIFIC_CHANNEL_ID = int(os.getenv("DISCORD_CHANNEL_ID"))
@@ -61,6 +83,7 @@ class MyClient(discord.Client):
61
  if comments and transcript:
62
  replies = await generate_replies(comments, transcript)
63
  await create_thread_and_send_replies(message, video_id, comments, replies)
 
64
  else:
65
  await message.channel.send("์ž๋ง‰์ด๋‚˜ ๋Œ“๊ธ€์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
66
  else:
@@ -131,7 +154,8 @@ async def get_video_comments(video_id):
131
 
132
  for item in response.get('items', []):
133
  comment = item['snippet']['topLevelComment']['snippet']['textOriginal']
134
- comments.append(comment)
 
135
 
136
  logging.debug(f'Fetched comments: {comments}')
137
  return comments
@@ -141,15 +165,15 @@ async def generate_replies(comments, transcript):
141
  ๋Œ“๊ธ€๊ณผ ์ž๋ง‰์„ ๊ธฐ๋ฐ˜์œผ๋กœ LLM ๋‹ต๊ธ€์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
142
  """
143
  replies = []
144
- for comment in comments:
145
  messages = [
146
  {"role": "system", "content": f"๋น„๋””์˜ค ์ž๋ง‰: {transcript}"},
147
  {"role": "user", "content": comment}
148
  ]
149
  loop = asyncio.get_event_loop()
150
  response = await loop.run_in_executor(None, lambda: hf_client.chat_completion(
151
- messages, max_tokens=500, temperature=0.7, top_p=0.85))
152
-
153
  if response.choices and response.choices[0].message:
154
  reply = response.choices[0].message['content'].strip()
155
  else:
@@ -164,10 +188,29 @@ async def create_thread_and_send_replies(message, video_id, comments, replies):
164
  ๋Œ“๊ธ€๊ณผ ๋‹ต๊ธ€์„ ์ƒˆ๋กœ์šด ์“ฐ๋ ˆ๋“œ์— ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
165
  """
166
  thread = await message.channel.create_thread(name=f"{message.author.name}์˜ ๋Œ“๊ธ€ ๋‹ต๊ธ€", message=message)
167
- for comment, reply in zip(comments, replies):
168
  embed = discord.Embed(description=f"**๋Œ“๊ธ€**: {comment}\n**๋‹ต๊ธ€**: {reply}")
169
  await thread.send(embed=embed)
170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  if __name__ == "__main__":
172
  discord_client = MyClient(intents=intents)
173
  discord_client.run(os.getenv('DISCORD_TOKEN'))
 
5
  import asyncio
6
  from huggingface_hub import InferenceClient
7
  from googleapiclient.discovery import build
8
+ from google.oauth2.credentials import Credentials
9
+ from google_auth_oauthlib.flow import InstalledAppFlow
10
+ from google.auth.transport.requests import Request
11
  from youtube_transcript_api import YouTubeTranscriptApi
12
  from youtube_transcript_api.formatters import TextFormatter
13
  from dotenv import load_dotenv
 
28
  # ์ถ”๋ก  API ํด๋ผ์ด์–ธํŠธ ์„ค์ •
29
  hf_client = InferenceClient("CohereForAI/c4ai-command-r-plus", token=os.getenv("HF_TOKEN"))
30
 
31
+ # YouTube API ํ‚ค ์„ค์ • ๋ฐ OAuth 2.0 ์ธ์ฆ ์„ค์ •
32
  YOUTUBE_API_KEY = os.getenv("YOUTUBE_API_KEY")
33
+ SCOPES = ["https://www.googleapis.com/auth/youtube.force-ssl"]
34
+ creds = None
35
+
36
+ # ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ • (ํ† ํฐ์„ ์ €์žฅํ•  ํŒŒ์ผ ๊ฒฝ๋กœ)
37
+ TOKEN_PATH = 'token.json'
38
+ CREDENTIALS_PATH = 'credentials.json'
39
+
40
+ if os.path.exists(TOKEN_PATH):
41
+ creds = Credentials.from_authorized_user_file(TOKEN_PATH, SCOPES)
42
+ if not creds or not creds.valid:
43
+ if creds and creds.expired and creds.refresh_token:
44
+ creds.refresh(Request())
45
+ else:
46
+ flow = InstalledAppFlow.from_client_secrets_file(
47
+ CREDENTIALS_PATH, SCOPES)
48
+ creds = flow.run_local_server(port=0)
49
+ with open(TOKEN_PATH, 'w') as token:
50
+ token.write(creds.to_json())
51
+
52
+ youtube_service = build('youtube', 'v3', credentials=creds)
53
 
54
  # ํŠน์ • ์ฑ„๋„ ID
55
  SPECIFIC_CHANNEL_ID = int(os.getenv("DISCORD_CHANNEL_ID"))
 
83
  if comments and transcript:
84
  replies = await generate_replies(comments, transcript)
85
  await create_thread_and_send_replies(message, video_id, comments, replies)
86
+ await post_replies_to_youtube(video_id, comments, replies)
87
  else:
88
  await message.channel.send("์ž๋ง‰์ด๋‚˜ ๋Œ“๊ธ€์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
89
  else:
 
154
 
155
  for item in response.get('items', []):
156
  comment = item['snippet']['topLevelComment']['snippet']['textOriginal']
157
+ comment_id = item['snippet']['topLevelComment']['id']
158
+ comments.append((comment, comment_id)) # ๋Œ“๊ธ€๊ณผ ๋Œ“๊ธ€ ID๋ฅผ ํ•จ๊ป˜ ์ €์žฅ
159
 
160
  logging.debug(f'Fetched comments: {comments}')
161
  return comments
 
165
  ๋Œ“๊ธ€๊ณผ ์ž๋ง‰์„ ๊ธฐ๋ฐ˜์œผ๋กœ LLM ๋‹ต๊ธ€์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
166
  """
167
  replies = []
168
+ for comment, _ in comments:
169
  messages = [
170
  {"role": "system", "content": f"๋น„๋””์˜ค ์ž๋ง‰: {transcript}"},
171
  {"role": "user", "content": comment}
172
  ]
173
  loop = asyncio.get_event_loop()
174
  response = await loop.run_in_executor(None, lambda: hf_client.chat_completion(
175
+ messages, max_tokens=400, temperature=0.7, top_p=0.85)) # max_tokens ๊ฐ’์„ ์กฐ์ •
176
+
177
  if response.choices and response.choices[0].message:
178
  reply = response.choices[0].message['content'].strip()
179
  else:
 
188
  ๋Œ“๊ธ€๊ณผ ๋‹ต๊ธ€์„ ์ƒˆ๋กœ์šด ์“ฐ๋ ˆ๋“œ์— ์ „์†กํ•ฉ๋‹ˆ๋‹ค.
189
  """
190
  thread = await message.channel.create_thread(name=f"{message.author.name}์˜ ๋Œ“๊ธ€ ๋‹ต๊ธ€", message=message)
191
+ for (comment, _), reply in zip(comments, replies):
192
  embed = discord.Embed(description=f"**๋Œ“๊ธ€**: {comment}\n**๋‹ต๊ธ€**: {reply}")
193
  await thread.send(embed=embed)
194
 
195
+ async def post_replies_to_youtube(video_id, comments, replies):
196
+ """
197
+ ์ƒ์„ฑ๋œ ๋‹ต๊ธ€์„ YouTube ๋Œ“๊ธ€๋กœ ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค.
198
+ """
199
+ for (comment, comment_id), reply in zip(comments, replies):
200
+ try:
201
+ youtube_service.comments().insert(
202
+ part='snippet',
203
+ body={
204
+ 'snippet': {
205
+ 'parentId': comment_id,
206
+ 'textOriginal': reply
207
+ }
208
+ }
209
+ ).execute()
210
+ logging.debug(f'Posted reply to comment: {comment_id}')
211
+ except Exception as e:
212
+ logging.error(f'Error posting reply to comment {comment_id}: {e}')
213
+
214
  if __name__ == "__main__":
215
  discord_client = MyClient(intents=intents)
216
  discord_client.run(os.getenv('DISCORD_TOKEN'))