{"id":334858,"date":"2022-06-23T09:00:25","date_gmt":"2022-06-23T09:00:25","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=334858"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=334858","title":{"rendered":"<span>Mattermost self-hosted \u0445\u0430\u043a \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u044b\u0445 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u043c\u044b \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u043f\u0435\u0440\u0435\u0435\u0445\u0430\u043b\u0438 \u0432 \u043c\u0435\u0441\u0441\u0435\u043d\u0434\u0436\u0435\u0440 Mattermost \u043d\u0430 \u0437\u0430\u043c\u0435\u043d\u0443 Slack, \u043d\u043e \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u043e\u0434\u043d\u043e\u0439 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439. \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0432 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u0442\u0435\u0433 \u0433\u0440\u0443\u043f\u043f\u044b <code>@groupname<\/code>  \u0432 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u044d\u0442\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0435\u0442, \u0438 \u0433\u0440\u0443\u043f\u043f \u043d\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043e.<\/p>\n<p>\u041f\u043e\u043a\u043e\u043f\u0430\u0432\u0448\u0438\u0441\u044c \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445, \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438 \u0447\u0442\u043e \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0435\u0441\u0442\u044c \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0434\u043b\u044f \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4eb\/ea7\/913\/4ebea791379dbfed3c4883cdf765c374.png\" alt=\"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\" title=\"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\" width=\"800\" height=\"826\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4eb\/ea7\/913\/4ebea791379dbfed3c4883cdf765c374.png\"\/><figcaption>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438 \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0438\u0434\u0435\u044e \u0435\u0441\u043b\u0438 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f @devops \u0438 \u0443\u043f\u043e\u043c\u044f\u043d\u0435\u043c \u0435\u0433\u043e \u0433\u0434\u0435 \u043d\u0438\u0431\u0443\u0434\u044c \u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ba0\/7f9\/f7e\/ba07f9f7ec65e963ece9f1d9a9e6dc8e.png\" alt=\"\" title=\"\" width=\"740\" height=\"295\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ba0\/7f9\/f7e\/ba07f9f7ec65e963ece9f1d9a9e6dc8e.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u0442\u043e, \u0447\u0442\u043e \u0443 \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0435\u0441\u0442\u044c \u0432 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432\u0430\u0445 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439 @devops \u0442\u043e\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435. \u0422\u0430\u043a \u0440\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u0438\u0434\u0435\u044f \u044d\u0442\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043a\u0430\u043a \u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u043a \u0411\u0414 Mattermost \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 3 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<pre><code class=\"sql\">table usergroups (     id             varchar(26) not null primary key,     name           varchar(64) unique,     displayname    varchar(128),     description    varchar(1024),     source         varchar(64),     remoteid       varchar(48),     createat       bigint,     updateat       bigint,     deleteat       bigint,     allowreference boolean,     unique (source, remoteid) );  table groupmembers (     groupid  varchar(26) not null,     userid   varchar(26) not null,     createat bigint,     deleteat bigint,     primary key (groupid, userid) );  table users (     id                 varchar(26) not null     primary key,     createat           bigint,     updateat           bigint,     deleteat           bigint,     username           varchar(64) unique,     password           varchar(128),     authdata           varchar(128) unique,     authservice        varchar(32),     email              varchar(128) unique,     emailverified      boolean,     nickname           varchar(64),     firstname          varchar(64),     lastname           varchar(64),     roles              varchar(256),     allowmarketing     boolean,     props              jsonb,     notifyprops        jsonb,     lastpasswordupdate bigint,     lastpictureupdate  bigint,     failedattempts     integer,     locale             varchar(5),     mfaactive          boolean,     mfasecret          varchar(128),     position           varchar(128),     timezone           jsonb,     remoteid           varchar(26) );  <\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u0435 2 \u0442\u0430\u0431\u043b\u0438\u0446\u044b <strong>usergroups<\/strong>, <strong>groupmembers<\/strong> \u0431\u044b\u043b\u0438 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u0438 \u0442\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0438 \u043c\u044b \u0438\u0445 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430 \u0438\u0445 \u0431\u0430\u0437\u0435.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c 2\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 Mattermost, <strong>devops<\/strong> \u0438 <strong>developers.<\/strong><\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0433\u0440\u0443\u043f\u043f\u044b \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438:<\/p>\n<pre><code class=\"sql\">INSERT INTO usergroups (id, name, displayname, description, source, remoteid, createat, updateat, deleteat,allowreference) VALUES ('1', 'devops', 'devops', null, null, null, null, null, null, null)  INSERT INTO usergroups (id, name, displayname, description, source, remoteid, createat, updateat, deleteat,allowreference) VALUES ('2', 'developers', 'developers', null, null, null, null, null, null, null)<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f <strong>testuser<\/strong> \u043a \u0433\u0440\u0443\u043f\u043f\u0435 <strong>devops<\/strong> \u0438 <strong>developers:<\/strong><\/p>\n<pre><code class=\"sql\">INSERT INTO groupmembers (groupid, userid, createat, deleteat) VALUES (         (select id from usergroups where          usergroups.name = 'devops'),         (select id from users where          users.username = 'testuser'),         null,null);  INSERT INTO groupmembers (groupid, userid, createat, deleteat) VALUES (         (select id from usergroups where          usergroups.name = 'developers'),         (select id from users where          users.username = 'testuser'),         null,null);<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043a \u043a\u0430\u043a\u0438\u043c \u0433\u0440\u0443\u043f\u043f\u0430\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438:<\/p>\n<pre><code class=\"sql\">select string_agg(concat('@', usergroups.name), ',') as groups, users.username from groupmembers          left join users on groupmembers.userid = users.id          left join usergroups on groupmembers.groupid = usergroups.id group by users.username;<\/code><\/pre>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">groups<\/p>\n<\/td>\n<td>\n<p align=\"left\">username<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">@developers,@devops<\/p>\n<\/td>\n<td>\n<p align=\"left\">testuser<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043d\u0430\u043c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0440\u043e\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u0430\u043a\u0443\u044e \u0436\u0435 \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0432 \u043a\u0430\u043a\u0438\u0445 \u0433\u0440\u0443\u043f\u043f\u0430\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u0442:<\/p>\n<pre><code class=\"sql\">select string_agg(concat('@', users.username), ',') as users, usergroups.name as groupname from groupmembers          left join users on groupmembers.userid = users.id          left join usergroups on groupmembers.groupid = usergroups.id group by usergroups.name;<\/code><\/pre>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"309\" width=\"309\">\n<p align=\"left\">users<\/p>\n<\/td>\n<td>\n<p align=\"left\">groupname<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"309\" width=\"309\">\n<p align=\"left\">@testuser<\/p>\n<\/td>\n<td>\n<p align=\"left\">developers<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"309\" width=\"309\">\n<p align=\"left\">@testuser<\/p>\n<\/td>\n<td>\n<p align=\"left\">devops<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 <strong>users<\/strong> \u0435\u0441\u0442\u044c \u0441\u0442\u043e\u043b\u0431\u0435\u0446 <strong>notifyprops<\/strong> \u0432 \u043d\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f jsonb \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u0430\u043c <strong>mention_keys, <\/strong>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043a \u0440\u0430\u0437 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430<strong> &#171;<\/strong>\u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0434\u043b\u044f \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439&#187; \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430.<\/p>\n<p>\u0418\u0434\u0435\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f. \u0417\u043d\u0430\u044f, \u043a \u043a\u0430\u043a\u0438\u043c \u0433\u0440\u0443\u043f\u043f\u0430\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0439\u0442\u0438 \u0438\u0445 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 <strong>users<\/strong> \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0443 \u043d\u0438\u0445 \u043f\u043e\u043b\u0435 <strong>mention_keys  <\/strong>\u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438\u0437 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<pre><code class=\"sql\">UPDATE users SET notifyprops = jsonb_set(notifyprops, '{mention_keys}', to_jsonb(subq.groups), true) from (select string_agg(concat('@', usergroups.name), ',') as groups, users.username as un       from groupmembers                left join users on groupmembers.userid = users.id                left join usergroups on groupmembers.groupid = usergroups.id       group by users.username) as subq where username = subq.un<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0433\u0440\u0443\u043f\u043f\u0430\u0445 \u0434\u043e\u0431\u0430\u0432\u044f\u0442\u0441\u044f \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0434\u043b\u044f \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439 \u0441 \u0442\u0435\u0433\u0430\u043c\u0438 \u044d\u0442\u0438\u0445 \u0433\u0440\u0443\u043f\u043f.<\/p>\n<p>\u041d\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c, \u043a\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u043d\u0430\u0448\u0438\u0445 &#171;\u0433\u0440\u0443\u043f\u043f\u0430\u0445&#187;, \u0435\u0441\u043b\u0438 \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0435 <strong>position,<\/strong> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u043c\u0430\u044f \u0434\u043e\u043b\u0436\u043d\u043e\u0441\u0442\u044c, \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u0445 \u0442\u0443\u0434\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d84\/26b\/979\/d8426b97945eb559c3e567df94635724.png\" width=\"924\" height=\"430\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d84\/26b\/979\/d8426b97945eb559c3e567df94635724.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u0445\u043e\u0434\u0438\u043c \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 <strong>position<\/strong> \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u0445 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0432 \u044d\u0442\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435.<\/p>\n<pre><code class=\"sql\">UPDATE users SET position = subq.users from (select string_agg(concat('@', users.username), ',') as users, usergroups.name as groupname       from groupmembers                left join users on groupmembers.userid = users.id                left join usergroups on groupmembers.groupid = usergroups.id       group by usergroups.name) as subq where username = subq.groupname<\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0441\u0435. \u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u0445\u0438\u0442\u0440\u044b\u0445 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0447\u0435\u043d\u044c \u043d\u0443\u0436\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0430.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/673036\/\"> https:\/\/habr.com\/ru\/post\/673036\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u043c\u044b \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u043f\u0435\u0440\u0435\u0435\u0445\u0430\u043b\u0438 \u0432 \u043c\u0435\u0441\u0441\u0435\u043d\u0434\u0436\u0435\u0440 Mattermost \u043d\u0430 \u0437\u0430\u043c\u0435\u043d\u0443 Slack, \u043d\u043e \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u043e\u0434\u043d\u043e\u0439 \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439. \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0432 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u0442\u0435\u0433 \u0433\u0440\u0443\u043f\u043f\u044b <code>@groupname<\/code>  \u0432 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u044d\u0442\u043e\u0439 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0435\u0442, \u0438 \u0433\u0440\u0443\u043f\u043f \u043d\u0435 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043e.<\/p>\n<p>\u041f\u043e\u043a\u043e\u043f\u0430\u0432\u0448\u0438\u0441\u044c \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445, \u0437\u0430\u043c\u0435\u0442\u0438\u043b\u0438 \u0447\u0442\u043e \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0435\u0441\u0442\u044c \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0434\u043b\u044f \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439.<\/p>\n<figure class=\"full-width\"><figcaption>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/figcaption><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438 \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0438\u0434\u0435\u044e \u0435\u0441\u043b\u0438 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f @devops \u0438 \u0443\u043f\u043e\u043c\u044f\u043d\u0435\u043c \u0435\u0433\u043e \u0433\u0434\u0435 \u043d\u0438\u0431\u0443\u0434\u044c \u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u0442\u043e, \u0447\u0442\u043e \u0443 \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0435\u0441\u0442\u044c \u0432 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432\u0430\u0445 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439 @devops \u0442\u043e\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0442 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435. \u0422\u0430\u043a \u0440\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u0438\u0434\u0435\u044f \u044d\u0442\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043a\u0430\u043a \u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c\u0441\u044f \u043a \u0411\u0414 Mattermost \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 3 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<pre><code class=\"sql\">table usergroups (     id             varchar(26) not null primary key,     name           varchar(64) unique,     displayname    varchar(128),     description    varchar(1024),     source         varchar(64),     remoteid       varchar(48),     createat       bigint,     updateat       bigint,     deleteat       bigint,     allowreference boolean,     unique (source, remoteid) );  table groupmembers (     groupid  varchar(26) not null,     userid   varchar(26) not null,     createat bigint,     deleteat bigint,     primary key (groupid, userid) );  table users (     id                 varchar(26) not null     primary key,     createat           bigint,     updateat           bigint,     deleteat           bigint,     username           varchar(64) unique,     password           varchar(128),     authdata           varchar(128) unique,     authservice        varchar(32),     email              varchar(128) unique,     emailverified      boolean,     nickname           varchar(64),     firstname          varchar(64),     lastname           varchar(64),     roles              varchar(256),     allowmarketing     boolean,     props              jsonb,     notifyprops        jsonb,     lastpasswordupdate bigint,     lastpictureupdate  bigint,     failedattempts     integer,     locale             varchar(5),     mfaactive          boolean,     mfasecret          varchar(128),     position           varchar(128),     timezone           jsonb,     remoteid           varchar(26) );  <\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u0435 2 \u0442\u0430\u0431\u043b\u0438\u0446\u044b <strong>usergroups<\/strong>, <strong>groupmembers<\/strong> \u0431\u044b\u043b\u0438 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u0438 \u0442\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0438 \u043c\u044b \u0438\u0445 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0440\u0435\u0448\u0438\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430 \u0438\u0445 \u0431\u0430\u0437\u0435.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c 2\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 Mattermost, <strong>devops<\/strong> \u0438 <strong>developers.<\/strong><\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0433\u0440\u0443\u043f\u043f\u044b \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438:<\/p>\n<pre><code class=\"sql\">INSERT INTO usergroups (id, name, displayname, description, source, remoteid, createat, updateat, deleteat,allowreference) VALUES ('1', 'devops', 'devops', null, null, null, null, null, null, null)  INSERT INTO usergroups (id, name, displayname, description, source, remoteid, createat, updateat, deleteat,allowreference) VALUES ('2', 'developers', 'developers', null, null, null, null, null, null, null)<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f <strong>testuser<\/strong> \u043a \u0433\u0440\u0443\u043f\u043f\u0435 <strong>devops<\/strong> \u0438 <strong>developers:<\/strong><\/p>\n<pre><code class=\"sql\">INSERT INTO groupmembers (groupid, userid, createat, deleteat) VALUES (         (select id from usergroups where          usergroups.name = 'devops'),         (select id from users where          users.username = 'testuser'),         null,null);  INSERT INTO groupmembers (groupid, userid, createat, deleteat) VALUES (         (select id from usergroups where          usergroups.name = 'developers'),         (select id from users where          users.username = 'testuser'),         null,null);<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043a \u043a\u0430\u043a\u0438\u043c \u0433\u0440\u0443\u043f\u043f\u0430\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438:<\/p>\n<pre><code class=\"sql\">select string_agg(concat('@', usergroups.name), ',') as groups, users.username from groupmembers          left join users on groupmembers.userid = users.id          left join usergroups on groupmembers.groupid = usergroups.id group by users.username;<\/code><\/pre>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"left\">groups<\/p>\n<\/td>\n<td>\n<p align=\"left\">username<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">@developers,@devops<\/p>\n<\/td>\n<td>\n<p align=\"left\">testuser<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043d\u0430\u043c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0440\u043e\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u0430\u043a\u0443\u044e \u0436\u0435 \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443, \u043d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0432 \u043a\u0430\u043a\u0438\u0445 \u0433\u0440\u0443\u043f\u043f\u0430\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u0442:<\/p>\n<pre><code class=\"sql\">select string_agg(concat('@', users.username), ',') as users, usergroups.name as groupname from groupmembers          left join users on groupmembers.userid = users.id          left join usergroups on groupmembers.groupid = usergroups.id group by usergroups.name;<\/code><\/pre>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"309\" width=\"309\">\n<p align=\"left\">users<\/p>\n<\/td>\n<td>\n<p align=\"left\">groupname<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"309\" width=\"309\">\n<p align=\"left\">@testuser<\/p>\n<\/td>\n<td>\n<p align=\"left\">developers<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"309\" width=\"309\">\n<p align=\"left\">@testuser<\/p>\n<\/td>\n<td>\n<p align=\"left\">devops<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 <strong>users<\/strong> \u0435\u0441\u0442\u044c \u0441\u0442\u043e\u043b\u0431\u0435\u0446 <strong>notifyprops<\/strong> \u0432 \u043d\u0435\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f jsonb \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u0430\u043c <strong>mention_keys, <\/strong>\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043a \u0440\u0430\u0437 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430<strong> &#171;<\/strong>\u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0434\u043b\u044f \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439&#187; \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430.<\/p>\n<p>\u0418\u0434\u0435\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f. \u0417\u043d\u0430\u044f, \u043a \u043a\u0430\u043a\u0438\u043c \u0433\u0440\u0443\u043f\u043f\u0430\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0439\u0442\u0438 \u0438\u0445 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 <strong>users<\/strong> \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0443 \u043d\u0438\u0445 \u043f\u043e\u043b\u0435 <strong>mention_keys  <\/strong>\u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438\u0437 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<pre><code class=\"sql\">UPDATE users SET notifyprops = jsonb_set(notifyprops, '{mention_keys}', to_jsonb(subq.groups), true) from (select string_agg(concat('@', usergroups.name), ',') as groups, users.username as un       from groupmembers                left join users on groupmembers.userid = users.id                left join usergroups on groupmembers.groupid = usergroups.id       group by users.username) as subq where username = subq.un<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0433\u0440\u0443\u043f\u043f\u0430\u0445 \u0434\u043e\u0431\u0430\u0432\u044f\u0442\u0441\u044f \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0434\u043b\u044f \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043d\u0438\u0439 \u0441 \u0442\u0435\u0433\u0430\u043c\u0438 \u044d\u0442\u0438\u0445 \u0433\u0440\u0443\u043f\u043f.<\/p>\n<p>\u041d\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c, \u043a\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u043d\u0430\u0448\u0438\u0445 &#171;\u0433\u0440\u0443\u043f\u043f\u0430\u0445&#187;, \u0435\u0441\u043b\u0438 \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0435 <strong>position,<\/strong> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u043c\u0430\u044f \u0434\u043e\u043b\u0436\u043d\u043e\u0441\u0442\u044c, \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u0445 \u0442\u0443\u0434\u0430.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u0445\u043e\u0434\u0438\u043c \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 <strong>position<\/strong> \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u0445 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0432 \u044d\u0442\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435.<\/p>\n<pre><code class=\"sql\">UPDATE users SET position = subq.users from (select string_agg(concat('@', users.username), ',') as users, usergroups.name as groupname       from groupmembers                left join users on groupmembers.userid = users.id                left join usergroups on groupmembers.groupid = usergroups.id       group by usergroups.name) as subq where username = subq.groupname<\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0441\u0435. \u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u0445\u0438\u0442\u0440\u044b\u0445 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0447\u0435\u043d\u044c \u043d\u0443\u0436\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0430.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/673036\/\"> https:\/\/habr.com\/ru\/post\/673036\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-334858","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/334858","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=334858"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/334858\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=334858"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=334858"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=334858"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}