docs/main/administration-guide/onboard/bulk-loading-data.mdx
Large quantities of data can be imported from a JSONL file into Mattermost at the command line using the bulk loading feature. This feature is most suitable for migrating data from an existing system, or for pre-populating a new installation with data.
You can import the following data types:
Importing additional types of posts is not yet supported.
The bulk loading command is interruptible and idempotent
If the import is interrupted for any reason, it continues from where it left off the next time you run it. You can run the command repeatedly with the same data file, and the data is imported only once. Posts with matching timestamps to incoming posts will have their attachments replaced by the incoming data. Prior to v5.20 any updates to posts with matching timestamps were appended to older posts.
You can run the bulk loading command on a live system
Although you don't need to shut down Mattermost to run the command, changes made by users of the system between runs can be overwritten if the corresponding fields exist in the data file.
Some data fields are optional
Not all fields are mandatory. If an optional field is missing from the object that is being imported, the field's current value in the database is not changed.
The bulk loading command is not a synchronization tool
You cannot use the bulk loading command to remove any objects or their fields from the Mattermost database. The command only creates or overwrites fields.
The bulk loading command runs in the mmctl and operates in the security context of the mmctl. This means it has full permissions to access and alter everything in the Mattermost database.
Before running the bulk loading command, you must first create a JSONL file that contains the data that you want to import in your Mattermost directory. The file can have any name, but in this example it's called data.jsonl. The format of the file is described in the data-format section.
Next, zip it by running the zip -r data.zip data.jsonl command.
From Mattermost v9.5, the mmctl bulk import process command in local mode supports processing an import file without uploading it to the server.
Run mmctl import process --bypass-upload <file>.zip --local to start your import and enable the Mattermost server to read from the file directly.
If you're not running mmctl commands in local mode:
mmctl import upload data.zip. After uploading, two IDs are returned: the first line contains the upload session ID, and the second line contains the filename.mmctl import process <upload_session_id>_data.zip where <upload_session_id> is the upload session ID returned from the upload command.The input data file must be a valid JSONL file with the following objects, each on its own line in the file. The objects must occur in the file in the order listed.
Version
Mandatory. The Version object must be the first line in the file, and must occur only once. The version is the version of the bulk importer tool, which is currently 1.
Scheme
Optional. If present, Scheme objects must occur after the Version object but before any Team objects.
Emoji
Optional. If present, Emoji objects must occur after the Version objects but before any Team objects.
Team
Optional. If present, Team objects must occur after any Scheme objects and before any Channel objects.
Channel
Optional. If present, Channel objects must occur after all Team objects and before any User objects.
User
Optional. If present, User objects must occur after the Team and Channel objects in the file and before any Post objects. Each User object defines the teams and channels that the user is a member of. If the corresponding teams and channels are not in the data file, then they must exist in the Mattermost database.
Post
Optional. If present, Post objects must occur after the last User object but before any DirectChannel objects. Each Post object defines the team, the channel, and the username of the user who posted the message. If the corresponding team, channel, or user are not in the data file, then they must exist in the Mattermost database.
DirectChannel
Optional. If present, DirectChannel objects must occur after all Post objects in the file and before any DirectPost objects.
DirectPost
Optional. If present, DirectPost objects must occur after all other objects in the file. Each DirectPost object defines the usernames of the channel members and the username of the user who posted the message. If the corresponding usernames are not in the data file, then they must exist in the Mattermost database.
With the exception of the Version object, each object has a field or a combination of fields that is used as the unique identifier of that object. The bulk loader uses the unique identifier to determine if the object being imported is a new object or an update to an existing object.
The identifiers for each object are listed in the following table:
<table> <caption>Objects and their unique identifiers</caption> <thead> <tr> <th>Object</th> <th>Unique Identifier</th> </tr> </thead> <tbody> <tr> <td>Version</td> <td>Not Applicable</td> </tr> <tr> <td>Scheme</td> <td><em>name</em></td> </tr> <tr> <td>Role</td> <td><em>name</em></td> </tr> <tr> <td>Emoji</td> <td><em>name</em></td> </tr> <tr> <td>Team</td> <td><em>name</em></td> </tr> <tr> <td>Channel</td> <td><em>name</em>, <em>team</em></td> </tr> <tr> <td>User</td> <td><em>username</em></td> </tr> <tr> <td>UserNotifyProps</td> <td><em>username</em></td> </tr> <tr> <td>UserTeamMembership</td> <td><em>team</em>, <em>username</em></td> </tr> <tr> <td>UserChannelMembership</td> <td><em>team</em>, <em>channel</em>, <em>username</em></td> </tr> <tr> <td>Post</td> <td><em>channel</em>, <em>message</em>, <em>create_at</em></td> </tr> <tr> <td>Reply</td> <td><em>post</em>, <em>message</em>, <em>create_at</em></td> </tr> <tr> <td>Reaction</td> <td><em>post</em>, <em>emoji_name</em>, <em>create_at</em></td> </tr> <tr> <td>Attachment</td> <td><em>path</em></td> </tr> <tr> <td>DirectChannel</td> <td><em>members</em></td> </tr> <tr> <td>DirectPost</td> <td><em>channel_members</em>, <em>user</em>, <em>message</em>, <em>create_at</em></td> </tr> </tbody> </table>The following fragment is from a file that imports two teams, each with two channels, many users, and many posts.
{ "type": "version", ... }
{ "type": "team", "team": { "name": "TeamA", ...} }
{ "type": "team", "team": { "name": "TeamB", ...} }
{ "type": "channel", "channel": { "team": "TeamA", "name": "channel_a1", ...} }
{ "type": "channel", "channel": { "team": "TeamA", "name": "channel_a2", ...} }
{ "type": "channel", "channel": { "team": "TeamB", "name": "channel_b1", ...} }
{ "type": "channel", "channel": { "team": "TeamB", "name": "channel_b2", ...} }
{ "type": "user", "user": { "username": "user001", ...} }
{ "type": "user", "user": { "username": "user002", ...} }
{ "type": "user", "user": { "username": "user003", ...} }
{ "type": "user", ... }
{ "type": "user", ... }
{ "type": "user", ... }
.
.
.
{ "type": "post", { "team": "TeamA", "name": "channel_a1", "user": "user001", ...} }
{ "type": "post", { "team": "TeamA", "name": "channel_a1", "user": "user001", ...} }
{ "type": "post", { "team": "TeamA", "name": "channel_a1", "user": "user001", ...} }
.
.
.
The Version object must be the first object in the data file, and can appear only once. The version represents the version of the bulk import tool and currently is 1.
For clarity, the object is shown using regular JSON formatting, but in the data file it cannot be spread across several lines. It must be all on one line.
{
"type": "version",
"version": 1
}
Scheme objects represent Permissions Schemes in the Mattermost permissions system. If present, Scheme objects must occur after the Version object and before any Team objects.
For clarity, the object is shown using regular JSON formatting, but in the data file it cannot be spread across several lines. It must be all on one line.
{
"type": "scheme",
"scheme": {
"name": "custom_scheme_name",
"display_name": "Custom Scheme Name",
"description": "This is a custom override scheme.",
"scope": "team",
"default_team_admin_role": {
"name": "custom_scheme_team_admin_role",
"display_name": "Custom Scheme Team Admin Role",
"description": "This is the default team admin role for the custom scheme.",
"permissions": ["add_user_to_team", "manage_team_roles"],
},
"default_team_user_role": {
"name": "custom_scheme_team_user_role",
"display_name": "Custom Scheme Team User Role",
"description": "This is the default team user role for the custom scheme.",
"permissions": ["create_public_channel", "create_private_channel"],
},
"default_channel_admin_role": {
"name": "custom_scheme_channel_admin_role",
"display_name": "Custom Scheme Channel Admin Role",
"description": "This is the default channel admin role for the custom scheme.",
"permissions": ["manage_private_channel_members", "manage_channel_roles"],
},
"default_channel_user_role": {
"name": "custom_scheme_channel_user_role",
"display_name": "Custom Scheme Channel User Role",
"description": "This is the default channel user role for the custom scheme.",
"permissions": ["manage_public_channel_members", "manage_public_channel_properties"],
},
}
}
This object is a member of the Scheme object.
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}> <tr class="row-odd"> <th class="head">Field name</th> <th class="head">Type</th> <th class="head">Description</th> <th class="head">Validated</th> <th class="head">Mandatory</th> </tr> <tr class="row-odd"> <td valign="middle">name</td> <td valign="middle">string</td> <td>The scheme name.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">Yes</td> </tr> <tr class="row-odd"> <td valign="middle">display_name</td> <td valign="middle">string</td> <td>The display name for the scheme.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">Yes</td> </tr> <tr class="row-odd"> <td valign="middle">description</td> <td valign="middle">string</td> <td>The description of the scheme.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">permissions</td> <td valign="middle">array</td> <td>The permissions the role should grant. This is an array of strings where the strings are the names of individual permissions in the Mattermost permissions system.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> </table>Emoji objects represent custom Emoji. If present, Emoji objects must occur after the Version object and before any Team objects.
For clarity, the object is shown using regular JSON formatting, but in the data file it cannot be spread across several lines. It must be all on one line.
{
"type": "emoji",
"emoji": {
"name": "custom-emoji-troll",
"image": "bulkdata/emoji/trollolol.png"
}
}
If present, Team objects must occur after the Version object and before any Channel objects.
For clarity, the object is shown using regular JSON formatting, but in the data file it cannot be spread across several lines. It must be all on one line.
{
"type": "team",
"team": {
"name": "team-name",
"display_name": "Team Display Name",
"type": "O",
"description": "The Team Description",
"allow_open_invite": true
}
}
If present, Channel objects must occur after all Team objects and before any User objects.
For clarity, the object is shown using regular JSON formatting, but in the data file it cannot be spread across several lines. It must be all on one line.
{
"type": "channel",
"channel": {
"team": "team-name",
"name": "channel-name",
"display_name": "Channel Name",
"type": "O",
"header": "The Channel Header",
"purpose": "The Channel Purpose",
}
}
If present, User objects must occur after the Team and Channel objects in the file and before any Post objects.
For clarity, the object is shown using regular JSON formatting, but in the data file it cannot be spread across several lines. It must be all on one line.
{
"type": "user",
"user": {
"profile_image": "profile-picture.png",
"username": "username",
"email": "[email protected]",
"auth_service": "",
"password": "passw0rd",
"nickname": "bobuser",
"first_name": "Bob",
"last_name": "User",
"position": "Senior Developer",
"roles": "system_user",
"locale": "pt_BR",
"teams": [
{
"name": "team-name",
"theme": "{
\"awayIndicator\":\"#DBBD4E\",
\"buttonBg\":\"#23A1FF\",
\"buttonColor\":\"#FFFFFF\",
\"centerChannelBg\":\"#ffffff\",
\"centerChannelColor\":\"#333333\",
\"codeTheme\":\"github\",
\"linkColor\":\"#2389d7\",
\"mentionBg\":\"#2389d7\",
\"mentionColor\":\"#ffffff\",
\"mentionHighlightBg\":\"#fff2bb\",
\"mentionHighlightLink\":\"#2f81b7\",
\"newMessageSeparator\":\"#FF8800\",
\"onlineIndicator\":\"#7DBE00\",
\"sidebarBg\":\"#fafafa\",
\"sidebarHeaderBg\":\"#3481B9\",
\"sidebarHeaderTextColor\":\"#ffffff\",
\"sidebarText\":\"#333333\",
\"sidebarTextActiveBorder\":\"#378FD2\",
\"sidebarTextActiveColor\":\"#111111\",
\"sidebarTextHoverBg\":\"#e6f2fa\",
\"sidebarUnreadText\":\"#333333\",
}",
"roles": "team_user team_admin",
"channels": [
{
"name": "channel-name",
"roles": "channel_user",
"notify_props": {
"desktop": "default",
"mark_unread": "all"
}
}
]
}
]
}
}
This object is a member of the User object.
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}> <tfoot><tr><td colspan="5">[1] Not validated, but an error occurs if no such team exists when running in apply mode.</td></tr></tfoot> <tr class="row-odd"> <th class="head">Field name</th> <th class="head">Type</th> <th class="head">Description</th> <th class="head">Validated</th> <th class="head">Mandatory</th> </tr> <tr class="row-odd"> <td valign="middle">desktop</td> <td valign="middle">string</td> <td>Preference for sending desktop notifications. Must be one of the following values: <kbd>"all"</kbd> - For all activity. <kbd>"mention"</kbd> - Only for mentions. <kbd>"none"</kbd> - Never.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">desktop_sound</td> <td valign="middle">string</td> <td>Preference for whether desktop notification sound is played. Must be one of the following values: <kbd>"true"</kbd> - Sound is played. <kbd>"false"</kbd> - Sound is not played.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">email</td> <td valign="middle">string</td> <td>Preference for email notifications. Must be one of the following values: <kbd>"true"</kbd> - Email notifications are sent based on the email_interval setting <kbd>"false"</kbd> - Email notifications are not sent.</td> <td align="center" valign="middle">No</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">mobile</td> <td valign="middle">string</td> <td>Preference for sending mobile push notifications. Must be one of the following values: <kbd>"all"</kbd> - For all activity. <kbd>"mention"</kbd> - Only for mentions. <kbd>"none"</kbd> - Never.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">mobile_push_status</td> <td valign="middle">string</td> <td>Preference for when push notifications are triggered. Must be one of the following values: <kbd>"online"</kbd> - When online, away or offline. <kbd>"away"</kbd> - When away or offline. <kbd>"offline"</kbd> - When offline.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">channel</td> <td valign="middle">string</td> <td>Whether @all, @channel and @here trigger mentions. Must be one of the following values: <kbd>"true"</kbd> - Mentions are triggered. <kbd>"false"</kbd> - Mentions are not triggered.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">comments</td> <td valign="middle">string</td> <td>Preference for reply mention notifications. Must be one of the following values: <kbd>"any"</kbd> - Trigger notifications on messages in reply threads that the user starts or participates in. <kbd>"root"</kbd> - Trigger notifications on messages in threads that the user starts. <kbd>"never"</kbd> - Do not trigger notifications on messages in reply threads unless the user is mentioned.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">mention_keys</td> <td valign="middle">string</td> <td>Preference for custom non-case sensitive words that trigger mentions. Words must be separated by commas.</td> <td align="center" valign="middle">No</td> <td align="center" valign="middle">No</td> </tr> </table>This object is a member of the User object.
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}> <tfoot><tr><td colspan="5">[1] Not validated, but an error occurs if no such team exists when running in apply mode.</td></tr></tfoot> <tr class="row-odd"> <th class="head">Field name</th> <th class="head">Type</th> <th class="head">Description</th> <th class="head">Validated</th> <th class="head">Mandatory</th> </tr> <tr class="row-odd"> <td valign="middle">name</td> <td valign="middle">string</td> <td>The name of the team this user should be a member of.</td> <td align="center" valign="middle">No [1]</td> <td align="center" valign="middle">Yes</td> </tr> <tr class="row-odd"> <td valign="middle">theme</td> <td valign="middle">string</td> <td>The user’s theme for the specified team. Formatted as a Mattermost theme string.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">roles</td> <td valign="middle">string</td> <td>The roles the user should have within this team. Must be one of the following values: <kbd>"team_user"</kbd> <kbd>"team_admin team_user"</kbd> </td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">channels</td> <td valign="middle">array</td> <td>The channels within this team that the user should be made a member of. Must be an array of <b>UserChannelMembership</b> objects.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> </table>This object is a member of the TeamMembership object.
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}> <tfoot><tr><td colspan="5">[1] Not validated, but an error occurs if the parent channel does not exist when running in apply mode.</td></tr></tfoot> <tr class="row-odd"> <th class="head">Field name</th> <th class="head">Type</th> <th class="head">Description</th> <th class="head">Validated</th> <th class="head">Mandatory</th> </tr> <tr class="row-odd"> <td valign="middle">name</td> <td valign="middle">string</td> <td>The name of the channel in the parent team that this user should be a member of.</td> <td align="center" valign="middle">No [1]</td> <td align="center" valign="middle">Yes</td> </tr> <tr class="row-odd"> <td valign="middle">roles</td> <td valign="middle">string</td> <td>The roles the user should have within this channel. Must be one of the following values: <kbd>"channel_user"</kbd> <kbd>"channel_user channel_admin"</kbd> </td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">notify_props</td> <td valign="middle">object</td> <td>The notify preferences for this user in this channel. Must be a <b>ChannelNotifyProps</b> object</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">favorite</td> <td valign="middle">boolean</td> <td>Whether to favorite the channel. Must be one of the following values: <kbd>"true"</kbd> - Yes. <kbd>"false"</kbd> - No.</td> <td align="center" valign="middle">No</td> <td align="center" valign="middle">No</td> </tr> </table>This object is a member of the ChannelMembership object.
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}> <tr class="row-odd"> <th class="head">Field name</th> <th class="head">Type</th> <th class="head">Description</th> <th class="head">Validated</th> <th class="head">Mandatory</th> </tr> <tr class="row-odd"> <td valign="middle">desktop</td> <td valign="middle">string</td> <td>Preference for sending desktop notifications. Must be one of the following values: <kbd>"default"</kbd> - Global default. <kbd>"all"</kbd> - For all activity. <kbd>"mention"</kbd> - Only for mentions. <kbd>"none"</kbd> - Never.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">mobile</td> <td valign="middle">string</td> <td>Preference for sending mobile notifications. Must be one of the following values: <kbd>"default"</kbd> - Global default. <kbd>"all"</kbd> - For all activity. <kbd>"mention"</kbd> - Only for mentions. <kbd>"none"</kbd> - Never.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">mark_unread</td> <td valign="middle">string</td> <td>Preference for marking channel as unread. Must be one of the following values: <kbd>"all"</kbd> - For all unread messages. <kbd>"mention"</kbd> - Only for mentions. </td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> </table>If present, Post objects must occur after the last User object in the file, but before any DirectChannel objects.
For clarity, the object is shown using regular JSON formatting, but in the data file it cannot be spread across several lines. It must be all on one line.
{
"type": "post",
"post": {
"team": "team-name",
"channel": "channel-name",
"user": "username",
"message": "The post message",
"props": {
"attachments": [{
"pretext": "This is the attachment pretext.",
"text": "This is the attachment text."
}]
},
"create_at": 140012340013,
"flagged_by": [
"username1",
"username2",
"username3"
],
"replies": [{
"user": "username4",
"message": "The reply message",
"create_at": 140012352049,
"attachments": [{
"path": "/some/valid/file/path/1"
}],
}, {
"user": "username5",
"message": "Other reply message",
"create_at": 140012353057,
}],
"reactions": [{
"user": "username6",
"emoji_name": "+1",
"create_at": 140012356032,
}, {
"user": "username7",
"emoji_name": "heart",
"create_at": 140012359034,
}],
"attachments": [{
"path": "/some/valid/file/path/1"
}, {
"path": "/some/valid/file/path/2"
}]
}
}
This object is a member of the Post/DirectPost object.
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}> <tr class="row-odd"> <th class="head">Field name</th> <th class="head">Type</th> <th class="head">Description</th> <th class="head">Validated</th> <th class="head">Mandatory</th> </tr> <tr class="row-odd"> <td valign="middle">user</td> <td valign="middle">string</td> <td>The username of the user for this reply.</td> <td align="center" valign="middle">No [3]</td> <td align="center" valign="middle">Yes</td> </tr> <tr class="row-odd"> <td valign="middle">message</td> <td valign="middle">string</td> <td>The message that the reply contains.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">Yes</td> </tr> <tr class="row-odd"> <td valign="middle">create_at</td> <td valign="middle">int</td> <td>The timestamp for the reply, in milliseconds since the Unix epoch.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">Yes</td> </tr> <tr class="row-odd"> <td valign="middle">flagged_by</td> <td valign="middle">array</td> <td>Must contain a list of members who have flagged the post.</td> <td align="center" valign="middle">No</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">reactions</td> <td valign="middle">array</td> <td>The emoji reactions to this post. Must be an array of <a href="#fields-of-the-reaction-object">Reaction</a> objects.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> <tr class="row-odd"> <td valign="middle">attachments</td> <td valign="middle">array</td> <td>The file attachments to this post. Must be an array of <a href="#fields-of-the-attachment-object">Attachment</a> objects.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">No</td> </tr> </table>This object is a member of the Post/DirectPost object.
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}> <tr class="row-odd"> <th class="head">Field name</th> <th class="head">Type</th> <th class="head">Description</th> <th class="head">Validated</th> <th class="head">Mandatory</th> </tr> <tr class="row-odd"> <td valign="middle">user</td> <td valign="middle">string</td> <td>The username of the user for this reply.</td> <td align="center" valign="middle">No [3]</td> <td align="center" valign="middle">Yes</td> </tr> <tr class="row-odd"> <td valign="middle">emoji_name</td> <td valign="middle">string</td> <td>The emoji of the reaction.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">Yes</td> </tr> <tr class="row-odd"> <td valign="middle">create_at</td> <td valign="middle">int</td> <td>The timestamp for the reply, in milliseconds since the Unix epoch.</td> <td align="center" valign="middle">Yes</td> <td align="center" valign="middle">Yes</td> </tr> </table>This object is a member of the Post/DirectPost object.
<table width="100%" border="1" cellpadding="5px" style={{marginBottom: '20px'}}> <tfoot> <tr> <td colspan="5"> [1] Not validated, but an error occurs if the file path is not found or accessible when running in apply mode. </td> </tr> </tfoot> <tr class="row-odd"> <th class="head">Field name</th> <th class="head">Type</th> <th class="head">Description</th> <th class="head">Validated</th> <th class="head">Mandatory</th> </tr> <tr class="row-odd"> <td valign="middle">path</td> <td valign="middle">string</td> <td>The path to the file to be attached to the post.</td> <td align="center" valign="middle">No [1]</td> <td align="center" valign="middle">Yes</td> </tr> </table>A direct channel can have from two to eight users as members of the channel. If there are only two members, Mattermost treats it as a Direct Message channel. If there are three or more members, Mattermost treats it as a Group Message channel.
For clarity, the object is shown using regular JSON formatting, but in the data file it cannot be spread across several lines. It must be all on one line.
{
"type": "direct_channel",
"direct_channel": {
"members": [
"username1",
"username2",
"username3"
],
"header": "The Channel Header",
"favorited_by": [
"username1",
"username2",
"username3"
]
}
}
DirectPost objects must occur after all other objects in the file.
For clarity, the object is shown using regular JSON formatting, but in the data file it cannot be spread across several lines. It must be all on one line.
{
"type": "direct_post",
"direct_post": {
"channel_members": [
"username1",
"username2",
"username3",
],
"user": "username2",
"message": "Hello Group Channel",
"create_at": 140012340013,
"flagged_by": [
"username1",
"username2",
"username3"
],
"replies": [{
"user": "username4",
"message": "The reply message",
"create_at": 140012352049,
}, {
"user": "username5",
"message": "Other reply message",
"create_at": 140012353057,
}],
"reactions": [{
"user": "username6",
"emoji_name": "+1",
"create_at": 140012356032,
}, {
"user": "username7",
"emoji_name": "heart",
"create_at": 140012359034,
}]
}
}
Run the bulk import command as the mattermost user. Running it as root or any other user will cause issues with file permissions on imported attachments.
Ensure that file attachments are enabled, that you have enough free space in your file storage system to support the incoming attachments, and that your maximum file size is appropriate.
Make sure you have enough free space for logs on the Mattermost server as well as free space on the database server for both the database itself and transaction logs.
Disable anti-virus or any other plugins that might interfere with attachment uploading. They could potentially block uploading of attachments and cause the import to fail if configured incorrectly. If you need anti-virus scanning, scan the attachment folder before the import.
If you have Bleve search indexing enabled, temporarily disable it in System Console > Experimental > Bleve and run the command again.
Bleve does not support multiple processes opening and manipulating the same index. Therefore, if the Mattermost server is running, an attempt to run the bulk loading tool will lock when trying to open the indeces.