1 (изменено: wladkokopops, 2019-04-11 23:04:14)

Тема: AHK: Отправка фото на сервер

Проблема крутится вокруг Vk Api , сколько не искал и не читал, не могу понять как отправляется фото на сервер.
- Вызовите метод photos.getChatUploadServer, чтобы получить адрес для загрузки фото.
Вызвал метод, получил ответ ,получил адрес, окей.
-Передайте файл на адрес upload_url, полученный в предыдущем пункте, сформировав POST-запрос с полем file. Это поле должно содержать изображение в формате multipart/form-data.
Ага, а вот тут я встал в ступор,
допустим вот так я использую POST запрос:

whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
whr.Open("POST", "URL", true) 
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36") 
whr.SetRequestHeader("Content-Type","multipart/form-data") 
whr.Send() 
whr.WaitForResponse()

Но как передать сам файл?
Разве просто fileread? Или глупая идея?

2

Re: AHK: Отправка фото на сервер

whr.Send(binaryData)

3

Re: AHK: Отправка фото на сервер

MandarinKa02
Подробней можно?

whr.Send(binaryData)

это бинарный код отправить
а теперь как файл в бинарный перевести?

4

Re: AHK: Отправка фото на сервер

wladkokopops пишет:

а теперь как файл в бинарный перевести?

С трудом пытаюсь понять, что это значит.
https://autohotkey.com/docs/objects/File.htm#RawRead

5

Re: AHK: Отправка фото на сервер

MandarinKa02


fileread,jpeg,3.jpeg
binarydata := File.RawRead(jpeg, Bytes)

так?

6

Re: AHK: Отправка фото на сервер

Еще раз взываю о помощи!
Сколько бы не посылал вариаций Data файла,
приходит в ответ только META и пустой ответ photo!
как правильнее построить запрос на отсылку фото в лс?
Есть люди которые посылали уже файлы на сервер посредством AHK?

7

Re: AHK: Отправка фото на сервер

Вот тут по ссылке, вполне доступно рассказано.

При отправке данных методом POST с типом кодирования multipart/form-data, требуется:
1) В поле Content-Type указать строку вида

multipart/form-data; boundary=XXXXXXXXXX

Где "XXXXXXXXXX" является сгенерированной строкой разделителем данных (например: RaNdOmDeLiMiTeR). С помощью него серверная часть, получив из заголовка значение boundary и разбирая поток данных, может понять где закончились данные одного поля и начались данные другого поля.

В случае использования объекта WinHttpRequest / XmlHttpRequest это можно сделать методом SetRequestHeader

Object.SetRequestHeader("Content-Type","multipart/form-data; boundary=RaNdOmDeLiMiTeR")

2) Пример запроса:

--RaNdOmDeLiMiTeR
Content-Disposition: form-data; name="textField1"

test
--RaNdOmDeLiMiTeR
Content-Disposition: form-data; name="file1"; filename="image.jpg"
Content-Type: application/octet-stream

...[тело файла]....
--RaNdOmDeLiMiTeR--

Поясню.
а) Каждый блок данных начинается с разделителя boundary c начальными двумя дефисами (В данном случае "--RaNdOmDeLiMiTeR").
б) В тексте выше переданы два блока данных. Содержимое текстового поля "textField1" и тело файла с именем поля "file1"
Для передачи файловых полей после заголовка Content-Disposition вставляется ещё и заголовок Content-Type с указанием типа содержимого. Список значений для него можно посмотреть здесь

Для простоты можно использовать application/octet-stream, как универсальное значение при передаче двоичных данных.

в) В конце данных вставляется последний boundary и на его хвосте добавляются 2 дефиса. В нашем случае это будет --RaNdOmDeLiMiTeR--

3) По умолчанию текстовые данные формы передаются в кодировке UTF-8, а двоичные данные передаются как есть.

Вот как-то так.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

8 (изменено: wladkokopops, 2019-04-16 18:05:01)

Re: AHK: Отправка фото на сервер

Xameleon

ComObjError(false) 
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
whr.Open("POST", uploadurl, true)
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36") 
whr.SetRequestHeader("Content-Type","multipart/form-data; boundary=RaNdOmDeLiMiTeR")
whr.Send(oFile)
whr.WaitForResponse()
jsontext := % whr.ResponseText
msgbox % jsontext

Как в моём случае использовать делимитер?
Именно чтобы AHK не ругался на инородный код?

9

Re: AHK: Отправка фото на сервер

wladkokopops

1) Про сам AHK мне трудно сейчас подсказать, так как на ПК нет его среды для теста. К тому же кодил я на нём всего 1-2 раза в жизни и очень давно.

А в чём выражается "AHK ругается на инородный код" ?

2) Судя по коду, я не вижу, чтобы вы выполнили все необходимые действия с данными, которые отправляете на сервер.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

10

Re: AHK: Отправка фото на сервер

Xameleon
А можно подключить JS скрипт для отправки фото?
есть готовые варианты для VK?
Пусть AHK выкладывает UPLOAD_URL в текстовик, а JS по нему будет слать, и ответ обратно в текстовик.

11

Re: AHK: Отправка фото на сервер

wladkokopops. Хм... Ну пмсм, вариант крайне корявый + плюс наверняка придётся передавать cookie от объекта, которым Вы изначально авторизовывались в API. Но в принципе - можете попробовать.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

12

Re: AHK: Отправка фото на сервер

wladkokopops, учитесь пользоваться поиском.

13 (изменено: MandarinKa02, 2019-04-16 21:24:46)

Re: AHK: Отправка фото на сервер

*deleted*

14

Re: AHK: Отправка фото на сервер

wladkokopops, возможно Вам пригодится мой сэмпл загрузки файла на ресурс uploadfiles.io. Но сразу предупрежу он на JS. Для упрощения сборки запроса используется Windows Script Component (скриптовый компонент) webFormDataBuilder.wsc. Думаю, при желании, Вы можете использовать его из AHK.

Post's attachments

upload_sample.zip 137.71 kb, 3 downloads since 2019-04-16 

You don't have the permssions to download the attachments of this post.
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

15

Re: AHK: Отправка фото на сервер

Решил всё-таки тряхнуть стариной. Как вариант для AHK, наверное, можно так. Положите этот скрипт в папку с содержимым примера выше.


;Создание и настройка объекта для построения данных формы
form			:= ComObjGet("script:file:webFormDataBuilder.wsc")
form.method		:= "POST"
form.action		:= "https://up.uploadfiles.io/upload"
form.enctype	:= "multipart/form-data"

;Загрузка тела файла в буффер
fileName := "картинка.jpg"
;Открытие файла на чтение
file := FileOpen(fileName,"r")
if !IsObject(file)
{
    MsgBox Can't open "%FileName%" for reading.
    return
}

;Добавление тела файла в запрос
form.addFileField("file", "картинка.jpg", file.Read())
file.Close()

;Подготовка запроса к сервису
whr	:= ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.open(form.method, form.action, false)
whr.setRequestHeader("Content-Type",form.contentType)
whr.send(form.build())

;Загрузка объекта HTMLDocument
document := ComObjCreate("htmlfile")
;Установка режима совместимости
document.writeln("<meta http-equiv=""x-ua-compatible"" content=""IE=Edge""/>")
;Получение объекта JSON для разбора JSON данных
JSON := document.parentWindow.JSON

try {
    url := JSON.parse(whr.responseText).url
	ComObjCreate("WScript.Shell").Run(url)
} catch e {
	MsgBox JSON parsing failed !
}
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

16

Re: AHK: Отправка фото на сервер

Xameleon
Вот что у меня получилось, и что не получается в итоге.

Token := "TOKENVKONTAKTE"
ID := "94" ; ид беседы в которую загрузить фото, если меньше 10 то подставить 0 (04,07 и.т.д)

ComObjError(false) 
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
whr.Open("POST", "https://api.vk.com/method/photos.getMessagesUploadServer?peer_id=20000000" ID "&access_token=" Token "&v=5.95", true) 
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36") 
whr.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
whr.Send() 
whr.WaitForResponse()
jsontext := % whr.ResponseText
JSON = 
(LTrim Join
%jsontext% 
) 
htmldoc := ComObjCreate("htmlfile") 
Script := htmldoc.Script 
Script.execScript(" ", "JScript") 
oJSON := Script.eval("(" . JSON . ")")
upload_url := % oJSON.response.upload_url ;Получил ответ с ссылкой
uploadurl := StrReplace(upload_url, "\/", "/", count) ;Избавился от лишних слешей \

;ДАЛЕЕ ВАШ КОД
;Создание и настройка объекта для построения данных формы
form			:= ComObjGet("script:file:webFormDataBuilder.wsc")
form.method		:= "POST"
form.action		:= "%uploadurl%" ; Вводил переменную с ссылкой как % uploadurl  , но ругается на ошибку
form.enctype	:= "multipart/form-data"

;Загрузка тела файла в буффер
fileName := "3.jpeg"
;Открытие файла на чтение
file := FileOpen(fileName,"r")
if !IsObject(file)
{
    MsgBox Can't open "%FileName%" for reading.
    return
}

;Добавление тела файла в запрос
form.addFileField("file", "картинка.jpg", file.Read())
file.Close()

;Подготовка запроса к сервису
whr	:= ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.open(form.method, form.action, false)
whr.setRequestHeader("Content-Type",form.contentType)
whr.send(form.build())

;Загрузка объекта HTMLDocument
document := ComObjCreate("htmlfile")
;Установка режима совместимости
document.writeln("<meta http-equiv=""x-ua-compatible"" content=""IE=Edge""/>")
;Получение объекта JSON для разбора JSON данных
JSON := document.parentWindow.JSON
try {
    url := JSON.parse(whr.responseText).url
	ComObjCreate("WScript.Shell").Run(url)
} catch e {
	MsgBox JSON parsing failed !
}

Откуда ответ сервера вытянуть теперь?

17

Re: AHK: Отправка фото на сервер

Ладно, не обязательно загружать фото/картинку на Вк сервер, нужен любой хостинг картинок, который в ответ даст URL,
и уже URL можно подгрузить на VK.
Есть идеи что использовать?

18

Re: AHK: Отправка фото на сервер

Поиск.

19

Re: AHK: Отправка фото на сервер

Да нет, тут поиск пока бесполезен. Для начала нужно научиться знаком := правильно пользоваться. Так что справка, переменные и выражения.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

20 (изменено: wladkokopops, 2019-04-17 15:24:59)

Re: AHK: Отправка фото на сервер

ComObjError(false) 
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
whr.Open("POST", "https://api.vk.com/method/photos.getMessagesUploadServer?peer_id=20000000" ID "&access_token=" Token "&v=5.95", true) 
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36") 
whr.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
whr.Send() 
whr.WaitForResponse()
jsontext := % whr.ResponseText
JSON = 
(LTrim Join
%jsontext% 
) 
htmldoc := ComObjCreate("htmlfile") 
Script := htmldoc.Script 
Script.execScript(" ", "JScript") 
oJSON := Script.eval("(" . JSON . ")")
upload_url := % oJSON.response.upload_url ;Получил ответ с ссылкой
uploadurl := StrReplace(upload_url, "\/", "/", count) ;Избавился от лишних слешей \

;ДАЛЕЕ ВАШ КОД
;Создание и настройка объекта для построения данных формы
form			:= ComObjGet("script:file:webFormDataBuilder.wsc")
form.method		:= "POST"
form.action		:= StrReplace(upload_url, "\/", "/", count)
form.enctype	:= "multipart/form-data"

;Загрузка тела файла в буффер
fileName := "3.jpg"
;Открытие файла на чтение
file := FileOpen(fileName,"r")

;Добавление тела файла в запрос
form.addFileField("file", "3.jpg", file.Read())
file.Close()

;Подготовка запроса к сервису
whr	:= ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.open(form.method, form.action, false)
whr.setRequestHeader("Content-Type",form.contentType)
whr.send(form.build())

;Загрузка объекта HTMLDocument
document := ComObjCreate("htmlfile")
;Установка режима совместимости
document.writeln("<meta http-equiv=""x-ua-compatible"" content=""IE=Edge""/>")
;Получение объекта JSON для разбора JSON данных
jsontext := % whr.ResponseText
msgbox % jsontext

В ответ выдает сервер, хэш, но Photo = null
что не так? Использовал всё как сказали.

vk api :
Передайте файлы на адрес upload_url, полученный в предыдущем пункте, сформировав POST-запрос с полем photo. Это поле должно содержать изображения в формате multipart/form-data.

После успешной загрузки сервер возвращает в ответе JSON-объект с полями server, photo, hash.

21

Re: AHK: Отправка фото на сервер

wladkokopops пишет:

что не так? Использовал всё как сказали.

Ну видимо не совсем "всё как сказали". )

Вы же сами написали:

wladkokopops пишет:

.... сформировав POST-запрос с полем photo

А в коде у Вас:

wladkokopops пишет:

form.addFileField("file", "3.jpg", file.Read())

wladkokopops пишет:

Ладно, не обязательно загружать фото/картинку на Вк сервер, нужен любой хостинг картинок, который в ответ даст URL,
и уже URL можно подгрузить на VK.
Есть идеи что использовать?

Так в моём же примере, который я выложил в ZIP архиве, пример загрузки файла на https://uploadfiles.io/

Можно загрузить и на https://imgur.com/. Вот аналогичный скрипт для загрузки файла на него:

+ открыть спойлер

// Создание объекта для построения данных формы для отправки на сервер
var form = GetObject("script:file:webFormDataBuilder.wsc");
// Указание URL назначения
form.action = "https://imgur.com/upload";
// Указание метода отправки
form.method	= "POST";
// Указание типа кодирования
form.enctype = "multipart/form-data";
// Добавление поля "Filedata" c телом файла
form.addFileField("Filedata","картинка.jpg",readFile("картинка.jpg"));
// Создание объекта для отправки данных
whr = new ActiveXObject('WinHttp.WinHttpRequest.5.1');
// Установка User-Agent для отправки
whr.option(0) = 'Mozilla/5.0';
// Настройка объекта для отправки
whr.open(form.method, form.action, false);
// Установка Content-Type
whr.setRequestHeader('Content-Type',form.contentType);
whr.setRequestHeader('Referer','https://imgur.com/upload');
// Отправка подготовленных данных на сервер
var data = form.build();
// Сохранение дампа отправляемых данных для удобной отладки
saveDump(data,'post_dump.txt');
// Отправка файла на сервер
whr.send(data);

// На этом моменте отправка заканчивается и дальше идёт обработка ответа

// Проверка успешности загрузки

if(whr.status != '200') {
	WSH.Echo('Upload failed !');
} else {
	// Создание объекта для разбора JSON данных
	var JSON = (function(){
		// Загрузка объекта HTMLDocument
		var document = new ActiveXObject('htmlfile');
		// Установка режима совместимости
		document.writeln('<meta http-equiv="x-ua-compatible" content="IE=Edge"/>');
		// Подключение обработчика ошибок
		document.parentWindow.onerror = function(message, url, line, column, error){
			throw new Error(error);
		}
		return document.parentWindow.JSON;
	})();
	// Разбор JSON ответа
	try {
		var result = JSON.parse(whr.responseText);
		WSH.Echo(whr.responseText);
	} catch(e) {
		WSH.Echo('Ошибка разбора JSON данных. ' + e.description + '\r\n\r\n' + whr.responseText)
		WSH.Quit();
	}
	// Открытие URL загруженного файла
	new ActiveXObject('WScript.Shell').Run('https://imgur.com/' + result.data.hash)
}


// Внутренняя функция чтения файла
function readFile(fileName){
	var stream = new ActiveXObject("ADODB" + ".Stream");
	stream.Type = 1;
	stream.Open();
	stream.LoadFromFile(fileName);
	return stream.Read();
}

// Функция сохранения двоичного дампа отправляемых данных
function saveDump(data,fileName){
	var stream = new ActiveXObject('ADODB.Stream');
	stream.type = 1;
	stream.open();
	stream.Write(data);
	stream.SaveToFile(fileName,2);	
}
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

22 (изменено: wladkokopops, 2019-04-19 17:57:56)

Re: AHK: Отправка фото на сервер

Xameleon

Token := "TOKEN"
ID := "94" ; ид беседы в которую загрузить фото, если меньше 10 то подставить 0 (04,07 и.т.д)

ComObjError(false) 
whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") 
whr.Open("POST", "https://api.vk.com/method/photos.getMessagesUploadServer?peer_id=20000000" ID "&access_token=" Token "&v=5.95", true) 
whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36") 
whr.SetRequestHeader("Content-Type","application/x-www-form-urlencoded")
whr.Send() 
whr.WaitForResponse()
jsontext := % whr.ResponseText
JSON = 
(LTrim Join
%jsontext% 
) 
htmldoc := ComObjCreate("htmlfile") 
Script := htmldoc.Script 
Script.execScript(" ", "JScript") 
oJSON := Script.eval("(" . JSON . ")")
upload_url := % oJSON.response.upload_url ;Получил ответ с ссылкой
Url := StrReplace(upload_url, "\/", "/", count)
;Создание и настройка объекта для построения данных формы
form 		:= ComObjGet("script:file:webFormDataBuilder.wsc")
form.method	:= "POST"
form.action	 := Url
form.enctype := "multipart/form-data"

;Загрузка тела файла в буффер
fileName := "3.jpg"
;Открытие файла на чтение
file := FileOpen(fileName,"r")
fileout := file.Read()

;Добавление тела файла в запрос
form.addFileField("photo","3.jpg", fileout)
;Подготовка запроса к сервису
whr	:= ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.open(form.method, form.action, false)
whr.setRequestHeader("Content-Type",form.contentType)
whr.send(form.build())
;ответ ↓
jsontext := % whr.ResponseText
msgbox % jsontext

Вот , всё, ну всё как должно быть, а в ответе photo["Null"] ...
Ссылка получается правильной, запрос именно на неё,ответ приходит, но значение фото нулевое.

23

Re: AHK: Отправка фото на сервер

wladkokopops пишет:

:= %

wladkokopops, откуда вы все берёте такой синтаксис?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

24

Re: AHK: Отправка фото на сервер

wladkokopops, покажите, пожалуйста, ссылку на раздел документации, который читаете.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

25

Re: AHK: Отправка фото на сервер

vk api
https://vk.com/dev/upload_files?f=4.%20 … 0сообщение
Xameleon