Upload аудиофайла, кодированного base64

159
23 января 2019, 16:30

В спецификации API Bitrix24 есть метод telephony.externalCall.attachRecord, который позволяет загрузить в облако аудиозапись звонка.

Собственно запрос выглядит так:

https://test.bitrix24.ru/rest/1/tokenXXX/telephony.externalCall.attachRecord?CALL_ID=XXX&FILENAME=file.mp3&FILE_CONTENT=...<base64>...

Я использую метод:

public void externalCallAttachRecord(String call_id, File file) {
        String encoded = util.encodeToBase64(file);
        MultivaluedMap queryParams = new MultivaluedMapImpl();
        String path = properties.getBitrixId() + "/"
                + properties.getBitrixOutterWebhook() + "/telephony.externalCall.attachRecord";
        queryParams.add("CALL_ID", call_id);
        queryParams.add("FILENAME", file.getName().split(".wav")[0].concat(".mp3"));
        queryParams.add("FILE_CONTENT", encoded);
        String jsonString = request(path, queryParams);
        log.debug("externalCallAttachRecord reply is {}", jsonString);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        try {
            bitrixUploadCallEntity.setUrlEntity(objectMapper.readValue(jsonString,BitrixUploadCallEntity.class).getUrlEntity());
        } catch (IOException e) {
            e.printStackTrace();
        }
private String request(String path, MultivaluedMap queryParams) {
        String response = "";
        service = Client.create(new DefaultClientConfig()).resource("https://"+ properties.getBitrixDomain()+"/rest/");
        try {
            log.debug("===query is {}", service.path(path).queryParams(queryParams).toString());
            ClientResponse clientResponse = service
                    .queryParams(queryParams)
                    .path(path)
//                    .post(ClientResponse.class);
                    .get(ClientResponse.class);
            if (clientResponse.getStatus() == apiState) {
                response = clientResponse.getEntity(String.class);
                log.debug("Response status is {}", clientResponse.getStatusInfo());
            } else {
                apiState = clientResponse.getStatus();
//                sendEmail(clientResponse);
                log.warn("Failed : HTTP error code : {}", clientResponse.getStatus());
                log.warn("Failed : HTTP error message : {}", clientResponse.getStatusInfo());
//                throw new RuntimeException("Failed : HTTP error code : "
//                        + clientResponse.getStatus());
            }
        } catch (Exception e) {
            log.warn(e.toString());
        }
        return response;
    }

У меня проблема в том, что получившийся GET запрос, слишком длинный и я получаю ошибку 414.

А можно как-то по другому передать в этом запросе тело файла?

Есть там второй способ, это сделать GET запрос, получить URL на который можно закачать файл.

Вот выдержка из спецификации:

Методы REST-сервиса получают файлы в виде строки, закодированной в base64. Также можно отправить обычный массив, первым элементом которого будет имя файла, вторым - содержимое в base64.

В случае полностью клиентского приложения можно либо воспользоваться объектом FileReader, либо просто отдать в качестве значения поля запроса ссылку на элемент формы типа "файл" ()

Я пробую на полученный URL загрузить методом POST:

public void uploadFile(String urlString, String fieldName, File file) {
        HttpClient httpClient = HttpClientBuilder.create().build(); 
        try {
            HttpPost request = new HttpPost(urlString);
            StringEntity params = new StringEntity("{\"file\":[\""+file.getName().split(".wav")[0].concat(".mp3")+"\",\"" + encodeToBase64(file) + "\"]}");
            request.addHeader("Connection", "Keep-Alive");
            request.addHeader("Content-Type", "multipart/form-data;");
            request.setEntity(params);
            HttpResponse response = httpClient.execute(request);
        } catch (Exception e) {
            log.warn(e.getMessage());
        }

но получаю:

{"error":"","error_description":"Error: required parameter file is not found"}[\r][\n]"

Причем

new StringEntity("{\"file\":[\""+file.getName().split(".wav")[0].concat(".mp3")+"\",\"" + encodeToBase64(file) + "\"]}");

я в каких только вариациях не формировал... всегда ответ один и тот же...

READ ALSO
Как данные с сервиса передать в custom tag?

Как данные с сервиса передать в custom tag?

Я работаю с сервлетами и кастом тегамиЯ занимаюсь созданием капчей

211
Java многопоточный клиент

Java многопоточный клиент

Я разрабатываю программу которая работает с изображениями

166
Как найти предыдущий элемент?

Как найти предыдущий элемент?

Поиск предыдущего:

169
получение нового массива [дубликат]

получение нового массива [дубликат]

Данный вопрос является точным дубликатом:

151