Media editor

Позволяет создать или отредактировать компоненту для отправки сообщений

Описание Media editor

Communication media editor служит для создания нового или редактирования существующего средства связи для формирования отправки сообщений пользователям. Например, это могут быть сообщения о различных событиях, либо об изменении статуса задач, либо сообщение об обработке администратором событий в dashboard либо какое-то общее оповещение, транслируемое через систему громкой связи и так далее.

Каждому пользователю системы может быть назначен адрес для каждого средства связи. Например, для средства связи типа email пользователю можно назначить его email адрес. Для средства связи типа SMS пользователю, в качестве адреса, можно назначить номер мобильного телефона.

Для каждого адреса можно установить приоритет, в соответствии с которым система будет выбирать средство связи для отправки сообщений пользователю. Например, для сообщений с нормальным и низким приоритетом можно можно установить средство связи email, а для сообщений с высоким приоритетом можно установить средство связи - SMS. Для каждого пользователя можно установить собственные приоритеты для каждого средства связи. Средства связи и приоритеты для них настраиваются в действии Administration\Users editor

Компоненты системы, которым требуется отправить сообщения, будут отправлять их, устанавливая соответствующий приоритет каждому сообщению. Приоритеты для разных типов сообщений настраиваются администратором. Система, в зависимости от приоритета сообщения, будет выбирать соответствующее ему средство связи и выполнять отправку сообщений по соответствующему протоколу. Таким образом, например, важные сообщения могут быть отправлены по SMS, а сообщения с более низким приоритетом могут быть отправлены по email.

Для удобства в Communication media Editor встроен редактор JavaScript и редактор шаблонов PUG. Communication media editor имеет все необходимые средства для разработки новых компонент для средств связи и не требует установки дополнительных сред разработки.

Возвращаемое значение: Communication media ID (имя папки, в которой расположено средство связи)

Описание интерфейса

Communication media

Select communication media

Позволяет выбрать существующее средство связи из списка, либо создать новое.

New communication media

Если вы создаете новое средство связи, то его название необходимо ввести в это поле. Название средства связи так же является это папкой, в которой хранятся его файлы. Если вы выбрали существующее средство связи, его название появится в этом поле. Если изменить название, папка будет переименована.

Delete media

При выборе этого checkbox выбранное средство связи будет удалено. Информация, связанная с данным средством связи (адреса, приоритеты) так же будет удалена из базы данных.

Вкладки

Вкладка SERVER позволяет создать или отредактировать исходный код компоненты для выбранного средства связи.

Вкладка CONFIGURATION используется для создания или правки параметров выбранного средства связи

Вкладка HELP используется для формирования или редактирования файла помощи для выбранного средства связи

Формирования файла помощи во вкладке HELP

Help page language

Можно выбрать страницу помощи для требуемого языка. При выборе нового языка, все текущие изменения, сделанные на странице помощи, не сохраняются. Если страницы помощи не существовало, в этом поле будет установлен язык, используемый в браузере по умолчанию. Если существует страница помощи с языком, используемым в браузере по умолчанию, она будет отображена в первую очередь. Иначе отображается страница помощи на английском языке. Если страницы помощи на языке, установленном в браузере и страницы помощи на английском языке не существует, будет отображена первая попавшаяся страница помощи.

Add new language

Если в это поле добавить новый язык и нажать на кнопку "+", он будет добавлен в список языков. Help page language. Затем можно создать страницу помощи на добавленном языке.

Использования средств связи в компонентах ALEPIZ

Для использования средств связи необходимо подключить API с помощью команды require:

const communication = require('../../lib/communication');

API экспортирует две функции: communication.getMedias и communication.send.

Функция communication.getMedias(callback)

Через функцию callback можно получить список всех доступных в системе средств связи в виде объекта. Функция callback принимает параметры callback(err, medias), где:

  • err - стандартный объект с ошибкой, если произошла ошибка
  • medias - объект, содержащий сведения о доступных средствах связи в формате {<mediaID1>: { description: <media description>, address: <media address description>, re: <regExp for checking media address> }, <mediaID2>: {...}, ...}.

Пример объекта medias:

{
    "email": {
        "description": "Sending emails via SMTP",
        "address": "E-mail address",
        "re": "^(([^<>()\\[\\].,;:\\s@\"]+(\\.[^<>()\\[\\].,;:\\s@\"]+)*)|(\".+\"))@(([^<>()\\[\\].,;:\\s@\"]+\\.)+[^<>()\\[\\].,;:\\s@\"]{2,})$",
    },
    "SMS": {
        "description": "Sending SMS via SMS provider",
        "address": "SMS phone number",
        "re": "^+\\d{11}$",
    }
}

Функция communication.send(param, callback)

Функция служит для отправки сообщений через средства связи. Параметр param является объектом и служит для задания параметров отправляемому сообщению. Функция callback принимает параметр err - стандартный объект с ошибкой, если произошла ошибка.

Формат объекта param следующий:

{
    priorities: <array> [<num1>, <num2>,..] array of priorities ID from userCommunicationPriorities.priority.
    configID: <string> configID or don't set for default
    sender: <string> userName from users.name table
    rcpt: <array> array of userNames from users.name table
    text: <string> message text,
    variables: <object> {<NAME1>, <value1>,..} object with variables for replace in text and all message parameters
    mediaID: <string>. if set mediaID then priorities will be skipped
    message: {
        <message template>
    }
}

Описание параметров:

  • priorities: массив из идентификаторов приоритетов для выбора средств связи с помощью которых будет отправлено сообщение. Идентификатор приоритета должен быть в числовом формате. Доступные значения идентификаторов приоритетов можно посмотреть в действии Administration\Users editor
  • configID: строка - идентификатор конфигурации для средства связи из файла конфигурации. Если не указан, берется идентификатор по умолчанию "default"
  • sender: строка - имя пользователя (login), который является отправителем сообщения. Список имен пользователей можно посмотреть в действии Administration\Users editor
  • rcpt: массив строк - имена пользователей (login), которые являются получателями сообщения. Список имен пользователей можно посмотреть в действии Administration\Users editor
  • text: строка - текст сообщения
  • variables: объект - переменные в формате {<NAME1>: <val1>, <NAME2>: <val2>, ...}. В параметре text и во всех строковых параметрах объекта message переменные виде %:NAME:% будут заменены на их значения, если они присутствуют в объекте variables
  • mediaID: строка - если по какой-то причине необходимо отключить автоматический выбор средств связи, можно явно указать его идентификатор. Идентификатором средства связи является название каталога, в котором расположены файлы средства связи. Если указан параметр mediaID, параметр priorities не используется.
  • message: объект - шаблон сообщения. Обычно используется, если известно, какое средство связи будет использовано, например, если указан параметр mediaID. В зависимости от выбранного средства связи параметры объекта message могут быть разными. Параметры объекта message описаны на его странице помощи средства связи

Файл конфигурации средства связи

Конфигурации находится в файле config.json в формате json и может содержать следующие параметры:

{
    "description": "Communication media description",
    "address": "Communication media address description",
    "re": "Regular expression for validate address",
    "default": {
        "transport": {
            <transport configuration1>
        }
    },
    "anotherMessageTemplate": {
        "transport": "default",
        "message": {
            <message template2>
        }
    }
}

Описание параметров файла конфигурации:

  • description: Описание средства связи, например "Sending email via SMTP"
  • address: Описание адреса средства связи, например "E-mail address" или ""Phone number"
  • re: регулярное выражение с помощью которого можно проверить корректность адреса для средства связи
  • <configID>: идентификатор конфигурации средства связи. Для одного средства связи можно сделать несколько конфигураций и в дальнейшем выбирать требуемую конфигурацию при отправке сообщения. Например, в разных конфигурациях одного и того же средства связи могут быть различные провайдеры для отправки СМС.
    • transport: объект с параметрами для средства связи. Предназначение параметров средства связи можно посмотреть на странице помощи средства связи. Если значение transport не объект, а строка, то она будет интерпретирована как ссылка на идентификатор конфигурации, из которого необходимо взять параметры средства связи. Это позволяет не дублировать одинаковые конфигурации для разных шаблонов сообщений. В примере выше, в конфигурации для идентификатора "anotherMessageTemplate", "transport" ссылается на идентификатор конфигурации "default"
    • message: объект, который служит в качестве шаблона сообщения для средства связи. Параметр message может отсутствовать. Описание параметров шаблона сообщения средства связи можно посмотреть на странице помощи средства связи.

Разработка нового средства связи

Средство связи состоит из нескольких стандартных компонент:

  • server.js - исполняемый код средства связи
  • config.json - файл с конфигурацией
  • help\index.ru.pug - статическая страница помощи

В Communication media editor созданы готовые шаблоны, используя которые можно быстро разработать собственное средство связи.

Подключение дополнительных модулей nodejs

Если требуется подключить внешний модуль nodejs, необходимо установить его в каталог node_modules, который должен находится в корневом каталоге разрабатываемой компоненты. Для этого можно воспользоваться утилитой npm и в корневом каталоге компоненты выполнить следующие шаги:

  • создать файл package.json вручную либо запустить npm init и ответить на вопросы.
  • выполнить nmp i <имя модуля>. Появится каталог node_modules в который будет установлен требуемый модуль

server.js - файл с исходным кодом средства связи

Файл с исходным кодом средства связи является стандартным модулем nodejs и должен экспортировать объект с функцией send:

var media = {};
module.exports = media;

media.send = function (param, callback) {
    ...
};

param является объектом с параметрами для средства связи, а callback - функцией, принимающей параметр callback(err), err - стандартный объект с ошибкой, если произошла ошибка.

объект param содержит следующие параметры:

  • configID: строка - идентификатор конфигурации средства связи из файла конфигурации.
  • transport: объект содержит параметры для средства связи. Объект формируются в зависимости от указанного идентификатора конфигурации configID из файла конфигурации средства связи. Для каждого средства связи используются свои параметры, описанные на странице помощи соответствующего средства связи.
  • message: объект - шаблон формирования сообщения. В шаблоне могут быть указаны поля, специфичные для сообщения, использующегося в выбранном средстве связи. Шаблон будет сформирован из шаблона, расположенного в файле конфигурации средства связи с соответствующим идентификатором configID. Эти параметры будут дописаны или перезаписаны параметрами из шаблона, переданного в функцию communication.send() инициатором отправки сообщения. Обычно шаблон message не указывается, так как выбор средства связи происходит автоматически.
  • sender: массив длинной в 1 элемент в котором находится объект с отправителем сообщения: [{address: <address>, fullName: <user full name>}]
  • rcpt: массив в котором находятся объекты с получателями сообщения: [{address: <address1>, fullName: <user1 full name>}, {address: <address2>, fullName: <user2 full name>}, ...]
  • text: строка - текст сообщения

Пример объекта param для средства связи email:

{
    configID: "default",
    transport: {
        host: "smtp.alepiz.com",
        port: 465,
        secure: true,
        ignoreTLS: false,
        requireTLS: false,
        authMethod: "PLAIN",
        auth: {
            type: "login",
            user: "alepizSMTPUser",
            pass: "passwordForSMTP"
        },
        tls: {
            rejectUnauthorized: false
        },
        name: "alepiz.com",
        connectionTimeout: 120000,
        greetingTimeout: 30000,
        socketTimeout: 600000,
        logger: false
    },
    message: {
        subject: "Test message",
        replyTo: "support@alepiz.com"
    },
    sender: [{
        address: "admin@alepiz.com",
        fullName: "Administrator of the system"
    }],
    rcpt: [{
        address: "support@alepiz.com",
        fullName: "Support"
    }, {
        address: "admin@alepiz.com",
        fullName: "Administrator of the system"
    }],
    text: "Message for test"
}

Пример исходного кода средства связи, отправляющего email сообщения по протоколу SMTP:

/* Copyright © 2020. Alexander Belov. Contacts: <asbel@alepiz.com> */
var nodeMailer = require('nodemailer');
var log = require('../../lib/log')(module);

var media = {}, transporter = {};
module.exports = media;

media.send = function (param, callback) {

    if(!transporter[param.configID]) {
        transporter[param.configID] = nodeMailer.createTransport(param.transport);
    }

    var message = param.message || {};

    if(!message.form && param.sender) message.from = createAddress(param.sender);
    if(!message.to && param.rcpt) message.to = createAddress(param.rcpt);
    if(!message.text && !message.html && param.text) message.text = param.text;

    transporter[param.configID].sendMail(message, function(err, info, response) {
        if(err) {
            return callback(new Error('Can\'t sent email for ' + JSON.stringify(message) +
            ' : ' + err.message));
        }

        log.info('Email successfully sending for ', message, '; messageID: ', info.messageId,
            '; response: ', response);
        callback();
    });
};

// users: array of objects [{address: <address>, fullName: <full name>}, ...]
function createAddress(users) {
    if(!Array.isArray(users) || !users.length) return callback();

    var re = /^(([^<>()\[\].,;:\s@"]+(\.[^<>()\[\].,;:\s@"]+)*)|(".+"))@(([^<>()\[\].,;:\s@"]+\.)+[^<>()\[\].,;:\s@"]{2,})$/i;

    var addresses = [];
    users.forEach(function (user) {
        if(!user.address || !re.test(user.address)) {
            log.warn('Address ' + user.address + ' is not a valid email address in ', users);
            return;
        }
        if(user.fullName) addresses.push('"' + user.fullName.replace(/"/g, "'") + '" <'+ user.address +'>');
        else addresses.push(user.address);
    });

    return addresses.join(', ');
}

help\index.ru.pug - страница помощи с описанием средства связи

Для формирования страниц помощи используется шаблонизатор PUG , который, используя препроцессор, формирует HTML страницу. Никаких специальных требований к странице помощи нет. Для того, чтобы все компоненты интерфейса ALEPIZ были созданы в одном стиле, желательно использовать готовый шаблон, предоставляемый Communication media editor и элементы фреймворка materializecss.

Скрипт help.js, включенный в шаблон страницы помощи, автоматически сформирует оглавление документа из заголовков, добавит нижний колонтитул с информацией о copyright и плавающий элемент слева для перехода к верхней части страницы:

  • Оглавление добавляется в первый элемент на странице с классом offset-m1
  • Нижний колонтитул будет добавлен в элемент с тегом body
  • copyright формируется из элемента meta("author"), например meta(name="author" content="Alexander Belov <asbel@alepiz.com>") добавит соответствующий copyright и ссылку для составления почтового сообщения. Год формируется из document.lastModified || document.lastModifiedDate
  • плавающий элемент слева для перехода к верхней части страницы будет добавлен в элемент с тегом main