Dropnet code in vb not working - vb.net

I'm trying to use dropnet for file upload on Dropbox in vb, but does not work. Results the following error: Received Response [Unauthorized]: Expected to see [OK]. The HTTP response was [{"error": "Request token not found."}]
Here is my code:
_client = New DropNetClient("xxxxxxx", "xxxxxxx")
Dim login As UserLogin = _client.GetToken()
_client.UserLogin = login
Dim url = _client.BuildAuthorizeUrl()
Process.Start(url)
Dim tokenAcess = _client.GetAccessToken()
_client.GetAccessTokenAsync(Function(accessToken)
_client = New DropNetClient("xxxxxx", "xxxxxx", tokenAcess)
End Function, Function([error]) MessageBox.Show([error].Message)
End Function)
Try
Dim rawData As Byte() = File.ReadAllBytes("c:\image.png")
Dim result As MetaData = _client.UploadFile("/", "image.png", rawData)
MessageBox.Show("Successfully uploaded to Dropbox.", "Uploaded to Dropbox")
Catch dropboxEx As Exception
MessageBox.Show("Error: " + dropboxEx.Message)
End Try

Related

Oauth 2.0 SMTP send email with EASendEmail VB

Following the changes, I try to connect and send mails via EAGetMail/EASendMail.
The connection is good, I have good access to the token and also to my mailbox.
However, when I want to send an email via "smtp.office365.com" I get an error: 535 5.7.3 Authentication unsuccessful.
I do not understand where the error can come from, I take the same token as when connecting to the mailbox.
Below is just the code to send emails, I have a token and it works perfectly to connect to my email
If someone has a project that works with smtp and Oauth 2.0 (without using a browser)...
Module Module1
Sub Main(ByVal args As String())
Try
RetrieveEmail()
Catch ep As Exception
Console.WriteLine(ep.ToString())
End Try
Console.ReadKey()
End Sub
Function _generateFileName(ByVal sequence As Integer) As String
Dim currentDateTime As DateTime = DateTime.Now
Return String.Format("{0}-{1:000}-{2:000}.eml",
currentDateTime.ToString("yyyyMMddHHmmss", New CultureInfo("en-US")),
currentDateTime.Millisecond,
sequence)
End Function
Function _postString(ByVal uri As String, ByVal requestData As String) As String
Dim httpRequest As HttpWebRequest = TryCast(WebRequest.Create(uri), HttpWebRequest)
httpRequest.Method = "POST"
httpRequest.ContentType = "application/x-www-form-urlencoded"
Using requestStream As Stream = httpRequest.GetRequestStream()
Dim requestBuffer As Byte() = Encoding.UTF8.GetBytes(requestData)
requestStream.Write(requestBuffer, 0, requestBuffer.Length)
requestStream.Close()
End Using
Try
Dim httpResponse As HttpWebResponse = TryCast(httpRequest.GetResponse(), HttpWebResponse)
Using reader As New StreamReader(httpResponse.GetResponseStream())
Dim responseText = reader.ReadToEnd()
Return responseText
End Using
Catch ex As WebException
If ex.Status = WebExceptionStatus.ProtocolError Then
Dim response = TryCast(ex.Response, HttpWebResponse)
If response IsNot Nothing Then
Console.WriteLine("HTTP: " & response.StatusCode)
' reads response body
Using reader As StreamReader = New StreamReader(response.GetResponseStream())
Dim responseText As String = reader.ReadToEnd()
Console.WriteLine(responseText)
End Using
End If
End If
Throw ex
End Try
End Function
Public Sub RetrieveEmail()
Try
Dim client_id As String = "XXXXXXXXXXXXXXXXXXXX"
Dim client_secret As String = "XXXXXXXXXXXXXXXXXXXXXXXXX"
' If your application is not created by Office365 administrator,
' please use Office365 directory tenant id, you should ask Offic365 administrator to send it to you.
' Office365 administrator can query tenant id in https://portal.azure.com/ - Azure Active Directory.
Dim tenant As String = "XXXXXXXXXXXXXXXXXX"
Dim requestData As String = String.Format("client_id={0}&client_secret={1}&scope=https://outlook.office365.com/.default&grant_type=client_credentials",
client_id, client_secret)
Dim tokenUri As String = String.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", tenant)
Dim responseText As String = _postString(tokenUri, requestData)
Dim parser As EASendMail.OAuthResponseParser = New EASendMail.OAuthResponseParser()
parser.Load(responseText)
Dim officeUser As String = "tma#XXXX.fr"
Dim oServerSend As SmtpServer = New SmtpServer("smtp.office365.com")
oServerSend.ConnectType = SmtpConnectType.ConnectSSLAuto
oServerSend.Port = 587
oServerSend.AuthType = SmtpAuthType.XOAUTH2
oServerSend.User = officeUser
oServerSend.Password = parser.AccessToken
Dim oMailSend As SmtpMail = New SmtpMail("TryIt")
oMailSend.From = "tma#XXX.fr"
' Please change recipient address to yours for test
oMailSend.[To] = "XXXXXXXXXXX"
oMailSend.Subject = "test email from Hotmail account with OAUTH 2"
oMailSend.TextBody = "this is a test email sent from VB.NET project with Hotmail."
Console.WriteLine("start to send email using OAUTH 2.0 ...")
Dim oSmtp As SmtpClient = New SmtpClient()
oSmtp.SendMail(oServerSend, oMailSend)
' Quit and expunge emails marked as deleted from server.
Console.WriteLine("Completed!")
Catch ep As Exception
Console.WriteLine(ep.ToString())
End Try
End Sub
End Module

Reading Rest API Call Response Status Code in VB.NET

I am a beginner in the API ecosystem. I am using VB.NET to call API. Code used for the same given below:
Try
Dim s As HttpWebRequest
Dim enc As UTF8Encoding
Dim postdata As String
Dim postdatabytes As Byte()
Dim jo As New JObject
jo.Add("apiid", objProp.Text7)
jo.Add("apiData", objProp.Text8)
postdata = jo.ToString()
s = HttpWebRequest.Create(objProp.Text6)
enc = New System.Text.UTF8Encoding()
postdatabytes = enc.GetBytes(postdata)
s.Method = "POST"
s.ContentType = "application/json"
s.ContentLength = postdatabytes.Length
s.Headers.Add("user-name", "MjRKQGU1NypQJkxZYVpCdzJZXnpKVENmIXFGQyN6XkI=")
s.Headers.Add("api-key", "UjMhTDZiUlE1MkhMWmM2RkclJXJhWUJTTWZDeHVEeDQ=")
Using stream = s.GetRequestStream()
stream.Write(postdatabytes, 0, postdatabytes.Length)
End Using
Dim result = s.GetResponse()
Dim responsedata As Stream = result.GetResponseStream
Dim responsereader As StreamReader = New StreamReader(responsedata)
Dim xResponse = responsereader.ReadToEnd
Try
Dim opData = JObject.Parse(xResponse)("apiData").ToString
objProp = JsonConvert.DeserializeObject(Of default_prop)(opData)
Catch ex As Exception
End Try
Catch myerror As OracleException
'Status
objProp.Text5 = "500"
'Failure Response Message
objProp.Text11 = "Internal Server Error..."
db_close()
End Try
My issue is that I could not find the proper syntax to retrieve API Response Status Code from the response. Request your guidance
With some small changes on your code you can do the trick as follow:
'....... other code here
Using stream = s.GetRequestStream()
stream.Write(postdatabytes, 0, postdatabytes.Length)
End Using
Dim result As HttpWebResponse = CType(s.GetResponse(), HttpWebResponse)
Console.WriteLine(result.StatusCode)

Check if URL has valid page

I want to check if URL has valid page (not 404, just 200).
Code I've tried:
Dim request As HttpWebRequest = DirectCast(WebRequest.Create(myurl), HttpWebRequest)
request.KeepAlive = True
Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
If response.StatusCode = HttpStatusCode.OK Then
MsgBox("OK")
End If
Yet every URL that I enter leaves OK response, even if I enter http://mywebsite.com/blahblah.
It's not same on all websites (works fine with example.com), but it doesn't work on my website. Why?
In my browser I see 404 page, but code says it's OK.
Edit: Just to mention that my website has Cloudflare on.
Try this out and see if it work's for you... As mentioned above in my comment's:
A 404 just means the page isn't found on the server, status will return ok even if a page isn't found and the server was reached and responded
Public Class WebPage
Public Property PageSource As String = String.Empty
Public Property Status As HttpStatusCode = HttpStatusCode.NotFound
Public Property WebError As String = String.Empty
End Class
Public Shared Function GetWebPage(ByVal Website As String) As WebPage
Dim web As New WebPage() With {.Status = HttpStatusCode.OK}
Try
Using source As New System.Net.WebClient()
web.PageSource = source.DownloadString(Website)
End Using
Return web
Catch exweb As WebException
If exweb.Status = WebExceptionStatus.ProtocolError AndAlso exweb.Message.Contains("404") Then
web.Status = HttpStatusCode.NotFound
Else
web.Status = HttpStatusCode.BadRequest
End If
web.WebError = exweb.Message
Catch ex As Exception
web.Status = HttpStatusCode.NotFound
web.WebError = ex.Message
End Try
Return web
End Function
Usage Example
Dim webObj As WebPage = GetWebPage("THESITE")
If Not String.IsNullOrEmpty(webObj.WebError) Then
MessageBox.Show(webObj.WebError)
ElseIf webObj.Status = HttpStatusCode.OK Then
MessageBox.Show("OK")
End If
This will do what you want.
Function URLExists(url As String) As Boolean
Dim Request As Object
Dim ff As Integer
Dim rc As Variant
On Error GoTo EndNow
Set Request = CreateObject("WinHttp.WinHttpRequest.5.1")
With Request
.Open "GET", url, False
.send
rc = .StatusText
End With
Set Request = Nothing
If rc = "OK" Then URLExists = True
Exit Function
EndNow:
End Function

Acessing Google Calendar API from Windows Service

I am writing a windows service application in Visual Studio (VB) that polls a users google calendar for any events that are happening within the next 5 minutes.
Ideally, I'd like my service to generate the credentials, but I don't think a windows service can pop up a browser page to authenticate someone. Currently I am generating the credentials in a specific location from a console app that can pop up a browser, and having the service look for credentials in that location. I'd like to get rid of the console app altogether, but if it's necessary I'll just run it in the batch file that installs the service.
The big issue I'm having is generating the credentials file (secondary concern), and more importantly refreshing it so it doesn't expire after an hour (primary concern).
Here is my windows service code (this works perfectly fine for the hour after I run my console app and allow access to my calendar):
Dim Scopes As String() = {CalendarService.Scope.CalendarReadonly}
Dim ApplicationName As String = "Google Calendar API .NET Quickstart"
Private Sub writeUpdateTimerEvent(source As Object, e As ElapsedEventArgs)
Dim credential As UserCredential
Try
Using stream = New FileStream("FILE PATH TO client_secret.json", FileMode.Open, FileAccess.Read)
Dim credPath As String = "FILE PATH TO WHERE MY CONSOLE APP IS STORING THE CREDENTIALS FILE"
credPath = Path.Combine(credPath, ".credentials/calendar-dotnet-quickstart.json")
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, Scopes, "user", CancellationToken.None, New FileDataStore(credPath, True)).Result
If credential Is Nothing Then
credential.RefreshTokenAsync(CancellationToken.None)
End If
End Using
' Create Google Calendar API service.
Dim service = New CalendarService(New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = ApplicationName
})
' Define parameters of request.
Dim request As EventsResource.ListRequest = service.Events.List("primary")
request.TimeMin = DateTime.Now
request.TimeMax = DateTime.Now.AddMinutes(5)
request.ShowDeleted = False
request.SingleEvents = True
request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime
' List events.
Dim eventsString As String = ""
Dim events As Events = request.Execute()
If events.Items IsNot Nothing AndAlso events.Items.Count > 0 Then
'This is where I do my operations on events occuring in the next 5 minutes
EventLog1.WriteEntry("Event occuring within 5 minutes")
Else
EventLog1.WriteEntry("No event occuring within 5 minutes")
End If
Catch ex As Exception
EventLog1.WriteEntry("error grabbing events." & Environment.NewLine & ex.message)
End Try
End Sub
Here is my console app code (pretty much the same as above):
Module Module1
Dim Scopes As String() = {CalendarService.Scope.CalendarReadonly}
Dim ApplicationName As String = "Google Calendar API .NET Quickstart"
Sub Main()
Dim credential As UserCredential
Using stream = New FileStream("client_secret.json", FileMode.Open, FileAccess.Read)
Dim credPath As String = "SAME FILE PATH AS IN MY SERVICE"
credPath = Path.Combine(credPath, ".credentials/calendar-dotnet-quickstart.json")
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, Scopes, "user", CancellationToken.None, New FileDataStore(credPath, True)).Result
Console.WriteLine(Convert.ToString("Credential file saved to: ") & credPath)
End Using
' Create Google Calendar API service.
Dim service = New CalendarService(New BaseClientService.Initializer() With {
.HttpClientInitializer = credential,
.ApplicationName = ApplicationName
})
' Define parameters of request.
Dim request As EventsResource.ListRequest = service.Events.List("primary")
request.TimeMin = DateTime.Now
request.ShowDeleted = False
request.SingleEvents = True
request.MaxResults = 10
request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime
' List events.
Dim events As Events = request.Execute()
Console.WriteLine("Upcoming events:")
If events.Items IsNot Nothing AndAlso events.Items.Count > 0 Then
For Each eventItem As Object In events.Items
Dim [when] As String = eventItem.Start.DateTime.ToString()
If [String].IsNullOrEmpty([when]) Then
[when] = eventItem.Start.[Date]
End If
Console.WriteLine("{0} ({1})", eventItem.Summary, [when])
Next
Console.WriteLine("You may now close this window.")
System.Environment.Exit(0)
Else
Console.WriteLine("No upcoming events found.")
End If
Console.Read()
End Sub
End Module
Got it working now, using a service account instead of a user account. No need for dealing with generating credentials or refreshing the token.
Dim serviceAccountEmail As [String] = ConfigurationManager.AppSettings("ServiceAcct")
Dim certificate = New X509Certificate2("key.p12", "notasecret", X509KeyStorageFlags.Exportable)
Dim credential1 As New ServiceAccountCredential(New ServiceAccountCredential.Initializer(serviceAccountEmail) With {
.Scopes = Scopes
}.FromCertificate(certificate))
Dim service = New CalendarService(New BaseClientService.Initializer() With {
.HttpClientInitializer = credential1,
.ApplicationName = ApplicationName
})

Uploading to dropbox using dropnet

I started to develop a project to create some dll to comunicate with Dropbox (Desktop).
After searching a while in google I found dropnet and started to use it.
I have two problems with this library on accessing the token and when I'm doing an upload.
Code:
Dim client As DropNetClient
If Not dropboxLoggedIn Then
client = New DropNetClient("XXXXXXXXXXXX", "YYYYYYYYYY")
client.UseSandbox = True
Dim token As UserLogin
Dim url As String = ""
Try
token = client.GetToken()
url = client.BuildAuthorizeUrl()
Dim aw As New AuthorizationWindow(url)
aw.ShowDialog()
If (Not dropboxLoggedIn) Then
client.GetAccessToken()
dropboxAsecret = client.UserLogin.Secret
dropboxAtoken = client.UserLogin.Token
Else
client.UserLogin.Token = dropboxAtoken
client.UserLogin.Secret = dropboxAsecret
End If
dropboxLoggedIn = True
Dim rawData As Byte() = File.ReadAllBytes("c:\users\mysuser\Pictures\anypic.JPG")
Dim result As MetaData = client.UploadFile("/", "anypic.JPG", rawData)
Catch ex As DropNet.Exceptions.DropboxException
MessageBox.Show(ex.Message)
End Try
Else
Try
client = New DropNetClient("XXXXXXXXXXXX", "YYYYYYYYYY", dropboxAtoken, dropboxAsecret)
client.UseSandbox = True
Dim rawData As Byte() = File.ReadAllBytes("c:\users\mysuser\Pictures\anypic.JPG")
Dim result As MetaData = client.UploadFile("/", "anypic.JPG", rawData)
Catch ex As DropNet.Exceptions.DropboxException
MessageBox.Show(ex.Message)
End Try
End If
So, after I do an upload nothing goes to dropbox folder. The result has nothing in properties. Is strange because no error is given.
Also, GetAccessToken not always work.
Can anyone help please?