HTTPS POST Request VBA - vba

I want to create POST request for my ServiceNow Instance API. But I don't know how to use library VBA-Web.
I want to create a row in my table in ServiceNow.
My code:
Sub ToRequestSN()
Dim Body As New Dictionary
Body.Add "u_any_string", "test"
Body.Add "u_any_numeral", 12
Dim Client As New WebClient
Dim Response As WebResponse
Set Response = Client.PostJson("https://instance.sn.ru/api/now/table/u_table_test", Body)
Debug.Print Response.Content
End Sub
But I got this message -
{"error":{"message":"User Not Authenticated","detail":"Required to provide Auth information"},"status":"failure"}
How I can log in using VBA-Web?

I found solution. I did send selected mail (email of sender) and pass to Service Now.
Sub RequestToSN()
Dim Client As New WebClient
Dim Response As WebResponse
Dim Auth As New HttpBasicAuthenticator
Dim Body As New Dictionary
Dim myOlSel As Outlook.Selection
Dim oMail As Outlook.MailItem
Dim myOlExp As Outlook.Explorer
MsgTxt = ""
Set myOlExp = Application.ActiveExplorer
Set myOlSel = myOlExp.Selection
For x = 1 To myOlSel.Count
If myOlSel.Item(x).Class = OlObjectClass.olMail Then
Set oMail = myOlSel.Item(x)
MsgTxt = MsgTxt & oMail.SenderName
''Date = Date & oMail.CreationTime
End If
Next x
Body.Add "u_any_string", MsgTxt
Body.Add "u_any_numeral", 123
Auth.Setup _
Username:="user", _
Password:="user"
Set Client.Authenticator = Auth
Set Response = Client.PostJson("https://service.sn.com/api/now/table/u_table_test", Body)
End Sub

Related

VB.net Crystal report export to html and send as html mail body using outlook

I am trying to send contents of a crystal report as email body using outlook application.
Here is my code in VB.net
Imports outlook = Microsoft.Office.Interop.Outlook
Dim a As String = something.ConnectionString
Dim cryRpt As ReportDocument
Dim username As String = a.Split("=")(3).Split(";")(0) 'get username
Dim password As String = a.Split("=")(4).Split(";")(0) 'get password
cryRpt = New ReportDocument()
Dim Path As String = Application.StartupPath
Dim svPath As String = Application.StartupPath & "\PDF"
If Not Directory.Exists(svPath) Then
Directory.CreateDirectory(svPath)
End If
cryRpt.Load(Path & "\Reports\dr.rpt")
CrystalReportViewer1.ReportSource = cryRpt
cryRpt.SetDatabaseLogon(username, password)
CrystalReportViewer1.Refresh()
Dim myExportOptions As ExportOptions
myExportOptions = cryRpt.ExportOptions
myExportOptions.ExportDestinationType = ExportDestinationType.DiskFile
myExportOptions.ExportFormatType = ExportFormatType.HTML40 'i tried HTML32 also
Dim html40FormatOptions As HTMLFormatOptions = New HTMLFormatOptions()
html40FormatOptions.HTMLBaseFolderName = svPath
html40FormatOptions.HTMLFileName = "dr.htm"
html40FormatOptions.HTMLEnableSeparatedPages = False
html40FormatOptions.HTMLHasPageNavigator = False
html40FormatOptions.UsePageRange = False
myExportOptions.FormatOptions = html40FormatOptions
cryRpt.Export()
Try
Dim oApp As outlook.Application
oApp = New outlook.Application
Dim oMsg As outlook.MailItem
oMsg = oApp.CreateItem(outlook.OlItemType.olMailItem)
oMsg.Subject = txtSubject.Text
oMsg.BodyFormat = outlook.OlBodyFormat.olFormatHTML
oMsg.HTMLBody = ""
oMsg.HTMLBody = getFileAsString(svPath & "\PoPrt\QuotPrt.html")
oMsg.To = txtEmailId.Text
Dim ccArray As New List(Of String)({txtCC1.Text, txtCC2.Text, txtCC3.Text})
Dim cclis As String = String.Join(",", ccArray.Where(Function(ss) Not String.IsNullOrEmpty(ss)))
oMsg.CC = cclis
oMsg.Display(True)
Catch ex As Exception
MsgBox("Something went wrong", vbExclamation)
End Try
SvFormPanel3.Visible = False
the function
Private Function getFileAsString(ByVal file As String) As String
Dim reader As System.IO.FileStream
Try
reader = New System.IO.FileStream(file, IO.FileMode.Open)
Catch e As Exception
MsgBox("Something went wrong. " + e.Message, vbInformation)
End Try
Dim resultString As String = ""
Dim b(1024) As Byte
Dim temp As UTF8Encoding = New UTF8Encoding(True)
Do While reader.Read(b, 0, b.Length) > 0
resultString = resultString & temp.GetString(b)
Array.Clear(b, 0, b.Length)
Loop
reader.Close()
Return resultString
End Function
The report will get exported to the specified location as html. And when we manually open that html file it displays perfectly with border lines and all.
But when its getting added as html body of outlook application, the formatting will be gone, and looks scattered.
can anyone help
Did you try this?
Open outlook, go to, File>Options>Mail
go to section MessageFormat and untick "Reduce message size by removing format..."
I have solved the issue by exporting it into PDF and then convert to Image and embed in email body.

How to fix "Windows Security Warning" popup issue while extracting data from a website

I have an application which extracts data from a website and loads it into a server table. When I run the application first time in a day it is showing a popup and asking for Yes/No input. How to overcome this popup as I wanted to auto schedule the application and run it without manual intervention.
Public Sub Resolve_Date()
Dim XMLReq As MSXML2.XMLHTTP60 = New MSXML2.XMLHTTP60
Dim HTMLDoc = New mshtml.HTMLDocument
'Dim htmlbody As HtmlDocument.body = New HTML
Dim ObjXL As New Excel.Application
Dim Table As mshtml.IHTMLElement
Dim Tr As mshtml.IHTMLElement
Dim Tc As mshtml.IHTMLElement
Dim Trs As mshtml.IHTMLElementCollection
Dim URL As String
Dim x As Integer, y As Integer
URL = "https://tt.wiki.com/search?category=&assigned_group=3p-asin"
XMLReq.open("GET", URL, False) '--pop up is appearing here
XMLReq.send()
If XMLReq.status <> 200 Then
msgBox("Error" & vbNewLine & XMLReq.status & " - " & XMLReq.statusText)
Exit Sub
End If
Dim HTMLDoc1 As mshtml.IHTMLDocument = HTMLDoc
HTMLDoc1.write("<html><body>test</body></html>")
HTMLDoc1.close()
HTMLDoc = HTMLDoc1
HTMLDoc.body.innerHTML = XMLReq.responseText
''msgBox(HTMLDoc.body.innerHTML)
'MsgBox(HTMLDoc.body.innerHTML)
XMLReq = Nothing
Table = HTMLDoc.getElementById("search_results")
Trs = Table.getElementsByTagName("tr")
For Each Tr In Trs
--code to insert data into Table
Next Tr
I could do more if I knew what you were doing with the table... probably avoid the obsolte MsHtml API (HTMLDocument and friends) entirely. But with just the context we have, this is a rewrite that uses at least some more modern techniques and considerably simplifies the code.
Public Sub Resolve_Date()
Dim URL As String = "https://tt.wiki.com/search?category=&assigned_group=3p-asin"
Dim results As String = ""
Try
Using wc As New WebClient()
results = wc.DownloadString(URL)
End Using
Catch Ex As Exception
MsgBox($"Error{vbNewLine}{Ex.Message}")
Exit Sub
End Try
Dim HTMLDoc As New mshtml.HTMLDocument()
HTMLDoc.Write(results);
Dim Table As mshtml.IHTMLElement = HTMLDoc.getElementById("search_results")
Dim Trs As mshtml.IHTMLElementCollection = Table.getElementsByTagName("tr")
Dim ObjXL As New Excel.Application
Dim x As Integer, y As Integer
For Each Tr As mshtml.IHTMLElement In Trs
' code to insert data into Table
Next Tr
End Sub

i need to make status message on excel after calling the api

I need to make status message on excel after calling the api . status message in xml format so how to parse the data accurately.
Below given codes are using to get API info
Sub Test()
Dim xmlHTTP As Object
Set xmlHTTP = CreateObject("MSXML2.ServerXMLHTTP.6.0")
myURL = "http://xxxxxxxxxxxxx:15555/gateway/StatusTracking/1.0/shipment/tracking?housebill=cvvvv"
xmlHTTP.Open "GET", myURL, False
xmlHTTP.SetRequestHeader "APIKey", "xxxx-xxx-xxxxx-xxxx-xxxx"
xmlHTTP.SetRequestHeader "Accept", "application/json"
xmlHTTP.Send
Dim strReap As String
strReap = hReq.ResponseText
Dim xmlDoc As New MSXML2.DOMDocument
If Not xmlDoc.LoadXML(strReap) Then
MsgBox "Load error"
End If
Dim xnodelist As MSXML2.IXMLDOMNodeList
Set xnodelist = xmlDoc.getElementsByTagName("ShipmentTracking")
Dim xnode As MSXML2.IXMLDOMNode Set xnode = xnodelist.Item(0)
Dim obAtt1 As MSXML2.IXMLDOMAttribute
Dim obAtt2 As MSXML2.IXMLDOMAttribute
Dim xChild As MSXML2.IXMLDOMNode
Dim intRow As Integer
intRow = 2
Dim strCol1 As String
strCol1 = "A"
Dim strCol2 As String
strCol1 = "B"
Dim Shipment As String
For Each xChild In xnode.ChildNodes
Set obAtt1 = xChild.Attributes.getNamedItem("Shipment")
ws.Cells(intRow, 2) = obAtt1
intRow = intRow + 1
Next xChild
Set hReq = Nothing
Set xmlDoc = Nothing
End Sub
normal xml status message format given below
<Shipment tracking>
<type/>
<object/>
<properties/>
<Shipment>
<Origin/>
<type/>
<properties/>
<LocationCode/>
<CountryCode/>
</Shipment>
</Shipment tracking>
I am newbie in vba programming and i tried with this code but not working fine. I just want output,from shipment(xmltagname) to end in excel sheet. Please help me on this
You have written code Attributes.getNamedItem when in fact you have no attributes. Also to query for elements I'd prefer selectNodes and selectSingleNode instead of getElementsByTagName.
So try
xChild.selectSingleNode("Shipment")
and change the declaration for the receiving variable from IXMLDOMAttribute to IXMLDOMElement

Access another Inbox which is not mine Outlook Addin

How would I get a folder that I, as a user, have been added to.
I need to do an addin for work, how would I access an inbox which isn't mine?
So the top one is my personal inbox, I need to access the inbox within 'MIS'.
Private Sub ThisApplication_NewMail() Handles Application.NewMail
Dim myNameSpace = Application.GetNamespace("MAPI")
Dim oParentFolder = myNameSpace.Folders("MIS")
Dim mis = oParentFolder.Folders.Item("Inbox")
Dim moveMail As Outlook.MailItem = Nothing
Dim mItems As Outlook.Items = mis.Items
mItems.Restrict("[Read] = true")
Dim destFolder As Outlook.MAPIFolder = mis.Folders("Test")
Dim SubjName = "TestingAddin123"
Dim sender As String = "michael"
Dim FName As String = "[Some recurring subject]"
Dim tStamp As String = Format(DateTime.Now, "ddMMyy").ToString()
Try
For Each eMail As Object In mItems
moveMail = TryCast(eMail, Outlook.MailItem)
If Not moveMail Is Nothing Then
If InStr(moveMail.SenderEmailAddress, sender) Then
If InStr(moveMail.Subject, SubjName) > 0 Then
Dim rn As New Random
Dim n = rn.Next(1, 9999)
'n()
moveMail.SaveAs("W:\NS\" & FName & "_" & tStamp & n.ToString() + ".html", Outlook.OlSaveAsType.olHTML)
moveMail.Move(destFolder)
End If
End If
End If
Next eMail
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
So I'm using the above code so far but I don't seem to be able to find the MIS Inbox.
How would I achieve this?
Try to use the Namespace.CreateRecipient / Namespace.GetSharedDefaultFolder methods.

Excel vba and XMLHTTP with ADFS - not returning xml

I have an Excel macro that has been in use for years which posts to a database using an XMLHttp call. The code is digitally signed.
Recently the site which is being posted to has enabled ADFS. Now instead of getting xml back I get the contents of the ADFS authentication form. There is no prompt for credentials in it since authentication already occurred. It I open the url from a web browser it goes through as expected with existing credentials used and the page loaded.
I tried setting the trusted setting for the url and allowed external content but that didn't matter.
Have I missed something?
The html I get back looks like...
<html><head><title>Working...</title></head><body><form method="POST" name="hiddenform" action="https://isvcci.jttest.com:444/"><input type="hidden" name="wa" value="wsignin1.0" />
...
<noscript><p>Script is disabled. Click Submit to continue.</p><input type="submit" value="Submit" /></noscript></form><script language="javascript">window.setTimeout('document.forms[0].submit()', 0);</script></body></html>
This is the vba:
Sub PostXml(strType As String, strAddress As String, objXml As MSXML2.DOMDocument60)
Dim objHttp As MSXML2.XMLHTTP60, objXmlResponse As MSXML2.DOMDocument60, objNode As MSXML2.IXMLDOMNode
Dim strText As String
Set objHttp = New MSXML2.XMLHTTP60
objHttp.Open "POST", strAddress, False
objHttp.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
objHttp.send objXml
Set objXmlResponse = objHttp.responseXML
rem responseXML is always empty but responseText has the adfs page <------
Set objNode = objXmlResponse.SelectSingleNode("root/errorMessage")
If objNode Is Nothing Then
MsgBox "Error: Unable to retrieve expected response from the server." + vbCrLf + "The opportunity may not have been updated."
Else
... code for success goes here
End If
End Sub
Thanks for any assistance!
XMLHttp wouldn't work over adfs so I used an InternetExplorer control instead. It's a hassle to get the resulting xml back though using a page which sets a form value would probably be simpler. The resulting xml gets returned formatted like what you see in a web browser. I use a simple regex to remove dashes outside of tags.
I'm not that experienced with vba and excel so there might be better ways to code this but it works.
Sub PostXml(strType As String, strAddress As String, objXml As MSXML2.DOMDocument60)
Dim objHttp As MSXML2.XMLHTTP60, objXmlResponse As MSXML2.DOMDocument60, objNode As MSXML2.IXMLDOMNode
Dim objDoc As MSHTML.HTMLDocument
Dim strText As String, strHeaders As String, strPostData As String
Dim MyBrowser As InternetExplorer
Dim PostData() As Byte
Dim expr As VBScript_RegExp_55.RegExp
Dim colMatch As VBScript_RegExp_55.MatchCollection
Dim vbsMatch As VBScript_RegExp_55.Match
Dim sMatchString As String
' XMLHttp doesn't work with ADFS so browser was used
Set MyBrowser = New InternetExplorer
strHeaders = "Content-Type: text/xml; charset=utf-8" & vbCrLf
PostData = StrConv(objXml.XML, vbFromUnicode)
MyBrowser.Visible = False
MyBrowser.navigate strAddress, 0, "", PostData, strHeaders
Do While MyBrowser.Busy Or MyBrowser.readyState <> 4
Loop
Set objDoc = MyBrowser.Document
strText = objDoc.body.innerText
Set expr = New VBScript_RegExp_55.RegExp
expr.Pattern = "(?:\s| |^)(-)(?=\s|\r|\n|$)"
expr.IgnoreCase = True
expr.MultiLine = True
expr.Global = True
strText = expr.Replace(strText, "")
Set objXmlResponse = New MSXML2.DOMDocument60
Set objNode = Nothing
If objXmlResponse.LoadXML(strText) Then
Set objNode = objXmlResponse.SelectSingleNode("root/errorMessage")
'Else
'MsgBox "Invalid XML " & objXmlResponse.parseError.ErrorCode & "," & objXmlResponse.parseError.reason
End If
MyBrowser.Quit
Set MyBrowser = Nothing
Rem MsgBox "response =" & vbCrLf & objXmlResponse.XML
If objNode Is Nothing Then
MsgBox "Error: Unable to retrieve expected response from the server."
Else
strText = objNode.Text
If strText > "" Then
MsgBox strText, vbOKOnly, "Error"
Else
' it worked, read the xml here
End If
End If
End Sub