FastComments.com

실시간 댓글 API

FastComments API

FastComments는 다양한 리소스와 상호작용하기 위한 API를 제공합니다. 우리 플랫폼과의 통합을 구축하거나, 자체 클라이언트를 직접 만들어보세요!

이 문서에서는 API가 지원하는 모든 리소스를 요청 및 응답 타입과 함께 문서화하여 확인할 수 있습니다.

엔터프라이즈 고객의 경우 모든 API 접근은 감사 로그에 기록됩니다.

Generated SDKs

FastComments는 이제 코드로부터 API Spec을 생성합니다 (아직 완전하진 않지만 많은 API가 포함되어 있습니다).

또한 다음과 같은 인기 언어용 SDK도 제공합니다:

Authentication

API는 API 키X-API-KEY 헤더 또는 API_KEY 쿼리 매개변수로 전달하여 인증합니다. 또한 API 호출을 위해 tenantId가 필요합니다. 이 값은 API 키와 동일한 페이지에서 확인할 수 있습니다.

Security Note

이 라우트들은 서버에서 호출되도록 설계되었습니다. 절대 브라우저에서 호출하지 마세요. 이렇게 하면 API 키가 노출되어 페이지 소스 코드를 볼 수 있는 누구에게나 계정 전체에 대한 액세스 권한이 제공됩니다!

Authentication Option One - Headers

  • Header: X-API-KEY
  • Header: X-TENANT-ID

Authentication Option Two - Query Parameters

  • Query Param: API_KEY
  • Query Param: tenantId

자신의 작성 내용 읽기

FastComments는 Active-Active 가용성을 제공합니다. 데이터센터에서 보내는 요청은 자동으로 귀하의 위치에 가장 가까운 the nearest point of presence로 라우팅됩니다. 이는 자동으로 이루어지며, 보통은 자신의 쓰기(작성)를 읽는 동작을 관찰할 수 있습니다. 자신의 작성 내용을 확실히 읽고 싶다면 해당 리전을 API 호스트로 사용하여 요청을 특정 리전에 고정(pinning)할 수 있습니다(그러나 대부분의 통합에서는 보통 필요하지 않습니다):

  • gdc-oregon.fastcomments.com
  • gdc-virginia.fastcomments.com
  • gdc-singapore.fastcomments.com
  • gdc-falkenstein2.fastcomments.com
  • gdc-sao-paulo.fastcomments.com
  • eudc-helsinki2.fastcomments.com
  • eudc-limburg.fastcomments.com
  • eudc-france.fastcomments.com

참고: 이렇게 할 경우 과거에 엔트리포인트 노드를 더 이상 사용하지 않게(deprecated)하고 전환 시 새 이름을 사용한 사례가 있으므로 페일백(fallback)을 정의하는 것이 좋습니다.

감사 로그 구조 Internal Link


AuditLog는 이 기능에 접근 권한이 있는 테넌트에 대해 감사된 이벤트를 나타내는 객체입니다.

AuditLog 객체의 구조는 다음과 같습니다:

AuditLog 구조
Copy Copy
1
2interface AuditLog {
3 id: string;
4 userId?: string;
5 username?: string;
6 resourceName: string;
7 crudType: 'c' | 'r' | 'u' | 'd' | 'login';
8 from: string;
9 url?: string;
10 ip?: string;
11 when: string;
12 description?: string;
13 serverStartDate: string;
14 objectDetails?: object;
15}
16

감사 로그는 불변입니다. 수동으로 쓸 수도 없습니다. FastComments.com만 감사 로그에 기록할 시점을 결정할 수 있습니다. 그러나 이 API를 통해 감사 로그를 읽을 수 있습니다.

이 감사 로그의 이벤트는 2년 후에 만료됩니다.


댓글 구조 Internal Link

A Comment object represents a comment left by a user.

The relationship between parent and child comments is defined via parentId.

The structure for the Comment object is as follows:

댓글 구조
Copy Copy
1
2interface Comment {
3 /** READONLY: 스팸 엔진이 댓글을 스팸으로 판정한 경우 true로 설정됩니다. **/
4 aiDeterminedSpam?: boolean
5 /** 댓글이 표시되도록 승인되었는지 여부. 댓글 저장 시 true로 설정되며, 그렇지 않으면 숨겨집니다. **/
6 approved?: boolean
7 /** 사용자의 아바타. **/
8 avatarSrc?: string
9 /** 하위 댓글. 모든 상황에서 채워지지는 않습니다. API를 통해 asTree가 true로 설정된 경우 사용됩니다. **/
10 children: Comment[]
11 /** 작성자가 입력한 원본 댓글. **/
12 comment: string
13 /** READONLY: 작성자의 댓글을 HTML로 파싱한 결과. **/
14 commentHTML?: string
15 /** 작성자의 이메일. 익명 댓글 허용이 꺼져 있으면 필요합니다. **/
16 commenterEmail?: string
17 /** 작성자의 링크(예: 블로그). **/
18 commenterLink?: string
19 /** 작성자의 이름. 항상 필요합니다. 사용 불가능한 경우 'Anonymous' 같은 값을 설정하세요. **/
20 commenterName: string
21 /** 댓글이 남겨진 날짜(UTC epoch). **/
22 date: number
23 /** 댓글의 '표시 레이블' — 예: 'Admin', 'Moderator' 또는 'VIP User'와 같은 값. **/
24 displayLabel?: string
25 /** 댓글이 게시된 도메인. **/
26 domain?: string
27 /** READONLY: 댓글이 신고된 횟수. **/
28 flagCount?: number
29 /** 댓글에 작성되어 성공적으로 파싱된 #해시태그들. 검색용으로 해시태그를 수동으로 추가할 수도 있지만, 자동으로 댓글 본문에 표시되지는 않습니다. **/
30 hashTags?: CommentHashTag[]
31 /** READONLY: 댓글에 이미지가 포함되어 있는지 여부. **/
32 hasImages?: boolean
33 /** READONLY: 댓글에 링크가 포함되어 있는지 여부. **/
34 hasLinks?: boolean
35 /** READONLY: 고유 댓글 ID. **/
36 id: string
37 /** 생성 시에만 사용됩니다! 저장을 위해 해시 처리됩니다. **/
38 ip?: string
39 /** READONLY: 현재 사용자가 이 댓글을 작성한 사용자를 차단했는지 여부. **/
40 isBlocked?: boolean
41 /** READONLY: 댓글 작성자가 관리자(admin)인지 여부. userId를 기반으로 자동 설정됩니다. **/
42 isByAdmin?: boolean
43 /** READONLY: 댓글 작성자가 중재자(moderator)인지 여부. userId를 기반으로 자동 설정됩니다. **/
44 isByModerator?: boolean
45 /** 댓글이 소프트 삭제된 경우 true로 설정됩니다(다른 구성으로 인해 자리 표시자가 남겨져야 했던 경우). **/
46 isDeleted?: boolean
47 /** 사용자의 계정이 삭제되어 댓글을 유지해야 했던 경우 true로 설정됩니다. **/
48 isDeletedUser?: boolean
49 /** READONLY: 현재 로그인한 사용자(contextUserId)가 이 댓글을 신고했는지 여부. **/
50 isFlagged?: boolean
51 /** 댓글이 고정되었는지 여부. **/
52 isPinned?: boolean
53 /** 댓글이 잠겼는지 여부. true이면 잠금 해제될 때까지 누구(중재자 포함)도 답글, 편집 또는 삭제를 할 수 없습니다. **/
54 isLocked?: boolean
55 /** 댓글이 스팸인지 여부. **/
56 isSpam?: boolean
57 /** READONLY: 현재 사용자(contextUserId)가 이 댓글에 대해 다운보트했는지 여부. **/
58 isVotedDown?: boolean
59 /** READONLY: 현재 사용자(contextUserId)가 이 댓글에 대해 업보트했는지 여부. **/
60 isVotedUp?: boolean
61 /** 댓글의 로케일. 제공되지 않으면 HTTP의 Accept-Language 헤더에서 파생됩니다. **/
62 locale?: 'de_de' | 'en_us' | 'es_es' | 'fr_fr' | 'it_it' | 'ja_jp' | 'ko_kr' | 'pl_pl' | 'pt_br' | 'ru_ru' | 'tr_tr' | 'zh_cn' | 'zh_tw'
63 /** READONLY: 댓글에 작성되어 성공적으로 파싱된 @멘션들. **/
64 mentions?: CommentUserMention[]
65 /** 댓글에 연결된 선택적 메타데이터. **/
66 meta?: Record<string, string | number | boolean>
67 /** 이 댓글과 연관된 선택적 중재 그룹 ID 목록. **/
68 moderationGroupIds?: string[]|null
69 /** READONLY: 현재 사용자(contextUserId)가 이 댓글에 한 투표에 해당하는 투표 객체의 ID. **/
70 myVoteId?: string
71 /** 댓글 작성자에게 이 댓글에 대한 알림이 전송되었는지 여부. 가져오기(imports) 시 알림 전송을 방지하려면 이 값을 true로 설정하세요. **/
72 notificationSentForParent?: boolean
73 /** 테넌트 사용자에게 이 댓글에 대한 알림이 전송되었는지 여부. 가져오기 시 알림 전송을 방지하려면 이 값을 true로 설정하세요. **/
74 notificationSentForParentTenant?: boolean
75 /** 이 댓글이 달린 페이지의 제목. **/
76 pageTitle?: string
77 /** 답글일 경우 응답 대상 댓글의 ID입니다. **/
78 parentId?: string|null
79 /** 댓글이 검토됨으로 표시되었는지 여부. **/
80 reviewed: boolean
81 /** 댓글이 속한 테넌트 ID. **/
82 tenantId: string
83 /** 댓글을 작성한 사용자. 이름/이메일과 함께 댓글을 저장할 때 자동으로 생성됩니다. **/
84 userId?: string|null
85 /** 이 댓글이 표시되는 위치의 URL(예: 블로그 게시물). **/
86 url: string
87 /** 전달한 urlId의 '정리된' 버전. 저장 시 이 필드를 지정하지만, 댓글을 가져오면 이 값은 '정리'되어 원래 값은 urlIdRaw로 이동합니다. **/
88 urlId: string
89 /** READONLY: 전달한 원래의 urlId. **/
90 urlIdRaw?: string
91 /** 사용자와 이 댓글이 검증되었는지 여부. **/
92 verified: boolean
93 /** 업보트 수. **/
94 votesUp?: number
95 /** 다운보트 수. **/
96 votesDown?: number
97 /** 댓글의 '카르마'(= 업보트 - 다운보트). **/
98 votes?: number
99}
100

Some of these fields are marked READONLY - these are returned by the API but cannot be set.

댓글 텍스트 구조

Comments are written in a FastComments flavor of markdown, which is just markdown plus traditional bbcode style tags for images, like [img]path[/img].

텍스트는 두 필드에 저장됩니다. 사용자가 입력한 텍스트는 수정되지 않은 채 comment 필드에 저장됩니다. 렌더링된 결과는 commentHTML 필드에 저장됩니다.

The allowed HTML tags are b, u, i, strike, pre, span, code, img, a, strong, ul, ol, li, and br.

HTML은 아주 작은 부분집합이므로 HTML을 렌더링하는 것을 권장합니다. 렌더러를 만드는 것은 비교적 간단합니다. 예를 들어 React Native와 Flutter용으로 이를 도와주는 여러 라이브러리가 있습니다

You may choose to render the un-normalized value of the comment field. An example parser is here..

예제 파서는 HTML에 맞게 조정하여 HTML 태그를 플랫폼에 맞는 렌더링 요소로 변환하도록 할 수도 있습니다.

태깅

When users are tagged in a comment, the information is stored in a list called mentions. Each object in that list has the following structure.

댓글 멘션 객체
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** 사용자 ID. SSO 사용자인 경우 테넌트 ID가 접두사로 붙습니다. **/
4 id: string
5 /** 최종 @멘션 태그 텍스트( @ 기호 포함). **/
6 tag: string
7 /** 원본 @멘션 태그 텍스트( @ 기호 포함). **/
8 rawTag: string
9 /** 어떤 유형의 사용자가 태그되었는지. user = FastComments.com 계정, sso = SSO 사용자. **/
10 type: 'user'|'sso'
11 /** 사용자가 알림 수신을 거부한 경우에도 이 값은 true로 설정됩니다. **/
12 sent: boolean
13}
14

해시태그

When hashtags are used and successfully parsed, the information is stored in a list called hashTags. Each object in that list has the following structure. Hashtags can also be manually added to the comment hashTags array for querying, if retain is set.

댓글 해시태그 객체
Copy CopyRun External Link
1
2interface CommentHashTag {
3 /** 해시태그 ID. **/
4 id: string
5 /** 최종 #해시태그 태그 텍스트(# 기호 포함). **/
6 tag: string
7 /** 해시태그가 커스텀 URL과 연결되어 있으면 이 값이 정의됩니다. **/
8 url?: string
9 /** 댓글을 업데이트할 때 댓글 본문에 존재하지 않더라도 해시태그를 유지할지 여부. 댓글 본문을 변경하지 않고 댓글에 태그를 달 때 유용합니다. **/
10 retain?: boolean
11}
12

이메일 템플릿 구조 Internal Link

EmailTemplate 객체는 테넌트의 맞춤 이메일 템플릿 구성을 나타냅니다.

시스템은 사용할 이메일 템플릿을 다음 기준으로 선택합니다:

  • 유형 식별자 — 이를 emailTemplateId라고 합니다. 이 값들은 상수입니다.
  • domain. 먼저 관련 객체(예: Comment)가 속한 도메인에 대한 템플릿을 찾습니다. 일치하는 템플릿이 없으면 domain이 null이거나 *인 템플릿을 찾습니다.

다음은 EmailTemplate 객체의 구조입니다:

이메일 템플릿 구조
Copy Copy
1
2interface EmailTemplate {
3 id: string
4 tenantId: string
5 emailTemplateId: string
6 displayName: string
7 /** 읽기 전용 **/
8 createdAt: string
9 /** 읽기 전용 **/
10 updatedAt: string
11 /** 읽기 전용 **/
12 updatedByUserId: string
13 /** 템플릿이 연관된 도메인. **/
14 domain?: string | '*' | null
15 /** EJS 구문으로 된 이메일 템플릿 콘텐츠. **/
16 ejs: string
17 /** 지원되는 각 로케일에 대해 재정의된 번역 키와 값의 맵. **/
18 translationOverridesByLocale: Record<string, Record<string, string>>
19 /** 템플릿의 렌더 컨텍스트를 나타내는 객체. **/
20 testData: object
21}
22

참고

  • 유효한 emailTemplateId 값은 /definitions 엔드포인트에서 확인할 수 있습니다.
  • /definitions 엔드포인트에는 기본 번역과 테스트 데이터도 포함되어 있습니다.
  • 템플릿은 구조나 테스트 데이터가 유효하지 않으면 저장에 실패합니다.

해시태그 구조 Internal Link

HashTag 객체는 사용자가 남길 수 있는 태그를 나타냅니다. HashTags는 외부 콘텐츠로 연결하거나 관련된 댓글들을 묶는 데 사용할 수 있습니다.

The structure for the HashTag object is as follows:

HashTag 구조
Copy Copy
1
2interface HashTag {
3 /** "#" 또는 원하는 문자로 시작해야 합니다. **/
4 tag: string
5 /** 해시태그가 가리킬 수 있는 선택적 URL입니다. 해시태그로 댓글을 필터링하는 대신, UI는 클릭 시 이 URL로 리디렉션합니다. **/
6 url?: string
7 /** 읽기 전용 **/
8 createdAt: string
9}
10

Notes:

  • In some API endpoints you will see that the hashtag is used in the URL. Remember to URI-Encoded values. For example, # should instead be represented as %23.
  • Some of these fields are marked READONLY - these are returned by the API but cannot be set.

알림 카운트 구조 Internal Link


NotificationCount 객체는 사용자의 읽지 않은 알림 수와 메타데이터를 나타냅니다.

읽지 않은 알림이 없으면 해당 사용자에 대한 NotificationCount가 존재하지 않습니다.

NotificationCount 객체는 자동으로 생성되며 API를 통해 생성할 수 없습니다. 또한 1년 후에 만료됩니다.

사용자의 NotificationCount를 삭제하면 읽지 않은 알림 수를 초기화할 수 있습니다.

NotificationCount 객체의 구조는 다음과 같습니다:

NotificationCount 구조
Copy Copy
1
2interface NotificationCount {
3 id: string // 사용자 ID
4 count: number
5 createdAt: string // 날짜 문자열
6 expireAt: string // 날짜 문자열
7}
8

알림 구조 Internal Link

A Notification 객체는 사용자를 위한 알림을 나타냅니다.

Notification 객체는 자동으로 생성되며 API를 통해 생성할 수 없습니다. 또한 1년 후에 만료됩니다. 알림은 삭제할 수 없습니다. 하지만 viewedfalse로 설정하여 업데이트할 수 있으며, viewed로 조회할 수 있습니다.

사용자는 알림에서 특정 댓글에 대해 optedOuttrue로 설정하여 알림을 받지 않도록 선택할 수 있습니다. false로 설정하면 다시 수신하도록 할 수 있습니다.

알림 유형은 다양합니다 - relatedObjectTypetype을 확인하세요.

알림이 생성되는 방식은 매우 유연하며 다양한 시나리오에 의해 트리거될 수 있습니다 (NotificationType 참조).

현재 Notification이 존재한다고 해서 이메일이 전송되거나 전송되어야 함을 의미하지 않습니다. 대신 알림은 알림 피드와 관련 통합에 사용됩니다.

Notification 객체의 구조는 다음과 같습니다:

알림 구조
Copy Copy
1
2enum NotificationObjectType {
3 Comment = 0,
4 Profile = 1,
5 Tenant = 2
6}
7
8enum NotificationType {
9 /** If someone replied to you. **/
10 RepliedToMe = 0,
11 /** If someone replied anywhere in a thread (even children of children) of a thread you commented on. **/
12 RepliedTransientChild = 1,
13 /** If your comment was up-voted. **/
14 VotedMyComment = 2,
15 /** If a new comment is left on the root of a page you're subscribed to. **/
16 SubscriptionReplyRoot = 3,
17 /** If someone commented on your profile. **/
18 CommentedOnProfile = 4,
19 /** If you have a DM. **/
20 DirectMessage = 5,
21 /** TrialLimits is for tenant users only. **/
22 TrialLimits = 6,
23 /** If you were @mentioned. **/
24 Mentioned = 7
25}
26
27interface Notification {
28 id: string
29 tenantId: string
30 /** With SSO, the user id is in the format `<tenant id>:<user id>`. **/
31 userId?: string
32 /** When working with SSO, you only have to worry about `userId`. **/
33 anonUserId?: string
34 /** urlId is almost always defined. It is only optional for tenant-level notifications, which are infrequent. **/
35 urlId?: string
36 /** URL is cached for quick navigation to the source of the notification. **/
37 url?: string
38 /** Page Title is cached for quick reading of notification source. **/
39 pageTitle?: string
40 relatedObjectType: NotificationObjectType
41 /** For example, comment id. **/
42 relatedObjectId: string
43 viewed: boolean
44 createdAt: string // date string
45 type: NotificationType
46 fromCommentId?: string
47 fromVoteId?: string
48 /** fromUserName and fromUserAvatarSrc are cached here for quick displaying of the notification. They are updated when the user is updated. **/
49 fromUserName: string
50 fromUserId: string
51 fromUserAvatarSrc?: string
52 /** Set this to true to stop getting notifications for this object. **/
53 optedOut?: boolean
54}
55

페이지 구조 Internal Link

A Page 객체는 여러 댓글이 속할 수 있는 페이지를 나타냅니다. 이 관계는 urlId로 정의됩니다.

A Page는 페이지 제목, 댓글 수, 및 urlId와 같은 정보를 저장합니다.

Page 객체의 구조는 다음과 같습니다:

페이지 구조
Copy Copy
1
2interface Page {
3 id: string
4 urlId: string
5 url: string
6 title?: string
7 createdAt: string
8 commentCount: number
9 rootCommentCount: number
10 /** 이를 null로 설정하면 모든 SSO 사용자가 페이지를 볼 수 있습니다. 빈 리스트는 모든 사용자에게 닫혀 있음을 의미합니다. **/
11 accessibleByGroupIds?: string[] | null
12 /** 이 페이지가 새 댓글 작성에 대해 닫혀 있나요? **/
13 isClosed?: boolean
14}
15

보류 중인 웹훅 이벤트 구조 Internal Link

A PendingWebhookEvent 객체는 대기 중인 큐에 저장된 웹훅 이벤트를 나타냅니다.

PendingWebhookEvent 객체는 자동으로 생성되며 API를 통해 수동으로 생성할 수 없습니다. 또한 1년 후 만료됩니다. 큐에서 작업을 제거하는 삭제가 가능합니다.

이벤트 유형에는 여러 가지가 있습니다 - eventType (OutboundSyncEventType) 및 type (OutboundSyncType)을 확인하세요.

이 API의 일반적인 사용 사례 중 하나는 맞춤형 모니터링 구현입니다. 주기적으로 /count 엔드포인트를 호출하여 주어진 필터에 대한 미해결 수를 폴링할 수 있습니다.

PendingWebhookEvent 객체의 구조는 다음과 같습니다:

PendingWebhookEvent 구조
Copy Copy
1
2enum OutboundSyncEventType {
3 Create: 0,
4 Delete: 1,
5 Update: 2
6}
7
8enum OutboundSyncType {
9 /** WordPress 전용 동기화 작업. **/
10 WP: 0,
11 Webhook: 1
12}
13
14interface PendingWebhookEvent {
15 id: string
16 /** 이벤트와 연관된 댓글 ID. **/
17 commentId: string
18 /** 이벤트 시점의 댓글 객체. 2023년 11월부터 추가하기 시작했습니다. **/
19 comment: Comment
20 /** 댓글과 연결될 수 있는 외부 ID. **/
21 externalId: string | null
22 createdAt: Date
23 tenantId: string
24 attemptCount: number
25 /** 첫 시도 전에 설정되며, 실패할 때마다 갱신됩니다. **/
26 nextAttemptAt: Date
27 /** 생성, 삭제, 또는 업데이트 이벤트인지 여부. **/
28 eventType: OutboundSyncEventType
29 /** 수행할 동기화 유형 (WordPress, API 호출 등). **/
30 type: OutboundSyncType
31 /** 댓글과 일치한 도메인. 이 도메인을 사용하여 API 키를 선택합니다. **/
32 domain: string
33 /** 발생한 마지막 오류. 이 타입은 구체적으로 정의되어 있지 않으며 발생한 내용을 그대로 덤프한 것입니다. 일반적으로 statusCode, body, headers 맵을 포함하는 객체를 담고 있습니다. **/
34 lastError: object | null
35}
36

SSO 사용자 구조 Internal Link

FastComments는 사용하기 쉬운 SSO 솔루션을 제공합니다. HMAC 기반 통합으로 사용자의 정보를 업데이트하는 것은 사용자가 업데이트된 페이로드로 페이지를 로드하도록 하는 것만큼 간단합니다.

하지만 일관된 애플리케이션 관리를 위해 해당 흐름 외부에서 사용자를 관리하는 것이 바람직할 수 있습니다.

SSO 사용자 API는 우리가 SSOUsers라고 부르는 객체를 CRUD할 수 있는 방법을 제공합니다. 이 객체들은 일반 Users와 다르며 타입 안전성을 위해 분리되어 보관됩니다.

SSOUser 객체의 구조는 다음과 같습니다:

SSOUser 구조
Copy Copy
1
2interface SSOUser {
3 id: string
4 username: string
5 email?: string
6 websiteUrl?: string
7 signUpDate: number
8 createdFromUrlId?: string
9 loginCount?: number
10 avatarSrc?: string
11 optedInNotifications?: boolean
12 optedInSubscriptionNotifications?: boolean
13 displayLabel?: string
14 displayName?: string
15 isAccountOwner?: boolean // 관리자 권한 - 이 플래그가 설정된 SSO 사용자는 일반 SSO 사용자와 별도로 SSO 관리자 요금으로 청구됩니다
16 isAdminAdmin?: boolean // 관리자 권한 - 이 플래그가 설정된 SSO 사용자는 일반 SSO 사용자와 별도로 SSO 관리자 요금으로 청구됩니다
17 isCommentModeratorAdmin?: boolean // 중재자 권한 - 이 플래그가 설정된 SSO 사용자는 일반 SSO 사용자와 별도로 SSO 중재자 요금으로 청구됩니다
18 /** null이면 해당 사용자에게 접근 제어가 적용되지 않습니다. 빈 리스트이면 이 사용자는 어떤 페이지도 볼 수 없고 다른 사용자를 @멘션할 수 없습니다. **/
19 groupIds?: string[] | null
20 createdFromSimpleSSO?: boolean
21 /** 다른 사용자가 이 사용자의 프로필에서 댓글을 포함한 활동을 보지 못하게 합니다. 기본값은 안전한 프로필을 위해 true 입니다. **/
22 isProfileActivityPrivate?: boolean
23 /** 다른 사용자가 사용자의 프로필에 댓글을 남기거나 기존 프로필 댓글을 보지 못하게 합니다. 기본값은 false 입니다. **/
24 isProfileCommentsPrivate?: boolean
25 /** 다른 사용자가 이 사용자에게 직접 메시지를 보내지 못하게 합니다. 기본값은 false 입니다. **/
26 isProfileDMDisabled?: boolean
27 karma?: number
28 /** 사용자 배지에 대한 선택적 구성입니다. **/
29 badgeConfig?: {
30 /** 사용자에게 할당할 배지 ID 배열입니다. 30개 배지로 제한됩니다. 순서는 유지됩니다. 이들은 모든 페이지에서 보이는 글로벌 배지입니다. **/
31 badgeIds: string[]
32 /** 현재 페이지(urlId)에 범위가 지정된 배지 ID 배열입니다. 이 배지들은 할당된 페이지에서만 표시됩니다. **/
33 pageBadgeIds?: string[]
34 /** true이면, 기존에 표시된 모든 배지를 제공된 배지로 대체합니다. 글로벌 배지와 페이지 범위 배지는 독립적으로 덮어써집니다. false이면 기존 배지에 추가됩니다. **/
35 override?: boolean
36 /** true이면, 사용자가 로그인할 때 테넌트 구성에서 배지 표시 속성을 업데이트합니다. **/
37 update?: boolean
38 }
39}
40

SSO 사용자 요금 청구

SSO 사용자는 권한 플래그에 따라 다르게 청구됩니다:

  • 일반 SSO 사용자: 관리 또는 중재자 권한이 없는 사용자는 일반 SSO 사용자로 청구됩니다
  • SSO 관리자: isAccountOwner 또는 isAdminAdmin 플래그가 있는 사용자는 SSO 관리자(일반 테넌트 관리자와 동일한 요율)로 별도 청구됩니다
  • SSO 중재자: isCommentModeratorAdmin 플래그가 있는 사용자는 SSO 중재자(일반 중재자와 동일한 요율)로 별도 청구됩니다

중요: 이중 청구를 방지하기 위해 시스템은 이메일 주소로 SSO 사용자를 일반 테넌트 사용자 및 중재자와 자동으로 중복 제거합니다. SSO 사용자가 일반 테넌트 사용자 또는 중재자와 동일한 이메일을 가지고 있으면 두 번 청구되지 않습니다.

접근 제어

사용자는 그룹으로 나눌 수 있습니다. 이것이 groupIds 필드의 용도이며 선택 사항입니다.

@Mentions

기본적으로 @mentions@ 문자를 입력할 때 다른 SSO 사용자를 검색하기 위해 username을 사용합니다. displayName이 사용되면, displayName과 일치하는 결과가 있을 때 username과 일치하는 결과는 무시되며 @mention 검색 결과는 displayName을 사용합니다.

구독

FastComments에서는 사용자가 댓글 위젯의 종 모양 아이콘을 클릭하고 구독을 클릭하면 페이지를 구독할 수 있습니다.

일반 사용자와는 그들의 알림 설정에 따라 알림 이메일을 보냅니다.

SSO 사용자와 함께 우리는 이를 하위 호환성을 위해 분리합니다. 사용자는 optedInSubscriptionNotificationstrue로 설정한 경우에만 이러한 추가 구독 알림 이메일을 받습니다.

배지

badgeConfig 속성을 사용하여 SSO 사용자에게 배지를 할당할 수 있습니다. 배지는 댓글에서 사용자 이름 옆에 표시되는 시각적 표시기입니다.

  • badgeIds - 사용자에게 할당할 배지 ID 배열입니다. 이들은 모든 페이지에서 보이는 글로벌 배지입니다. FastComments 계정에서 생성된 유효한 배지 ID여야 합니다. 30개의 배지로 제한됩니다.
  • pageBadgeIds - 현재 페이지(urlId)에 범위가 지정된 선택적 배지 ID 배열입니다. 이 배지들은 할당된 페이지에서만 표시됩니다. 서로 다른 페이지는 동일한 사용자에 대해 서로 다른 페이지 범위 배지를 가질 수 있습니다.
  • override - true이면 기존에 표시된 모든 배지를 제공된 배지로 대체합니다. 글로벌 배지와 페이지 범위 배지는 독립적으로 덮어써지므로 글로벌 배지를 덮어써도 페이지 범위 배지에는 영향을 주지 않으며 그 반대도 마찬가지입니다. false이거나 생략된 경우 제공된 배지는 기존 배지에 추가됩니다.
  • update - true이면 사용자가 로그인할 때마다 테넌트 구성에서 배지 표시 속성이 업데이트됩니다.

구독 구조 Internal Link

Subscription 객체는 사용자의 구독을 나타냅니다.

Subscription 객체는 사용자가 댓글 위젯의 알림 벨을 클릭하고 "이 페이지 구독"을 클릭할 때 생성됩니다.

구독은 API를 통해서도 생성할 수 있습니다.

Subscription 객체가 있으면 연관된 페이지의 루트에 새 댓글이 남겨질 때 해당 Subscription의 대상인 페이지에 대해 Notification 객체가 생성되고 이메일이 전송됩니다. 이메일 전송은 사용자 유형에 따라 달라집니다. 일반 사용자에게는 optedInNotifications에 따라 결정됩니다. SSO 사용자에게는 optedInSubscriptionNotifications에 따라 결정됩니다. 일부 애플리케이션은 웹에서 접근 가능한 페이지 개념이 없을 수 있으므로, 그런 경우 구독하려는 항목의 id(댓글 위젯에 전달할 urlId와 동일한 값)를 urlId에 설정하면 됩니다.

Subscription 객체의 구조는 다음과 같습니다:

구독 구조
Copy Copy
1
2interface Subscription {
3 id: string
4 tenantId: string
5 /** SSO의 경우, 사용자 id는 `<tenant id>:<user id>` 형식입니다. **/
6 userId: string
7 anonUserId?: string
8 urlId: string
9 url?: string
10 pageTitle?: string
11 createdAt: string // 날짜 문자열
12}
13

테넌트 일일 사용량 구조 Internal Link

A TenantDailyUsage 객체는 특정 날짜에 대한 테넌트의 사용량을 나타냅니다. 특정 테넌트가 해당 날짜에 활동이 없었다면 그 날짜에는 TenantDailyUsage 객체가 생성되지 않습니다.

The TenantDailyUsage object is not real time and may be minutes behind actual usage.

TenantDailyUsage 객체의 구조는 다음과 같습니다:

TenantDailyUsage 구조
Copy Copy
1
2export interface TenantDailyUsage {
3 yearNumber: number
4 monthNumber: number
5 dayNumber: number
6 commentFetchCount?: number
7 commentCreateCount?: number
8 conversationCreateCount?: number
9 voteCount?: number
10 accountCreatedCount?: number
11 userMentionSearch?: number
12 hashTagSearch?: number
13 gifSearchTrending?: number
14 gifSearch?: number
15 apiCreditsUsed?: number
16 createdAt: string
17 billed: boolean
18 /** 청구에서 무시됩니다. **/
19 ignored: boolean
20}
21

테넌트 구조 Internal Link

Tenant는 FastComments.com의 고객을 정의합니다. 화이트 라벨링 권한이 있는 테넌트는 API를 통해 생성할 수 있습니다. 화이트 라벨 테넌트는 다른 화이트 라벨 테넌트를 생성할 수 없습니다(중첩은 한 단계만 허용됩니다).

다음은 Tenant 객체의 구조입니다:

테넌트 구조
Copy Copy
1
2export enum SiteType {
3 Unknown = 0,
4 WordPress = 1
5}
6
7/** 이는 DomainConfig API로도 처리할 수 있습니다. **/
8export interface TenantDomainConfig {
9 domain: string
10 emailFromName?: string
11 emailFromEmail?: string
12 createdAt?: string,
13 siteType?: FastCommentsSiteType, // 아마 Unknown을 원할 것입니다
14 logoSrc?: string, // 원본 이미지 경로
15 logoSrc100px?: string, // 썸네일용으로 리사이즈됨
16 footerUnsubscribeURL?: string,
17 emailHeaders?: Record<string, string>,
18 disableUnsubscribeLinks?: boolean,
19 dkim?: {
20 domainName: string,
21 keySelector: string,
22 privateKey: string
23 }
24}
25
26export interface TenantBillingInfo {
27 name: string
28 address: string
29 city: string
30 state: string
31 zip: string
32 country: string
33}
34
35export enum TenantPaymentFrequency {
36 Monthly = 0,
37 Annually = 1
38}
39
40export interface Tenant {
41 id: string
42 name: string
43 email?: string
44 signUpDate: number; // '레거시' 이유로 number 타입입니다
45 packageId?: string | null
46 paymentFrequency?: TenantPaymentFrequency
47 billingInfoValid?: boolean
48 billingHandledExternally?: boolean
49 createdBy?: string
50 isSetup?: boolean
51 domainConfiguration: FastCommentsAPITenantDomainConfig[]
52 billingInfo?: FastCommentsAPITenantBillingInfo
53 stripeCustomerId?: string
54 stripeSubscriptionId?: string
55 stripePlanId?: string
56 enableProfanityFilter?: boolean
57 enableSpamFilter?: boolean
58 lastBillingIssueReminderDate?: string
59 removeUnverifiedComments?: boolean
60 unverifiedCommentsTTLms?: number
61 commentsRequireApproval?: boolean
62 autoApproveCommentOnVerification?: boolean
63 sendProfaneToSpam?: boolean
64 /** @readonly - packageId를 기반으로 계산됩니다. **/
65 hasFlexPricing?: boolean
66 /** @readonly **/
67 flexLastBilledAmount?: number
68 /** @readonly - packageId를 기반으로 계산됩니다. **/
69 hasAuditing?: boolean
70 /** 테넌트에 키-값 쌍을 저장하여 쿼리에 사용할 수 있습니다. 키에는 "." 또는 "$"를 포함할 수 없고 길이는 100자를 초과할 수 없습니다. 값은 2k 문자를 초과할 수 없습니다. **/
71 meta?: Record<string, string | null>
72}
73

사용자 구조 Internal Link

User는 모든 사용자들의 공통 분모를 나타내는 객체입니다.

FastComments에서는 사용자에 대한 여러 가지 다른 사용 사례가 있다는 점을 염두에 두세요:

  • Secure SSO
  • Simple SSO
  • Tenant Users (For example: Administrators)
  • Commenters

이 API는 CommentersSimple SSO를 통해 생성된 사용자들을 위한 것입니다. 기본적으로 사이트를 통해 생성된 모든 사용자는 이 API로 접근할 수 있습니다. Tenant Users도 이렇게 가져올 수 있지만, /tenant-users/ API와 상호작용하면 더 많은 정보를 얻을 수 있습니다.

Secure SSO의 경우에는 /sso-users/ API를 사용하세요.

이 유형의 사용자는 업데이트할 수 없습니다. 이들은 귀하의 사이트를 통해 계정을 생성했기 때문에 일부 읽기 전용 기본 액세스만 제공되며 변경은 할 수 없습니다. 이런 흐름을 원하시면 Secure SSO를 설정해야 합니다.

User 객체의 구조는 다음과 같습니다:

User 구조
Copy Copy
1
2export interface User {
3 /** 이것은 댓글 객체의 userId로도 사용되는 id입니다. **/
4 id: string
5 username: string
6 /** 예: 댓글 작성자의 블로그 링크입니다. **/
7 websiteUrl?: string
8 email: string
9 signUpDate: number
10 createdFromUrlId: string
11 createdFromTenantId: string
12 avatarSrc?: string
13 locale: FastCommentsLocale
14 displayLabel?: string
15 karma?: number
16}
17

투표 구조 Internal Link


Vote 객체는 사용자가 남긴 투표를 나타냅니다.

댓글과 투표 간의 관계는 commentId로 정의됩니다.

Vote 객체의 구조는 다음과 같습니다:

Vote 구조
Copy Copy
1
2interface Vote {
3 id: string
4 urlId: string
5 commentId: string
6 userId: string
7 direction: 1 | -1
8 createdAt: string
9}
10

질문 구성 구조 Internal Link

FastComments는 질문을 구성하고 그 결과를 집계하는 방법을 제공합니다. 질문의 예(이하 QuestionConfig라고 함)는 별점, 슬라이더, 또는 NPS 질문(type에 의해 결정될 수 있음)이 될 수 있습니다.

질문 데이터는 개별적으로, 함께, 시간 경과에 따라, 전체적으로, 페이지별로 등으로 집계할 수 있습니다.

이 프레임워크는 클라이언트 측 위젯(이 API 앞에 서버를 두는 방식), 관리자 대시보드 및 리포팅 도구를 구축하는 데 필요한 모든 기능을 제공합니다.

먼저 QuestionConfig를 정의해야 합니다. 구조는 다음과 같습니다:

QuestionConfig 구조
Copy Copy
1
2type QuestionConfigType = 'nps' | 'slider' | 'star' | 'thumbs';
3
4interface QuestionConfig {
5 id: string
6 tenantId: string
7 name: string
8 question: string
9 helpText?: string
10 createdAt: string
11 createdBy: string
12 /** 읽기 전용 - 각 새 응답마다 증가합니다. **/
13 usedCount: number
14 /** 구성이 마지막으로 사용(결과가 남겨진)된 시점의 날짜 문자열입니다. **/
15 lastUsed?: string
16 type: QuestionConfigType
17 numStars?: number
18 min?: number
19 max?: number
20 defaultValue?: number
21 labelNegative?: string
22 labelPositive?: string
23 subQuestionIds?: string[]
24 alwaysShowSubQuestions?: boolean
25 reportingOrder: number
26}
27

질문 결과 구조 Internal Link

질문에 대한 결과를 저장하려면 QuestionResult를 생성합니다. 그런 다음 질문 결과를 집계할 수 있고, 또한 보고 목적을 위해 댓글에 연결할 수도 있습니다.

QuestionResult 구조
Copy Copy
1
2interface QuestionResultMeta {
3 name: string
4 values: string[]
5}
6
7interface QuestionResult {
8 id: string
9 tenantId: string
10 urlId: string
11 anonUserId?: string
12 userId?: string
13 createdAt?: string
14 value: number
15 commentId?: string
16 questionId: string
17 meta?: QuestionResultMeta[]
18}
19

사용자 배지 구조 Internal Link

UserBadge는 FastComments 시스템에서 사용자에게 할당된 배지를 나타내는 객체입니다.

배지는 활동(예: 댓글 수, 응답 시간, 베테랑 상태)에 따라 자동으로 사용자에게 할당되거나 사이트 관리자가 수동으로 할당할 수 있습니다.

The structure for the UserBadge object is as follows:

UserBadge 구조
Copy Copy
1
2export interface UserBadge {
3 /** 이 사용자 배지 할당의 고유 식별자 */
4 id: string
5 /** 이 배지가 할당된 사용자의 ID */
6 userId: string
7 /** 테넌트의 배지 카탈로그에 있는 배지 정의의 ID */
8 badgeId: string
9 /** 이 배지를 생성/할당한 테넌트의 ID */
10 fromTenantId: string
11 /** 이 배지가 생성된 시각 (에포크 이후 밀리초) */
12 createdAt?: number
13 /** 사용자가 이 배지를 받은 시각 (에포크 이후 밀리초) */
14 receivedAt?: number
15 /**
16 * 배지 유형:
17 * 0=CommentCount, 1=CommentUpVotes, 2=CommentReplies, 3=CommentsPinned,
18 * 4=Veteran, 5=NightOwl, 6=FastReplyTime, 7=ModeratorCommentsDeleted,
19 * 8=ModeratorCommentsApproved, 9=ModeratorCommentsUnapproved, 10=ModeratorCommentsReviewed,
20 * 11=ModeratorCommentsMarkedSpam, 12=ModeratorCommentsMarkedNotSpam, 13=RepliedToSpecificPage,
21 * 14=Manual
22 */
23 type: number
24 /** 임계값 기반 배지의 임계값 */
25 threshold?: number
26 /** 배지의 이름/레이블 */
27 name?: string
28 /** 배지의 상세 설명 */
29 description?: string
30 /** 배지에 표시되는 텍스트 */
31 displayLabel?: string
32 /** 배지에 표시될 이미지의 URL */
33 displaySrc?: string
34 /** 배지의 배경색 (헥스 코드) */
35 backgroundColor?: string
36 /** 배지의 테두리 색 (헥스 코드) */
37 borderColor?: string
38 /** 배지의 텍스트 색 (헥스 코드) */
39 textColor?: string
40 /** 스타일링을 위한 추가 CSS 클래스 */
41 cssClass?: string
42 /** 베테랑 배지의 경우 시간 임계값(밀리초) */
43 veteranUserThresholdMillis?: number
44 /** 이 배지가 사용자의 댓글에 표시되는지 여부 */
45 displayedOnComments: boolean
46 /** 배지의 표시 순서 */
47 order?: number
48 /** 설정된 경우, 이 배지는 일치하는 urlId를 가진 페이지에만 표시됩니다. 전역 배지의 경우 null. */
49 urlId?: string | null
50}
51

사용자 배지 진행 상황 구조 Internal Link

UserBadgeProgress는 FastComments 시스템에서 사용자가 다양한 배지를 획득하기 위한 진행 상황을 나타내는 객체입니다.

이 추적은 사용자의 활동 및 커뮤니티 참여를 기반으로 언제 자동으로 배지를 수여할지 결정하는 데 도움이 됩니다.

The structure for the UserBadgeProgress object is as follows:

UserBadgeProgress 구조
Copy Copy
1
2export interface UserBadgeProgress {
3 /** 이 진행 기록의 고유 식별자 */
4 id: string
5 /** 이 진행 기록이 속한 테넌트의 ID */
6 tenantId: string
7 /** 이 진행 기록이 추적하는 사용자의 ID */
8 userId: string
9 /** 시스템에서 사용자의 첫 댓글 ID */
10 firstCommentId?: string
11 /** 사용자의 첫 댓글 날짜(에포크 이후 밀리초) */
12 firstCommentDate?: number
13 /** 사용자 활동을 기반으로 자동 계산된 신뢰도 */
14 autoTrustFactor?: number
15 /** 관리자가 수동으로 설정한 신뢰도 */
16 manualTrustFactor?: number
17 /** 여러 지표를 포함한 상세 진행 객체, 키는 BadgeType 열거형과 일치함 */
18 progress: {
19 /** 0: CommentCount - 사용자가 작성한 댓글 수 */
20 '0'?: number
21 /** 1: CommentUpVotes - 사용자가 받은 추천(업보트) 수 */
22 '1'?: number
23 /** 2: CommentReplies - 사용자가 작성한 답글 수 */
24 '2'?: number
25 /** 3: CommentsPinned - 사용자가 고정한 댓글 수 */
26 '3'?: number
27 /** 4: Veteran - 사용자 계정 생성 후 경과 시간 */
28 '4'?: number
29 /** 5: NightOwl - 사용자가 야간 시간대에 게시한 횟수 */
30 '5'?: number
31 /** 6: FastReplyTime - 평균 답글 시간(밀리초) */
32 '6'?: number
33 /** 7: ModeratorCommentsDeleted - 모더레이터 배지의 경우 삭제된 댓글 수 */
34 '7'?: number
35 /** 8: ModeratorCommentsApproved - 모더레이터 배지의 경우 승인된 댓글 수 */
36 '8'?: number
37 /** 9: ModeratorCommentsUnapproved - 모더레이터 배지의 경우 미승인된 댓글 수 */
38 '9'?: number
39 /** 10: ModeratorCommentsReviewed - 모더레이터 배지의 경우 검토된 댓글 수 */
40 '10'?: number
41 /** 11: ModeratorCommentsMarkedSpam - 모더레이터 배지의 경우 스팸으로 표시된 댓글 수 */
42 '11'?: number
43 /** 12: ModeratorCommentsMarkedNotSpam - 모더레이터 배지의 경우 스팸 아님으로 표시된 댓글 수 */
44 '12'?: number
45 /** 13: RepliedToSpecificPage - 각 페이지에 대한 답글 수 */
46 '13'?: Record<string, number>
47 }
48}
49

결론

저희 API 문서가 포괄적이고 이해하기 쉬웠기를 바랍니다. 누락된 부분이 있다면 아래에 알려주세요.