Продукты Р7
Корпоративный сервер 2024
Корпоративный сервер 2024
Сервер документов
Сервер документов
Редакторы
Редакторы
Корпоративный сервер 2019
Корпоративный сервер 2019
Графика
Графика
Команда
Команда
Мобильные редакторы
Мобильные редакторы
Облачный офис
Облачный офис
Почта
Почта
Органайзер
Органайзер
Дополнительно
Часто задаваемые вопросы
Разработчикам
Интеграции
Новые возможности

Обработчик обратных вызовов

Обновлено: 25.12.25

Сервис редактирования документов оповещает сервис хранения документов о статусе редактирования документа, используя callbackUrl из JavaScript APIСервис редактирования документов использует POST запросы с параметрами в теле.

Параметры и их описание:

Параметр Описание Тип Наличие
Определяет полученный объект, если новый пользователь, был подключен к совместному редактированию документа или отключен от него. В первом случае значение поля тип равно 1, во втором — 0. Значение поля userid является идентификатором пользователя, который был подключен к совместному редактированию документа, или отключен от него. массив объектов необязательный
Определяет массив объектов с историей изменения документа. Объект присутствует только если значение параметра status равно 2 или 3. Должен быть отправлен как свойство changes, объекта, который был передан методу refreshHistory в качестве аргумента. Удалено, начиная с версии 4.2, пожалуйста, используйте history. массив объектов необязательный
Определяет ссылку на файл с данными об изменениях документа, используемый для отображения истории изменения этого документа. Ссылка присутствует только если значение параметра status равно 2 или 3. Файл должен быть сохранён, а его адрес должен быть отправлен как параметр changesUrl, используя метод setHistoryData, чтобы показать изменения, относящиеся к конкретной версии документа. строка необязательный
Определяет тип инициатора запроса на выполнение принудительного сохранения. Может быть равным следующим значениям:

  • 0 — запрос на принудительное сохранение отправляется к командному сервису.
  • 1 — запрос на принудительное сохранение выполняется каждый раз, когда производится сохранение (например, нажимается кнопка Сохранить), что доступно лишь в случае, если значение параметра forcesave равно true.
  • 2 — запрос на принудительное сохранение выполняется таймером с настройками от конфигурации сервера.

Тип присутствует только если значение параметра status равно 6 или 7.

целочисленный необязательный
Определяет объект с информацией об истории изменения документа. Объект присутствует только если значение параметра status равно 2 или 3. Содержит объекты serverVersion и changes, которые должны быть отправлены как свойства serverVersion и changes объекта, который был передан в качестве аргумента методу refreshHistory. объект необязательный
Определяет идентификатор отредактированного документа. строка обязательный
Определяет статус документа. Может быть равным следующим значениям:

  • 0 — не найден документ с данным идентификатором,
  • 1 — документ редактируется,
  • 2 — документ готов к сохранению,
  • 3 — во время сохранения документа произошла ошибка,
  • 4 — документ был закрыт без изменений,
  • 6 — документ редактируется, но текущее его состояние сохранено,
  • 7 — во время принудительного сохранения документа произошла ошибка.
целочисленный обязательный
Определяет ссылку на отредактированный документ, который будет сохранён сервисом хранения документов. Ссылка присутствует только если значение параметра status равно 2 или 3. строка необязательный
Определяет пользовательскую информацию, отправляемую командному сервису в случае, если она была передана в запросе. строка необязательный
Определяет список идентификаторов пользователей, который открыли документ для редактирования; когда документ был изменён, объект users вернёт идентификатор пользователя, который последним редактировал документ (для ответов со статусами 2 и 6). массив строк необязательный
Определяет расширение документа, загружаемого по ссылке, указанной в параметре url. По умолчанию используется тип файла OOXML, но если параметр сервера assemblyFormatAsOrigin включен, файл будет сохранен в исходном формате. строковый необязательный

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

Начиная с версии 7.0 callbackUrl используется с последней вкладки того же пользователя. До версии 7.0 использовался callbackUrl из первой пользовательской вкладки.

Возможные статусы документов и их описание

Статус 1 будет получен каждый раз, когда пользователь подключается к совместному редактированию документа или отключается от него.

Обратите внимание, что статус 1 может быть получен и при возврате пользователя к документу без изменений после проблем с интернетом. Эту ситуацию можно описать следующим образом:

  • Когда пользователь открывает документ, статус 1 отправляется.
  • Если интернет-соединение потеряно и пользователь не вносил никаких изменений в документ, высылается статус 4. На экран выводится ошибка и документ открывается в просмотрщике.
  • В течение 100 секунд интернет-соединение восстанавливается, пользователь повторно подключается к документу и снова отправляется статус 1.
  • Теперь пользователь может продолжить редактирование документа. Статус 2 или 4 будет получен в зависимости от того, вносил ли пользователь какие-либо изменения в документ или нет.

Статус 2 (3) будет получен через 10 секунд после закрытия документа, с идентификатором пользователя, от которого сервисом редактирования документов в последний раз были получены изменения. Используется callbackUrl от пользователя, внесшего последние изменения в файл.

Статус 4 будет получен после закрытия документа, если пользователь не вносил в него никаких изменений. Используется их callbackUrl.

Статус 6 (7) будет получен при выполнении запроса на принудительное сохранение.

CallbackUrl зависит от параметра forcesavetype:

  • Если для параметра forceavetype установлено значение 1, используется callbackUrl от пользователя, который нажал кнопку «Сохранить».
  • Если для параметра forceavetype задано значение 0 или 2, используется callbackUrl от пользователя, внесшего последние изменения в файл.
  • Начиная с версии 5.5 до версии 6.1 всегда используется callbackUrl от пользователя, внесшего последние изменения в файл.

Пример JSON объекта, отправляемого на адрес «callbackUrl» сервисом редактирования документов, когда 2 пользователя редактируют документ совместно:

{
    "actions": [{"type": 1, "userid": "78e1e841"}],
    "key": "Khirz6zTPdfd7",
    "status": 1,
    "users": ["6d5a81d0", "78e1e841"]
}

Пример JSON объекта, отправляемого «callbackUrl» сервисом редактирования документов, когда пользователь изменил документ и закрыл его:

{
    "actions": [{"type": 0, "userid": "78e1e841"}],
    "changesurl": "https://documentserver/url-to-changes.zip",
    "history": {
        "changes": changes,
        "serverVersion": serverVersion
    },
    "key": "Khirz6zTPdfd7",
    "status": 2,
    "url": "https://documentserver/url-to-edited-document.docx",
    "users": ["6d5a81d0"]
}

Пример JSON объекта, отправляемого на адрес «callbackUrl» сервисом редактирования документов, когда последний пользователь закрыл документ без изменений:

{
    "key": "Khirz6zTPdfd7",
    "status": 4
}

Пример JSON объекта, отправляемого на адрес «callbackUrl» сервисом редактирования документов, после того, как была получена команда forcesave:

{
    "changesurl": "https://documentserver/url-to-changes.zip",
    "forcesavetype": 0,
    "history": {
        "changes": changes,
        "serverVersion": serverVersion
    },
    "key": "Khirz6zTPdfd7",
    "status": 6,
    "url": "https://documentserver/url-to-edited-document.docx",
    "users": ["6d5a81d0"],
    "userdata": "sample userdata"
}

Ответ от сервиса хранения документов.
Сервис хранения документов должен отправить следующий ответ, в противном случае, редактор документов покажет сообщение об ошибке:

{
    "error": 0
}

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

Пример сохранения документа на .Net (C#):

public class WebEditor : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        string body;
        using (var reader = new StreamReader(context.Request.InputStream))
            body = reader.ReadToEnd();

        var fileData = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(body);
        if ((int) fileData["status"] == 2)
        {
            var req = WebRequest.Create((string) fileData["url"]);

            using (var stream = req.GetResponse().GetResponseStream())
            using (var fs = File.Open(PATH_FOR_SAVE, FileMode.Create))
            {
                var buffer = new byte[4096];
                int readed;
                while ((readed = stream.Read(buffer, 0, 4096)) != 0)
                    fs.Write(buffer, 0, readed);
            }
        }
        context.Response.Write("{\"error\":0}");
    }
}
Уточнение

PATH_FOR_SAVE — абсолютный путь к папке на вашем компьютере, включая имя файла, в которую будет сохранён этот файл.

Пример сохранения документа на Java:

public class IndexServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter writer = response.getWriter();

        Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
        String body = scanner.hasNext() ? scanner.next() : "";

        JSONObject jsonObj = (JSONObject) new JSONParser().parse(body);

        if((long) jsonObj.get("status") == 2)
        {
            String downloadUri = (String) jsonObj.get("url");

            URL url = new URL(downloadUri);
            java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
            InputStream stream = connection.getInputStream();

            File savedFile = new File(pathForSave);
            try (FileOutputStream out = new FileOutputStream(savedFile)) {
                int read;
                final byte[] bytes = new byte[1024];
                while ((read = stream.read(bytes)) != -1) {
                    out.write(bytes, 0, read);
                }

                out.flush();
            }

            connection.disconnect();
        }
        writer.write("{\"error\":0}");
    }
}

Уточнение

pathForSave — абсолютный путь к папке на вашем компьютере, включая имя файла, в которую будет сохранён этот файл.


Пример сохранения документа на Node.js:

var fs = require("fs");

app.post("/track", function (req, res) {

    var updateFile = function (response, body, path) {
        if (body.status == 2)
        {
            var file = syncRequest("GET", body.url);
            fs.writeFileSync(path, file.getBody());
        }

        response.write("{\"error\":0}");
        response.end();
    }

    var readbody = function (request, response, path) {
        var content = "";
        request.on("data", function (data) {
            content += data;
        });
        request.on("end", function () {
            var body = JSON.parse(content);
            updateFile(response, body, path);
        });
    }

    if (req.body.hasOwnProperty("status")) {
        updateFile(res, req.body, pathForSave);
    } else {
        readbody(req, res, pathForSave)
    }
});

Уточнение

pathForSave — абсолютный путь к папке на вашем компьютере, включая имя файла, в которую будет сохранён этот файл.


Пример сохранения документа на PHP:

<!--?php

if (($body_stream = file_get_contents("php://input"))===FALSE){
    echo "Bad Request";
}

$data = json_decode($body_stream, TRUE);

if ($data["status"] == 2){
    $downloadUri = $data["url"];
        
    if (($new_data = file_get_contents($downloadUri))===FALSE){
        echo "Bad Response";
    } else {
        file_put_contents($path_for_save, $new_data, LOCK_EX);
    }
}
echo "{\"error\":0}";

?-->

Уточнение

$path_for_save — абсолютный путь к папке на вашем компьютере, включая имя файла, в которую будет сохранён этот файл.


Пример сохранения документа на Ruby:

class ApplicationController < ActionController::Base def index body = request.body.read file_data = JSON.parse(body) status = file_data["status"].to_i if status == 2 download_uri = file_data["url"] uri = URI.parse(download_uri) http = Net::HTTP.new(uri.host, uri.port) if download_uri.start_with?("https") http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_NONE end req = Net::HTTP::Get.new(uri.request_uri) res = http.request(req) data = res.body File.open(path_for_save, "wb") do |file| file.write(data) end end render :text => "{\"error\":0}"
    end
end
Уточнение

path_for_save — абсолютный путь к папке на вашем компьютере, включая имя файла, в которую будет сохранён этот файл.