• BLOG

  • Secret Santa, version slack (FR)

    sam. 24 novembre 2018 Dan Lousqui

    Share on: Twitter - Facebook - Google+

    santa

    Pour les fêtes de fin d'année, un collègue a eu l'idée très sympathique de faire un secret santa. Le principe est simple on met le nom de tout le monde dans un chapeau, chacun tire un nom et chacun doit faire un cadeau (nous avons mis un budget d'environ 20€) à la personne tirée.

    Forcément ... Nous n'allions pas faire ça de façon classique avec un chapeau et des bouts de papiers, nous sommes au XXIème siècle ! Il fallait faire ça comme un hackeur.

    Le cahier des charges est le suivant :

    • On ne doit pas pouvoir se piocher soi-même ;
    • Il faut empêcher que quelqu'un pioche celui qui l'a pioché ;
    • Il faut que le tirage reste secret de tous ! (sauf celui à qui on doit offrir quelque chose).

    Les solutions existantes

    En bon hackeur, on se doit d'être flemmard. Du coup, regardons ce qui existe déjà. Direction google, avec les mots clés secret santa generator. Voici les résultats les plus pertinents :

    • namedrawing: Malgré une interface pas très agréable, l'application permet de remplir une liste de noms, et une liste d'affinité (qui veut offrir à qui, et qui ne veut pas offrir à qui), ce qui est pas mal intéressant. Cependant, un gros défaut est que la génération du résultat s'affiche directement sur la page... donc l'organisateur verra forcement qui offre à qui, ce qui enlèvera indéniablement de la surprise.

    • secretsantaorganizer: Cette version est beaucoup plus intéressante, on remplie la liste des personnes et leurs emails, puis un email sera envoyé à chaque participant avec le nom de la personne qu'elle doit gâter. Le seul problème est que nous n'avions pas envie de donner nos adresses emails à ce genre de site, cela aurait été du spam garanti.

    • arcanis/secretsanta: Ici, on change l'approche, on n'envoie plus les noms des personnes par email, mais on les chiffre en AES. Du coup, la personne qui organise l'événement rentre les noms des participants, l'application générera la liste et donnera à l'organisateur des liens pour chaque participant qui une fois cliqué, révélera le nom de la personne choisie. C'est une bonne approche, mais malheureusement, l'organisateur peut "cliquer" sur un lien avant de le donner afin de savoir qui offrira quelque chose à qui.

    Bref, aucune solution n'est satisfaisante... tant mieux, on va coder ça nous-mêmes !

    La solution comme un hackeur

    On ne change pas une équipe qui gagne, on va faire ça en python.

    Premier défi : comment tirer au sort qui offre à qui.

    Tout d'abord, on commence avec une liste de participants :

    user = ["dan", "maxou", "clément", "mehdi", "stephan", "tim", "victor"]
    

    Il faut ensuite, pour chaque élément de cette liste, en tirer un. C'est un peu fastidieux, car il y a le risque que quelqu'un tombe sur lui-même. De plus, cette personne peut être la dernière sur laquelle on boucle, impliquant un retry, et random + retry ne font jamais bon ménage (car la fin ne serait plus déterministe).

    Une façon plus intelligente de le faire, est de mélanger le tableau, et que l'élément n du tableau doit offrir à l'élément n + 1. Pour cela, la fonction random.shuffle en python est parfaite :

    import random
    random.shuffle(user)
    for i in range(len(user)):
      print(f"🎅 Secret Santa 🎅 {user[i]} offrira une 🎁 surprise 🎁 à {user[(i + 1) % len(user)]} 🎉🎉🎉")
    

    Ce qui donne le résultat :

    🎅 Secret Santa 🎅 dan offrira une 🎁 surprise 🎁 à mehdi 🎉🎉🎉
    🎅 Secret Santa 🎅 mehdi offrira une 🎁 surprise 🎁 à stephan 🎉🎉🎉
    🎅 Secret Santa 🎅 stephan offrira une 🎁 surprise 🎁 à victor 🎉🎉🎉
    🎅 Secret Santa 🎅 victor offrira une 🎁 surprise 🎁 à tim 🎉🎉🎉
    🎅 Secret Santa 🎅 tim offrira une 🎁 surprise 🎁 à clément 🎉🎉🎉
    🎅 Secret Santa 🎅 clément offrira une 🎁 surprise 🎁 à maxou 🎉🎉🎉
    🎅 Secret Santa 🎅 maxou offrira une 🎁 surprise 🎁 à dan 🎉🎉🎉
    

    Parfait ! Sauf que l'organisateur qui exécutera le script vera qui offre à qui, et surtout, comment les gens sauront à qui offrir ?

    Pour cela, une solution simple est d'utiliser l'API de Slack ! En créant un Incoming Webhooks, on peut envoyer directement des messages privés via Slack :

    import requests
    slack_url = "https://hooks.slack.com/services/XXX/XXX/XXX"
    requests.post(
        slack_url,
        json={
          "text":"🎅 Secret Santa 🎅 FOO offrira une 🎁 surprise 🎁 à BAR 🎉🎉🎉",
          "channel":"@USERNAME"
        }
    )
    

    Ce qui donne le résultat :

    <Response [200]>
    

    Mais enverra au destinataire :

    slack

    Résultat final

    Du coup, en remplaçant les print par des envois sur Slack, on obtient le code suivant :

    import requests
    import random
    
    slack_url="https://hooks.slack.com/services/XXX/XXX/XXX"
    user=["dan", "maxou", "clément", "mehdi", "stephan", "tim", "victor"]
    random.shuffle(user)
    for i in range(len(user)):
      requests.post(
        slack_url,
        json={
          "text":f"🎅 Secret Santa 🎅 {user[i]} offrira une 🎁 surprise 🎁 à {user[(i + 1) % len(user)]} 🎉🎉🎉",
          "channel":f"@{user[i]}"
        }
      )
    

    Qui affichera à l'organistateur :

    <Response [200]>
    <Response [200]>
    <Response [200]>
    <Response [200]>
    <Response [200]>
    <Response [200]>
    <Response [200]>
    

    Et enverra anonymement l'information à chaque participant !

  • Comments