Обработка файлов, загружаемых в чат

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

В статье используется понятие Webim Server. Это серверное программное обеспечение сервиса Webim (бекэнд). Оно может быть установлено либо на серверах сервиса Webim, либо на серверах заказчика.

Ограничения отправки файлов в чат

Ограничения, связанные с обменом файлами в чате, регламентируются системными настройками, которые указываются в специальном табличном редакторе ресурсов по отдельному URL (account config). Если у Вас есть к нему доступ, Вы можете редактировать настройки самостоятельно, в противном случае попросите об этом техническую поддержку Webim.

В первую очередь стоит упомянуть настройки, которые по умолчанию разрешают и оператору, и посетителю слать файлы в чат:

  • visitor_upload_file определяет, могут ли посетители отправлять файлы в чат. По умолчанию true.
  • operator_file_upload_disable определяет, не запрещено ли оператору отправлять файлы в чат. По умолчанию установлено значение false (не запрещено).

Также ограничивать можно типы файлов, отправляемых посетителями и ботами, допустимые размеры файлов. При этом оператор из РМО сможет отправлять типы файлов, которые не могут отправлять посетители. В случае с каналами общения корректность доставки и отображения файлов, отправленных оператором, в том или ином канале общения зависит от особенностей конкретного канала.

Ограничения по типам файлов

  • allowed_upload_file_types — задаёт список расширений файлов, которые посетителю разрешается отправлять (белый список). По умолчанию указаны следующие типы файлов: png, jpg, jpeg, doc, rtf, gif, txt, pdf, docx, webp, oga, ogg.
  • restricted_upload_file_types — список запрещённых типов файлов для загрузки (чёрный список). Таким образом, если Вы хотите не допустить отправку посетителем лишь некоторых типов файлов, можно указать их здесь. По умолчанию запрещена загрузка файлов следующих типов: msi, exe, scr, html, mht, htm, js, php.
  • allowed_upload_file_content_types — задаёт список допустимых content-type для загрузки посетителем. По умолчанию доступны следующие: image/png, image/jpeg, image/pjpeg, application/msword, application/rtf, image/gif, text/plain, application/pdf, application/vnd.openxmlformats-officedocument.wordprocessingml.document, image/webp, audio/ogg.
  • robot_allowed_upload_file_types — определяет, какие типы файлов сможет отправлять посетителю бот. По умолчанию набор допустимых типов аналогичен набору оператора: png, jpg, jpeg, doc, rtf, gif, txt, pdf, docx, webp, oga, ogg.

Механизм работы ограничений:

  • Если неизвестно расширение файла, такой файл не будет отправлен.
  • Если в перечне расширений белого списка расширение отсутствует, то, даже если его нет в чёрном списке, файл отправлен не будет (приоритет белого списка над чёрным).
  • Параллельно с анализом белого и чёрного списков анализируется список допустимых content-type (параметр allowed_upload_file_content_types). Если известен content-type файла и при этом он отсутствует в заданном перечне, то файл доставлен не будет.

Ограничения по размерам файла

  • max_visitor_upload_file_size — максимальный размер файла, который может загрузить посетитель. Указывается в мегабайтах и по умолчанию установлен в 10 Мб.
  • max_robot_upload_file_size — максимальный размер файла, загружаемого ботом. Указывается в мегабайтах и по умолчанию установлен в 10 Мб.

При этом ограничение по максимальному допустимому размеру файла есть и на стороне веб-сервера nginx. Необходимо, чтобы размер файла не превышал оба этих значения. Если параметр максимального допустимого размера файла в Webim больше параметра на стороне nginx (client_max_body_size) и соответствующего ему параметра nginx_upload_size в файле main.ini, то будет использовано значение параметра nginx_upload_size, по умолчанию равное 10 Мб.

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

Оператор скачивает файл из Webim Server

  1. Оператор начинает скачивать файл из Webim Server.
  2. Веб-фронтэнд отправляет запрос файла по ссылке на веб-сервер Nginx.
    Пример ссылки: '/l/o/download/2dda66441cfc481eb2b3f8a7c33b5df/photo_2019-07-17_18-20-35.jpg'.
  3. Происходит реверсивное проксирование запросов на Python сервис.
  4. Python сервис проверяет наличие файла в файловом хранилище по пути /var/pro/client-data/cd/ACCOUNT_NAME/files и соответствие запрашиваемого имени тому, что хранится в мета-информации, производит дополнительные обработки изображений (при запросе превью изображения отдаёт файл 2dda66441cfc481eb2b3f8a7c33b5df_300x300 в разрешении 300x300 (разрешение по умолчанию)).

Схема работы сервиса при скачивании файла оператором:

Схема скачивания файла оператором

Оператор загружает файл на Webim Server

  1. Оператор начинает загружать файл на Webim Server.
  2. Веб-фронтэнд отправляет файл на /l/o/action.php?action=upload_file веб-сервера Nginx.
  3. Происходит реверсивное проксирование запросов на Python сервис.
  4. Python сервис сохраняет файл и мета-информацию о нём в файловое хранилище. Имя файла генерируется как guid — например, 2dda66441cfc481eb2b3f8a7c33b5df. Мета-информация хранится в файле 2dda66441cfc481eb2b3f8a7c33b5df.desc (в соответствии с примером выше). Список хранимых полей:
    • content_type;
    • внутренний id пользователя;
    • имя файла;
    • guid;
    • объём файла.

    Сервис сохраняет файл по пути /var/pro/client-data/cd/ACCOUNT_NAME/files.

Схема работы сервиса при загрузке файла оператором:

Схема загрузки файла оператором

Пользователь скачивает файл из Webim Server

  1. Пользователь начинает скачивать файл из Webim Server.
  2. Веб-фронтэнд или мобильное приложение (работает через Webim Mobile SDK) отправляет запрос файла по ссылке на веб-сервер Nginx.
    Пример ссылки для веб-фронтэнда: '/l/v/download/2dda66441cfc481eb2b3f8a7c33b5df/photo_2019-07-17_18-20-35.jpg?expires=1564763939&hash=592d5761a5d70ff96ed846e907c59206d83c6d13642a04956425026be3b78739'.
    Пример ссылки для мобильного приложения (работает через Webim Mobile SDK): '/l/v/m/download/2dda66441cfc481eb2b3f8a7c33b5df/photo_2019-07-17_18-20-35.jpg?expires=1564763939&hash=592d5761a5d70ff96ed846e907c59206d83c6d13642a04956425026be3b78739'.
  3. Происходит реверсивное проксирование запросов на Python сервис.
  4. Python сервис проверяет наличие файла в файловом хранилище по пути /var/pro/client-data/cd/ACCOUNT_NAME/files и соответствие запрашиваемого имени тому, что хранится в мета-информации, производит дополнительные обработки изображений (при запросе превью изображения отдаёт отдаёт файл 2dda66441cfc481eb2b3f8a7c33b5df_300x300 в разрешении 300x300 (разрешение по умолчанию)).

Скачивание файла через Webim Mobile SDK

  1. Ссылка на скачивание генерируется сервером. Она содержит:
    • момент запроса,
    • поле expires, в свою очередь содержащее: параметр file_url_expiring_timeout, который определяет время доступа к скачиванию файла по ссылке для каналов общения (по умолчанию равняется 86400 секундам, т.е. 1 день); параметр file_url_expiring_timeout_for_web_and_mobile, определяющий то же самое для веб-обращений (по умолчанию 300 секунд, т.е. 5 минут). Для чатов из мобильного приложения время работы ссылки всегда равняется 5 минутам.
  2. Мобильное приложение получает данную ссылку от Webim Mobile SDK через метод getUrl().

Используются следующие эндпоинты:

  • /l/c/download (для каналов)
  • /l/v/m/download (для мобильных приложений)

Схема работы сервиса при скачивании файла пользователем:

Схема скачивания файла пользователем

Пользователь загружает файл на Webim Server

  1. Пользователь начинает загружать файл на Webim Server.
  2. Веб-фронтэнд отправляет файл на /l/v/upload (/l/v/m/upload для мобильного приложения (работает через Webim Mobile SDK)) веб-сервера Nginx.
  3. Происходит реверсивное проксирование запросов на Python сервис.
  4. Python сервис сохраняет файл и мета-информацию о нём в файловое хранилище. Имя файла генерируется как guid — например, 2dda66441cfc481eb2b3f8a7c33b5df. Мета-информация хранится в файле 2dda66441cfc481eb2b3f8a7c33b5df.desc (в соответствии с примером выше). Список хранимых полей:
    • content_type;
    • внутренний id пользователя;
    • имя файла;
    • guid;
    • объём файла.

    Сервис сохраняет файл по пути /var/pro/client-data/cd/ACCOUNT_NAME/files.

Схема работы сервиса при загрузке файла пользователем:

Схема загрузки файла пользователем

Привязка загруженного файла к обращению

Каждое загруженное вложение имеет свой guid-код, который его идентифицирует. Кроме этого, в метаданных файла содержится id посетителя, в чате с которым вложение загружалось. Это позволяет однозначно идентифицировать чат, в который загружается файл.

Список полей:

  • client_content_type - тип файла, заявленный его отправителем;
  • внутренний id пользователя;
  • имя файла;
  • content_type - тип файла, распознанный Webim при помощи библиотеки python-magic;
  • guid;
  • объём файла.

Пример:

{
    "client_content_type":"application/sql",
    "visitor_id":"10750f378f50c6ccdb572520f3ae9bdc",
    "filename":"filename.ext",
    "content_type":"text/plain",
    "guid":"73fff01266414934b181a93061cf26bf",
    "size":2384
}