참고: 이 가이드는 Discourse 포럼에서 승인된 봇을 운영한다고 가정합니다. User API 또는 Admin API Key를 사용할 수 있습니다. 봇이 관리자에 의해 차단된 경우, 봇의 목적에 대해 관리자와 논의하고 차단 우회를 시도하지 마세요.
봇을 서버에서 실행하는 것이 더 나은가요? 대신 플러그인을 만드는 것을 고려해 보세요: Developing Discourse Plugins - Part 1 - Create a basic plugin
소개
이 가이드는 봇 사용자가 봇의 사용자가 접근할 수 있는 Discourse 포럼의 모든 게시글(개인 메시지 제외)을 검사하고 처리하는 알고리즘을 제시합니다.
성공적으로 처리된 가장 높은 게시글 ID라는 단일 정수를 위한 영구 저장소가 필요합니다. 예를 들어, 이를 Redis나 평문 파일에 기록할 수 있습니다. Redis를 사용하면 프로세스 재시작 시 메시지 버스 구독을 유지할 수 있습니다.
그룹 및 개인 메시지에 필요한 대로 추가할 수 있도록 봇을 위한 완전히 새로운 사용자 계정을 만드는 것을 강력히 권장합니다. @system 계정을 사용하는 것을 피하세요.
다음 알고리즘 집합은 WHATWG 사양 스타일을 모방하여 작성되었으며, _새로운 게시글을 지속적으로 모니터링_하는 알고리즘으로 점진적으로 발전합니다.
알고리즘 사양
포럼 기본 URL은 뒤따르는 슬래시가 없는 사이트의 URL을 의미합니다 - 예를 들어 https://meta.discourse.org 또는 서브폴더 설치의 경우 https://www.contoso.com/forum.
다음 최근 게시글 가져오기
정수 _가장 높은 확인된 게시글 ID_와 메시지 버스 트리거 플래그가 주어졌을 때 다음 최근 게시글을 가져오기 위해 다음 단계를 실행합니다:
- 최대 응답 게시글 ID를 _가장 높은 확인된 게시글 ID_에 오십(50)을 더한 결과로 설정합니다.
- 요청 URI를 포럼 기본 URL,
/posts.json,?before=, 그리고 _최대 응답 게시글 ID_의 연결로 설정합니다. - 응답을 _요청 URI_와 _자격 증명_을 사용하여 _
레이트 리밋을 준수하여 JSON 가져오기_의 결과로 설정합니다. - _응답_이 HTTP 오류인 경우, 오류와 함께 이 단계를 중단합니다.
- 게시글을 응답 내부의
latest_posts경로에 있는 JSON 배열로 설정합니다. - 새 게시글 확인 플래그를 해제 상태로 설정합니다.
- 게시글 내의 각 JSON 객체 _게시글_에 대해 역순으로 다음 단계를 실행합니다:
- 게시글 ID를 게시글 내부의
id경로에 있는 JSON 숫자로 설정합니다. - _가장 높은 확인된 게시글 ID_를 _게시글 ID_로 설정합니다.
- 새 게시글 확인 플래그를 설정합니다.
_게시글_을 출력합니다. (
즉: 원하는 대로 커스텀 처리를 수행하기 위해 게시글을 전송합니다.)- _emit_이 백프레셔 신호를 반환한 경우, 이 루프를 중단합니다.
- 게시글 ID를 게시글 내부의
-
위의 루프는 역순으로 실행되므로 코드가 가장 오래된 게시글을 먼저, 가장 새로운 게시글을 마지막으로 확인합니다. - 새 게시글 확인 플래그가 설정된 경우:
- _가장 높은 확인된 게시글 ID_를 사용하여
상태를 저장소에 영구 저장하기 단계를 실행합니다.
- _가장 높은 확인된 게시글 ID_를 사용하여
- _가장 높은 확인된 게시글 ID_를 반환하며 이 단계를 종료합니다.
높은 기존 게시글 ID 탐색
높은 기존 게시글 ID를 탐색하기 위해 다음 단계를 실행합니다:
- 최신 탐색 요청 URI를 _포럼 기본 URL_과
/posts.json의 연결로 설정합니다. - 최신 탐색 응답을 _최신 탐색 요청 URI_와 _자격 증명_을 사용하여 _
레이트 리밋을 준수하여 JSON 가져오기_의 결과로 설정합니다. - 최신 탐색 응답이 HTTP 오류인 경우, 오류와 함께 이 단계를 중단합니다.
- 탐색 게시글을 최신 탐색 응답 내부의
latest posts경로에 있는 JSON 배열로 설정합니다. - 탐색 게시글 내의 각 JSON 객체 _게시글_에 대해:
- 게시글 id를 게시글 내부의
id경로에 있는 JSON 숫자로 설정합니다. - _게시글 id_를 반환하며 이 단계를 종료합니다.
- 게시글 id를 게시글 내부의
- 오류와 함께 이 단계를 중단합니다.
최신에서 백필
선택적 정수 _가장 높은 확인된 게시글 ID_가 주어졌을 때 최신에서 백필하기 위해 다음 단계를 실행합니다:
- 최소 게시글 ID를 _가장 높은 확인된 게시글 ID_가 존재하는 경우 해당 값, 그렇지 않으면 영(0)으로 설정합니다.
- 높은 기존 게시글 ID를 _높은 기존 게시글 ID 탐색_의 결과로 설정합니다.
- _최대 게시글 ID_가 오류인 경우, 오류와 함께 이 단계를 중단합니다.
- _최소 게시글 ID_와 _높은 기존 게시글 ID_를 사용하여 백필 단계를 실행합니다.
백필
두 정수 _최소 게시글 ID_와 _높은 기존 게시글 ID_가 주어졌을 때 백필하기 위해:
- 현재 최소 게시글 ID를 _최소 게시글 ID_로 설정합니다.
- 다음 단계를 반복합니다:
- _현재 최소 게시글 ID_와 해제된 메시지 버스 트리거 플래그를 사용하여 다음 최근 게시글 가져오기 단계를 실행합니다.
- 다음 최근 게시글 가져오기 단계가 성공적으로 완료되지 않은 경우:
- 지수 백오프 알고리즘을 실패 신호로 업데이트하고 지정된 시간만큼 대기합니다.
- 다음 루프 반복으로 계속 진행합니다(_현재 최소 게시글 ID_를 업데이트하지 않음).
- 후보 최대 응답 게시글 ID를 _현재 최소 게시글 ID_에 오십(50)을 더한 결과로 설정합니다.
- _후보 최대 응답 게시글 ID_가 _높은 기존 게시글 ID_보다 크거나 같으면,
이 단계를 종료합니다. - _현재 최소 게시글 ID_를 _후보 최대 응답 게시글 ID_로 설정합니다.
새로운 게시글을 지속적으로 모니터링
새로운 게시글을 지속적으로 모니터링하기 위해 다음 단계를 실행합니다:
- 가장 높은 확인된 게시글 ID를 해제된 선택적 정수로 설정합니다.
- _가장 높은 확인된 게시글 ID_를
저장소에서 상태 복원하기의 결과로 설정합니다. - _가장 높은 확인된 게시글 ID_가 해제된 경우:
- 초기 게시글 ID를 _높은 기존 게시글 ID 탐색_의 결과로 설정합니다.
- _초기 게시글 ID_를 사용하여
상태를 저장소에 영구 저장하기 단계를 실행합니다. - _가장 높은 확인된 게시글 ID_를 _초기 게시글 ID_로 설정합니다.
- 알림을 채널이
/latest인
메시지 버스 구독하기 단계를 실행한 결과로 설정합니다. - 다음 단계를 반복적으로 실행합니다:
- _새 가장 높은 확인된 게시글 ID_를 _다음 최근 게시글 가져오기_의 결과로 설정합니다. 메시지 버스 업데이트가 발생하면 메시지 버스 트리거 플래그가 설정되고, _가장 높은 확인된 게시글 ID_가 사용됩니다.
- 다음 최근 게시글 가져오기 단계가 성공적으로 완료되지 않은 경우:
- 지수 백오프 알고리즘을 실패 신호로 업데이트하고 지정된 시간만큼 대기합니다.
- 다음 루프 반복으로 계속 진행합니다.
- _새 가장 높은 확인된 게시글 ID_가 _가장 높은 확인된 게시글 ID_와 다른 경우:
- 지수 백오프 알고리즘을 성공 신호로 업데이트합니다.
- _가장 높은 확인된 게시글 ID_를 _새 가장 높은 확인된 게시글 ID_로 설정합니다.
- _알림_에 대한 메시지 또는 구현에서 정의한 타임아웃이 발생하기를 기다립니다. 이 타임아웃은 10분보다 짧을 수 없으며, 합리적으로 24시간 또는 그보다 약간 더 길게 설정될 수 있습니다.
제공해야 하는 알고리즘:
요청 URI와 선택적 자격 증명을 받아 레이트 리밋을 준수하여 JSON 가져오기.
- 429 오류가 표시되면 지수 백오프 알고리즘 및/또는 서버에서 제공된
Retry-After정보를 사용하여 자동으로 백오프하고 재시도해야 합니다.
- 429 오류가 표시되면 지수 백오프 알고리즘 및/또는 서버에서 제공된
저장소에서 상태 복원하기
정수를 받아 상태를 저장소에 영구 저장하기
메시지 버스 구독하기