snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
This commit is contained in:
460
server/cmd/mmctl/commands/sampledata_util.go
Normal file
460
server/cmd/mmctl/commands/sampledata_util.go
Normal file
@@ -0,0 +1,460 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
//nolint:gosec
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/app"
|
||||
"github.com/mattermost/mattermost/server/v8/channels/app/imports"
|
||||
|
||||
"github.com/icrowley/fake"
|
||||
)
|
||||
|
||||
func randomPastTime(seconds int) int64 {
|
||||
now := time.Now()
|
||||
today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.FixedZone("UTC", 0))
|
||||
return (today.Unix() * 1000) - int64(rand.Intn(seconds*1000))
|
||||
}
|
||||
|
||||
func sortedRandomDates(size int) []int64 {
|
||||
dates := make([]int64, size)
|
||||
for i := range size {
|
||||
dates[i] = randomPastTime(50000)
|
||||
}
|
||||
slices.Sort(dates)
|
||||
return dates
|
||||
}
|
||||
|
||||
func randomEmoji() string {
|
||||
emojis := []string{"+1", "-1", "heart", "blush"}
|
||||
return emojis[rand.Intn(len(emojis))]
|
||||
}
|
||||
|
||||
func randomReaction(users []string, parentCreateAt int64) app.ReactionImportData {
|
||||
user := users[rand.Intn(len(users))]
|
||||
emoji := randomEmoji()
|
||||
date := parentCreateAt + int64(rand.Intn(100000))
|
||||
return app.ReactionImportData{
|
||||
User: &user,
|
||||
EmojiName: &emoji,
|
||||
CreateAt: &date,
|
||||
}
|
||||
}
|
||||
|
||||
func randomReply(users []string, parentCreateAt int64) imports.ReplyImportData {
|
||||
user := users[rand.Intn(len(users))]
|
||||
message := randomMessage(users)
|
||||
date := parentCreateAt + int64(rand.Intn(100000))
|
||||
return imports.ReplyImportData{
|
||||
User: &user,
|
||||
Message: &message,
|
||||
CreateAt: &date,
|
||||
}
|
||||
}
|
||||
|
||||
func randomMessage(users []string) string {
|
||||
var message string
|
||||
switch rand.Intn(30) {
|
||||
case 0:
|
||||
mention := users[rand.Intn(len(users))]
|
||||
message = "@" + mention + " " + fake.Sentence()
|
||||
case 1:
|
||||
switch rand.Intn(2) {
|
||||
case 0:
|
||||
mattermostVideos := []string{"Q4MgnxbpZas", "BFo7E9-Kc_E", "LsMLR-BHsKg", "MRmGDhlMhNA", "mUOPxT7VgWc"}
|
||||
message = "https://www.youtube.com/watch?v=" + mattermostVideos[rand.Intn(len(mattermostVideos))]
|
||||
case 1:
|
||||
mattermostTweets := []string{"943119062334353408", "949370809528832005", "948539688171819009", "939122439115681792", "938061722027425797"}
|
||||
message = "https://twitter.com/mattermosthq/status/" + mattermostTweets[rand.Intn(len(mattermostTweets))]
|
||||
}
|
||||
case 2:
|
||||
message = ""
|
||||
if rand.Intn(2) == 0 {
|
||||
message += fake.Sentence()
|
||||
}
|
||||
lenList := rand.Intn(4) + 1
|
||||
for range lenList {
|
||||
message += "\n * " + fake.Word()
|
||||
}
|
||||
default:
|
||||
if rand.Intn(2) == 0 {
|
||||
message = fake.Sentence()
|
||||
} else {
|
||||
message = fake.Paragraph()
|
||||
}
|
||||
if rand.Intn(3) == 0 {
|
||||
message += "\n" + fake.Sentence()
|
||||
}
|
||||
if rand.Intn(3) == 0 {
|
||||
message += "\n" + fake.Sentence()
|
||||
}
|
||||
if rand.Intn(3) == 0 {
|
||||
message += "\n" + fake.Sentence()
|
||||
}
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
func createUser(idx int, teamMemberships int, channelMemberships int, teamsAndChannels map[string][]string, profileImages []string, userType string) imports.LineImportData {
|
||||
firstName := fake.FirstName()
|
||||
lastName := fake.LastName()
|
||||
position := fake.JobTitle()
|
||||
|
||||
username := fmt.Sprintf("%s.%s", strings.ToLower(firstName), strings.ToLower(lastName))
|
||||
roles := "system_user"
|
||||
|
||||
var password string
|
||||
var email string
|
||||
|
||||
switch userType {
|
||||
case guestUser:
|
||||
password = fmt.Sprintf("SampleGu@st-%03d", idx)
|
||||
email = fmt.Sprintf("guest-%d@sample.mattermost.com", idx)
|
||||
roles = "system_guest"
|
||||
if idx == 0 {
|
||||
username = "guest"
|
||||
email = "guest@sample.mattermost.com"
|
||||
}
|
||||
case deactivatedUser:
|
||||
password = fmt.Sprintf("SampleDe@ctivated-%d", idx)
|
||||
email = fmt.Sprintf("deactivated-%d@sample.mattermost.com", idx)
|
||||
default:
|
||||
password = fmt.Sprintf("SampleUs@r-%03d", idx)
|
||||
email = fmt.Sprintf("user-%d@sample.mattermost.com", idx)
|
||||
if idx == 0 {
|
||||
username = "sysadmin"
|
||||
password = "Sys@dmin-sample1"
|
||||
email = "sysadmin@sample.mattermost.com"
|
||||
} else if idx == 1 {
|
||||
username = "user-1"
|
||||
}
|
||||
|
||||
if idx%5 == 0 {
|
||||
roles = "system_admin system_user"
|
||||
}
|
||||
}
|
||||
|
||||
// The 75% of the users have custom profile image
|
||||
var profileImage *string
|
||||
if rand.Intn(4) != 0 {
|
||||
profileImageSelector := rand.Int()
|
||||
if len(profileImages) > 0 {
|
||||
profileImage = &profileImages[profileImageSelector%len(profileImages)]
|
||||
}
|
||||
}
|
||||
|
||||
useMilitaryTime := "false"
|
||||
if idx != 0 && rand.Intn(2) == 0 {
|
||||
useMilitaryTime = "true"
|
||||
}
|
||||
|
||||
collapsePreviews := "false"
|
||||
if idx != 0 && rand.Intn(2) == 0 {
|
||||
collapsePreviews = "true"
|
||||
}
|
||||
|
||||
messageDisplay := "clean"
|
||||
if idx != 0 && rand.Intn(2) == 0 {
|
||||
messageDisplay = "compact"
|
||||
}
|
||||
|
||||
channelDisplayMode := "full"
|
||||
if idx != 0 && rand.Intn(2) == 0 {
|
||||
channelDisplayMode = "centered"
|
||||
}
|
||||
|
||||
// Some users has nickname
|
||||
nickname := ""
|
||||
if rand.Intn(5) == 0 {
|
||||
nickname = fake.Company()
|
||||
}
|
||||
|
||||
// sysadmin, user-1 and user-2 users skip tutorial steps
|
||||
// Other half of users also skip tutorial steps
|
||||
tutorialStep := "999"
|
||||
if idx > 2 {
|
||||
switch rand.Intn(6) {
|
||||
case 1:
|
||||
tutorialStep = "1"
|
||||
case 2:
|
||||
tutorialStep = "2"
|
||||
case 3:
|
||||
tutorialStep = "3"
|
||||
}
|
||||
}
|
||||
|
||||
teams := []imports.UserTeamImportData{}
|
||||
possibleTeams := []string{}
|
||||
for teamName := range teamsAndChannels {
|
||||
possibleTeams = append(possibleTeams, teamName)
|
||||
}
|
||||
slices.Sort(possibleTeams)
|
||||
for range teamMemberships {
|
||||
if len(possibleTeams) == 0 {
|
||||
break
|
||||
}
|
||||
position := rand.Intn(len(possibleTeams))
|
||||
team := possibleTeams[position]
|
||||
possibleTeams = append(possibleTeams[:position], possibleTeams[position+1:]...)
|
||||
if teamChannels, err := teamsAndChannels[team]; err {
|
||||
teams = append(teams, createTeamMembership(channelMemberships, teamChannels, &team, userType == guestUser))
|
||||
}
|
||||
}
|
||||
|
||||
var deleteAt int64
|
||||
if userType == deactivatedUser {
|
||||
deleteAt = model.GetMillis()
|
||||
}
|
||||
|
||||
user := imports.UserImportData{
|
||||
Avatar: imports.Avatar{
|
||||
ProfileImage: profileImage,
|
||||
},
|
||||
Username: &username,
|
||||
Email: &email,
|
||||
Password: &password,
|
||||
Nickname: &nickname,
|
||||
FirstName: &firstName,
|
||||
LastName: &lastName,
|
||||
Position: &position,
|
||||
Roles: &roles,
|
||||
Teams: &teams,
|
||||
UseMilitaryTime: &useMilitaryTime,
|
||||
CollapsePreviews: &collapsePreviews,
|
||||
MessageDisplay: &messageDisplay,
|
||||
ChannelDisplayMode: &channelDisplayMode,
|
||||
TutorialStep: &tutorialStep,
|
||||
DeleteAt: &deleteAt,
|
||||
}
|
||||
return imports.LineImportData{
|
||||
Type: "user",
|
||||
User: &user,
|
||||
}
|
||||
}
|
||||
|
||||
func createTeamMembership(numOfchannels int, teamChannels []string, teamName *string, guest bool) imports.UserTeamImportData {
|
||||
roles := "team_user"
|
||||
if guest {
|
||||
roles = "team_guest"
|
||||
} else if rand.Intn(5) == 0 {
|
||||
roles = "team_user team_admin"
|
||||
}
|
||||
channels := []imports.UserChannelImportData{}
|
||||
teamChannelsCopy := append([]string(nil), teamChannels...)
|
||||
for range numOfchannels {
|
||||
if len(teamChannelsCopy) == 0 {
|
||||
break
|
||||
}
|
||||
position := rand.Intn(len(teamChannelsCopy))
|
||||
channelName := teamChannelsCopy[position]
|
||||
teamChannelsCopy = append(teamChannelsCopy[:position], teamChannelsCopy[position+1:]...)
|
||||
channels = append(channels, createChannelMembership(channelName, guest))
|
||||
}
|
||||
|
||||
return imports.UserTeamImportData{
|
||||
Name: teamName,
|
||||
Roles: &roles,
|
||||
Channels: &channels,
|
||||
}
|
||||
}
|
||||
|
||||
func createChannelMembership(channelName string, guest bool) imports.UserChannelImportData {
|
||||
roles := "channel_user"
|
||||
if guest {
|
||||
roles = "channel_guest"
|
||||
} else if rand.Intn(5) == 0 {
|
||||
roles = "channel_user channel_admin"
|
||||
}
|
||||
favorite := rand.Intn(5) == 0
|
||||
|
||||
return imports.UserChannelImportData{
|
||||
Name: &channelName,
|
||||
Roles: &roles,
|
||||
Favorite: &favorite,
|
||||
}
|
||||
}
|
||||
|
||||
func getSampleTeamName(idx int) string {
|
||||
for {
|
||||
name := fmt.Sprintf("%s-%d", fake.Word(), idx)
|
||||
if !model.IsReservedTeamName(name) {
|
||||
return name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createTeam(idx int) imports.LineImportData {
|
||||
displayName := fake.Word()
|
||||
name := getSampleTeamName(idx)
|
||||
allowOpenInvite := rand.Intn(2) == 0
|
||||
|
||||
description := fake.Paragraph()
|
||||
if len(description) > 255 {
|
||||
description = description[0:255]
|
||||
}
|
||||
|
||||
teamType := "O"
|
||||
if rand.Intn(2) == 0 {
|
||||
teamType = "I"
|
||||
}
|
||||
|
||||
team := imports.TeamImportData{
|
||||
DisplayName: &displayName,
|
||||
Name: &name,
|
||||
AllowOpenInvite: &allowOpenInvite,
|
||||
Description: &description,
|
||||
Type: &teamType,
|
||||
}
|
||||
return imports.LineImportData{
|
||||
Type: "team",
|
||||
Team: &team,
|
||||
}
|
||||
}
|
||||
|
||||
func createChannel(idx int, teamName string) imports.LineImportData {
|
||||
displayName := fake.Word()
|
||||
name := fmt.Sprintf("%s-%d", fake.Word(), idx)
|
||||
header := fake.Paragraph()
|
||||
purpose := fake.Paragraph()
|
||||
|
||||
if len(purpose) > 250 {
|
||||
purpose = purpose[0:250]
|
||||
}
|
||||
|
||||
channelType := model.ChannelTypePrivate
|
||||
if rand.Intn(2) == 0 {
|
||||
channelType = model.ChannelTypeOpen
|
||||
}
|
||||
|
||||
channel := imports.ChannelImportData{
|
||||
Team: &teamName,
|
||||
Name: &name,
|
||||
DisplayName: &displayName,
|
||||
Type: &channelType,
|
||||
Header: &header,
|
||||
Purpose: &purpose,
|
||||
}
|
||||
return imports.LineImportData{
|
||||
Type: "channel",
|
||||
Channel: &channel,
|
||||
}
|
||||
}
|
||||
|
||||
func createPost(team string, channel string, allUsers []string, createAt int64) imports.LineImportData {
|
||||
message := randomMessage(allUsers)
|
||||
user := allUsers[rand.Intn(len(allUsers))]
|
||||
|
||||
// Some messages are flagged by a user
|
||||
flaggedBy := []string{}
|
||||
if rand.Intn(10) == 0 {
|
||||
flaggedBy = append(flaggedBy, allUsers[rand.Intn(len(allUsers))])
|
||||
}
|
||||
|
||||
reactions := []app.ReactionImportData{}
|
||||
if rand.Intn(10) == 0 {
|
||||
for {
|
||||
reactions = append(reactions, randomReaction(allUsers, createAt))
|
||||
if rand.Intn(3) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
replies := []imports.ReplyImportData{}
|
||||
if rand.Intn(10) == 0 {
|
||||
for {
|
||||
replies = append(replies, randomReply(allUsers, createAt))
|
||||
if rand.Intn(4) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post := imports.PostImportData{
|
||||
Team: &team,
|
||||
Channel: &channel,
|
||||
User: &user,
|
||||
Message: &message,
|
||||
CreateAt: &createAt,
|
||||
FlaggedBy: &flaggedBy,
|
||||
Reactions: &reactions,
|
||||
Replies: &replies,
|
||||
}
|
||||
return imports.LineImportData{
|
||||
Type: "post",
|
||||
Post: &post,
|
||||
}
|
||||
}
|
||||
|
||||
func createDirectChannel(members []string) imports.LineImportData {
|
||||
header := fake.Sentence()
|
||||
var p []*imports.DirectChannelMemberImportData
|
||||
|
||||
for _, m := range members {
|
||||
p = append(p, &imports.DirectChannelMemberImportData{
|
||||
Username: new(m),
|
||||
})
|
||||
}
|
||||
|
||||
channel := imports.DirectChannelImportData{
|
||||
Participants: p,
|
||||
Header: &header,
|
||||
}
|
||||
return imports.LineImportData{
|
||||
Type: "direct_channel",
|
||||
DirectChannel: &channel,
|
||||
}
|
||||
}
|
||||
|
||||
func createDirectPost(members []string, createAt int64) imports.LineImportData {
|
||||
message := randomMessage(members)
|
||||
user := members[rand.Intn(len(members))]
|
||||
|
||||
// Some messages are flagged by an user
|
||||
flaggedBy := []string{}
|
||||
if rand.Intn(10) == 0 {
|
||||
flaggedBy = append(flaggedBy, members[rand.Intn(len(members))])
|
||||
}
|
||||
|
||||
reactions := []app.ReactionImportData{}
|
||||
if rand.Intn(10) == 0 {
|
||||
for {
|
||||
reactions = append(reactions, randomReaction(members, createAt))
|
||||
if rand.Intn(3) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
replies := []imports.ReplyImportData{}
|
||||
if rand.Intn(10) == 0 {
|
||||
for {
|
||||
replies = append(replies, randomReply(members, createAt))
|
||||
if rand.Intn(4) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post := imports.DirectPostImportData{
|
||||
ChannelMembers: &members,
|
||||
User: &user,
|
||||
Message: &message,
|
||||
CreateAt: &createAt,
|
||||
FlaggedBy: &flaggedBy,
|
||||
Reactions: &reactions,
|
||||
Replies: &replies,
|
||||
}
|
||||
return imports.LineImportData{
|
||||
Type: "direct_post",
|
||||
DirectPost: &post,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user