Итак, это моя проблема. Чтобы поделиться публикацией с изображением через linkedin API, вам сначала нужно зарегистрировать файл изображения, вы делаете это с помощью почтового запроса, в котором вы отправляете свой двоичный файл. Затем вы используете URN изображения в исходном запросе, чтобы отправить сообщение. Мой запрос проходит, возвращает код 201 (который должен быть успешным запросом), но в итоге не публикует изображение или текст. Если я пытаюсь опубликовать только текст, это работает. Я попытался зарегистрировать свое изображение с помощью curl, и оно было размещено на LinkedIn, поэтому я думаю, что неправильно отправляю двоичный файл в запросе, это мой запрос:
HttpClient client = HttpClientBuilder.create().build();
HttpPut request = new HttpPut(uploadUrl);
request.addHeader("Content-Type", "data/binary");
request.setHeader("X-Restli-Protocol-Version", "2.0.0");
request.setHeader("Authorization", "Bearer " + myToken);
File file = new File(pictureUrl);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("upload-file", file);
request.setEntity(builder.build());
HttpResponse response = client.execute(request);
Я получаю код 201 с этим кодом, но он все равно не публикуется. Это curl-пример запроса, который они дают на Поделиться документом по API.
curl -i --upload-file /Users/peter/Desktop/superneatimage.png --header "Authorization: Bearer redacted" 'https://api.linkedin.com/mediaUpload/C5522AQGTYER3k3ByHQ/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQJbrN86Zm265gAAAWemyz2pxPSgONtBiZdchrgG872QltnfYjnMdb2j3A&app=1953784&sync=0&v=beta&ut=2H-IhpbfXrRow1'
Можете ли вы сказать мне, что не так с моим эквивалентом Java?
Редактировать: забыл сказать, что я даже пытался вызвать завиток из java, тот же код, который я использовал в терминале, и он все еще не работал.
Process p;
try {
p = Runtime.getRuntime().exec("curl -i --upload-file" + " " + pictureUrl + " " + "--header \"Authorization: Bearer " + myToken + "\" '" + uploadUrl + "'");
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
String outputController = "";
while ((line = reader.readLine()) != null) {
outputController = outputController + '\n' + line;
}
System.out.println("out: ");
System.out.println(outputController);
return true;
} catch (IOException | InterruptedException ex) {
return false;
}
Вывод вернул пустую строку.
Edit2: Еще одна забавная вещь, когда я выполняю основной запрос, в котором я отправляю текст и медиа-урны, которые я получаю после отправки изображений, я снова получаю 201, как будто это успешно, и в ответ я даже получаю идентификатор сообщения. Затем я пытаюсь использовать другую конечную точку API и извлекать этот пост, используя идентификатор, который я получил из ответа, и я получаю все данные, например, пост опубликован. В json даже говорится, что я получаю, что жизненный цикл ПУБЛИКУЕТСЯ, а статус носителя - ГОТОВ. Единственное, что отличается от json-сообщения с изображением, которое есть на linkedin, это то, что у медиа-объекта есть миниатюры, а в этом случае их нет, это просто пустой массив json.




Не знаком с Java, но у меня была такая же проблема с использованием Ruby, и я исправил ее, добавив MIME-тип загружаемого изображения в качестве Content-Type в заголовках запроса. Итак, в вашем конкретном случае это будет:
request.addHeader("Content-Type", "image/png");
Также взгляните на мое решение с использованием Ruby RestClient и Minimagick: https://stackoverflow.com/a/54902863/7844946
Я попытался изменить тип контента на тип пантомимы изображения, но все равно не повезло. Где вы видите статус актива?
Вы можете сделать запрос GET к api.linkedin.com/v2/assets/{ASSET_ID}. Идентификатор актива возвращается из вызова registerUpload. P.S. Идентификатор актива, а не урна, т.е. GET api.linkedin.com/v2/assets/C4D22AQHzpy09pIC8tw
Да... получаю "CLIENT_ERROR"
Если ресурс не имеет статуса «ДОСТУПНО», публикация не будет отображаться в LinkedIn. Скорее всего файл не отправляется должным образом. Я бы хотел, чтобы я все еще помнил Java. Я удивлен, что вызов curl в Java не работает. Был ли pictureUrl абсолютным путем?
Да, pictureUrl — это абсолютный путь. Если я попробую ту же строку, которую я использовал в вызове java curl в терминале, это сработает. Да, я думаю, что запрос не отправляется должным образом, будем надеяться, что кто-то сможет исправить мой java. Спасибо за попытку в любом случае.
Я снова попытался использовать curl из java и проверил статус актива, теперь статус застрял на «WAITING_UPLOAD» на 10 минут.
WAITING_UPLOAD означает, что вы еще не позвонили, чтобы загрузить изображение. Как только вы сделаете вызов, статус изменится на PROCESSING, а затем либо на AVAILABLE, либо на CLIENT_ERROR в зависимости от запроса.
Ах, хорошо, значит, я тоже неправильно вызываю curl из java, ха-ха.
Ты вообще не звонишь, ха-ха
Я получаю ту же проблему в php. CLIEN_ERROR в активах. Кто-нибудь, пожалуйста, помогите.
Это не сработало для меня .. добавление заголовка запроса content-type: multipart/form-data для загрузки файлов работает для меня
Хорошо, я решил это, если кто-то столкнется с той же проблемой, это то, что я сделал неправильно. В запросе я добавил multipart в тело запроса, это неправильно, вы просто получаете RAW. Итак, вместо
File file = new File(pictureUrl);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("upload-file", file);
request.setEntity(builder.build());
ты только что положил
request.setEntity(new FileEntity(new File(pictureUrl), ContentType.create(picture.getContentType())));
а дальше все нормально.
как насчет следующего шага для этого (поделиться публикацией), для этого требуется идентификатор пользователя в теле запроса, но я не могу получить его в бэкэнде (ошибка 500)
Если вы используете api.linkedin.com/v2/ugcPosts, вам не требуется идентификатор пользователя, вам нужна ваша урна в поле автора. URN строится следующим образом: "urn:{namespace}:{entityType}:{id}". Пространство имен всегда «li», тип объекта может быть «organization/person/sponsoredAccount», а идентификатор вы получаете при вызове api.linkedin.com/v2/me. Я использую свою страницу, чтобы делиться сообщениями, поэтому моя урна urn:li:organization:myCustomId
Я нашел конвертер curl в C# https://curl.olsh.me/ ниже генерируется фрагмент кода:
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("PUT"), "https://api.linkedin.com/mediaUpload/C5522AQGTYER3k3ByHQ/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQJbrN86Zm265gAAAWemyz2pxPSgONtBiZdchrgG872QltnfYjnMdb2j3A&app=1953784&sync=0&v=beta&ut=2H-IhpbfXrRow1"))
{
request.Headers.TryAddWithoutValidation("Authorization", "Bearer redacted");
request.Content = new ByteArrayContent(File.ReadAllBytes("/test.png"));
var response = await httpClient.SendAsync(request);
}
}
Я писал на kotlin, и после долгой борьбы с одной и той же проблемой мне удалось ее исправить, для тех, кто борется с похожей проблемой, я оставлю свои примеры кода ниже. Для визуала необходимо указать прямой путь URI, также обратите внимание на структуру заголовка.
Вот коды.
var file = File(ImageURI)
val urls = URL(url)
var connection: HttpsURLConnection = urls.openConnection() as HttpsURLConnection
connection.setRequestProperty("Authorization","Bearer " + accesToken)
connection.setRequestProperty("Content-Type", "image/png")
connection.setRequestProperty("cache-control", "no-cache")
connection.setRequestProperty("X-Restli-Protocol-Version", "2.0.0")
connection.requestMethod = "POST"
connection.doOutput = true
connection.doInput = true
var request = DataOutputStream(connection.outputStream)
request.write(file.readBytes())
request.flush()
println("Response: "+connection.responseCode)
Кстати, в каком состоянии ваш актив? Это "CLIENT_ERROR"?