|
| 1 | +module Discord |
| 2 | + module Events |
| 3 | + class PuzzleAnswer |
| 4 | + def initialize(bot) |
| 5 | + @bot = bot |
| 6 | + end |
| 7 | + |
| 8 | + def listen |
| 9 | + # Listen for button clicks and filter based on custom_id pattern |
| 10 | + @bot.button { |event| handle(event) if valid_puzzle_answer?(event) } |
| 11 | + end |
| 12 | + |
| 13 | + def handle(event) |
| 14 | + answer, puzzle_id = event.custom_id.split("__") |
| 15 | + |
| 16 | + # Find the associated puzzle |
| 17 | + puzzle = find_puzzle(puzzle_id.to_i) |
| 18 | + return unless puzzle |
| 19 | + |
| 20 | + # Find or create the user |
| 21 | + user = User.find_or_create_by(user_id: event.user.id) do |user| |
| 22 | + user.username = event.user.username |
| 23 | + # Users with permission to manage the server are admins, all other users fall under the member role |
| 24 | + user.role = event.user.permission?(:manage_server) ? 1 : 0 |
| 25 | + end |
| 26 | + |
| 27 | + if user.persisted? |
| 28 | + user.update(username: event.user.username, role: event.user.permission?(:manage_server) ? 1 : 0) |
| 29 | + end |
| 30 | + |
| 31 | + # Check if the user has already answered this puzzle |
| 32 | + existing_answer = Answer.find_by(puzzle_id: puzzle.id, user_id: user.id) |
| 33 | + if existing_answer |
| 34 | + # If the user has already answered, prevent them from changing their answer |
| 35 | + event.respond( |
| 36 | + content: "You have already answered this puzzle. You cannot change your answer.", |
| 37 | + ephemeral: true # Only the user sees this message |
| 38 | + ) |
| 39 | + return |
| 40 | + end |
| 41 | + |
| 42 | + # Create the answer record |
| 43 | + answer = Answer.create!( |
| 44 | + puzzle_id: puzzle.id, |
| 45 | + user_id: user.id, |
| 46 | + choice: answer, # 'ruby' or 'rails' |
| 47 | + is_correct: puzzle.answer.to_s == answer # Correct answer check |
| 48 | + ) |
| 49 | + |
| 50 | + # Respond to the user with the result |
| 51 | + event.respond( |
| 52 | + content: nil, |
| 53 | + embeds: [ answer_embed(answer, puzzle) ], |
| 54 | + ephemeral: true # Only the user sees this message |
| 55 | + ) |
| 56 | + end |
| 57 | + |
| 58 | + private |
| 59 | + |
| 60 | + def answer_embed(answer, puzzle) |
| 61 | + Discordrb::Webhooks::Embed.new( |
| 62 | + title: answer.is_correct ? "Correct! 🎉" : "Incorrect 😢", |
| 63 | + description: puzzle.explanation, |
| 64 | + color: 0xe60000, |
| 65 | + footer: Discordrb::Webhooks::EmbedFooter.new(text: "Your answer has been recorded, you cannot change it.") |
| 66 | + ) |
| 67 | + end |
| 68 | + |
| 69 | + def valid_puzzle_answer?(event) |
| 70 | + # Check if the custom_id matches the pattern (ruby__NUMBER or rails__NUMBER) |
| 71 | + event.custom_id.match?(/^(ruby|rails)__\d+$/) |
| 72 | + end |
| 73 | + |
| 74 | + def find_puzzle(puzzle_id) |
| 75 | + Puzzle.find_by(id: puzzle_id) |
| 76 | + end |
| 77 | + end |
| 78 | + end |
| 79 | +end |
0 commit comments