Creating a staged user with an API call

We currently have a workflow where users submit data by sending an email to a custom incoming email address, creating a staged user and a private message to a Discourse group.

Is it possible to achieve the same workflow using API calls? Basically 1) create staged user, 2) generate API key for that user, then 3) post on that users behalf? I see how to post group messages for existing users using the API docs, but don’t know if steps 1) and 2) are possible currently.

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 ...

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.

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

/admin/email/handle_email API 호출을 통해 스테이징된 사용자와 해당 사용자를 대신한 주제를 생성할 때, 어떤 헤더와 필드를 포함해야 하는지 구체적으로 알려 주실 수 있나요?

또한, 그렇게 생성된 사용자는 해당 주제에 새 게시물이 등록되면 알림을 받고, 이메일을 통해 해당 게시물에 답글을 달 수 있다는 제 이해가 맞는지 확인하고 싶습니다.

그리고 활성 사용자의 이메일 주소를 사용하여 API 호출로 스테이징된 사용자와 주제를 생성하려고 하면 어떻게 되나요? 이 주제가 해당 활성 사용자를 대신해 생성되나요?

올바른 엔드포인트가 /admin/email/handle_mail(handle_email이 아님)이라는 것은 이미 알아냈지만, API 요청에 무엇을 넣어야 하는지는 여전히 파악이 안 됩니다.

이 엔드포인트가 받는 유일한 매개변수는 유효한 email 메시지입니다:

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.
"

이러한 이메일을 받을 수 있도록 카테고리나 그룹을 올바르게 설정했는지 확인해야 합니다. email_in을 올바르게 활성화해야 합니다:

네, 그렇게 생각됩니다.

네, 해당 주제는 해당 사용자를 대신해 생성됩니다.

Blake님, 감사합니다. 하지만 제 환경에서는 여전히 작동하지 않습니다. API에서 "email has been received and is queued for processing"라는 응답을 받았지만, Discourse에는 아무것도 표시되지 않습니다. 새로운 주제도, 대기 중인 사용자도 없습니다.

설정 검토 내용은 다음과 같습니다:
전역:

  • email_in: on
  • email_in_min_trust: 0
  • enable_staged_users: on

카테고리:

  • 사용자 지정 수신 이메일 주소: [my_name]@gmail.com으로 설정
  • 계정이 없는 익명 사용자의 이메일 허용: on

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."

어떤 문제가 있을까요?

Sidekiq가 정상적으로 실행되고 있나요?

그걸 어떻게 확인할 수 있나요?

/sidekiq으로 이동하여 Sidekiq가 실행 중인지 확인할 수 있습니다. 하지만 이제 API 요청이 성공하고 있으므로, 현재는 원본 이메일(raw email)에 문제가 있을 가능성이 높습니다. 관리 대시보드에는 이메일 오류를 확인할 수 있는 여러 탭이 있습니다.

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

API 호출을 통해 생성한 이메일이 위 탭 중 하나에 있는지 확인해 보세요. 해당 이메일과 관련된 오류 메시지를 볼 수 있을 것입니다.

네, sidekiq는 실행 중입니다. /admin/email 탭을 확인해 보니, 제 "이메일"이 실제로는 거부(rejected)되고 있네요.
다음과 같은 결과를 얻고 있습니다:

“고급 텍스트(Advanced text)” 탭에 동일한 이메일 텍스트를 입력해 보니, 각 항목(날짜, 발신자, 수신자, 제목)이 새 줄로 시작하고 본문은 두 개의 줄바꿈으로 구분될 경우 작동하는 것 같습니다. curl과 정확히 같은 방식으로 텍스트를 입력하면 아무것도 반환되지 않습니다. 이는 원시(raw) 이메일의 줄바꿈 때문일까요? 그렇다면 어떻게 해야 할까요?

/n, %0A, $'[text/n]'을 시도해 보았지만, 어느 것도 작동하지 않습니다.

확신은 없습니다. 이메일의 어떤 필드도 제대로 인식하지 못하는 것 같습니다.

ruby를 사용해 curl 명령을 생성하고, 내가 작성한 이메일 텍스트 파일을 읽었습니다. 하지만 그렇습니다. 줄바꿈 관련 문제인 것으로 보입니다.

실제 줄바꿈이 포함된 이메일 파일을 curl이 읽을 수 있는지 확인해 주실 수 있을까요?

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

맞아요 - 줄바꿈 문제였네요. Postman에서 동일한 API 호출을 시도해 봤는데, 성공했습니다 - 새로운 스테이징 사용자가 생성되었고, 그 사용자를 대신하여 토픽이 생성되었습니다.

하지만: 이 사용자의 이메일 주소로 이메일이 발송되지 않았습니다! 토픽에 댓글을 작성해 봤는데, 이메일 알림도 없었습니다. 이를 방지하는 설정이 있을까요? 찾아보려 했지만 찾을 수 없었습니다.

UPD: 실제로 게시글 알림 전송을 방지하는 설정이 있었네요 :slight_smile: 이제 두 가지 다른 질문이 있습니다:

  1. 스테이징 사용자에게 토픽이 생성되었음을 알리고 해당 링크를 보내는 이메일이 왜 발송되지 않았나요?
    (포럼에 로그인하는 방법에 대한 설명도 추가하고 싶은데, 어떤 템플릿을 수정해야 하는지 알면요.)
  2. 게시글 알림 이메일에 토픽 링크가 왜 없나요? 구독 해지 링크도 없습니다.
    템플릿은 동일한 것 같은데 - "user_posted"입니다.

관심 있는 분들을 위해, 어떤 설정이었나요? 저는 아무것도 변경하지 않은 것 같아서 궁금합니다.

이것은 의도된 동작이라고 생각합니다. Discourse 그룹으로 이메일을 보내는 경우에도 동일한 일이 발생합니다. 사용자는 자신이 Discourse 포럼으로 이메일을 보내고 있다는 사실조차 모를 수 있도록 설계되어 있기 때문입니다. 일반 이메일 계정으로 이메일을 보내면, 이메일 제공업체로부터 이메일이 수신되었다는 답장을 받지 않듯이, 우리는 그것이 작동한다고 믿고 있습니다.

스테이징된 사용자가 수신하는 알림 이메일의 예시는 다음과 같습니다:

하지만 스테이징되지 않은 사용자가 수신하는 내용은 다음과 같습니다:

스테이징된 사용자와 스테이징되지 않은 사용자 사이에 차이가 있는 것으로 보입니다. 사용자는 스테이징 상태이므로, 일반 이메일을 통한 상호작용과 동일하게 처리되기 때문일 가능성이 높습니다.

실제로 여러 가지가 있었습니다.

  • 기본 이메일 수준 - 기본값은 "부재 중에만"입니다.
  • 이메일 시간 창 - 기본값은 10분으로, 알림 이메일이 즉시 전송되지 않습니다.
  • 이메일 비활성화 - 기본값은 "아니오"이지만, 이전에 변경해 두었다가 잊고 있었습니다 :man_facepalming:

음, 제게는 게시물 알림이 일반 이메일처럼 보이지 않습니다. 예를 들어, 포럼에서 게시물 작성자의 프로필로 가는 링크가 두 번이나 있지만, 주제(토픽)로 가는 링크는 없습니다.

또한, 스테이지된 사용자에게 실제로 포럼에 로그인할 수 있다는 사실을 알려주고 싶습니다.
이 이메일 템플릿을 사용자 지정할 수 있는 방법이 있나요?

설계상, 단계적 승인(staged) 사용자의 이메일 템플릿에서는 응답 지침과 같은 여러 필드가 생략됩니다:

그 이유에 대해 정확히 확신은 없지만, 코드 상으로는 이렇게 구현되어 있으므로, 현재는 Discourse가 기본적으로 지원하지 않는 작업을 시도하고 있어 상당한 어려움에 직면해 있다고 볼 수 있습니다.

네, 이메일 템플릿을 수정할 수는 있지만, 커스터마이징할 수 있는 범위는 매우 제한적입니다. 예를 들어, 단계적 승인 사용자와 일반 사용자에게 각각 다른 스타일의 이메일 템플릿을 적용하는 것은 불가능하다고 생각합니다. 대신, 알림 이메일 하단에 메시지를 추가하여 이메일로만 상호작용하는 대신 웹사이트를 방문하도록 유도하는 링크를 넣는 것은 가능합니다.

실제로는 일반 사용자와 스테이징 사용자에게 템플릿이 동일하게 보이면 충분합니다 :slight_smile:
어떤 조치를 취할 수 있을지 생각해 보겠습니다. 자세한 설명 감사합니다!

마지막으로 한 가지 질문입니다(바라는 대로라면): 스테이징된 사용자가 자신의 이름으로 생성된 주제에 대한 새 게시물을 받는 것을 구독 해제하려면 어떻게 해야 하나요?