Created
September 14, 2020 09:22
-
-
Save boudra/f84a7680ba6688eea23471fa9032de3a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule TBOE.Tasks.LunchBot do | |
@token "token here" | |
@channel "#lunch-bot" | |
@slack_endpoint "https://slack.com/api" | |
@last_couples_file "/tmp/lunch_last_couples.txt" | |
@greeting """ | |
Hello @channel :wave: | |
:point_down: Here are next week's couples! have coffee or lunch anytime next week with the person you've been paired with :hugging_face: | |
{{couples}} | |
Bon profit :yum: and remember to post selfies! :selfie: | |
_Did I forget about you? :disappointed: Don't worry, have some patience and I'll match you next week._ | |
""" | |
# usernames of users you wan't to prevent from being matched | |
@user_blacklist [ | |
] | |
@start_apps [ | |
:hackney, | |
:ssl, | |
:httpoison | |
] | |
def config do | |
%{ | |
token: @token, | |
channel: @channel, | |
greeting: @greeting | |
} | |
end | |
def run() do | |
Enum.each(@start_apps, &Application.ensure_all_started/1) | |
case do_run(config()) do | |
{:error, error} -> | |
raise inspect(error) | |
_ -> | |
IO.puts("success") | |
end | |
end | |
defp do_run(%{token: token, greeting: greeting} = config) do | |
with {:ok, members} <- retrieve_users(token) do | |
banned = @user_blacklist | |
filtered_members = | |
members | |
|> Enum.reject(fn user -> | |
user["is_bot"] || user["is_app_user"] || user["is_restricted"] || user["deleted"] || | |
user["tz"] != "Europe/Amsterdam" || Enum.member?(banned, user["name"]) | |
end) | |
|> Enum.map(&Map.get(&1, "id")) | |
user_count = Float.floor(Enum.count(filtered_members) * 0.8) |> round | |
last_selected_couples = last_selected_couples() |> Enum.take(user_count) | |
last_selected_users = last_selected_couples() |> List.flatten() |> Enum.take(user_count * 2) | |
couples = | |
filtered_members | |
|> Enum.sort_by(&Enum.member?(last_selected_users, &1)) | |
|> Enum.take(user_count) | |
|> Enum.shuffle() | |
|> Enum.chunk_every(2, 2, :discard) | |
|> Kernel.--(last_selected_couples) | |
couples | |
|> build_text(greeting) | |
|> post_to_slack(config) | |
|> case do | |
{:ok, _} -> | |
serialized_last_couples = | |
couples | |
|> Enum.map_join("", fn [a, b] -> | |
"#{a},#{b}\n" | |
end) | |
File.write(@last_couples_file, serialized_last_couples, [:append]) | |
error -> | |
error | |
end | |
end | |
end | |
defp last_selected_couples() do | |
@last_couple_file | |
|> File.read() | |
|> case do | |
{:ok, data} -> | |
data | |
|> String.split("\n") | |
|> Enum.map(&String.split(&1, ",")) | |
{:error, _} -> | |
[] | |
end | |
end | |
defp post_to_slack(text, %{token: token, channel: channel}) do | |
HTTPoison.post( | |
"#{@slack_endpoint}/chat.postMessage", | |
{:form, [as_user: true, token: token, channel: channel, text: text, link_names: true]} | |
) | |
end | |
def build_text(couples, greeting) do | |
text = | |
couples | |
|> Enum.map(fn [a, b] -> | |
"<@#{a}> with <@#{b}>" | |
end) | |
|> Enum.join("\n") | |
String.replace(greeting, "{{couples}}", text) | |
end | |
def retrieve_users(token) do | |
case HTTPoison.post( | |
"#{@slack_endpoint}/users.list", | |
{:form, [token: token]} | |
) do | |
{:ok, resp} -> | |
members = | |
resp | |
|> Map.get(:body, "") | |
|> Poison.decode!() | |
|> Map.get("members", []) | |
{:ok, members} | |
error -> | |
error | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment