naonauno commited on
Commit
a6e928a
Β·
verified Β·
1 Parent(s): 548be15

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -36
app.py CHANGED
@@ -22,6 +22,7 @@ intents = discord.Intents.default()
22
  intents.message_content = True
23
  client = discord.Client(intents=intents)
24
  tree = app_commands.CommandTree(client)
 
25
 
26
  def get_available_voices():
27
  """Fetch only custom voices from ElevenLabs account"""
@@ -39,63 +40,129 @@ def get_remaining_credits():
39
 
40
  def format_credits_message(credits_info):
41
  """Format credits information into a readable message"""
42
- used = credits_info["character_limit"] - credits_info["character_count"]
43
- total = credits_info["character_limit"]
44
- return f"Credits: {credits_info['character_count']} / {total} characters remaining ({used} used)"
45
 
46
  # Discord bot commands
47
- @tree.command(name="voice", description="✨ Voice generation commands")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  @app_commands.describe(
49
- action="Choose 'list' to see available voices or 'create' to make a new voice message~",
50
- text="What would you like me to say?",
51
- voice_name="Choose which voice to use~",
52
  stability="Voice stability (0-1)",
53
  clarity="Voice clarity (0-1)",
54
  style="Speaking style (0-1)"
55
  )
56
- @app_commands.choices(action=[
57
- app_commands.Choice(name="list", value="list"),
58
- app_commands.Choice(name="create", value="create")
59
- ])
60
- async def voice(
61
  interaction: discord.Interaction,
62
- action: str,
63
- text: str = None,
64
- voice_name: str = None,
65
  stability: float = 0.5,
66
  clarity: float = 0.75,
67
  style: float = 0.5
68
  ):
69
- # Add autocomplete for voice names
70
- @voice.autocomplete('voice_name')
71
- async def voice_name_autocomplete(interaction: discord.Interaction, current: str):
72
- voices = list(get_available_voices().keys())
73
- return [
74
- app_commands.Choice(name=voice, value=voice)
75
- for voice in voices if current.lower() in voice.lower()
76
- ][:25]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  logger.info(f"Received voice command: action={action}, voice_name={voice_name}")
78
  await interaction.response.defer()
79
 
80
  if action.lower() == "list":
81
  available_voices = get_available_voices()
82
- voice_list = "\n".join([f"✨ {name}" for name in available_voices.keys()])
83
  credits_info = get_remaining_credits()
84
- credits_msg = f"\n\nπŸ’« Credits remaining: {credits_info['character_count']} / {credits_info['character_limit']}"
85
 
86
  embed = discord.Embed(
87
- title="πŸŽ€ Available Voices πŸŽ€",
88
  description=f"{voice_list}\n{credits_msg}",
89
- color=0xFFC0CB # Pink color
90
  )
91
  await interaction.followup.send(embed=embed)
92
 
93
  elif action.lower() == "create":
94
  if not all([text, voice_name]):
95
  embed = discord.Embed(
96
- title="πŸ’ Oopsie!",
97
- description="Please provide both text and voice name~ Use `/voice list` to see available voices!",
98
- color=0xFFC0CB
99
  )
100
  await interaction.followup.send(embed=embed)
101
  return
@@ -103,9 +170,9 @@ async def voice(
103
  available_voices = get_available_voices()
104
  if voice_name not in available_voices:
105
  embed = discord.Embed(
106
- title="πŸ’ Voice Not Found",
107
- description=f"I couldn't find the voice '{voice_name}' >~< \nUse `/voice list` to see available voices!",
108
- color=0xFFC0CB
109
  )
110
  await interaction.followup.send(embed=embed)
111
  return
@@ -135,9 +202,9 @@ async def voice(
135
  credits_msg = f"Credits remaining: {credits_info['character_count']} / {credits_info['character_limit']}"
136
 
137
  embed = discord.Embed(
138
- title="✨ Voice Generated! ✨",
139
- description=f"πŸŽ€ Using voice: {voice_name}\nπŸ’« {credits_msg}",
140
- color=0xFFC0CB
141
  )
142
  await interaction.followup.send(
143
  embed=embed,
 
22
  intents.message_content = True
23
  client = discord.Client(intents=intents)
24
  tree = app_commands.CommandTree(client)
25
+ tree.add_command(voice_group)
26
 
27
  def get_available_voices():
28
  """Fetch only custom voices from ElevenLabs account"""
 
40
 
41
  def format_credits_message(credits_info):
42
  """Format credits information into a readable message"""
43
+ return f"Credits Remaining: {credits_info['character_count']}"
 
 
44
 
45
  # Discord bot commands
46
+ # Command group for voice commands
47
+ voice_group = app_commands.Group(name="voice", description="Voice generation commands")
48
+
49
+ @voice_group.command(name="list", description="List all available voices")
50
+ async def voice_list(interaction: discord.Interaction):
51
+ await interaction.response.defer()
52
+ available_voices = get_available_voices()
53
+ voice_list = "\n".join([f"β€’ {name}" for name in available_voices.keys()])
54
+ credits_info = get_remaining_credits()
55
+ credits_msg = format_credits_message(credits_info)
56
+
57
+ embed = discord.Embed(
58
+ title="Available Voices",
59
+ description=f"{voice_list}\n\n{credits_msg}",
60
+ color=0x2B2D31
61
+ )
62
+ await interaction.followup.send(embed=embed)
63
+
64
+ @voice_group.command(name="create", description="Create a voice message")
65
  @app_commands.describe(
66
+ text="Text to convert to speech",
67
+ voice_name="Select a voice to use",
 
68
  stability="Voice stability (0-1)",
69
  clarity="Voice clarity (0-1)",
70
  style="Speaking style (0-1)"
71
  )
72
+ async def voice_create(
 
 
 
 
73
  interaction: discord.Interaction,
74
+ text: str,
75
+ voice_name: str,
 
76
  stability: float = 0.5,
77
  clarity: float = 0.75,
78
  style: float = 0.5
79
  ):
80
+ await interaction.response.defer()
81
+
82
+ available_voices = get_available_voices()
83
+ if voice_name not in available_voices:
84
+ embed = discord.Embed(
85
+ title="Voice Not Found",
86
+ description=f"The voice '{voice_name}' was not found. Use `/voice list` to see available voices.",
87
+ color=0x2B2D31
88
+ )
89
+ await interaction.followup.send(embed=embed)
90
+ return
91
+
92
+ try:
93
+ voice_settings = VoiceSettings(
94
+ stability=stability,
95
+ similarity_boost=clarity,
96
+ style=style,
97
+ use_speaker_boost=True
98
+ )
99
+
100
+ audio = generate(
101
+ text=text,
102
+ voice=Voice(
103
+ voice_id=available_voices[voice_name],
104
+ settings=voice_settings
105
+ )
106
+ )
107
+
108
+ # Save audio to temporary file
109
+ with open("temp.mp3", "wb") as f:
110
+ f.write(audio)
111
+
112
+ # Get updated credits
113
+ credits_info = get_remaining_credits()
114
+ credits_msg = format_credits_message(credits_info)
115
+
116
+ embed = discord.Embed(
117
+ title="Voice Generated",
118
+ description=f"Voice: {voice_name}\n{credits_msg}",
119
+ color=0x2B2D31
120
+ )
121
+ await interaction.followup.send(
122
+ embed=embed,
123
+ file=discord.File("temp.mp3")
124
+ )
125
+
126
+ # Clean up
127
+ os.remove("temp.mp3")
128
+
129
+ except Exception as e:
130
+ logger.error(f"Error generating audio: {str(e)}", exc_info=True)
131
+ await interaction.followup.send(f"Error generating audio: {str(e)}")
132
+
133
+ # Add autocomplete for voice names
134
+ @voice_create.autocomplete('voice_name')
135
+ async def voice_name_autocomplete(
136
+ interaction: discord.Interaction,
137
+ current: str,
138
+ ) -> List[app_commands.Choice[str]]:
139
+ voices = list(get_available_voices().keys())
140
+ return [
141
+ app_commands.Choice(name=voice, value=voice)
142
+ for voice in voices if current.lower() in voice.lower()
143
+ ][:25]
144
  logger.info(f"Received voice command: action={action}, voice_name={voice_name}")
145
  await interaction.response.defer()
146
 
147
  if action.lower() == "list":
148
  available_voices = get_available_voices()
149
+ voice_list = "\n".join([f"β€’ {name}" for name in available_voices.keys()])
150
  credits_info = get_remaining_credits()
151
+ credits_msg = f"\n\nCredits remaining: {credits_info['character_count']} / {credits_info['character_limit']}"
152
 
153
  embed = discord.Embed(
154
+ title="Available Voices",
155
  description=f"{voice_list}\n{credits_msg}",
156
+ color=0x2B2D31 # Discord dark theme color
157
  )
158
  await interaction.followup.send(embed=embed)
159
 
160
  elif action.lower() == "create":
161
  if not all([text, voice_name]):
162
  embed = discord.Embed(
163
+ title="Missing Information",
164
+ description="Please provide both text and voice name. Use `/voice list` to see available voices.",
165
+ color=0x2B2D31
166
  )
167
  await interaction.followup.send(embed=embed)
168
  return
 
170
  available_voices = get_available_voices()
171
  if voice_name not in available_voices:
172
  embed = discord.Embed(
173
+ title="Voice Not Found",
174
+ description=f"The voice '{voice_name}' was not found. Use `/voice list` to see available voices.",
175
+ color=0x2B2D31
176
  )
177
  await interaction.followup.send(embed=embed)
178
  return
 
202
  credits_msg = f"Credits remaining: {credits_info['character_count']} / {credits_info['character_limit']}"
203
 
204
  embed = discord.Embed(
205
+ title="Voice Generated",
206
+ description=f"Voice: {voice_name}\n{credits_msg}",
207
+ color=0x2B2D31
208
  )
209
  await interaction.followup.send(
210
  embed=embed,