-
Notifications
You must be signed in to change notification settings - Fork 1
/
secretsanta.rb
127 lines (96 loc) · 3.13 KB
/
secretsanta.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
require 'twilio-ruby'
require 'dotenv'
module SecretSanta
extend self
class Participant
attr_reader :name, :phone_number
attr_accessor :assignment
def initialize(name:, phone_number:, exclusions:)
@name = name
@phone_number = phone_number
@exclusions = exclusions
@assignment = nil
end
def ==(other)
other.name == self.name
end
def valid?
!invalid?
end
def invalid?
assignment_is_excluded? || assignment_is_self? || assignment_is_circular?
end
def to_participant_message
"Hey #{name}, you are #{assignment.name}'s secret santa"
end
def to_backup_message
"#{name} has #{assignment.name}"
end
private
attr_reader :exclusions
def assignment_is_excluded?
exclusions.include? assignment.name
end
def assignment_is_self?
assignment == self
end
def assignment_is_circular?
assignment.assignment == self
end
end
module SMSClient
extend self
# Send text messages to all participants with their assignment.
#
# @param [Array<Particpant>]
def notify_participants participants
participants.each do |participant|
send_message participant.to_participant_message, participant.phone_number
puts "#{participant.name} has received a text message at #{participant.phone_number}"
end
end
# sends a backup message to a specified phone number with all assignments.
# @param [Array<Particpant>]
# @param [String] number to contact. e.g. `"555-867-5309"`
def send_backup_message participants, phone_number
intro = "here are the secret santa assignments:\n"
message = intro + participants.map(&:to_backup_message).join("\n")
send_message message, phone_number
puts "a backup of all assignments has been sent to #{phone_number}"
end
private
def send_message message, phone_number
Dotenv.load
client = Twilio::REST::Client.new ENV['TWILIO_SID'], ENV['TWILIO_AUTH']
client.api.account.messages.create(
:from => ENV['TWILIO_NUMBER'],
:to => phone_number,
:body => message
)
end
end
# produces assignments for secret santa. each entry in participant info must
# look like this:
#
# `{ name: 'A', exclusions: ['B','C'], phone_number: "555-555-5555" }`
#
# where exclusions denotes the participants that `A` cannot give presents to.
#
# @param [Array<Hash>] participant info.
# * :name [String] name of participant. must be unique.
# * :phone_number [String] phone number to contact, used by Twillio.
# * :exclusions [Array<String>] names of participants to which the individual cannot give presents.
# @return [Array<Particpant>]
def assign_all participants_hash
participants = participants_hash.map { |info| Participant.new(info) }
do_assign_all participants
end
private
def do_assign_all(participants)
new_participants = participants.
shuffle.
zip(participants).
map { |giver, getter| giver.assignment = getter }
new_participants.all?(&:valid?) ? new_participants : do_assign_all(participants)
end
end