dcsimg
Results 1 to 15 of 15

Thread: Reading data from WebAPI

  1. #1

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Reading data from WebAPI

    I have as SMS provider for sending SMS's from my program by way of a POST code line:
    xmlHttp.Open "POST", strSend, False
    People can reply to this SMS once.
    To retrieve the return SMS with its associated data of date and time etc., I need to put the link in the internet browser which then returns one long string in the browser.
    I have used the browser control previously in one of my programs, but only for retrieving a web page, but never for data.
    Is there a way that I can send this link from my program and receive the data string into the program.
    Thanks
    PK

  2. #2
    Frenzied Member wqweto's Avatar
    Join Date
    May 2011
    Posts
    1,582

    Re: Reading data from WebAPI

    Here is a short crash-course how you can access web services in general (no web browser control needed per se):

    - Use xmlHttp.Open "POST", strUrl, False where strUrl is the address of the service end-point

    - Use xmlHttp.Send strData where strData is some XML or JSON or pain-text data

    - Use Debug.Print xmlHttp.ResponseText to read the result as paint-text

    - Optionally parse the response into some DOM (doc-object model) like XML or JSON to work easier with it

    cheers,
    </wqw>
    p.s. xmlHttp is an instance of CreateObject("MSXML2.XMLHTTP") or MSXML2.ServerXMLHTTP or WinHttp.WinHttpRequest.5.1

  3. #3
    Member
    Join Date
    Apr 2015
    Posts
    38

    Re: Reading data from WebAPI

    There are more simple one line methods that download a file that you have to read. But I prefer loading direct to string:

    data = PostInfo("server.com", "/?action=page", "user=hello")


    Code:
    Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal lpszCallerName As String, ByVal dwAccessType As Long, ByVal lpszProxyName As String, ByVal lpszProxyBypass As String, ByVal dwFlags As Long) As Long
    Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (ByVal hInternetSession As Long, ByVal lpszServerName As String, ByVal nProxyPort As Integer, ByVal lpszUsername As String, ByVal lpszPassword As String, ByVal dwService As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
    Private Declare Function InternetReadFile Lib "wininet.dll" (ByVal hFile As Long, ByVal sBuffer As String, ByVal lNumBytesToRead As Long, lNumberOfBytesRead As Long) As Integer
    Private Declare Function HttpOpenRequest Lib "wininet.dll" Alias "HttpOpenRequestA" (ByVal hInternetSession As Long, ByVal lpszVerb As String, ByVal lpszObjectName As String, ByVal lpszVersion As String, ByVal lpszReferer As String, ByVal lpszAcceptTypes As String, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
    Private Declare Function HttpSendRequest Lib "wininet.dll" Alias "HttpSendRequestA" (ByVal hHttpRequest As Long, ByVal sHeaders As String, ByVal lHeadersLength As Long, ByVal sOptional As String, ByVal lOptionalLength As Long) As Boolean
    Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal hInternetHandle As Long) As Boolean
    Private Declare Function HttpAddRequestHeaders Lib "wininet.dll" Alias "HttpAddRequestHeadersA" (ByVal hHttpRequest As Long, ByVal sHeaders As String, ByVal lHeadersLength As Long, ByVal lModifiers As Long) As Integer
    
    Private Declare Function InternetOpenUrl Lib "wininet.dll" Alias "InternetOpenUrlA" (ByVal hInternetSession As Long, ByVal lpszUrl As String, ByVal lpszHeaders As String, ByVal dwHeadersLength As Long, ByVal dwFlags As Long, ByVal dwContext As Long) As Long
    Private Declare Function InternetSetOption Lib "wininet.dll" Alias "InternetSetOptionA" (ByVal hInternet As Long, ByVal lOption As Long, ByRef sBuffer As Any, ByVal lBufferLength As Long) As Integer
    
    
    Const INTERNET_FLAG_RELOAD = &H80000000
    Const HTTP_ADDREQ_FLAG_ADD = &H20000000
    Const HTTP_ADDREQ_FLAG_REPLACE = &H80000000
    
    Const INTERNET_OPEN_TYPE_PRECONFIG = 0
    
    
    Public Function PostInfo(Server As String, Script As String, PostData As String) As String
        Dim hInternetOpen As Long
        Dim hInternetConnect As Long
        Dim hHttpOpenRequest As Long
        Dim bRet As Boolean
        Dim bDoLoop  As Boolean
        Dim sReadBuffer As String * 4096
        Dim lNumberOfBytesRead  As Long
        Dim sBuffer As String
        Dim sHeader As String
        Dim lPostDataLen As Long
        
        Const INTERNET_SERVICE_HTTP = 3
        Const INTERNET_DEFAULT_HTTP_PORT = 80
        Const INTERNET_DEFAULT_HTTPS_PORT = 443
        Const INTERNET_FLAG_SECURE = &H800000
        Const INTERNET_OPTION_HTTP_DECODING = 65
        Const INTERNET_OPEN_TYPE_PRECONFIG = 0
        
        hInternetOpen = InternetOpen("MyBrowser", INTERNET_OPEN_TYPE_PRECONFIG, vbNullString, vbNullString, 0)
        
        If hInternetOpen <> 0 Then
            hInternetConnect = InternetConnect(hInternetOpen, Server, INTERNET_DEFAULT_HTTPS_PORT, vbNullString, "HTTP/1.0", INTERNET_SERVICE_HTTP, 0, 0)
        
            If hInternetConnect <> 0 Then
                hHttpOpenRequest = HttpOpenRequest(hInternetConnect, "POST", Script, "HTTP/1.1", vbNullString, "*/*" & vbNullString, INTERNET_FLAG_SECURE, 0)
                If hHttpOpenRequest <> 0 Then
                    sHeader = "Accept: */*" & vbLf & "Content-Type: application/x-www-form-urlencoded" ' & vbLf & "Accept-Encoding: gzip"
                    lPostDataLen = Len(PostData)
                    bRet = HttpSendRequest(hHttpOpenRequest, sHeader, Len(sHeader), PostData, lPostDataLen)
                    
                    bDoLoop = True
                    Do While bDoLoop
                        sReadBuffer = vbNullString
                        bDoLoop = InternetReadFile(hHttpOpenRequest, sReadBuffer, Len(sReadBuffer), lNumberOfBytesRead)
                        sBuffer = sBuffer & Left(sReadBuffer, lNumberOfBytesRead)
                        If Not CBool(lNumberOfBytesRead) Then bDoLoop = False
                    Loop
                    
                    PostInfo = sBuffer
                    bRet = InternetCloseHandle(hHttpOpenRequest)
                  End If
                  bRet = InternetCloseHandle(hInternetConnect)
              End If
              bRet = InternetCloseHandle(hInternetOpen)
         End If
         
    End Function

  4. #4

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Re: Reading data from WebAPI

    wqweto,

    I have used the open and send commands like you iterated above, but in VB6 I only get sent this string '<dataset/>' whilst in the browser I get the correct reply SMS with times and dates and reference numbers.

    PsuFan,
    Interesting.
    Can you please set up my data request with this API request:

    "http://www.budgetmessaging.com/smsreply.ashx?user=*****&password=*****&ref=" & Ref

    Thanks
    PK

  5. #5
    Frenzied Member wqweto's Avatar
    Join Date
    May 2011
    Posts
    1,582

    Re: Reading data from WebAPI

    @Peekay: Probably missing headers

    - Use xmlHttp.SetRequestHeader "Accept", "application/json" to set all request headers the browser is sending too

    It is *always* possible to emulate 100% of the browser request to get exact same results. Just have to capture *everything* the browser is sending that can be used by the service to "finger-print" it.

    @PsuFan: All good but will it do async requests with all those "l33t" API calls?

    cheers,
    </wqw>

  6. #6
    Member
    Join Date
    Apr 2015
    Posts
    38

    Re: Reading data from WebAPI

    @ Peekay, where's the post data? Is this just a GET request?

    data = PostInfo("budgetmessaging.com", "/smsreply.ashx?user=*****&password=*****&ref=" & Ref, "WHERE_IS_POST=DATA?")

    @ wqweto, no you cant use it for big files without yielding. I use UserControl.AsyncRead for async.

  7. #7

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Re: Reading data from WebAPI

    wqweto,

    Thanks, I got it working.

    PK

  8. #8

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Re: Reading data from WebAPI

    Deleted
    Last edited by Peekay; Jul 3rd, 2019 at 09:13 AM.

  9. #9
    Member
    Join Date
    Apr 2015
    Posts
    38

    Re: Reading data from WebAPI

    .Open requires URL, NewStrSend can't be the URL and the post data...

    .open("POST", "smsreply.ashx?user=*****&password=*****&ref=" & Ref, false)
    .send("POST DATA HERE")

    Also refer to HTTP protocol documentation, you can't just invent your own context-type: plain/text/xml
    Last edited by PsuFan; Jul 3rd, 2019 at 09:27 AM.

  10. #10

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Re: Reading data from WebAPI

    PsuFan,

    Thanks for the help on the protocol.
    When I do not specifiy any content-type I think it uses text/html which is fine.
    However, for some chunks I get a type of binary data (sorry Olaf) such as shown below. I think it may be a SMS provider problem:

    1360092127832559898278200703803611Ok cancel staff meeting2019-05-05T12:47:13+02:00201954131116
    1360093127832559898278200703803611Ok cancel staff meeting2019-05-05T12:47:13+02:00201954131116
    1360094127832559898278200703801031Invite accepted2019-05-05T12:47:34+02:00201954123547
    140728212772421046727820070380691�R�e�j�e�c�t2019-06-13T14:28:40+02:00201961314234
    1430300127832559898278200703805281�T�h�a�n�k�s� �f�o�r� �i�n�v�i�t�e2019-07-04T11:08:35+02:00201973203853
    It is working perfectly well now with NewStrSend in both places, except for the byte data.

    I am not sure what "POST DATA HERE" entails.


    PK
    Last edited by Peekay; Jul 4th, 2019 at 08:13 AM.

  11. #11
    Member
    Join Date
    Apr 2015
    Posts
    38

    Re: Reading data from WebAPI

    Yeah that is pretty weird to get binary between characters, unless it's marking some kind of color or font, but who uses color SMS. Are you sending or receiving messages? If you're sending, you probably have to put your message in the post data. When you use method POST, you usually send data after the header, which could include login info, message string, etc. Don't know if it has an official name but everyone will know what post data is if you call it that. Any documentation? It's possible you can request another content type that won't have strange binary.

    Edit: or just take out every other character or convert to ASCII and only keep printable letters.

  12. #12

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Re: Reading data from WebAPI

    PsuFan,

    I send SMS's and allow people to reply. What I have published is the replies I received in IE or in html (with tags) in my program from SMS's I have sent.
    I think the binary data is a SMS supplier/provided error or change in their API. I think they have found out how I loved bytes!

    My NewStrSend to interrogate the SMS is:

    Code:
    https://www.????????.com/smsreply.ashx?user=Peekay&password=????????&startdate=19/03/2019&enddate=10/07/2019
    I will see if they are consistent with binary now, and then I can implement a routine to extract the real words.

    PK
    Last edited by Peekay; Jul 4th, 2019 at 09:23 AM.

  13. #13
    Member
    Join Date
    Apr 2015
    Posts
    38

    Re: Reading data from WebAPI

    Try: Content-Type: text/html; charset=utf-8

    https://www.w3.org/International/art...-charset/index

    Edit: Make sure you use "content-type", I thought I saw your code with typo "context-type"
    Last edited by PsuFan; Jul 4th, 2019 at 10:05 AM.

  14. #14
    Frenzied Member wqweto's Avatar
    Join Date
    May 2011
    Posts
    1,582

    Re: Reading data from WebAPI

    Quote Originally Posted by Peekay View Post
    When I do not specifiy any content-type I think it uses text/html which is fine.
    There are two types of headers here: headers on request you set with xmlHttp.SetRequestHeader and headers you get in response from the service e.g.
    Code:
    HTTP/1.1 200 OK
    Date: Thu, 04 Jul 2019 15:54:09 GMT
    Server: Apache
    Upgrade: h2,h2c
    Connection: Upgrade
    Content-Type: text/html
    The headers you specify are the ones on the request. When you want the service to return body content as html you set "Accept" request header to "text/html" not the "Content-Type" request header.

    Once you set "Accept" request header on your request you get a result that has "Content-Type" response header with "text/html" and the body of the response is in html.

    Now that the connection between "Accept" request header and "Content-Type" response header is clear let's consider a POST request. This is a request that has a body in itself. So only on such requests you can set "Content-Type" *request* header to "text/html" to specify that the body of the *request* is in html markup.

    For GET requests it just makes no sense to set "Content-Type" request header as you are not sending anything in the body.

    For both GET and POST requests in makes a lot of sense to set "Accept" request header to signal the web service what format you want the body of the response in. This is especially useful when you start wondering why you get binary when all you wanted was html or xml or json or plain text. . .

    cheers,
    </wqw>

  15. #15

    Thread Starter
    Hyperactive Member Peekay's Avatar
    Join Date
    Sep 2006
    Location
    Witbank, South Africa
    Posts
    373

    Re: Reading data from WebAPI

    wqweto,

    Thanks.

    Neither content-type nor Accept makes any difference in the text I get back.

    PK

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width