Creating a Microsoft Teams Meeting using VB.NET and Microsoft Graph API - vb.net

I have created a login authentication using the Microsoft Graph API which means after I sign in, as a result, I have the access token of the current user signed-in. My next step is to create a Microsoft Teams Meeting on behalf of the current user signed-in.
I have tried to follow the Microsoft documentation Application POST onlinemeetings, where It shows the required steps to achieve this scenario.
Unfortunately, they didn't provide an example of how it can be achieved in VB.Net (which is not a big deal because I have converted the code to VB).
Currently, I am stuck on sending a POST request to generate this meeting based on the hard coded values when the user clicks on the button.
Please have a look at the code below:
Imports System.IO
Imports System.Net
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Threading.Tasks
Imports Microsoft.Graph
Imports Microsoft.IdentityModel.Clients.ActiveDirectory
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class _Default
Inherits Page
Private Shared httpClient As HttpClient = New HttpClient()
Private Shared context As AuthenticationContext = Nothing
Private Shared credential As ClientCredential = Nothing
Private Shared graphClient As GraphServiceClient
Private Shared authprovider As IAuthenticationProvider
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim code = HttpContext.Current.Request.QueryString("Code")
If Not Page.IsPostBack Then
If code <> "" Then
Dim url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
Dim myParameters = "grant_type=authorization_code&code=" & code & "&redirect_uri=https://localhost:4312/&client_id=CLIENTID&client_secret=CLIENTSECRET"
Dim wb = New WebClient
wb.Headers(HttpRequestHeader.ContentType) = "application/x-www-form-urlencoded"
Dim response = wb.UploadString(url, "POST", myParameters)
responseToken.Text = response
Success.Text = "O365 login successful. Below is the response token"
Dim SurroundingClass = JsonConvert.DeserializeObject(Of SurroundingClass)(response)
Dim rss As JObject = JObject.Parse(response)
Dim token = rss.SelectToken("access_token")
Dim res = GetUsers(token)
End If
End If
End Sub
Private Shared Async Function GetUsers(ByVal result As String) As Task(Of String)
Try
Dim users As String = Nothing
Dim querystring As String = "api-version=1.6"
Dim uri = "https://graph.microsoft.com/v1.0/me"
httpClient.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", result)
httpClient.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
Dim User = GetMeAsync().Result
Console.WriteLine($"Welcome {User.DisplayName}!\n")
Dim getResult = Await httpClient.GetAsync(uri)
If getResult.Content IsNot Nothing Then
users = Await getResult.Content.ReadAsStringAsync()
End If
Return users
Catch ex As Exception
Throw ex
End Try
End Function
Protected Sub tes_Click(sender As Object, e As EventArgs)
Try
'Dim fr As System.Net.HttpWebRequest
Dim client_id = ""// App Client ID'
Dim uri = "https://localhost:4312/"
Dim targetURI As String = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" & client_id &
"&redirect_uri=" & uri & "&response_type=code&scope=openid+Mail.Read"
Response.Redirect(targetURI)
Catch ex As System.Net.WebException
'Error in accessing the resource, handle it
End Try
End Sub
Public Shared Async Function CreateMeeting() As Task(Of OnlineMeeting)
Try
graphClient = New GraphServiceClient(authprovider)
Dim onlineMeeting = New OnlineMeeting With {
.StartDateTime = DateTimeOffset.Parse("2020-04-23T21:33:30.8546353+00:00"),
.EndDateTime = DateTimeOffset.Parse("2020-04-23T22:03:30.8566356+00:00"),
.Subject = "Application Token Meeting",
.Participants = New MeetingParticipants With {
.Organizer = New MeetingParticipantInfo With {
.Identity = New IdentitySet With {
.User = New Identity With {
.Id = "MYID"
}
}
}
}
}
Dim encodings As New UTF8Encoding
Dim serializer As New JavaScriptSerializer()
Dim arrayJson As String = serializer.Serialize(onlineMeeting)
Dim result As String = Nothing
Dim postRequest As HttpWebRequest = DirectCast(WebRequest.Create("https://graph.microsoft.com/v1.0/me/onlineMeetings"), HttpWebRequest)
postRequest.Method = "POST"
postRequest.ContentType = "application/json"
httpClient.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", Token)
If postRequest.Method = "POST" Then
Dim parsedContent As String = JsonConvert.SerializeObject(onlineMeeting)
Dim encoding As ASCIIEncoding = New ASCIIEncoding()
Dim bytes As Byte() = encoding.GetBytes(parsedContent)
Dim newStream As Stream = postRequest.GetRequestStream()
newStream.Write(bytes, 0, bytes.Length)
newStream.Close()
End If
Dim createMeetings = Await graphClient.Communications.OnlineMeetings.Request().AddAsync(onlineMeeting)
Console.WriteLine("The meeting has been created")
Return createMeetings
Catch ex As ServiceException
Console.WriteLine($"Error while creating the meeting: {ex.Message}")
Return Nothing
End Try
End Function
Public Sub InvokeMeeting(sender As Object, e As EventArgs)
Try
Dim testing = CreateMeeting()
Catch ex As Exception
End Try
End Sub
PS: I have added the permission required to call this API to be able to create a Teams meeting.
Any suggestions on how to achieve the following scenario?
Any help will be greatly appreciated.
Thank you!

Related

How to execute a webrequest asynchronous to parse json

I need to get a value from an API and I'm using the follow code synchronous.
Dim request As HttpWebRequest
Dim response As HttpWebResponse = Nothing
Dim reader As StreamReader
Try
request = DirectCast(WebRequest.Create("http://ecc"), HttpWebRequest)
response = DirectCast(request.GetResponse(), HttpWebResponse)
reader = New StreamReader(response.GetResponseStream())
Dim rawresp As String
rawresp = reader.ReadToEnd()
Dim jResults As JObject = JObject.Parse(rawresp)
Label1.Text = jResults("result").ToString()
Catch ex As Exception
MsgBox(ex.ToString)
Finally
If Not response Is Nothing Then response.Close()
End Try
The problem is that's synchronous, I want to make it async in order not to freeze the form in the while.
How can I async it?
You can easily use WebClient and the nuget package NewtonSoft doing something like this:
Imports System.IO
Imports System.Net
Imports System.Text
Imports Newtonsoft.Json
Public Class Form1
Private ReadOnly wc As New WebClient()
Private Async Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
'stop timer to avoid simultaneous I/O operations
Timer1.Stop()
Dim downloadTasks As New List(Of Task(Of String))
'download api and add as a task of string
Dim APIValue = wc.DownloadStringTaskAsync("https://api.etc")
downloadTasks.Add(Value)
Await Task.WhenAll(downloadTasks)
Dim d = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(APIValue.Result)
Dim Price As String = d("result").ToString
Label1.Text = Price
Timer1.Start()
End Sub
End Class
Much simpler with HttpClient and JsonNode:
'// Web API:
'// app.MapGet("/api", () => new { id = 1, result = "100", name = "name1" });
Imports System.Net.Http
Imports System.Text.Json.Nodes
Using http = New HttpClient
Dim url = "https://localhost:5000/api"
Dim json = JsonNode.Parse(Await http.GetStreamAsync(url))
Label1.Text = json("result")
End Using

Problem with Crunch occurring after some time FtpWebRequest in vb.net

i have this Code From My Class
The code is working fine, but the memory is increasing, which is causing Crunch to close the program for itself
I tried all the methods and did not find a solution to this problem
Imports System.Net
Imports System.IO
Public Class class1
Private host As String
Private password As String
Private username As String
Dim x As New List(Of String)
Public Sub New(host As String, username As String, password As String)
Me.host = host
Me.username = username
Me.password = password
End Sub
Friend Sub start()
Try
Dim request As FtpWebRequest = WebRequest.Create("ftp://" + Me.host)
request.Timeout = 4000
request.Credentials = New NetworkCredential(Me.username, Me.password)
request.Method = WebRequestMethods.Ftp.ListDirectory
'-----------------------------------
Try
'-----------------------------------
Dim listResponse As FtpWebResponse = request.GetResponse()
' listResponse = request.GetResponse()
Dim reader As StreamReader = New System.IO.StreamReader(listResponse.GetResponseStream())
Dim Filedata As String = reader.ReadToEnd
'-----------------------------------
x.Add(Filedata)
'-----------------------------------
File.WriteAllLines(IO.Directory.GetCurrentDirectory() & "\logs.txt", x)
'-----------------------------------
Threading.Thread.Sleep(1000)
listResponse.Close()
listResponse.Dispose()
request.Abort()
Catch ex As WebException
request.Abort()
Exit Sub
End Try
Catch ex As Exception
Exit Sub
End Try
Exit Sub
End Sub
End Class
i Call this class from the main app
This method call
And use threading
Dim x As New testing(host, username, password)
x.start()
can anyone help me do this i am using Vb.net

What is Equivalent hash_hmac PHP on Visual Basic .Net

I'm rewriting hash_hmac code I got on PHP to VB.Net.
I need same result generated both in PHP and VB.Net.
This is hash_hmac code on PHP:
$data = urlencode('2019-07-21T15:30:57.465Z');
$data = '_ts='.$data;
$signatureSecretKey = "secrete";
$hash = hash_hmac('sha256',$data,$signatureSecretKey,true);
$signature = base64_encode($hash);
echo $signature;
The result shows:
upLQYFI3pI2m9Pu5fyiobpvCRhTvRmEyxrVDrdJOYG4=
And here is my code on VB:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim _ts, data, signature, secrete, hash
secrete = "secret"
_ts = DateTime.Now.ToString("2019-07-21T15:30:57.465Z")
data = "_ts=" & HttpUtility.UrlEncode(_ts)
signature = Encrypt(data, secrete)
TextBox1.Text = signature
End Sub
Public Function Encrypt(Content As String, Secret As String) As String
Dim kode As New System.Text.ASCIIEncoding()
Dim getkode As Byte() = kode.GetBytes(Secret)
Dim cont As Byte() = kode.GetBytes(Content)
Dim hmcKu As New HMACSHA256(getkode)
Dim HashCode As Byte() = hmcKu.ComputeHash(cont)
Return Convert.ToBase64String(HashCode)
End Function
Result of my code is:
892q1ArPxIqrX48PQegliVql703V2fcipb5A08F053o=
You can see my VB code generates different result from PHP.
I have tried almost every method I got from internet but the result always different. So, what is equivalent hash_hmac of PHP on VB and what is the right way to make this same result?
Please help?
Use this:
dim hmac as HMACSHA256 = new HMACSHA256(key) ' key = Encoding.ASCII.GetBytes("<secret>")
dim hashValue as byte() = hmac.ComputeHash(Encoding.ASCII.GetBytes("<message>"))
dim result as string = BitConverter.ToString(hashValue).Replace("-", "").ToLower()
hmac.dispose()
I found solution from fb community.
This is exact solution for this cases:
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Imports System.Text.RegularExpressions
Public Class Form1
Private Shared DES As New TripleDESCryptoServiceProvider
Private Shared MD5 As New MD5CryptoServiceProvider
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim _ts, data, signature, secrete
secrete = "secret"
_ts = DateTime.Now.ToUniversalTime.ToString("yyyy-MM-dd\THH:mm:ss.fff\Z")
data = "_ts=" & HttpUtility.UrlEncode(_ts)
Dim reg = New Regex("%[a-f0-9]{2}")
data = reg.Replace(data, Function(m) m.Value.ToUpperInvariant())
signature = Encrypt(data, secrete)
TextBox1.Text = signature
End Sub
Public Function Encrypt(Content As String, Secret As String) As String
Try
Dim kode As New System.Text.ASCIIEncoding()
Dim getkode As Byte() = kode.GetBytes(Secret)
Dim cont As Byte() = kode.GetBytes(Content)
Dim hmcKu As New HMACSHA256(getkode)
Dim HashCode As Byte() = hmcKu.ComputeHash(cont)
Return Convert.ToBase64String(HashCode)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function
End Class

Microsoft Graph / OneDrive requesting multiple authentications

I'm trying to write code to read files in a OneDrive folder of mine and, in the future, create, move and delete them.
The scrap of code below works, but it requests a new authentication (shows Microsoft's OAuth window) for each iteration in the For Each ... Next.
What am I doing wrong here?
Imports Microsoft.Graph
Public Class FormGraphClient
Private Shared client As GraphServiceClient
Private Async Sub FormGraphClient_Load(sender As Object, e As EventArgs) Handles MyBase.Load
client = AuthenticationHelper.GetAuthenticatedClient
Dim formsmonitor_items = Await client.Me.Drive.Root.ItemWithPath("FormsMonitor").Children.Request.GetAsync
Dim forms As New Dictionary(Of String, String)
For Each form In formsmonitor_items
If form.Name Like "*.json" Then
Using formstream = Await client.Me.Drive.Items.Item(form.Id).Content.Request.GetAsync
Using reader = New IO.StreamReader(formstream)
forms(form.Name) = reader.ReadToEnd
End Using
End Using
End If
Next
End Sub
End Class
I'm using also this helper class:
Imports System.Net.Http.Headers
Imports Microsoft.Graph
Imports Microsoft.Identity.Client
Public Class AuthenticationHelper
Shared clientId As String = "my-client-id"
Public Shared Scopes As String() = {"User.Read", "Files.ReadWrite.All"}
Public Shared IdentityClientApp As PublicClientApplication = New PublicClientApplication(clientId)
Public Shared TokenForUser As String = Nothing
Public Shared Expiration As DateTimeOffset
Private Shared graphClient As GraphServiceClient = Nothing
Public Shared Function GetAuthenticatedClient() As GraphServiceClient
If graphClient Is Nothing Then
Try
graphClient = New GraphServiceClient(
"https://graph.microsoft.com/v1.0",
New DelegateAuthenticationProvider(
Async Function(requestMessage)
Dim token = Await GetTokenForUserAsync()
requestMessage.Headers.Authorization = New AuthenticationHeaderValue("bearer", token)
requestMessage.Headers.Add("SampleID", "uwp-csharp-apibrowser-sample")
End Function))
Return graphClient
Catch ex As Exception
Debug.WriteLine("Could not create a graph client: " & ex.Message)
End Try
End If
Return graphClient
End Function
Public Shared Async Function GetTokenForUserAsync() As Task(Of String)
Dim authResult As AuthenticationResult
Dim ex As Exception = Nothing
Try
authResult = Await IdentityClientApp.AcquireTokenSilentAsync(Scopes, IdentityClientApp.GetUser("antonio.patricio#agu.gov.br"))
TokenForUser = authResult.AccessToken
Catch ex
If TokenForUser Is Nothing OrElse Expiration <= DateTimeOffset.UtcNow.AddMinutes(5) Then
End If
End Try
If ex IsNot Nothing Then
Try
authResult = Await IdentityClientApp.AcquireTokenAsync(Scopes)
TokenForUser = authResult.AccessToken
Expiration = authResult.ExpiresOn
Catch ex
End Try
End If
Return TokenForUser
End Function
End Class
I checked up samples here and there, and came up with this wrapper class. I think I'll work on it more, but for the moment, it solved the problem mentioned at this post:
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports Microsoft.Graph
Imports Microsoft.Identity.Client
Public Class MsGraph
Private Const baseUrl As String = "https://graph.microsoft.com/v1.0"
Private ReadOnly client_id As String
Private ReadOnly scopes As String()
Private authSuccess As Boolean
Private clientApp As PublicClientApplication
Public Sub New(app_client_id As String, ParamArray app_scopes As String())
client_id = app_client_id
If Not app_scopes.Contains("User.Read", StringComparer.InvariantCultureIgnoreCase) Then
app_scopes = {"User.Read"}.Concat(app_scopes).ToArray
End If
scopes = app_scopes
clientApp = New PublicClientApplication(client_id)
Dim authProvider = New DelegateAuthenticationProvider(AddressOf AuthenticateRequestAsync)
Try
Client = New GraphServiceClient(baseUrl, authProvider)
Catch ex As Exception
Stop
End Try
End Sub
Public ReadOnly Property Client As GraphServiceClient
Public Async Function AuthenticateRequestAsync(request As HttpRequestMessage) As Task
request.Headers.Authorization = New AuthenticationHeaderValue("bearer", Await GetTokenForUserAsync())
End Function
Private Async Function GetTokenForUserAsync() As Task(Of String)
Dim success As Boolean
Dim authResult As AuthenticationResult = Nothing
If clientApp.Users.Any Then
Try
authResult = Await clientApp.AcquireTokenSilentAsync(scopes, clientApp.Users.FirstOrDefault())
success = True
Catch ex As Exception
Stop
End Try
Else
Try
authResult = Await clientApp.AcquireTokenAsync(scopes)
success = True
Catch ex As Exception
Stop
End Try
End If
authSuccess = success
Return authResult?.AccessToken
End Function
End Class

Aramex API yielding "Server Error in '/' Application"

I am trying to implement the Aramex API for Tracking on my VB.NET website, but I'm getting an error.
Here is my code:
Imports TrackingReference
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim _Request As New ShipmentTrackingRequest
_Request.ClientInfo = New ClientInfo
_Request.ClientInfo.AccountCountryCode = "JO"
_Request.ClientInfo.AccountEntity = "AMM"
_Request.ClientInfo.AccountNumber = "20016"
_Request.ClientInfo.AccountPin = "331421"
_Request.ClientInfo.UserName = "reem#reem.com"
_Request.ClientInfo.Password = "123456789"
_Request.ClientInfo.Version = "v1.0"
_Request.Transaction = New Transaction
Dim _Shipments As New List(Of String)
_Shipments.Add("7055174991")
_Request.Shipments = _Shipments.ToArray()
_Request.GetLastTrackingUpdateOnly = True
Dim _Client As New Service_1_0Client()
Dim _response As ShipmentTrackingResponse = Nothing
_Client.Open()
_response = _Client.TrackShipments(_Request)
If Not _response Is Nothing Then
For Each _Result As KeyValuePair(Of String, TrackingResult()) In _response.TrackingResults
Dim _trResult() As TrackingResult = _Result.Value
For Each trR In _trResult
Response.Write(trR.UpdateLocation & "<br>")
Next
Next
End If
_Client.Close()
End Sub
End Class
This is my error:
I have found the Aramex Developer community to be full of questions but no answers. How can I fix the problem?