coollsd commited on
Commit
23567d4
·
verified ·
1 Parent(s): 05a366f

Update sportbet.py

Browse files
Files changed (1) hide show
  1. sportbet.py +161 -157
sportbet.py CHANGED
@@ -18,10 +18,14 @@ async def fetch_nhl_scores():
18
 
19
  async def fetch_nfl_scores():
20
  current_year = datetime.now().year
21
- url = f"https://api.foxsports.com/bifrost/v1/nfl/scoreboard/segment/{current_year}?apikey={API_KEY}"
22
- async with aiohttp.ClientSession() as session:
23
- async with session.get(url) as response:
24
- return await response.json()
 
 
 
 
25
 
26
  class SportSelect(discord.ui.Select):
27
  def __init__(self):
@@ -47,6 +51,9 @@ class SportSelect(discord.ui.Select):
47
  await interaction.followup.send("Select a game to bet on:", view=view, ephemeral=False)
48
  elif selected_sport == "NFL":
49
  scores = await fetch_nfl_scores()
 
 
 
50
  events = scores.get('sectionList', [])[0].get('events', [])
51
  upcoming_games = [game for game in events if game.get('eventStatus') == 2]
52
  if not upcoming_games:
@@ -78,13 +85,6 @@ class GameOptionSelect(discord.ui.Select):
78
  async def callback(self, interaction: discord.Interaction):
79
  selected_game_id = self.values[0]
80
  game_data = self.games.get(selected_game_id)
81
-
82
- # Restrict betting to one hour before the game starts
83
- game_start_time = datetime.fromisoformat(game_data['eventTime'].replace('Z', '+00:00'))
84
- if datetime.now(timezone.utc) > game_start_time - timedelta(hours=1):
85
- await interaction.response.send_message("Betting is closed for this game as it starts within an hour.", ephemeral=False)
86
- return
87
-
88
  if not game_data:
89
  await interaction.response.send_message("Selected game data not found.", ephemeral=False)
90
  return
@@ -116,11 +116,11 @@ class TeamOptionSelect(discord.ui.Select):
116
  selected_team = self.values[0]
117
  await interaction.response.send_modal(BetModal(selected_team, interaction.user.id, self.game, self.league))
118
 
119
- class BetModal(discord.ui.Modal):
120
  bet_amount = discord.ui.TextInput(label="Bet Amount", placeholder="Enter bet amount", required=True)
121
 
122
  def __init__(self, team, user_id, game_data, league):
123
- super().__init__(title="Place Your Bet")
124
  self.team = team
125
  self.user_id = user_id
126
  self.game_data = game_data
@@ -137,165 +137,169 @@ class BetModal(discord.ui.Modal):
137
  user_cash[self.user_id] -= bet_amount
138
  await interaction.response.send_message(f"Bet placed on **{self.team}** for **${bet_amount}**.", ephemeral=False)
139
 
140
- user_bets.setdefault(self.user_id, []).append({
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  "league": self.league,
142
  "team": self.team,
143
  "amount": bet_amount,
144
  "game_data": self.game_data
145
  })
146
 
147
- asyncio.create_task(self.monitor_game(interaction))
148
-
149
  except ValueError as e:
150
  await interaction.response.send_message(str(e), ephemeral=False)
151
 
152
- async def monitor_game(self, interaction):
153
- event_id = self.game_data['id']
154
- fetch_scores_func = fetch_nhl_scores if self.league == "NHL" else fetch_nfl_scores
155
-
156
- start_time_utc = datetime.fromisoformat(self.game_data['eventTime'].replace('Z', '+00:00'))
157
- sleep_duration_seconds = (start_time_utc - datetime.now(timezone.utc)).total_seconds()
158
- if sleep_duration_seconds > 0:
159
- await asyncio.sleep(sleep_duration_seconds)
160
-
161
- user_obj = await interaction.client.fetch_user(self.user_id)
162
- await user_obj.send(f"Your team **{self.team}** has started playing!")
163
-
164
- previous_scores_dicts_map={
165
- 'lowerTeam':self.game_data.get('lowerTeam', {}).get('score', 0),
166
- 'upperTeam':self.game_data.get('upperTeam', {}).get('score', 0)
167
- }
168
-
169
- while True:
170
- scores_dicts_map=await fetch_scores_func()
171
- current_game=None
172
-
173
- for section_dict in scores_dicts_map.get('sectionList', []):
174
- for event_dict in section_dict.get('events', []):
175
- if event_dict['id']==event_id:
176
- current_game=event_dict
177
- break
178
-
179
- if current_game:
180
- break
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
 
182
- if not current_game:
183
- await asyncio.sleep(60)
184
- continue
185
-
186
- event_status=current_game.get('eventStatus', 2)
187
- current_scores_dicts_map={
188
- 'lowerTeam':current_game['lowerTeam'].get('score', 0),
189
- 'upperTeam':current_game['upperTeam'].get('score', 0)
190
- }
191
-
192
- is_final_event_status_bool=(event_status==3)
193
-
194
- # Check and notify score updates.
195
- for team_key_str,current_score_int in current_scores_dicts_map.items():
196
- previous_score_int=previous_scores_dicts_map.get(team_key_str)
197
 
198
- if current_score_int>previous_score_int:
199
- team_name_str=self.game_data[team_key_str]['longName']
200
- message_str=f"**{team_name_str}** SCORED! Current score: {current_scores_dicts_map['lowerTeam']} - {current_scores_dicts_map['upperTeam']}"
201
- await user_obj.send(message_str)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
- previous_scores_dicts_map=current_scores_dicts_map.copy()
 
 
 
204
 
205
- if is_final_event_status_bool:
206
- lower_score_int=current_scores_dicts_map.get('lowerTeam', 0)
207
- upper_score_int=current_scores_dicts_map.get('upperTeam', 0)
208
- winner_str=self.game_data['lowerTeam']['name']if lower_score_int>upper_score_int else self.game_data['upperTeam']['name']
209
 
210
- if winner_str==self.team:
211
- winnings_int=(bet_amount*2)
212
- user_cash[self.user_id]+=winnings_int
213
- await user_obj.send(f"🎉 **Congratulations!** Your team **{self.team}** won! You won **${winnings_int}**.")
214
- else:
215
- await user_obj.send(f"😞 **Sorry!** Your team **{self.team}** lost. Better luck next time!")
216
 
217
- # Remove completed bets.
218
- user_bets[self.user_id]=[bet for bet in user_bets[self.user_id]if not(bet['league']==self.league and bet['team']==self.team and bet['game_data']['id']==event_id)]
219
- break
 
 
220
 
221
- await asyncio.sleep(60) # Check every minute.
222
 
223
- class SportBetView(discord.ui.View):
224
- def __init__(self):
225
- super().__init__()
226
- self.add_item(SportSelect())
227
 
228
- @discord.ui.button(label="View Bets", style=discord.ButtonStyle.secondary)
229
- async def view_bets(self ,interaction:discord.Interaction ,button:discord.ui.Button ):
230
- await show_current_bets(interaction )
231
-
232
- async def show_current_bets(interaction:discord.Interaction ):
233
- user_id=interaction.user.id
234
- if (user_id not in user_bets or not user_bets[user_id]):
235
- await interaction.response.send_message("You have no active bets." ,ephemeral=False )
236
- return
237
-
238
- embed=discord.Embed(title="Your Current Bets" ,color=0x787878 )
239
- for i,b et in enumerate(user_bets[user_id],1 ):
240
- league=b et["league"]
241
- team=b et["team"]
242
- amount=b et["amount"]
243
- g ame=b et["game_data"]
244
- g ame_description=f"{game['lowerTeam']['longName']} vs {game['upperTeam']['longName']}"
245
- s tart_time=g ame["eventTime"]
246
- score=f"{game['lowerTeam'].get('score','N/A')} - {game['upperTeam'].get('score','N/A')}"
247
- status="Final"if g ame.get("upperTeam", {}).get("score")is not None else f"Starts <t:{int(datetime.fromisoformat(start_time.replace('Z','+00:00')).timestamp())}:R>"
248
-
249
- embed.add_field(
250
- name=f"Bet {i}: {league}",
251
- value=(
252
- f"**Team:** {team}\n"
253
- f"**Amount:** ${amount}\n"
254
- f"**Game:** {game_description}\n"
255
- f"**Status:** {status}\n"
256
- f"**Current Score:** {score}\n"
257
- f"**Start Time:** <t:{int(datetime.fromisoformat(start_time.replace('Z','+00:00')).timestamp())}:F>"
258
- ),
259
- inline=False
260
- )
261
-
262
- view=discord.ui.View()
263
- cancel_select=discord.ui.Select(
264
- placeholder="Select a bet to cancel",
265
- min_values=1,
266
- max_values=1,
267
- options=[
268
- discord.SelectOption(label=f"Bet {i}",value=str(i-1))for i in range(1,len(user_bets[user_id])+1 )
269
- ]
270
- )
271
- view.add_item(cancel_select )
272
-
273
- async def cancel_callback(interaction_cancel:discord.Interaction ):
274
- if (interaction_cancel.user.id!=user_id ):
275
- await interaction_cancel.response.send_message("You cannot cancel other users' bets." ,ephemeral=False )
276
- return
277
-
278
- b et_index=int(cancel_select.values[0])
279
- c ancelled_bet=user_bets[user_id][bet_index]
280
- s tart_time=datetime.fromisoformat(cancelled_bet["game_data"]["eventTime"].replace("Z","+00:00"))
281
-
282
- if (datetime.now(timezone.utc)>=start_time ):
283
- await interaction_cancel.response.send_message("You cannot cancel your bet as the game has already started." ,ephemeral=False )
284
- return
285
-
286
- user_cash[user_id]+=cancelled_bet["amount"]
287
- u ser_bets[user_id].pop(bet_index )
288
- await interaction_cancel.response.send_message(f"Bet cancelled. **${cancelled_bet['amount']}** has been refunded." ,ephemeral=False )
289
-
290
- # Remove empty bets list for the user
291
- if (not user_bets[user_id] ):
292
- del user_bets[user_id]
293
-
294
- cancel_select.callback=cancel_callback
295
-
296
- await interaction.response.send_message(embed=embed ,view=view ,ephemeral=False )
297
-
298
- @app_commands.command(name="sportbet",description="Bet on sports games")
299
- async def sportbet(interaction:discord.Interaction ):
300
- view=SportBetView()
301
- await interaction.response.send_message("Select a sport to bet on:" ,view=view ,ephemeral=False )
 
18
 
19
  async def fetch_nfl_scores():
20
  current_year = datetime.now().year
21
+ for week in range(1, 18): # NFL regular season has 17 weeks
22
+ url = f"https://api.foxsports.com/bifrost/v1/nfl/scoreboard/segment/{current_year}-{week}-1?apikey={API_KEY}"
23
+ async with aiohttp.ClientSession() as session:
24
+ async with session.get(url) as response:
25
+ data = await response.json()
26
+ if data['sectionList'][0]['events'][0]['eventStatus'] == 2:
27
+ return data
28
+ return None # If no current week is found
29
 
30
  class SportSelect(discord.ui.Select):
31
  def __init__(self):
 
51
  await interaction.followup.send("Select a game to bet on:", view=view, ephemeral=False)
52
  elif selected_sport == "NFL":
53
  scores = await fetch_nfl_scores()
54
+ if not scores:
55
+ await interaction.followup.send("No NFL games available for betting this week.", ephemeral=False)
56
+ return
57
  events = scores.get('sectionList', [])[0].get('events', [])
58
  upcoming_games = [game for game in events if game.get('eventStatus') == 2]
59
  if not upcoming_games:
 
85
  async def callback(self, interaction: discord.Interaction):
86
  selected_game_id = self.values[0]
87
  game_data = self.games.get(selected_game_id)
 
 
 
 
 
 
 
88
  if not game_data:
89
  await interaction.response.send_message("Selected game data not found.", ephemeral=False)
90
  return
 
116
  selected_team = self.values[0]
117
  await interaction.response.send_modal(BetModal(selected_team, interaction.user.id, self.game, self.league))
118
 
119
+ class BetModal(discord.ui.Modal, title="Place Your Bet"):
120
  bet_amount = discord.ui.TextInput(label="Bet Amount", placeholder="Enter bet amount", required=True)
121
 
122
  def __init__(self, team, user_id, game_data, league):
123
+ super().__init__()
124
  self.team = team
125
  self.user_id = user_id
126
  self.game_data = game_data
 
137
  user_cash[self.user_id] -= bet_amount
138
  await interaction.response.send_message(f"Bet placed on **{self.team}** for **${bet_amount}**.", ephemeral=False)
139
 
140
+ user = await interaction.client.fetch_user(self.user_id)
141
+ embed = discord.Embed(title="Bet Placed", color=0x787878)
142
+ embed.add_field(name="League", value=self.league, inline=False)
143
+ embed.add_field(name="Team", value=self.team, inline=False)
144
+ embed.add_field(name="Amount", value=f"${bet_amount}", inline=False)
145
+ game_description = f"{self.game_data['lowerTeam']['longName']} vs {self.game_data['upperTeam']['longName']}"
146
+ start_time = self.game_data['eventTime']
147
+ embed.add_field(name="Game", value=game_description, inline=False)
148
+ embed.add_field(name="Start Time", value=f"<t:{int(datetime.fromisoformat(start_time.replace('Z', '+00:00')).timestamp())}:F>", inline=False)
149
+ await user.send(embed=embed)
150
+
151
+ if self.user_id not in user_bets:
152
+ user_bets[self.user_id] = []
153
+ user_bets[self.user_id].append({
154
  "league": self.league,
155
  "team": self.team,
156
  "amount": bet_amount,
157
  "game_data": self.game_data
158
  })
159
 
160
+ asyncio.create_task(self.monitor_game(interaction, bet_amount))
 
161
  except ValueError as e:
162
  await interaction.response.send_message(str(e), ephemeral=False)
163
 
164
+ async def monitor_game(self, interaction, bet_amount):
165
+ game_start = datetime.fromisoformat(self.game_data['eventTime'].replace('Z', '+00:00'))
166
+ event_id = self.game_data['id']
167
+ fetch_scores = fetch_nhl_scores if self.league == "NHL" else fetch_nfl_scores
168
+
169
+ sleep_duration = (game_start - datetime.now(timezone.utc)).total_seconds()
170
+ if sleep_duration > 0:
171
+ await asyncio.sleep(sleep_duration)
172
+
173
+ user = await interaction.client.fetch_user(self.user_id)
174
+ await user.send(f"Your team **{self.team}** has started playing!")
175
+
176
+ previous_scores = {
177
+ self.game_data['lowerTeam']['name']: self.game_data.get('lowerTeam', {}).get('score', 0),
178
+ self.game_data['upperTeam']['name']: self.game_data.get('upperTeam', {}).get('score', 0)
179
+ }
180
+
181
+ while True:
182
+ scores = await fetch_scores()
183
+ game = None
184
+ for section in scores.get('sectionList', []):
185
+ for evt in section.get('events', []):
186
+ if evt['id'] == event_id:
187
+ game = evt
188
+ break
189
+ if game:
190
+ break
191
+ if not game:
192
+ await asyncio.sleep(60)
193
+ continue
194
+
195
+ event_status = game.get('eventStatus', 2)
196
+ current_scores = {
197
+ game['lowerTeam']['name']: game['lowerTeam'].get('score', 0),
198
+ game['upperTeam']['name']: game['upperTeam'].get('score', 0)
199
+ }
200
+ is_final = event_status == 3
201
+
202
+ # Check for score updates
203
+ for team, score in current_scores.items():
204
+ if score > previous_scores.get(team, 0):
205
+ team_name = self.game_data['lowerTeam']['longName'] if team == self.game_data['lowerTeam']['name'] else self.game_data['upperTeam']['longName']
206
+ message = f"**{team_name}** SCORED! Current score: {current_scores[self.game_data['lowerTeam']['name']]} - {current_scores[self.game_data['upperTeam']['name']]}"
207
+ await user.send(message)
208
+
209
+ previous_scores = current_scores.copy()
210
+
211
+ if is_final:
212
+ away_score = current_scores.get(self.game_data['lowerTeam']['name'], 0)
213
+ home_score = current_scores.get(self.game_data['upperTeam']['name'], 0)
214
+ winner = self.game_data['lowerTeam']['name'] if away_score > home_score else self.game_data['upperTeam']['name']
215
+
216
+ if winner == self.team:
217
+ winnings = bet_amount * 2
218
+ user_cash[self.user_id] += winnings
219
+ await user.send(f"🎉 **Congratulations!** Your team **{self.team}** won! You won **${winnings}**!")
220
+ else:
221
+ await user.send(f"😞 **Sorry!** Your team **{self.team}** lost. Better luck next time!")
222
+
223
+ # Remove the completed bet
224
+ user_bets[self.user_id] = [bet for bet in user_bets[self.user_id] if not (bet['league'] == self.league and bet['team'] == self.team and bet['game_data']['id'] == event_id)]
225
+ break
226
+
227
+ await asyncio.sleep(60) # Check every minute
228
 
229
+ class SportBetView(discord.ui.View):
230
+ def __init__(self):
231
+ super().__init__()
232
+ self.add_item(SportSelect())
 
 
 
 
 
 
 
 
 
 
 
233
 
234
+ @discord.ui.button(label="View Bets", style=discord.ButtonStyle.secondary)
235
+ async def view_bets(self, interaction: discord.Interaction, button: discord.ui.Button):
236
+ await show_current_bets(interaction)
237
+
238
+ async def show_current_bets(interaction: discord.Interaction):
239
+ user_id = interaction.user.id
240
+ if user_id not in user_bets or not user_bets[user_id]:
241
+ await interaction.response.send_message("You have no active bets.", ephemeral=False)
242
+ return
243
+
244
+ embed = discord.Embed(title="Your Current Bets", color=0x787878)
245
+ for i, bet in enumerate(user_bets[user_id], 1):
246
+ league = bet['league']
247
+ team = bet['team']
248
+ amount = bet['amount']
249
+ game = bet['game_data']
250
+ game_description = f"{game['lowerTeam']['longName']} vs {game['upperTeam']['longName']}"
251
+ start_time = game['eventTime']
252
+ score = f"{game['lowerTeam'].get('score', 'N/A')} - {game['upperTeam'].get('score', 'N/A')}"
253
+ status = "Final" if game.get('upperTeam', {}).get('score') is not None else f"Starts <t:{int(datetime.fromisoformat(start_time.replace('Z', '+00:00')).timestamp())}:R>"
254
+
255
+ embed.add_field(
256
+ name=f"Bet {i}: {league}",
257
+ value=(
258
+ f"**Team:** {team}\n"
259
+ f"**Amount:** ${amount}\n"
260
+ f"**Game:** {game_description}\n"
261
+ f"**Status:** {status}\n"
262
+ f"**Current Score:** {score}\n"
263
+ f"**Start Time:** <t:{int(datetime.fromisoformat(start_time.replace('Z', '+00:00')).timestamp())}:F>"
264
+ ),
265
+ inline=False
266
+ )
267
+
268
+ view = discord.ui.View()
269
+ cancel_select = discord.ui.Select(
270
+ placeholder="Select a bet to cancel",
271
+ min_values=1,
272
+ max_values=1,
273
+ options=[
274
+ discord.SelectOption(label=f"Bet {i}", value=str(i-1)) for i in range(1, len(user_bets[user_id]) + 1)
275
+ ]
276
+ )
277
+ view.add_item(cancel_select)
278
 
279
+ async def cancel_callback(interaction_cancel: discord.Interaction):
280
+ if interaction_cancel.user.id != user_id:
281
+ await interaction_cancel.response.send_message("You cannot cancel other users' bets.", ephemeral=False)
282
+ return
283
 
284
+ bet_index = int(cancel_select.values[0])
285
+ cancelled_bet = user_bets[user_id][bet_index]
286
+ start_time = datetime.fromisoformat(cancelled_bet['game_data']['eventTime'].replace('Z', '+00:00'))
 
287
 
288
+ if datetime.now(timezone.utc) >= start_time:
289
+ await interaction_cancel.response.send_message("You cannot cancel your bet as the game has already started.", ephemeral=False)
290
+ return
 
 
 
291
 
292
+ user_cash[user_id] += cancelled_bet['amount']
293
+ user_bets[user_id].pop(bet_index)
294
+ await interaction_cancel.response.send_message(f"Bet cancelled. **${cancelled_bet['amount']}** has been refunded.", ephemeral=False)
295
+ if not user_bets[user_id]:
296
+ del user_bets[user_id]
297
 
298
+ cancel_select.callback = cancel_callback
299
 
300
+ await interaction.response.send_message(embed=embed, view=view, ephemeral=False)
 
 
 
301
 
302
+ @app_commands.command(name="sportbet", description="Bet on sports games")
303
+ async def sportbet(interaction: discord.Interaction):
304
+ view = SportBetView()
305
+ await interaction.response.send_message("Select a sport to bet on:", view=view, ephemeral=False)