Création d'un utilisateur en stage via un appel API

Nous disposons actuellement d’un flux de travail où les utilisateurs soumettent des données en envoyant un e-mail à une adresse e-mail entrante personnalisée, créant ainsi un utilisateur en attente et un message privé à un groupe Discourse.

Est-il possible d’obtenir le même flux de travail en utilisant des appels d’API ? Basically 1) créer un utilisateur en attente, 2) générer une clé API pour cet utilisateur, puis 3) publier au nom de cet utilisateur ? Je vois comment publier des messages de groupe pour les utilisateurs existants en utilisant la documentation de l’API, mais je ne sais pas si les étapes 1) et 2) sont possibles actuellement.

4 « J'aime »

Yes, just create a user via the api. They won’t be “staged” at this point since they actually exist. If they ever need to log in, they can just reset their password.

This is also possible


Here is a rough example of how to create a user, active them, and generate an api key for them.
    def create_user
      user = {
        name: example1,
        email: "example1@example.com",
        password: "ZvAmmkcSWQfsPQLBksg7wK59",
        username: example1,
        active: "false",
        approved: "true",
        approved_by_id: 1,
        approved_at: DateTime.now
      }

      new_user = @client.create_user(user)
      id = new_user['user_id']
      @client.activate(id)
      uri = URI.parse(@config.full_discourse_url)
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      request = Net::HTTP::Post.new("/admin/users/#{id}/generate_api_key?api_key=#{@client.api_key}&api_username=#{@client.api_username}")
      response = http.request(request)
      result = JSON.parse(response.body)
    end

Another option instead of generating an api key for each user is you can just instantiate a new discourse client using the same admin api key and just specify the new username:

client = DiscourseApi::Client.new("http://127.0.0.1:3000")
client.api_key = "a71cb5058c6be27e42806ad788bc7b0008af9c15170d1be1827a24c8e8334107"
client.api_username = "system"

... create user here...

client2 = DiscourseApi::Client.new("http://127.0.0.1:3000")
client2.api_key = "a71cb5058c6be27e42806ad788bc7b0008af9c15170d1be1827a24c8e8334107"
client2.api_username = example1

... create post here ...
10 « J'aime »

I’m trying to avoid creating a full-fledged user account and picking a username. Essentially I want to replicate whatever is happening in the email trigger (‘custom incoming email address’ in the group settings) where the sender’s email address will be ‘staged,’ such that if/when they do register, they’ll be able to claim any messages that were created on their behalf via the email trigger.

Does that make sense? Is there a way to ‘spoof’ an incoming email using API calls? Thanks for all your help!

You might just have to generate an email and send that to your Discourse instance.

EDIT: Actually there is an /admin/email/handle_mail POST route that you can send an API request to.

8 « J'aime »

Thank you, this is exactly what I was looking for!

1 « J'aime »

Pourriez-vous préciser quels en-têtes et champs doivent figurer dans l’appel API vers /admin/email/handle_email pour créer un utilisateur temporaire et un sujet en son nom ?

Aussi, ai-je bien compris que cet utilisateur recevra des notifications pour les nouveaux messages dans ce sujet et pourra y répondre par e-mail ?

Et que se passe-t-il si j’essaie de créer un utilisateur temporaire et un sujet via un appel API avec une adresse e-mail appartenant à un utilisateur actif ? Ce sujet sera-t-il créé au nom de cet utilisateur ?

J’ai déjà découvert que le bon point de terminaison est /admin/email/handle_mail (et non « handle_email »), mais je n’arrive toujours pas à comprendre ce qui doit figurer dans la requête API.

1 « J'aime »

Le seul paramètre que prend ce point de terminaison est un message email valide :

curl -i -sS -X POST "http://localhost:3000/admin/email/handle_mail" \
-H "Api-Key: 852b2d8556777aeb62346e0d8b36ed248a89b03f0261165a685c0aae9c8c2fdd" \
-H "Api-Username: system" \
-F "email=Date: Mon, 24 Feb 2020 13:13:34 -0700
From: stageduser2@example.com
To: awesome@example.com
Subject: test email5

This is a sample email message.
"

Vous devrez vous assurer d’avoir correctement activé email_in et configuré votre catégorie ou groupe pour recevoir ces e-mails :

Oui, je le crois.

Oui, le sujet sera créé au nom de l’utilisateur.

5 « J'aime »

Merci, Blake. Cependant, cela ne fonctionne toujours pas pour moi. J’ai reçu une réponse de l’API « email has been received and is queued for processing », mais rien n’apparaît dans Discourse – ni un nouveau sujet, ni un utilisateur en attente.

Voici un aperçu des paramètres :
Global :

  • email_in : activé
  • email_in_min_trust : 0
  • enable_staged_users : activé

Catégorie :

  • Adresse e-mail entrante personnalisée : définie sur [my_name]@gmail.com
  • Accepter les e-mails d’utilisateurs anonymes sans compte : activé

Appel API :
curl -i -sS -X POST "[my_domain]/admin/email/handle_mail" -H "Content-Type: multipart/form-data;" -H "Api-Key: [...]" -H "Api-Username: system" -F "email=Date: Mon, 24 Feb 2020 13:13:34 -0700 From: [some_name]@gmail.com To: [my_name]@gmail.com Subject: test API email post This is a sample email message."

Qu’est-ce qui pourrait être incorrect ?

Votre Sidekiq fonctionne-t-il correctement ?

Comment puis-je vérifier cela ?

Vous pouvez vérifier si Sidekiq est en cours d’exécution en accédant à /sidekiq, mais je pense qu’il y a probablement un problème avec les e-mails bruts maintenant que la requête API réussit. Il y a plusieurs onglets dans le tableau de bord d’administration que vous pouvez consulter pour les erreurs d’e-mail.

  • /admin/email/sent
  • /admin/email/skipped
  • /admin/email/bounced
  • /admin/email/received
  • /admin/email/rejected

Voyez si vous pouvez trouver les e-mails que vous créez via des appels API dans l’un de ces onglets ; vous pourrez peut-être voir un message d’erreur associé.

1 « J'aime »

Oui, sidekiq est en cours d’exécution. J’ai vérifié les onglets /admin/email – il semble que mes « emails » soient en fait rejetés.
Voici ce que j’obtiens :

J’ai inséré le même texte d’email dans l’onglet « Texte avancé », et cela semble fonctionner, à condition que chaque partie (Date, De, À, Objet) commence sur une nouvelle ligne et que le corps soit séparé par deux sauts de ligne. Lorsque j’insère le texte exactement comme dans curl, rien n’est renvoyé. Serait-ce dû aux sauts de ligne dans l’email brut ? Si oui, que dois-je faire ?

J’ai essayé /n, %0A et $'[text/n]', mais aucun ne fonctionne.

Je ne suis pas sûr. On dirait que cela n’accepte aucun des champs de votre e-mail.

J’ai utilisé Ruby pour générer la commande curl et Ruby pour lire le fichier texte de mon e-mail que j’ai écrit, mais oui, il semble s’agir d’un problème de saut de ligne.

Pouvez-vous faire en sorte que curl lise un fichier e-mail contenant de vrais sauts de ligne ?

curl -X POST -i -F parametername=@filename host:port/xxx

3 « J'aime »

Vous aviez raison — c’était un problème de saut de ligne. J’ai essayé le même appel API depuis Postman, et cela a fonctionné : un nouvel utilisateur en phase de test a été créé, ainsi qu’un sujet en son nom.

Cependant : aucun e-mail n’a été envoyé à l’adresse de cet utilisateur ! J’ai également publié un commentaire dans le sujet, mais aucune notification par e-mail non plus. Existe-t-il un paramètre qui l’empêche ? J’ai essayé d’en trouver un, mais sans succès.

MISE À JOUR : Il y avait effectivement un paramètre qui empêchait l’envoi des notifications de publication :slight_smile: J’ai donc maintenant deux questions différentes :

  1. Pourquoi aucun e-mail n’a informé l’utilisateur en phase de test que le sujet avait été créé et ne lui a pas envoyé le lien vers celui-ci ?
    (J’ajouterais également quelques instructions sur la façon de se connecter au forum, si je savais quel modèle modifier.)
  2. Pourquoi n’y a-t-il pas de lien vers le sujet dans les e-mails de notification de publication ? Il n’y a pas non plus de lien de désabonnement.
    Le modèle semble être le même : “user_posted”.

Quel est ce paramètre pour ceux qui suivent ? Je ne pense pas avoir eu à modifier quoi que ce soit, donc je suis simplement curieux.

Je pense que c’est conçu ainsi et que la même chose se produit si vous envoyez un e-mail à un groupe Discourse. Il est conçu pour fonctionner exactement comme un e-mail, car l’utilisateur pourrait même ne pas savoir qu’il envoie un e-mail dans un forum Discourse. Si je vous envoie un e-mail ordinaire à votre compte e-mail, je ne reçois pas de réponse de votre fournisseur de messagerie indiquant que vous avez reçu mon e-mail ; nous faisons simplement confiance au fait que cela fonctionne.

Voici un exemple de notification e-mail qu’un utilisateur mis en scène recevra :

mais voici ce qu’un utilisateur non mis en scène recevra :

Il semble y avoir une différence entre les utilisateurs mis en scène et les utilisateurs non mis en scène. Probablement parce que l’utilisateur est mis en scène, cela doit être comme interagir via un e-mail ordinaire.

2 « J'aime »

En fait, il y en avait plusieurs.

  • default email level (niveau e-mail par défaut) - la valeur par défaut est “seulement en cas d’absence”
  • email time window (fenêtre temporelle des e-mails) - la valeur par défaut est de 10 minutes, de sorte que l’e-mail de notification n’est pas envoyé immédiatement
  • disable emails (désactiver les e-mails) - la valeur par défaut est “non”, mais je l’avais modifiée auparavant et j’avais oublié :man_facepalming:

Bon, pour moi, la notification de publication ne ressemble pas vraiment à un e-mail classique de toute façon - par exemple, elle contient un lien vers le profil de l’auteur de la publication sur le forum (deux fois !), mais pas vers le sujet.

De plus, je voudrais informer l’utilisateur en cours de test qu’il peut en fait se connecter au forum.
Existe-t-il un moyen de personnaliser ce modèle d’e-mail ?

Par conception, plusieurs champs sont omis pour les utilisateurs en mode « staged » dans les modèles d’e-mails (comme les instructions de réponse) :

Je ne suis pas tout à fait certain de la raison, mais le code indique clairement que c’est ainsi. Vous vous lancez donc dans une bataille difficile, car vous tentez de faire quelque chose que Discourse est conçu pour ne pas faire.

Oui, vous pouvez modifier les modèles d’e-mails, mais vos possibilités de personnalisation sont assez limitées. Par exemple, je ne pense pas qu’il soit possible de configurer un modèle d’e-mail qui s’affiche différemment selon que l’utilisateur est en mode « staged » ou non. En revanche, vous pouvez ajouter un message avec un lien en bas de l’e-mail de notification, invitant les utilisateurs à visiter votre site plutôt que d’interagir uniquement par e-mail.

1 « J'aime »

En fait, il suffirait que le modèle ait le même aspect pour les utilisateurs réguliers et pour les utilisateurs en phase de test :slight_smile:
Je vais réfléchir à ce que je pourrais faire. Merci pour l’explication détaillée !

3 « J'aime »

Une dernière question (j’espère) : comment un utilisateur mis en scène peut-il se désabonner de la réception de nouveaux messages sur le sujet créé en son nom ?