FastComments.com

API FastComments

FastComments надає API для взаємодії з багатьма ресурсами. Створюйте інтеграції з нашою платформою або навіть пишіть власні клієнти!

У цій документації ви знайдете всі ресурси, що підтримуються API, задокументовані разом із типами запитів і відповідей.

Для корпоративних (Enterprise) клієнтів увесь доступ до API фіксується в журналі аудиту.

Згенеровані SDK

FastComments тепер генерує API Spec з нашого коду (це ще не завершено, але включає багато API).

Також тепер у нас є SDK для популярних мов:

Аутентифікація

Доступ до API аутентифікується шляхом передачі вашого api key у вигляді заголовка X-API-KEY або як параметра запиту API_KEY. Вам також знадобиться ваш tenantId для викликів API. Його можна отримати на тій же сторінці, що й ваш api key.

Примітка щодо безпеки

Ці маршрути призначені для виклику з серверу. НЕ викликайте їх з браузера. Це розкриє ваш API-ключ — це надасть повний доступ до вашого облікового запису будь-кому, хто може переглянути вихідний код сторінки!

Варіант аутентифікації 1 — Заголовки

  • Заголовок: X-API-KEY
  • Заголовок: X-TENANT-ID

Варіант аутентифікації 2 — Параметри запиту

  • Параметр запиту: API_KEY
  • Параметр запиту: tenantId

Структура журналу аудиту 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.

Записи в журналі аудиту зберігаються протягом двох років.

Структура коментаря Internal Link

Об'єкт Comment представляє коментар, залишений користувачем.

Взаємовідносини між батьківськими та дочірніми коментарями визначаються через parentId.

Структура об'єкта Comment наступна:

Структура об'єкта Comment
Copy Copy
1
2interface Comment {
3 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Встановлено у 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 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Текст коментаря, розпарсений у 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 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Кількість разів, коли коментар було позначено. **/
28 flagCount?: number
29 /** #хештеги, написані в коментарі, які були успішно розпарсені. Також можна вручну додавати хештеги, для запитів, але вони автоматично не відображатимуться в тексті коментаря. **/
30 hashTags?: CommentHashTag[]
31 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Чи містить коментар зображення? **/
32 hasImages?: boolean
33 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Чи містить коментар посилання? **/
34 hasLinks?: boolean
35 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Унікальний ідентифікатор коментаря. **/
36 id: string
37 /** Лише при створенні! Це хешується для зберігання. **/
38 ip?: string
39 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Чи заблокував поточний користувач автора цього коментаря? **/
40 isBlocked?: boolean
41 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Чи є коментар від адміністратора? Автоматично встановлюється на основі userId. **/
42 isByAdmin?: boolean
43 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Чи є коментар від модератора? Автоматично встановлюється на основі userId. **/
44 isByModerator?: boolean
45 /** Встановіть true, якщо коментар було м'яко видалено (залишено замінник через іншу конфігурацію). **/
46 isDeleted?: boolean
47 /** Встановіть true, якщо акаунт користувача було видалено і коментар довелося зберегти. **/
48 isDeletedUser?: boolean
49 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Чи позначив цей коментар поточний залогінений користувач (contextUserId)? **/
50 isFlagged?: boolean
51 /** Чи закріплено коментар? **/
52 isPinned?: boolean
53 /** Чи заблоковано коментар для нових відповідей (модератори все ще можуть відповідати)? **/
54 isLocked?: boolean
55 /** Чи є коментар спамом? **/
56 isSpam?: boolean
57 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Чи проголосував поточний користувач (contextUserId) проти цього коментаря? **/
58 isVotedDown?: boolean
59 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Чи проголосував поточний користувач (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 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: @згадки, написані в коментарі, які були успішно розпарсені. **/
64 mentions?: CommentUserMention[]
65 /** Необов'язкові метадані, пов'язані з коментарем. **/
66 meta?: Record<string, string | number | boolean>
67 /** Необов'язковий список id груп модерації, пов'язаних з цим коментарем. **/
68 moderationGroupIds?: string[]|null
69 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Ідентифікатор об'єкта голосування, що відповідає голосу поточного користувача (contextUserId) за цей коментар. **/
70 myVoteId?: string
71 /** Чи було надіслано повідомлення для авторів коментарів щодо цього коментаря. Щоб запобігти відправленню повідомлень під час імпорту, встановіть це у true. **/
72 notificationSentForParent?: boolean
73 /** Чи було надіслано повідомлення для користувачів тенанта щодо цього коментаря. Щоб запобігти відправленню повідомлень під час імпорту, встановіть це у true. **/
74 notificationSentForParentTenant?: boolean
75 /** Заголовок сторінки, на якій був цей коментар. **/
76 pageTitle?: string
77 /** Якщо ми відповідаємо на коментар, це ID коментаря, на який ми відповідаємо. **/
78 parentId?: string|null
79 /** Чи позначено коментар як перевірений. **/
80 reviewed: boolean
81 /** Ідентифікатор тенанта, якому належить коментар. **/
82 tenantId: string
83 /** Користувач, який написав коментар. Створюється автоматично при збереженні коментаря з ім'ям/електронною поштою. **/
84 userId?: string|null
85 /** URL місця, де видно цей коментар, наприклад допис у блозі. **/
86 url: string
87 /** «Очищена» версія urlId, яку ви передали. При збереженні ви вказуєте це поле, але коли отримаєте коментар назад це буде «очищене», а ваше оригінальне значення переміститься до "urlIdRaw". **/
88 urlId: string
89 /** ТІЛЬКИ ДЛЯ ЧИТАННЯ: Оригінальний urlId, який ви передали. **/
90 urlIdRaw?: string
91 /** Чи перевірено користувача і цей коментар? **/
92 verified: boolean
93 /** Кількість голосів за. **/
94 votesUp?: number
95 /** Кількість голосів проти. **/
96 votesDown?: number
97 /** «Карма» коментаря (= votes up - votes down). **/
98 votes?: number
99}
100

Деякі з цих полів позначені як READONLY — вони повертаються API, але їх не можна встановити.

Структура тексту коментаря

Коментарі пишуться у власному діалекті markdown від FastComments, який є стандартним markdown плюс традиційні bbcode-подібні теги для зображень, такі як [img]path[/img].

Текст зберігається у двох полях. Текст, який ввів користувач, зберігається без змін у полі comment. Його відрендерений варіант зберігається у полі commentHTML.

Дозволені HTML-теги: b, u, i, strike, pre, span, code, img, a, strong, ul, ol, li, and br.

Рекомендується рендерити HTML, оскільки це дуже невеликий піднабір HTML, і створити рендерер досить просто. Існує кілька бібліотек, наприклад для React Native і Flutter, які можуть у цьому допомогти.

Ви можете обрати рендеринг ненормалізованого значення поля comment. Приклад парсера тут..

Приклад парсера також можна налаштувати для роботи з HTML і перетворювати HTML-теги у очікувані елементи для рендерингу на вашій платформі.

Тегування

Коли користувачів згадують у коментарі, інформація зберігається у списку mentions. Кожен об'єкт у цьому списку має таку структуру.

Об'єкт згадки коментаря
Copy CopyRun External Link
1
2interface CommentUserMention {
3 /** Ідентифікатор користувача. Для SSO-користувачів до нього буде додано префікс ідентифікатора вашого тенанта. **/
4 id: string
5 /** Остаточний текст @mention, включно зі символом @. **/
6 tag: string
7 /** Початковий текст @mention, включно зі символом @. **/
8 rawTag: string
9 /** Тип тегнутого користувача. user = обліковий запис FastComments.com. sso = SSOUser. **/
10 type: 'user'|'sso'
11 /** Якщо користувач відмовився від повідомлень, це поле все одно буде встановлено в true. **/
12 sent: boolean
13}
14

Хештеги

Коли хештеги використовуються і успішно розпізнаються, інформація зберігається в масиві hashTags. Кожен об'єкт у цьому масиві має таку структуру. Хештеги також можна додавати вручну в масив hashTags коментаря для запитів, якщо встановлено retain.

Об'єкт хештегу коментаря
Copy CopyRun External Link
1
2interface CommentHashTag {
3 /** Ідентифікатор хештегу. **/
4 id: string
5 /** Остаточний текст #hashtag, включно зі символом #. **/
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 представляє тег, який може залишити користувач. Хештеги можуть використовуватися для зв'язування з зовнішнім вмістом або для об'єднання пов'язаних коментарів.

Структура об'єкта HashTag виглядає так:

Структура HashTag
Copy Copy
1
2interface HashTag {
3 /** Повинно починатися з символу "#" або іншого бажаного символу. **/
4 tag: string
5 /** Необов'язковий URL, на який може вказувати хештег. Замість фільтрації коментарів за хештегом, інтерфейс перенаправить на цей 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. Термін їх дії закінчується через один рік.

Ви можете очистити кількість непрочитаних сповіщень користувача, видаливши його NotificationCount.

Структура об'єкта NotificationCount виглядає так:

Структура NotificationCount
Copy Copy
1
2interface NotificationCount {
3 id: string // ідентифікатор користувача
4 count: number
5 createdAt: string // рядок дати
6 expireAt: string // рядок дати
7}
8

Структура сповіщення Internal Link

Об'єкт Notification представляє сповіщення для користувача.

Об'єкти Notification створюються автоматично і не можуть бути створені через API. Вони також закінчують термін дії через один рік. Сповіщення не можна видалити. Однак їх можна оновити, встановивши viewed в false, і можна виконувати запити за viewed.

Користувач також може відмовитись від сповіщень для конкретного коментаря, встановивши optedOut у сповіщенні в true. Ви можете знову підписатися, встановивши його в false.

Існують різні типи сповіщень — перевіряйте relatedObjectType і type.

Способи створення сповіщень досить гнучкі і можуть бути викликані багатьма сценаріями (див. NotificationType).

На сьогодні наявність Notification фактично не означає, що електронний лист надсилається або має бути надісланий. Швидше за все, сповіщення використовуються для стрічки сповіщень та пов'язаних інтеграцій.

Структура об'єкта Notification виглядає так:

Структура Notification
Copy Copy
1
2enum NotificationObjectType {
3 Comment = 0,
4 Profile = 1,
5 Tenant = 2
6}
7
8enum NotificationType {
9 /** Якщо хтось відповів вам. **/
10 RepliedToMe = 0,
11 /** Якщо хтось відповів будь-де в треді (навіть нащадки нащадків) треда, в якому ви коментували. **/
12 RepliedTransientChild = 1,
13 /** Якщо за ваш коментар проголосували. **/
14 VotedMyComment = 2,
15 /** Якщо на корені сторінки, на яку ви підписані, залишено новий коментар. **/
16 SubscriptionReplyRoot = 3,
17 /** Якщо хтось прокоментував ваш профіль. **/
18 CommentedOnProfile = 4,
19 /** Якщо у вас є приватне повідомлення (DM). **/
20 DirectMessage = 5,
21 /** TrialLimits призначено лише для користувачів tenant. **/
22 TrialLimits = 6,
23 /** Якщо вас згадали за допомогою @. **/
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 // рядок дати
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


Об'єкт Page представляє сторінку, якій можуть належати багато коментарів. Це відношення визначається urlId.

Об'єкт 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

Об'єкт PendingWebhookEvent представляє подію вебхука, яка знаходиться в черзі та очікує виконання.

PendingWebhookEvent об'єкти створюються автоматично і не можуть бути створені вручну через API. Їх термін дії також закінчується через один рік. Їх можна видалити, що видаляє завдання з черги.

Існують різні типи подій — перевіряйте 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 /** Ідентифікатор коментаря, пов'язаний із подією. **/
17 commentId: string
18 /** Об'єкт коментаря для події на момент її виникнення. Ми почали додавати їх у листопаді 2023 року. **/
19 comment: Comment
20 /** Зовнішній ідентифікатор, який може бути пов'язаний із коментарем. **/
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 /** Остання помилка, яка сталася. Цей тип не має строгої типізації і є "дампом" того, що трапилось. Зазвичай містить об'єкт зі статусним кодом, тілом і мапою заголовків. **/
34 lastError: object | null
35}
36

Структура користувача SSO Internal Link

FastComments provides an easy to use SSO solution. Updating a user's information with the HMAC-based integration is as simple as having the user load the page with an updated payload.

However, it may be desirable to manage a user outside that flow, to improve consistency of your application.

The SSO User API provides a way to CRUD objects that we call SSOUsers. These objects are different from regular Users and kept separate for type safety.

The structure for the SSOUser object is as follows:

Структура 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 /** Якщо true, замінює всі існуючі відображувані бейджі на надані. Якщо false або відсутній, додає до існуючих бейджів. **/
33 override?: boolean
34 /** Якщо true, оновлює параметри відображення бейджів згідно з конфігурацією орендаря. **/
35 update?: boolean
36 }
37}
38

Billing for SSO Users

SSO users are billed differently based on their permission flags:

  • Regular SSO Users: Users without admin or moderator permissions are billed as regular SSO users
  • SSO Admins: Users with isAccountOwner or isAdminAdmin flags are billed separately as SSO Admins (same rate as regular tenant admins)
  • SSO Moderators: Users with isCommentModeratorAdmin flag are billed separately as SSO Moderators (same rate as regular moderators)

Important: To prevent double billing, the system automatically deduplicates SSO users against regular tenant users and moderators by email address. If an SSO user has the same email as a regular tenant user or moderator, they will not be billed twice.

Access Control

Users can be broken into groups. This is what the groupIds field is for, and is optional.

@Mentions

By default @mentions will use username to search for other sso users when the @ character is typed. If displayName is used, then results matching username will be ignored when there is a match for displayName, and the @mention search results will use displayName.

Subscriptions

With FastComments, users can subscribe to a page by clicking the bell icon in the comment widget and clicking Subscribe.

With a regular user, we send them notification emails based on their notification settings.

With SSO Users, we split this up for backwards compatibility. Users will only get sent these additional subscription notification emails if you set optedInSubscriptionNotifications to true.

Badges

You can assign badges to SSO users using the badgeConfig property. Badges are visual indicators that appear next to a user's name in comments.

  • badgeIds - An array of badge IDs to assign to the user. These must be valid badge IDs created in your FastComments account. Limited to 30 badges.
  • override - If true, all existing badges displayed on comments will be replaced with the provided ones. If false or omitted, the provided badges will be added to any existing badges.
  • update - If true, badge display properties will be updated from the tenant configuration whenever the user logs in.

Структура підписки Internal Link

Об'єкт Subscription представляє підписку для користувача.

Subscription objects are created when a user clicks the notification bell in the comment widget and clicks "Підписатися на цю сторінку".

Підписки також можна створювати через API.

Наявність об'єкта Subscription призводить до створення об'єктів Notification і надсилання електронних листів, коли на корені пов'язаної сторінки, для якої призначена підписка, з'являються нові коментарі. Надсилання електронних листів залежить від типу користувача. Для звичайних користувачів це залежить від optedInNotifications. Для SSO-користувачів це залежить від optedInSubscriptionNotifications. Зверніть увагу, що деякі застосунки можуть не мати поняття веб-доступної сторінки; у такому випадку просто встановіть urlId в id елемента, на який ви підписуєтесь (те ж значення urlId, яке ви передали б віджету коментарів).

Структура об'єкта Subscription виглядає так:

Структура Subscription
Copy Copy
1
2interface Subscription {
3 id: string
4 tenantId: string
5 /** У SSO ідентифікатор користувача має формат `<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

Об'єкт TenantDailyUsage представляє використання для орендаря за конкретний день. Якщо для певного орендаря в певний день не було активності, у цей день не буде об'єкта TenantDailyUsage.

Об'єкт TenantDailyUsage не є в режимі реального часу і може відставати від фактичного використання на декілька хвилин.

Структура об'єкта 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 орендарями з доступом до white labeling. White labeled tenants не можуть створювати інших white labeled tenants (дозволено тільки один рівень вкладеності).

Структура об'єкта Tenant виглядає так:

Структура 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 через "legacy" причини
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 /** Ви можете зберегти у tenant пару ключ-значення, яку можна використовувати для запитів. Ключі не можуть містити "." або "$", або бути довшими за 100 символів. Значення не можуть бути довшими за 2000 символів. **/
71 meta?: Record<string, string | null>
72}
73

Структура користувача Internal Link

User — це об'єкт, що представляє найбільш загальний знаменник усіх користувачів.

Майте на увазі, що в FastComments у нас є кілька різних сценаріїв використання для користувачів:

  • Безпечний SSO
  • Простий SSO
  • Користувачі орендаря (наприклад: Адміністратори)
  • Коментатори

Цей API призначений для Коментаторів та користувачів, створених через Простий SSO. Насправді будь-який користувач, створений через ваш сайт, може бути отриманий через цей API. Користувачів орендаря також можна отримати цим способом, але ви отримаєте більше інформації, взаємодіючи з /tenant-users/ API.

Для Secure SSO будь ласка використовуйте /sso-users/ API.

Ви не можете оновлювати ці типи користувачів. Вони створили свій акаунт через ваш сайт, тому ми надаємо базовий доступ лише для читання, але ви не можете вносити зміни. Якщо ви хочете мати такий тип потоку — вам потрібно налаштувати Secure SSO.

Структура об'єкта User наступна:

Структура об'єкта User
Copy Copy
1
2export interface User {
3 /** Це також id, який використовується як userId в об'єктах коментарів. **/
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.

Бейджі можуть призначатися користувачам автоматично на основі їхньої активності (наприклад, кількість коментарів, час відповіді, статус ветерана) або вручну адміністраторами сайту.

Структура об'єкта UserBadge наступна:

Структура 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 /** Для бейджів Veteran — пороговий час у мілісекундах */
43 veteranUserThresholdMillis?: number
44 /** Чи відображається цей бейдж на коментарях користувача */
45 displayedOnComments: boolean
46 /** Порядок відображення бейджа */
47 order?: number
48}
49
---

Структура прогресу значка користувача Internal Link


UserBadgeProgress — це об'єкт, який представляє прогрес користувача щодо здобуття різних значків у системі FastComments.

Це відстеження допомагає визначити, коли користувачі повинні отримувати автоматичні значки на основі їхньої активності та участі у вашій спільноті.

Структура об'єкта UserBadgeProgress виглядає так:

Структура UserBadgeProgress
Copy Copy
1
2export interface UserBadgeProgress {
3 /** Унікальний ідентифікатор цього запису прогресу */
4 id: string
5 /** ID орендаря (tenant), якому належить цей запис прогресу */
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 /** Детальний об'єкт прогресу з різними метриками, ключі відповідають enum BadgeType */
18 progress: {
19 /** 0: CommentCount - Кількість коментарів, які залишив користувач */
20 '0'?: number
21 /** 1: CommentUpVotes - Кількість upvotes, які отримав користувач */
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 була для вас вичерпною та зрозумілою. Якщо ви знайдете будь-які прогалини, повідомте нам нижче.