• Hi All

    Please note that at the Chandoo.org Forums there is Zero Tolerance to Spam

    Post Spam and you Will Be Deleted as a User

    Hui...

  • When starting a new post, to receive a quicker and more targeted answer, Please include a sample file in the initial post.

Upload image using curl in VBA

YasserKhalil

Well-Known Member
Please edit post #17 as it has the API key.
And the response for that post was error at the message box which is a JSON resposnse
 

Marc L

Excel Ninja
The error raised 'cause of your local file instead of an URL and without the parameters names expected …

So according to your initial link and post #17 :​
  • Data = "key=…&image=…&name=…"

    Replace each '…' by the expected value.

  • .Open "POST", "https://api.imgbb.com/1/upload", False
 

YasserKhalil

Well-Known Member
This is my try till now according to your instructions .. I don't know what name in the parameters ..
Code:
Sub TestMarcL()
Dim objHTTP     As Object
Dim URL         As String
Dim Data        As String
Dim replyTXT

'Data = "key=…&image=…&name=…"
'Data = ThisWorkbook.Path & "\Logo.png"
'.Open "POST", "https://api.imgbb.com/1/upload", False

Data = "key=APIKEY&image=https://chandoo.org/forum/data/attachments/66/66552-39d726d427c8541323a79562f5cd140d.jpg&name=WHATNAME"

Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP")
''URL = "https://api.imgbb.com/1/upload"
'objHTTP.Open "POST", URL, False

objHTTP.Open "POST", "https://api.imgbb.com/1/upload", False

objHTTP.setRequestHeader "Content-type", "application/json" 'if you have/need headers
objHTTP.send Data
replyTXT = objHTTP.responseText
MsgBox (replyTXT)
End Sub
I got a message with JSON response that has error in it.
 

Marc L

Excel Ninja
As you can read in your initial link in the ' Example call ' you need a client API key​
clearly stated as ' required ' in the above ' Parameters ' section …​
 

YasserKhalil

Well-Known Member
Yes, you are right and I already have the API and used it in the code. It is working when using CURL command line ..but not for the WINHTTP request.
 

Marc L

Excel Ninja
As I read on Web about this subject maybe VBA is not the appropriate tool​
or as the name is optional try without it as maybe your name is not valid (w/o any extension)​
or for some reason something is missing, try to contact the website …​
 

YasserKhalil

Well-Known Member
I have already contacted them but I got no reply.
Do you mean with the name the name I registered with? On what basis you built those parameters in that way?
 

Marc L

Excel Ninja
Or maybe try the mix way : the key in the open URL like in the Curl example​
and only the image and name parameters in the send codeline (even just the image as the name is optional) …​
 

Chihiro

Excel Ninja
You are posting image correct?

Why is content type set to application/jason?

Code:
objHTTP.setRequestHeader "Content-type", "application/json" 'if you have/need headers
It's typically done using 'multipart/form-data'.

For sample code using 'multipart/form-data'...

Have a look at...
http://www.ericphelps.com/scripting/samples/reference/web/http_post.txt

FYI - CURL is much easier to handle 'multipart/form-data' since it has built in process to handle it using '-F' or '--form' flag. In VBA, unless you have some add-in or external library that handles this process, you'll need to write your own code to submit correct 'multipart/form' data for the file.
 
Last edited:

YasserKhalil

Well-Known Member
Thanks a lot. Do you mean using this line in that way
Code:
objHTTP.setRequestHeader "Content-type", "multipart/form-data"
I have reached the link you posted but I was still lost in dealing with it. Feel it complicated for me
 

YasserKhalil

Well-Known Member
I have tested such a code
Code:
Sub MyTest()
Dim sUrl As String
Dim sFile As String

sUrl = "https://api.imgbb.com/1/upload/?key=ea40e4aec91ead65f6cdb3f148ebf2b8&image=iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
sFile = ThisWorkbook.Path & "\Image.png"
pvPostFile sUrl, sFile ', True
End Sub

Private Function pvPostFile(sUrl As String, sFileName As String, Optional ByVal bAsync As Boolean) As String
    Const STR_BOUNDARY  As String = "3fbd04f5-b1ed-4060-99b9-fca7ff59c113"
    Dim nFile           As Integer
    Dim baBuffer()      As Byte
    Dim sPostData       As String
 
    '--- read file
    nFile = FreeFile
    Open sFileName For Binary Access Read As nFile
    If LOF(nFile) > 0 Then
        ReDim baBuffer(0 To LOF(nFile) - 1) As Byte
        Get nFile, , baBuffer
        sPostData = StrConv(baBuffer, vbUnicode)
    End If
    Close nFile
    '--- prepare body
    sPostData = "--" & STR_BOUNDARY & vbCrLf & _
        "Content-Disposition: form-data; name=""uploadfile""; filename=""" & Mid$(sFileName, InStrRev(sFileName, "\") + 1) & """" & vbCrLf & _
        "Content-Type: application/octet-stream" & vbCrLf & vbCrLf & _
        sPostData & vbCrLf & _
        "--" & STR_BOUNDARY & "--"
        
        '"key=ea40e4aec91ead65f6cdb3f148ebf2b8"
    '--- post
    With CreateObject("Microsoft.XMLHTTP")
        .Open "POST", sUrl, bAsync
        .setRequestHeader "Content-Type", "multipart/form-data; boundary=" & STR_BOUNDARY
        .send pvToByteArray(sPostData)
        If Not bAsync Then
            pvPostFile = .responseText
        End If
    End With
End Function
 
Private Function pvToByteArray(sText As String) As Byte()
    pvToByteArray = StrConv(sText, vbFromUnicode)
End Function
I have put a break point at the end of function and tested the returned message in the immediate window using ?pvPostFile
and I got
{"status_code":400,"error":{"message":"Upload using base64 source must be done using POST method.","code":130,"context":"Exception"},"status_txt":"Bad Request"}

That means the problem is in POST method but POST method is used!!!
 

Chihiro

Excel Ninja
Your boundary string is off. Should be... something like '----XXX' the part after dashes looks to be dynamic.
Note: In most cases you can use '---------------------------0123456789012' or something similar and API will accept.

Don't have time to test things out. But payload should look like something below. Though not all of them are needed.
Code:
------WebKitFormBoundaryvDXokdQDBvJGp0VS
Content-Disposition: form-data; name="source"; filename="NorthAmerica.png"
Content-Type: image/png


------WebKitFormBoundaryvDXokdQDBvJGp0VS
Content-Disposition: form-data; name="type"

file
------WebKitFormBoundaryvDXokdQDBvJGp0VS
Content-Disposition: form-data; name="action"

upload
------WebKitFormBoundaryvDXokdQDBvJGp0VS
Content-Disposition: form-data; name="timestamp"

1584972534353
------WebKitFormBoundaryvDXokdQDBvJGp0VS
Content-Disposition: form-data; name="auth_token"

c3563d3db7dcad3b5d9892663a0e126aa83b45a5
------WebKitFormBoundaryvDXokdQDBvJGp0VS--
 
Last edited:

YasserKhalil

Well-Known Member
In this line
Code:
cmd = "curl --location --request POST ""https://api.imgbb.com/1/upload?key=" & sAPIKey & """" & " --form image=@""" & picPath & """ -o " & sPath
-o parameter used to download the JSON response. How can I store the response in a string instead of downloading it?
 

YasserKhalil

Well-Known Member
I have tried to adopt Alex's solution on the link posted and I am confused how to use it
Code:
Debug.Print Redirect("Here is what I should do",cmd)
What's the first parameters should I type?
 
Top