This document describes about Discussion Forum architecture
Table of Contents |
---|
Background:
Problem Statement:
...
How to create an independent widget that will be having end-to-end functionality
How to use existing user service/DB instead of creating new users account in NodeBB
Proxy layer: List of API’s explosed & widget will communicate with these API’s
Solution:
NodeBB default UI options:
...
Default NodeBB UI with customization:
We built a plugin that will help to customize the UI functionality of page & new route exposed for custom logic. Similarly, any customization can be achieved with a custom plugin(Route & UI screen)
...
We have to handle the below privileges when we do custom UI:
...
Custom UI (for NodeBB) | Default UI (NodeBB) |
We can have independent widgets that can be added in any page as per the requirement | We have to load the entire UI in an Iframe & handle the redirect based on URL parameters |
Any new feature update by NodeBB should be implemented from fresh. If it is impacting on any existing functionality we should do again | Any feature will be available by default. All the configurations will be handled by the default UI itself |
Role/Privileges management to show/hide the options has to be implemented from scratch. can post, upvote, downvote, flag, group management, adding user, topic creation etc. | Role/Privileges management is already exist. |
Igot Requirement | Sunbird Requriement |
Any logged in user can add post/topic in any discussion thread | Only enrolled users of the course should able to post/topic in the specific thered attached to the course |
There is not nodebb groups concept. Hence any user can acees any discussion thread. | We should have groups concept to access discussion thread specific to groups. |
There is not privilege control UI. The same options will be available for Admin, Moderator, Members & Guest | Priviledge control UI required to manage Moderator & Memers. Moderator should able to do below actions
|
nodebb-Plugins:
NodeBB Censor Curse Words: https://github.com/ninenine/nodebb-plugin-beep
NodeBB Custom Route: https://github.com/vinukumar-vs/nodebb-plugin-vsv-homepage
Nodebb Plugin Quick Start: https://github.com/NodeBB/nodebb-plugin-quickstart
How to create an independent widget that will be having end-to-end functionality
Widgets list:
Categories list
Category list with details
Category list with only name(as a list)
Topics list
Filter options & search query should be the config for the widget (optional for now)
Note: Think this can be independent widget itself can be used at any place
Topic thread(with new post, list of posts & reply to post)
Create a Topic
Create Category
Post/Reply
Post card
Replay to post
After posting the reply(expanded view)
...
Middleware/Proxy layer: List of API’s explosed & widget will communicate with these API’s
...
After review: 10/11/2020
Don’t introduce the hubs in between. The frontend should able to call directly the nodebb default API's without nodebb-plugin. It is not mandatory all the calls should go via nodebb-plugin only.
Role Management:
...
Front-end | Middleware | Nodebb |
---|---|---|
ContentCreator(SB role) | ContentCreator → Maderator maderator | Moderator |
Anonymous/Public | Public → User | User |
API’s
NodeBB API’s documentation: https://docs.nodebb.org/api/#tag/topics/paths/~1api~1popular/get
NodeBB plugin:
nodebb-plugin-write-api : https://github.com/NodeBB/nodebb-plugin-write-api/blob/master/routes/v2/readme.md
POST: Create forum
POST api/discussion/v1/category/create
Request
Code Block |
---|
request: {
"context": {
"type": "Batch" // Possible types: Quiz/Resource/Course/Textbook/Batch etc..
"identifier":"0126825293972439041", // BatchId in this example
"channel": 01238392 // Optional: Channel/TenantId in this example
},
"parentCid": 1929 // Optional: parent category Id
"name": "Course 1- Batch 1",
"description": ""
} |
Response
Code Block |
---|
{
"id": "api.org.preferences.read",
"ver": "v2",
"ts": "2020-08-13 18:35:50:148+0000",
"params": {
"resmsgid": null,
"msgid": "3c75d002-15a6-3d5e-8dcd-1bf6179548b2",
"err": null,
"status": "success",
"errmsg": null
},
"responseCode": "OK",
"result": {
"categoryId": 12356 // "nodebb category id"
}
} |
POST: Creating Group
POST api/discussion/v1/group/create
Request
Code Block |
---|
request: {
"categoryId": 1929 // parent category Id
"userId": [creator],
"permissions": ["read", "vote", "post", "topic"] // Default "member" priviledges
} |
Response
Code Block |
---|
{
"id": "api.org.preferences.read",
"ver": "v2",
"ts": "2020-08-13 18:35:50:148+0000",
"params": {
"resmsgid": null,
"msgid": "3c75d002-15a6-3d5e-8dcd-1bf6179548b2",
"err": null,
"status": "success",
"errmsg": null
},
"responseCode": "OK",
"result": {
"group": 38301 // "nodebb group id"
}
} |
POST: Add user to Group
POST api/discussion/v1/group/membership/
Request
Code Block |
---|
request: {
"groupId": [2673] // GroupId
"userId": [2345] // Nodebb UserID
} |
Response
Code Block |
---|
{
"id": "api.org.preferences.read",
"ver": "v2",
"ts": "2020-08-13 18:35:50:148+0000",
"params": {
"resmsgid": null,
"msgid": "3c75d002-15a6-3d5e-8dcd-1bf6179548b2",
"err": null,
"status": "success",
"errmsg": null
},
"responseCode": "OK",
"result": {
"status": ok // "nodebb category id"
}
} |
Note:
By default, all the users with get guest
privileges
POST: User privileges
POST api/discussion/v1/privileges/
Request
Code Block |
---|
request: {
"categoryId": 1929 // parent category Id
"groupId": [2673] // Optional: GroupId
"userId": [2345] // Optional: Nodebb UserID
"permissions": ["read", "vote", "post", "topic", "moderate"]
} |
Response
Code Block |
---|
{
"id": "api.org.preferences.read",
"ver": "v2",
"ts": "2020-08-13 18:35:50:148+0000",
"params": {
"resmsgid": null,
"msgid": "3c75d002-15a6-3d5e-8dcd-1bf6179548b2",
"err": null,
"status": "success",
"errmsg": null
},
"responseCode": "OK",
"result": {
"status": ok // "nodebb category id"
}
} |
note:
GroupId or userId either one of these is mandatory.
Use authentication
Description:
Telemetry Events
Description: Telemetry events generated by discussion forum
Event Format:
Code Block |
---|
{
eid: INTERACT,
edata: {
id: 'category',
type: 'CLICK',
pageid: 'discussion-category',
},
context: [
{
type: Category
id: {categoryId}
},
{
type: Topic
id: {topicId}
},
{
type: Post
id: {postId}
},
]
} |
Integrating events triggered by the Discussion Library:
Code Block |
---|
import { DiscussionEventsService } from 'discussion-ui';
constructor(private discussionEvents: DiscussionEventsService) { }
ngOnInit() {
this.discussionEvents.telemetryEvent.subscribe(event => {
console.log('telemetryEvent', event);
});
} |
telemetryEvent:
Code Block |
---|
{
eid: INTERACT,
edata: {
id: 'category',
type: 'CLICK',
pageid: 'discussion-category',
},
context: [
{
type: 'Category'
id: '1'
}
]
}
|
Code Block |
---|
{
"eid": "IMPRESSION",
"edata": {
"type": "view",
"pageid": "discussion-home",
"uri": "/discussion"
}
} |
Related Wiki’s:
Discussion forum as a solution:
Discussion forum api's:
How to integrate discussion forum:
Discussion forum telemetry events:
Discussion Forum: Telemetry Events
Discussion forum generalization integration:
Discussion Forum: Generalisation of Course & Groups integration logic