Skip to content

Commit c329818

Browse files
committed
IIRR-22: QA feedback
- Add warning when adding bot to private channels - Scope leaderboard per server - Associate answers with servers so users can respond in multiple servers they are a part of - Make the sent flag a timestamp - Add ability to add a link to the answer to complement the explanation - Improve leaderboard copy and change embed color of the puzzle answer
1 parent 4992eff commit c329818

File tree

9 files changed

+60
-12
lines changed

9 files changed

+60
-12
lines changed

app/jobs/daily_puzzle_job.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class DailyPuzzleJob < ApplicationJob
22
queue_as :default
33

44
def perform
5-
puzzle = Puzzle.where(sent: false).order("RANDOM()").first
5+
puzzle = Puzzle.where(sent_at: nil).order("RANDOM()").first
66
return unless puzzle
77

88
Server.where(active: true).each do |server|
@@ -21,7 +21,7 @@ def perform
2121
)
2222
end
2323

24-
puzzle.update!(sent: true)
24+
puzzle.update!(sent_at: Time.current)
2525
end
2626

2727
private

app/jobs/weekly_leaderboard_job.rb

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,47 @@ def perform
77

88
leaderboard_data = Answer
99
.where(created_at: start_time..end_time, is_correct: true)
10-
.group(:user_id)
10+
.group(:server_id, :user_id)
1111
.order(Arel.sql("COUNT(*) DESC"))
1212
.count
1313

1414
return if leaderboard_data.empty?
15+
leaderboard_by_server = leaderboard_data.group_by { |(server_id, _), _| server_id }
1516

1617
Server.all.each do |server|
1718
channel = server.channel
19+
next unless channel
20+
21+
server_leaderboard = leaderboard_by_server[server.id]
22+
next unless server_leaderboard.present?
23+
24+
leaderboard = server_leaderboard.map { |(_server_id, user_id), count| [ user_id, count ] }.to_h
25+
1826
bot.send_message(
1927
channel.channel_id,
2028
"",
2129
false,
22-
leaderboard_embed(leaderboard_data),
30+
leaderboard_embed(leaderboard),
2331
nil,
2432
nil,
2533
nil,
26-
nil) if channel
34+
nil
35+
)
2736
end
2837
end
2938

3039
private
3140

3241
def leaderboard_embed(leaderboard_data)
42+
description =
43+
if leaderboard_data.size > 10
44+
"Here are the top 10 players from this week's competition!"
45+
else
46+
"Here are the top players from this week's competition!"
47+
end
3348
embed = Discordrb::Webhooks::Embed.new(
3449
title: "🏆 Weekly Leaderboard 🏆",
35-
description: "Here are the top 10 players from this week's competition!",
50+
description: description,
3651
color: 0xFFD700 # Gold color
3752
)
3853

app/lib/discord/events/puzzle_answer.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def handle(event)
2828

2929

3030
# Check if the user has already answered this puzzle
31-
existing_answer = Answer.find_by(puzzle_id: puzzle.id, user_id: user.id)
31+
existing_answer = Answer.find_by(puzzle_id: puzzle.id, user_id: user.id, server_id: event.server.id)
3232
if existing_answer
3333
# If the user has already answered, prevent them from changing their answer
3434
event.respond(
@@ -38,10 +38,13 @@ def handle(event)
3838
return
3939
end
4040

41+
server = Server.find_or_initialize_by(server_id: event.server.id)
42+
4143
# Create the answer record
4244
answer = Answer.create!(
4345
puzzle_id: puzzle.id,
4446
user_id: user.id,
47+
server_id: server.id,
4548
choice: answer, # 'ruby' or 'rails'
4649
is_correct: puzzle.answer.to_s == answer # Correct answer check
4750
)
@@ -57,12 +60,16 @@ def handle(event)
5760
private
5861

5962
def answer_embed(answer, puzzle)
60-
Discordrb::Webhooks::Embed.new(
63+
embed = Discordrb::Webhooks::Embed.new(
6164
title: answer.is_correct ? "Correct! 🎉" : "Incorrect 😢",
6265
description: puzzle.explanation,
63-
color: 0xe60000,
66+
color: answer.is_correct ? 0x00ff00 : 0xe60000,
6467
footer: Discordrb::Webhooks::EmbedFooter.new(text: "Your answer has been recorded, you cannot change it.")
6568
)
69+
if puzzle.link
70+
embed.add_field(name: "Learn more", value: puzzle.link, inline: false)
71+
end
72+
embed
6673
end
6774

6875
def valid_puzzle_answer?(event)

app/lib/discord/events/set_channel.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ def display_settings(event)
3232
content = <<~MSG
3333
Here you can configure the bot to suit the needs of the community!
3434
35+
⚠️ If you set this to a private channel, make sure to give the bot access to it, otherwise it can't send messages.
36+
3537
What's the best channel to send Ruby or Rails questions to?
3638
MSG
3739
channel_select = Discordrb::Components::View.new do |view|
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class ChangeSentToSentAtInPuzzles < ActiveRecord::Migration[8.0]
2+
def change
3+
remove_column :puzzles, :sent, :boolean
4+
add_column :puzzles, :sent_at, :datetime
5+
end
6+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddServerToAnswers < ActiveRecord::Migration[8.0]
2+
def change
3+
add_reference :answers, :server, null: false, foreign_key: true
4+
end
5+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddLinkToPuzzles < ActiveRecord::Migration[8.0]
2+
def change
3+
add_column :puzzles, :link, :string
4+
end
5+
end

db/schema.rb

Lines changed: 7 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

db/seeds.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22
# db/seeds.rb
33

4-
54
# Create Puzzle records
65
Puzzle.create!([
76
{ question: "Ruby or Rails provided this method? Array.new(5) { |i| i * 2 }", answer: :ruby, explanation: "`Array.new` is a core Ruby method that creates a new array with a specified size and optional block for initialization. This is part of Ruby’s core library." },
@@ -11,6 +10,9 @@
1110
{ question: "Ruby or Rails provided this method? params[:id]", answer: :rails, explanation: "`params[:id]` is used in Rails to fetch query parameters or URL parameters in controller actions." }
1211
])
1312

13+
# Create a server
14+
Server.create!(server_id: 1179555097060061245, name: "OmbuTest")
15+
1416
# Seed data for 10 users with answers
1517
users = [
1618
{ user_id: 101, username: "user1", role: "member" },
@@ -33,6 +35,7 @@
3335
Answer.create!(
3436
user_id: user.id,
3537
puzzle_id: Puzzle.all.sample.id,
38+
server_id: Server.first.id,
3639
choice: [ "ruby", "rails" ].sample,
3740
is_correct: [ true, false ].sample
3841
)

0 commit comments

Comments
 (0)