Create and edit a subreddit, get its settings
Signed-off-by: Vartan Benohanian <vartanbeno@gmail.com>
This commit is contained in:
parent
a76dfa0a00
commit
e14a54f64e
5 changed files with 323 additions and 24 deletions
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// APIError is an error coming from Reddit.
|
// APIError is an error coming from Reddit.
|
||||||
|
@ -44,14 +45,14 @@ type JSONErrorResponse struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *JSONErrorResponse) Error() string {
|
func (r *JSONErrorResponse) Error() string {
|
||||||
var message string
|
errorMessages := make([]string, len(r.JSON.Errors))
|
||||||
if len(r.JSON.Errors) > 0 {
|
for i, err := range r.JSON.Errors {
|
||||||
message = r.JSON.Errors[0].Error()
|
errorMessages[i] = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"%s %s: %d %s",
|
"%s %s: %d %s",
|
||||||
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, message,
|
r.Response.Request.Method, r.Response.Request.URL, r.Response.StatusCode, strings.Join(errorMessages, ";"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,103 @@ func (s *SubredditTrafficStats) UnmarshalJSON(b []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SubredditSettings are a subreddit's settings.
|
||||||
|
type SubredditSettings struct {
|
||||||
|
// The id of the subreddit.
|
||||||
|
ID string `url:"-" json:"subreddit_id,omitempty"`
|
||||||
|
|
||||||
|
// One of: public, restricted, private, gold_restricted, archived, employees_only, gold_only, user.
|
||||||
|
Type *string `url:"type,omitempty" json:"subreddit_type,omitempty"`
|
||||||
|
|
||||||
|
// A valid IETF language tag (underscore separated).
|
||||||
|
Language *string `url:"lang,omitempty" json:"language,omitempty"`
|
||||||
|
|
||||||
|
// No longer than 100 characters.
|
||||||
|
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||||
|
// Raw markdown text. No longer than 500 characters.
|
||||||
|
Description *string `url:"public_description,omitempty" json:"public_description,omitempty"`
|
||||||
|
// Raw markdown text. No longer than 10240 characters.
|
||||||
|
Sidebar *string `url:"description,omitempty" json:"description,omitempty"`
|
||||||
|
// Raw markdown text. No longer than 1024 characters.
|
||||||
|
SubmissionText *string `url:"submit_text,omitempty" json:"submit_text,omitempty"`
|
||||||
|
// Raw markdown text. No longer than 5000 characters.
|
||||||
|
WelcomeMessage *string `url:"welcome_message_text,omitempty" json:"welcome_message_text,omitempty"`
|
||||||
|
WelcomeMessageEnabled *bool `url:"welcome_message_enabled,omitempty" json:"welcome_message_enabled,omitempty"`
|
||||||
|
|
||||||
|
AllowCrossposts *bool `url:"allow_post_crossposts,omitempty" json:"allow_post_crossposts,omitempty"`
|
||||||
|
AllowChatPosts *bool `url:"allow_chat_post_creation,omitempty" json:"allow_chat_post_creation,omitempty"`
|
||||||
|
AllowPollPosts *bool `url:"allow_polls,omitempty" json:"allow_polls,omitempty"`
|
||||||
|
AllowFreeFormReports *bool `url:"free_form_reports,omitempty" json:"free_form_reports,omitempty"`
|
||||||
|
AllowOriginalContent *bool `url:"original_content_tag_enabled,omitempty" json:"original_content_tag_enabled,omitempty"`
|
||||||
|
// Allow image uploads and links to image hosting sites.
|
||||||
|
AllowImages *bool `url:"allow_images,omitempty" json:"allow_images,omitempty"`
|
||||||
|
AllowMultipleImagesPerPost *bool `url:"allow_galleries,omitempty" json:"allow_galleries,omitempty"`
|
||||||
|
|
||||||
|
ExcludeSitewideBannedUsersContent *bool `url:"exclude_banned_modqueue,omitempty" json:"exclude_banned_modqueue,omitempty"`
|
||||||
|
|
||||||
|
// An integer from 0 to 3.
|
||||||
|
CrowdControlChalLevel *int `url:"crowd_control_chat_level,omitempty" json:"crowd_control_chat_level,omitempty"`
|
||||||
|
|
||||||
|
// Mark all posts in this subreddit as Original Content (OC) on the desktop redesign.
|
||||||
|
AllOriginalContent *bool `url:"all_original_content,omitempty" json:"all_original_content,omitempty"`
|
||||||
|
|
||||||
|
// One of: none (recommended), confidence, top, new, controversial, old, random, qa, live.
|
||||||
|
SuggestedCommentSort *string `url:"suggested_comment_sort,omitempty" json:"suggested_comment_sort,omitempty"`
|
||||||
|
|
||||||
|
// No longer than 60 characters.
|
||||||
|
SubmitLinkPostLabel *string `url:"submit_link_label,omitempty" json:"submit_link_label,omitempty"`
|
||||||
|
// No longer than 60 characters.
|
||||||
|
SubmitTextPostLabel *string `url:"submit_text_label,omitempty" json:"submit_text_label,omitempty"`
|
||||||
|
|
||||||
|
// One of: any, link, self.
|
||||||
|
PostType *string `url:"link_type,omitempty" json:"content_options,omitempty"`
|
||||||
|
|
||||||
|
// One of: low (disable most filtering), high (standard), all (filter everything, requiring mod approval).
|
||||||
|
SpamFilterStrengthLinkPosts *string `url:"spam_links,omitempty" json:"spam_links,omitempty"`
|
||||||
|
// One of: low (disable most filtering), high (standard), all (filter everything, requiring mod approval).
|
||||||
|
SpamFilterStrengthTextPosts *string `url:"spam_selfposts,omitempty" json:"spam_selfposts,omitempty"`
|
||||||
|
// One of: low (disable most filtering), high (standard), all (filter everything, requiring mod approval).
|
||||||
|
SpamFilterStrengthComments *string `url:"spam_comments,omitempty" json:"spam_comments,omitempty"`
|
||||||
|
|
||||||
|
ShowContentThumbnails *bool `url:"show_media,omitempty" json:"show_media,omitempty"`
|
||||||
|
ExpandMediaPreviewsOnCommentsPages *bool `url:"show_media_preview,omitempty" json:"show_media_preview,omitempty"`
|
||||||
|
|
||||||
|
CollapseDeletedComments *bool `url:"collapse_deleted_comments,omitempty" json:"collapse_deleted_comments,omitempty"`
|
||||||
|
// An integer between 0 and 1440.
|
||||||
|
MinutesToHideCommentScores *int `url:"comment_score_hide_mins,omitempty" json:"comment_score_hide_mins,omitempty"`
|
||||||
|
|
||||||
|
// Enable marking posts as containing spoilers.
|
||||||
|
SpoilersEnabled *bool `url:"spoilers_enabled,omitempty" json:"spoilers_enabled,omitempty"`
|
||||||
|
|
||||||
|
// If there's an image header set, hovering the mouse over it will display this text.
|
||||||
|
HeaderMouseoverText *string `url:"header-title,omitempty" json:"header_hover_text,omitempty"`
|
||||||
|
|
||||||
|
// 6-digit rgb hex colour, e.g. #AABBCC.
|
||||||
|
// Thematic colour for the subreddit on mobile.
|
||||||
|
MobileColour *string `url:"key_color,omitempty" json:"key_color,omitempty"`
|
||||||
|
|
||||||
|
// Can only be set to true if subreddit type is gold_only.
|
||||||
|
HideAds *bool `url:"hide_ads,omitempty" json:"hide_ads,omitempty"`
|
||||||
|
// Require viewers to be over 18 years old.
|
||||||
|
NSFW *bool `url:"over_18,omitempty" json:"over_18,omitempty"`
|
||||||
|
|
||||||
|
// Show up in high-traffic feeds: Allow your community to be in r/all, r/popular, and trending lists where it can be
|
||||||
|
// seen by the general Reddit population.
|
||||||
|
AllowDiscoveryInHighTrafficFeeds *bool `url:"allow_top,omitempty" json:"default_set,omitempty"`
|
||||||
|
// Get recommended to individual redditors. Let Reddit recommend your community to people who have similar interests.
|
||||||
|
AllowDiscoveryByIndividualUsers *bool `url:"allow_discovery,omitempty" json:"allow_discovery,omitempty"`
|
||||||
|
|
||||||
|
// One of:
|
||||||
|
// - disabled: wiki is disabled for everyone except mods.
|
||||||
|
// - modonly: only mods, approved wiki contributors, or those on a page's edit list may edit.
|
||||||
|
// - anyone: anyone who can submit to the subreddit may edit.
|
||||||
|
WikiMode *string `url:"wikimode,omitempty" json:"wikimode,omitempty"`
|
||||||
|
// Account age (in days) required to create and edit wiki pages.
|
||||||
|
WikiMinimumAccountAge *int `url:"wiki_edit_age,omitempty" json:"wiki_edit_age,omitempty"`
|
||||||
|
// Subreddit karma required to create and edit wiki pages.
|
||||||
|
WikiMinimumKarma *int `url:"wiki_edit_karma,omitempty" json:"wiki_edit_karma,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SubredditService) getPosts(ctx context.Context, sort string, subreddit string, opts interface{}) ([]*Post, *Response, error) {
|
func (s *SubredditService) getPosts(ctx context.Context, sort string, subreddit string, opts interface{}) ([]*Post, *Response, error) {
|
||||||
path := sort
|
path := sort
|
||||||
if subreddit != "" {
|
if subreddit != "" {
|
||||||
|
@ -977,3 +1074,60 @@ func (s *SubredditService) UploadMobileHeader(ctx context.Context, subreddit, im
|
||||||
func (s *SubredditService) UploadMobileIcon(ctx context.Context, subreddit, imagePath, imageName string) (string, *Response, error) {
|
func (s *SubredditService) UploadMobileIcon(ctx context.Context, subreddit, imagePath, imageName string) (string, *Response, error) {
|
||||||
return s.uploadImage(ctx, subreddit, imagePath, "icon", imageName)
|
return s.uploadImage(ctx, subreddit, imagePath, "icon", imageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a subreddit.
|
||||||
|
func (s *SubredditService) Create(ctx context.Context, name string, request *SubredditSettings) (*Response, error) {
|
||||||
|
if request == nil {
|
||||||
|
return nil, errors.New("*SubredditSettings: cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
form, err := query.Values(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
form.Set("name", name)
|
||||||
|
form.Set("api_type", "json")
|
||||||
|
|
||||||
|
path := "api/site_admin"
|
||||||
|
req, err := s.client.NewRequest(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(ctx, req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit a subreddit.
|
||||||
|
// This endpoint expects all values of the request to be provided.
|
||||||
|
// To make this easier, it might be useful to get the subreddit's current settings via GetSettings(), and use that as a starting point.
|
||||||
|
func (s *SubredditService) Edit(ctx context.Context, subredditID string, request *SubredditSettings) (*Response, error) {
|
||||||
|
if request == nil {
|
||||||
|
return nil, errors.New("*SubredditSettings: cannot be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
form, err := query.Values(request)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
form.Set("sr", subredditID)
|
||||||
|
form.Set("api_type", "json")
|
||||||
|
|
||||||
|
path := "api/site_admin"
|
||||||
|
req, err := s.client.NewRequest(http.MethodPost, path, form)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.client.Do(ctx, req, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSettings gets the settings of a subreddit.
|
||||||
|
func (s *SubredditService) GetSettings(ctx context.Context, subreddit string) (*SubredditSettings, *Response, error) {
|
||||||
|
path := fmt.Sprintf("r/%s/about/edit", subreddit)
|
||||||
|
t, resp, err := s.client.getThing(ctx, path, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, resp, err
|
||||||
|
}
|
||||||
|
settings, _ := t.SubredditSettings()
|
||||||
|
return settings, resp, nil
|
||||||
|
}
|
||||||
|
|
|
@ -338,6 +338,68 @@ var expectedStyleSheet = &SubredditStyleSheet{
|
||||||
}`,
|
}`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var expectedSubredditSettings = &SubredditSettings{
|
||||||
|
ID: "t5_test",
|
||||||
|
|
||||||
|
Type: String("private"),
|
||||||
|
|
||||||
|
Language: String("en"),
|
||||||
|
|
||||||
|
Title: String("hello!"),
|
||||||
|
Description: String("description"),
|
||||||
|
Sidebar: String("sidebar"),
|
||||||
|
SubmissionText: String(""),
|
||||||
|
WelcomeMessage: String(""),
|
||||||
|
WelcomeMessageEnabled: Bool(false),
|
||||||
|
|
||||||
|
AllowCrossposts: Bool(false),
|
||||||
|
AllowChatPosts: Bool(true),
|
||||||
|
AllowPollPosts: Bool(false),
|
||||||
|
AllowFreeFormReports: Bool(true),
|
||||||
|
AllowOriginalContent: Bool(false),
|
||||||
|
AllowImages: Bool(true),
|
||||||
|
AllowMultipleImagesPerPost: Bool(true),
|
||||||
|
|
||||||
|
ExcludeSitewideBannedUsersContent: Bool(false),
|
||||||
|
|
||||||
|
CrowdControlChalLevel: Int(2),
|
||||||
|
|
||||||
|
AllOriginalContent: Bool(false),
|
||||||
|
|
||||||
|
SuggestedCommentSort: nil,
|
||||||
|
|
||||||
|
SubmitLinkPostLabel: String("submit a link!"),
|
||||||
|
SubmitTextPostLabel: String("submit a post!"),
|
||||||
|
|
||||||
|
PostType: String("any"),
|
||||||
|
|
||||||
|
SpamFilterStrengthLinkPosts: String("low"),
|
||||||
|
SpamFilterStrengthTextPosts: String("low"),
|
||||||
|
SpamFilterStrengthComments: String("low"),
|
||||||
|
|
||||||
|
ShowContentThumbnails: Bool(false),
|
||||||
|
ExpandMediaPreviewsOnCommentsPages: Bool(true),
|
||||||
|
|
||||||
|
CollapseDeletedComments: Bool(false),
|
||||||
|
MinutesToHideCommentScores: Int(0),
|
||||||
|
|
||||||
|
SpoilersEnabled: Bool(true),
|
||||||
|
|
||||||
|
HeaderMouseoverText: String("hello!"),
|
||||||
|
|
||||||
|
MobileColour: String(""),
|
||||||
|
|
||||||
|
HideAds: Bool(false),
|
||||||
|
NSFW: Bool(false),
|
||||||
|
|
||||||
|
AllowDiscoveryInHighTrafficFeeds: Bool(true),
|
||||||
|
AllowDiscoveryByIndividualUsers: Bool(true),
|
||||||
|
|
||||||
|
WikiMode: String("modonly"),
|
||||||
|
WikiMinimumAccountAge: Int(0),
|
||||||
|
WikiMinimumKarma: Int(0),
|
||||||
|
}
|
||||||
|
|
||||||
func TestSubredditService_HotPosts(t *testing.T) {
|
func TestSubredditService_HotPosts(t *testing.T) {
|
||||||
client, mux, teardown := setup()
|
client, mux, teardown := setup()
|
||||||
defer teardown()
|
defer teardown()
|
||||||
|
@ -1523,3 +1585,20 @@ func TestSubredditService_UploadImage_Error(t *testing.T) {
|
||||||
_, _, err = client.Subreddit.UploadImage(ctx, "testsubreddit", imageFile.Name(), "testname")
|
_, _, err = client.Subreddit.UploadImage(ctx, "testsubreddit", imageFile.Name(), "testname")
|
||||||
require.EqualError(t, err, "could not upload image: error one; error two")
|
require.EqualError(t, err, "could not upload image: error one; error two")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSubredditService_GetSettings(t *testing.T) {
|
||||||
|
client, mux, teardown := setup()
|
||||||
|
defer teardown()
|
||||||
|
|
||||||
|
blob, err := readFileContents("../testdata/subreddit/settings.json")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mux.HandleFunc("/r/testsubreddit/about/edit", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
require.Equal(t, http.MethodGet, r.Method)
|
||||||
|
fmt.Fprint(w, blob)
|
||||||
|
})
|
||||||
|
|
||||||
|
subredditSettings, _, err := client.Subreddit.GetSettings(ctx, "testsubreddit")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, expectedSubredditSettings, subredditSettings)
|
||||||
|
}
|
||||||
|
|
|
@ -6,26 +6,27 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
kindComment = "t1"
|
kindComment = "t1"
|
||||||
kindUser = "t2"
|
kindUser = "t2"
|
||||||
kindPost = "t3"
|
kindPost = "t3"
|
||||||
kindMessage = "t4"
|
kindMessage = "t4"
|
||||||
kindSubreddit = "t5"
|
kindSubreddit = "t5"
|
||||||
kindTrophy = "t6"
|
kindTrophy = "t6"
|
||||||
kindListing = "Listing"
|
kindListing = "Listing"
|
||||||
kindKarmaList = "KarmaList"
|
kindSubredditSettings = "subreddit_settings"
|
||||||
kindTrophyList = "TrophyList"
|
kindKarmaList = "KarmaList"
|
||||||
kindUserList = "UserList"
|
kindTrophyList = "TrophyList"
|
||||||
kindMore = "more"
|
kindUserList = "UserList"
|
||||||
kindLiveThread = "LiveUpdateEvent"
|
kindMore = "more"
|
||||||
kindLiveThreadUpdate = "LiveUpdate"
|
kindLiveThread = "LiveUpdateEvent"
|
||||||
kindModAction = "modaction"
|
kindLiveThreadUpdate = "LiveUpdate"
|
||||||
kindMulti = "LabeledMulti"
|
kindModAction = "modaction"
|
||||||
kindMultiDescription = "LabeledMultiDescription"
|
kindMulti = "LabeledMulti"
|
||||||
kindWikiPage = "wikipage"
|
kindMultiDescription = "LabeledMultiDescription"
|
||||||
kindWikiPageListing = "wikipagelisting"
|
kindWikiPage = "wikipage"
|
||||||
kindWikiPageSettings = "wikipagesettings"
|
kindWikiPageListing = "wikipagelisting"
|
||||||
kindStyleSheet = "stylesheet"
|
kindWikiPageSettings = "wikipagesettings"
|
||||||
|
kindStyleSheet = "stylesheet"
|
||||||
)
|
)
|
||||||
|
|
||||||
type anchor interface {
|
type anchor interface {
|
||||||
|
@ -91,6 +92,8 @@ func (t *thing) UnmarshalJSON(b []byte) error {
|
||||||
v = new(Post)
|
v = new(Post)
|
||||||
case kindSubreddit:
|
case kindSubreddit:
|
||||||
v = new(Subreddit)
|
v = new(Subreddit)
|
||||||
|
case kindSubredditSettings:
|
||||||
|
v = new(SubredditSettings)
|
||||||
case kindLiveThread:
|
case kindLiveThread:
|
||||||
v = new(LiveThread)
|
v = new(LiveThread)
|
||||||
case kindLiveThreadUpdate:
|
case kindLiveThreadUpdate:
|
||||||
|
@ -158,6 +161,11 @@ func (t *thing) Subreddit() (v *Subreddit, ok bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *thing) SubredditSettings() (v *SubredditSettings, ok bool) {
|
||||||
|
v, ok = t.Data.(*SubredditSettings)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (t *thing) LiveThread() (v *LiveThread, ok bool) {
|
func (t *thing) LiveThread() (v *LiveThread, ok bool) {
|
||||||
v, ok = t.Data.(*LiveThread)
|
v, ok = t.Data.(*LiveThread)
|
||||||
return
|
return
|
||||||
|
|
57
testdata/subreddit/settings.json
vendored
Normal file
57
testdata/subreddit/settings.json
vendored
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"kind": "subreddit_settings",
|
||||||
|
"data": {
|
||||||
|
"default_set": true,
|
||||||
|
"toxicity_threshold_chat_level": 1,
|
||||||
|
"crowd_control_chat_level": 2,
|
||||||
|
"disable_contributor_requests": false,
|
||||||
|
"subreddit_id": "t5_test",
|
||||||
|
"allow_images": true,
|
||||||
|
"free_form_reports": true,
|
||||||
|
"domain": null,
|
||||||
|
"show_media": false,
|
||||||
|
"wiki_edit_age": 0,
|
||||||
|
"submit_text": "",
|
||||||
|
"allow_polls": false,
|
||||||
|
"title": "hello!",
|
||||||
|
"collapse_deleted_comments": false,
|
||||||
|
"wikimode": "modonly",
|
||||||
|
"over_18": false,
|
||||||
|
"allow_videos": true,
|
||||||
|
"spoilers_enabled": true,
|
||||||
|
"new_pinned_post_pns_enabled": true,
|
||||||
|
"crowd_control_mode": false,
|
||||||
|
"welcome_message_enabled": false,
|
||||||
|
"welcome_message_text": "",
|
||||||
|
"suggested_comment_sort": null,
|
||||||
|
"restrict_posting": true,
|
||||||
|
"original_content_tag_enabled": false,
|
||||||
|
"description": "sidebar",
|
||||||
|
"submit_link_label": "submit a link!",
|
||||||
|
"allow_galleries": true,
|
||||||
|
"allow_post_crossposts": false,
|
||||||
|
"spam_comments": "low",
|
||||||
|
"public_traffic": false,
|
||||||
|
"restrict_commenting": false,
|
||||||
|
"crowd_control_level": 0,
|
||||||
|
"submit_text_label": "submit a post!",
|
||||||
|
"all_original_content": false,
|
||||||
|
"spam_selfposts": "low",
|
||||||
|
"key_color": "",
|
||||||
|
"language": "en",
|
||||||
|
"wiki_edit_karma": 0,
|
||||||
|
"hide_ads": false,
|
||||||
|
"header_hover_text": "hello!",
|
||||||
|
"allow_chat_post_creation": true,
|
||||||
|
"allow_discovery": true,
|
||||||
|
"exclude_banned_modqueue": false,
|
||||||
|
"public_description": "description",
|
||||||
|
"show_media_preview": true,
|
||||||
|
"comment_score_hide_mins": 0,
|
||||||
|
"subreddit_type": "private",
|
||||||
|
"spam_links": "low",
|
||||||
|
"allow_predictions": false,
|
||||||
|
"user_flair_pns_enabled": true,
|
||||||
|
"content_options": "any"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue