Visual Basic Twitch irc issue - vb.net

Here is my function:
Public Async Function SendChatMessage(channel As String, message As String, nickname As String, oauth As String) As Task
' Connect to the Twitch IRC server
Dim client As New ClientWebSocket()
Await client.ConnectAsync(New Uri("wss://irc-ws.chat.twitch.tv:443"), CancellationToken.None)
' Send CAP (optional), PASS, and NICK messages
Await client.SendAsync(New ArraySegment(Of Byte)(Encoding.UTF8.GetBytes("PASS " & oauth)), WebSocketMessageType.Text, True, CancellationToken.None)
Await client.SendAsync(New ArraySegment(Of Byte)(Encoding.UTF8.GetBytes("NICK " & nickname)), WebSocketMessageType.Text, True, CancellationToken.None)
Await client.SendAsync(New ArraySegment(Of Byte)(Encoding.UTF8.GetBytes("JOIN #" & channel)), WebSocketMessageType.Text, True, CancellationToken.None)
Await client.SendAsync(New ArraySegment(Of Byte)(Encoding.UTF8.GetBytes("PRIVMSG #" & channel & " :" & message)), WebSocketMessageType.Text, True, CancellationToken.None)
client.Dispose()
End Function
I am basically trying to post messages to my twitch channel.
I get no errors and the access token has read write scopes.
I am using:
Dim unused = SendChatMessage("#mychannel", "send a lovely message", "mychannel_bot", "my_access_token")
Can anyone see what might be going on here?
I expect to see messages popup on the stream chat, but nothing happens.

Related

vb.NET SmtpClient not able to send email using email

I'm trying to run this a block of code that exports the file I am working on to a PDF and emailing it to a 'client' using gmail.
I keep getting the message "Failure Sending Message", if you could help shed some light on this that would be appreciated.
I also purposely "*****" my emails credentials for obvious reasons.
<MiCode(ControlScriptEventType.AfterInkAdded, "Email")> _
Public Sub Ctl_Email_AfterInkAdded(ByVal e As AfterInkAddedEventArgs)
MsgBox("1")
Dim EmailTo As String = _EmailAddress.Value
Dim EmailToName As String = "Client"
Dim EmailFrom As String = "******"
Dim EmailFromName As String = "WHSD"
Dim fileName As String = String.Empty
Dim erl As New System.Collections.Generic.List(Of ExportResult)
For Each er As ExportResult In _form.Validator.ExportResults
erl.Add(er)
fileName = System.IO.Path.GetFileNameWithoutExtension(er.ExpandedFilePath)
Next
Try
Dim fromAddress As New MailAddress(EmailFrom, EmailFromName)
Dim toAddress As New MailAddress(EmailTo, EmailToName)
Using msg As New MailMessage(fromAddress, toAddress)
msg.Body = "This will be the body of the message you are sending." & VbCrLf & "Thank you for your purchase."
msg.Subject = (Me._form.Name & " (" & fileName & ")")
' Add the mail body - an HTML file attached to this form.
For Each attData As AttachmentData In _form.Attachments
If String.Compare(attData.Name, "Lead Generation.html") = 0 Then
msg.Body = System.Text.UTF8Encoding.UTF8.GetChars(attData.BinaryData())
msg.Body = msg.Body.Replace("[filename]", fileName)
End If
Next
' Add pdf/csv file attachments to mail - they are datapaths of the form.
For Each er As ExportResult In erl
If er.Success And ( er.DataPathName = "PDF" Or er.DataPathName = "CSV" ) Then
msg.Attachments.Add(New Attachment(er.ExpandedFilePath))
End If
Next
Dim client As New SmtpClient("aspmx.l.google.com", 25)
'client.EnableSsl = True
'client.Timeout = 10000
client.DeliveryMethod = SmtpDeliveryMethod.Network
client.UseDefaultCredentials = False
client.Credentials = New NetworkCredential("********", "******")
client.Send(msg)
Me.RecordExportResult("Email", True, "Sent email", "Sent email to " & EmailToName & "(" & EmailTo & ")", "")
MsgBox("Sent!")
End Using
Catch ex As Exception
Me.RecordExportResult("Email", False, ex.Message, ex.Message, ex.Message)
MsgBox(ex.Message)
End Try
End Sub
Looks like you are trying to use gmail as your mail server in which case you will definately need to use SSL/TLS and make sure your credentials are as follows;
Google's SMTP server requires authentication, so here's how to set it up:
SMTP server (i.e., outgoing mail): smtp.gmail.com
SMTP username: Your
full Gmail or Google Apps email address (e.g. example#gmail.com or
example#yourdomain.com)
SMTP password: Your Gmail or Google Apps
email password
SMTP port: 465
SMTP TLS/SSL required: yes
In order to store a copy of outgoing emails in your Gmail or Google Apps Sent folder, log into your Gmail or Google Apps email Settings and:
Click on the Forwarding/IMAP tab and scroll down to the IMAP Access section: IMAP must be enabled in order for emails to be properly copied to your sent folder.
NOTE: Google automatically rewrites the From line of any email you send via its SMTP server to the default Send mail as email address in your Gmail or Google Apps email account Settings. You need to be aware of this nuance because it affects the presentation of your email, from the point of view of the recepient, and it may also affect the Reply-To setting of some programs.
Workaround: In your Google email Settings, go to the Accounts tab/section and make "default" an account other than your Gmail/Google Apps account. This will cause Google's SMTP server to re-write the From field with whatever address you enabled as the default Send mail as address.

All the ports on my server are used up, what am I doing wrong?

I have a computer running Windows Server 2012 that I use to run a lot of my applications. Most of them are processing many asynchronous web requests in parallel (using HttpClient in .NET 4.5).
When I check NETSTAT, I see almost all available (assuming 66,536 is the maximum) ports are in use. The piped output from the basic NETSTAT call is a 4mb text file with 64,583 lines. The majority of these are in TIME_WAIT, lots are not attributed to any particular process but labelled as "System Process".
I understand TIME_WAIT is not necessarily a bad thing and my applications do not seem to be throwing exceptions explicitly stating they are unable to complete a request due to no available ports. However, this concerns me and I'm worried it might be causing time outs.
Is this to be expected? Should I reduce the TcpTimedWaitDelay value in the registry? I believe connections are kept in TIME_WAIT for 4 minutes by default. Also is it possible I'm doing something wrong in my code that leaves connections open like this? I reuse the HttpClient object where possible and always dispose of it when finished. Should I be looking out for connection: close headers in responses?
EDIT: Adding code, as requested. Here's the function that makes the request (part of a custom class wrapper for HttpClient);
Public Async Function WebRequestAsync(Url As String, Optional RequestMethod As RequestMethod = RequestMethod.GET, Optional Content As Object = Nothing, _
Optional ContentType As ContentType = ContentType.Default, Optional Accept As String = DefaultAcceptString, _
Optional AdditionalHeaders As NameValueCollection = Nothing, Optional Referer As String = Nothing, _
Optional NoCache As Boolean = False, Optional CustomCookieHandler As Boolean = False, _
Optional Attempts As Integer = 2, Optional CanBeCancelled As Boolean = True) _
As Tasks.Task(Of HttpResponseMessage)
If Attempts < 1 Then Attempts = 1
Dim Method As HttpMethod = Nothing
Select Case RequestMethod
Case Variables.RequestMethod.DELETE : Method = HttpMethod.Delete
Case Variables.RequestMethod.GET : Method = HttpMethod.Get
Case Variables.RequestMethod.OPTIONS : Method = HttpMethod.Options
Case Variables.RequestMethod.POST : Method = HttpMethod.Post
Case Variables.RequestMethod.PUT : Method = HttpMethod.Put
End Select
'prepare message
Dim Message As New HttpRequestMessage(Method, Url)
Message.Headers.ExpectContinue = False
Message.Headers.TryAddWithoutValidation("Accept", Accept)
If Referer IsNot Nothing Then Message.Headers.Add("Referer", Referer)
If NoCache Then
Message.Headers.Add("Pragma", "no-cache")
Message.Headers.Add("Cache-Control", "no-cache")
End If
If AdditionalHeaders IsNot Nothing Then
For Each Key In AdditionalHeaders.AllKeys
Message.Headers.TryAddWithoutValidation(Key, AdditionalHeaders(Key))
Next
End If
'set content
If Content IsNot Nothing Then
Dim ContentTypeString As String = GetEnumDescription(ContentType)
Dim ContentBytes As Byte() = Nothing
If TypeOf Content Is String Then
ContentBytes = Encoding.UTF8.GetBytes(CType(Content, String))
ElseIf TypeOf Content Is Byte() Then
ContentBytes = CType(Content, Byte())
ElseIf TypeOf Content Is MultiPartPostData Then
Dim MultiPartPostData As MultiPartPostData = CType(Content, MultiPartPostData)
ContentBytes = MultiPartPostData.Bytes
ContentTypeString += "; boundary=" & MultiPartPostData.Boundary
End If
Dim ByteArrayContent As New ByteArrayContent(ContentBytes)
ByteArrayContent.Headers.Add("Content-Type", ContentTypeString)
Message.Content = ByteArrayContent
End If
'get response
Output(RequestMethod.ToString & " " & Url, OutputType.Debug)
'Set cancellation token
Dim CToken As New CancellationToken
If CancellationToken IsNot Nothing AndAlso CancellationToken.HasValue AndAlso CanBeCancelled Then CToken = CancellationToken.Value
Dim Response As HttpResponseMessage = Nothing
For Attempt = 1 To Attempts
Try
Response = Await Client.SendAsync(Message, HttpCompletionOption.ResponseHeadersRead, CToken).ConfigureAwait(False)
Catch ex As Tasks.TaskCanceledException
If DebugMode Then Output(Method.ToString & " " & Url & " Timed out", OutputType.Error)
Catch ex As HttpRequestException
If ex.InnerException IsNot Nothing Then
If DebugMode Then Output(Method.ToString & " " & Url & " " & ex.InnerException.Message, OutputType.Error)
If ex.InnerException.Message = "Timed out" Then Continue For
Else
If DebugMode Then Output(Method.ToString & " " & Url & " " & ex.Message, OutputType.Error)
End If
Catch ex As Exception
If DebugMode Then Output(Method.ToString & " " & Url & " " & ex.Message, OutputType.Error)
End Try
Exit For
Next
If Response IsNot Nothing Then
Output(Method.ToString & " " & Url & " " & Response.StatusCode & " " & Response.StatusCode.ToString, OutputType.Debug)
If CustomCookieHandler AndAlso Cookies IsNot Nothing Then
Dim Values As IEnumerable(Of String) = Nothing
If Response.Headers.TryGetValues("Set-Cookie", Values) Then ManuallyExtractCookies(Values, New Uri(Url).GetLeftPart(UriPartial.Authority))
End If
End If
Return Response
End Function
And an example of making a request;
Using HttpClient As New HttpClientWrapper(User, Task)
Dim Response As String = Await HttpClient.WebRequestStringAsync("http://www.google.com")
If Response Is Nothing Then Return Nothing
End Using
In HTTP 1.1, all connections are considered persistent unless declared
otherwise.
So if you don't close the connection the server will keep waiting for a new request (at least until certain timeout).
The solution would be to add a Connection: close header or explicitly close the connection after receiving the response: Response.Dispose().

How can I tell if a response stream is valid for creating an image in VB.NET?

I'm pulling an image from a web server using VB.NET, and everything works fine when I debug on my workstation. However, when I deploy the app to my server it is failing. It appears it can't draw the image from the stream with an error of "Parameter is not valid", which occurs in the GetImage line below in the try catch block. I know the image can be retrieved on the server because if I put the URL in a browser address bar the image displays just fine. How can I go about troubleshooting the response stream to determine what is going on?
Function GetImage(ByVal URL As String) As System.Drawing.Image
Dim Request As System.Net.HttpWebRequest
Dim Response As System.Net.HttpWebResponse
GetImage = Nothing
Try
Request = System.Net.WebRequest.Create(URL)
Response = CType(Request.GetResponse, System.Net.WebResponse)
If Request.HaveResponse Then
If Response.StatusCode = Net.HttpStatusCode.OK Then
GetImage = System.Drawing.Image.FromStream(Response.GetResponseStream)
End If
End If
Catch e As Exception
txtActivity.Text = "Error retrieving image from URL " & URL & vbCrLf & e.ToString() & vbCrLf & txtActivity.Text
Exit Try
Finally
End Try
End Function

vb.net how to detect if an email is undeliverable in a win form program

I have the following code:
Public Function VerstuurMail(ByVal strFrom As String, ByVal strTo As String, ByVal strSubject As String, ByVal strBody As String, ByVal strMailSMTP As String, ByVal MailUser As String, ByVal MailPassword As String, ByVal MailPort As Integer, Optional ByVal AttachmentFiles As String = "") As String
Try
'create the mail message
Dim mail As New MailMessage()
Dim basicCredential As New NetworkCredential(MailUser, MailPassword)
'set the addresses
mail.From = New MailAddress(strFrom)
mail.To.Add(strTo)
'set the content
mail.Subject = strSubject
If File.Exists(strBody) = True Then
Dim objReader As New System.IO.StreamReader(strBody, System.Text.Encoding.GetEncoding(1252))
mail.Body = objReader.ReadToEnd
objReader.Close()
End If
mail.IsBodyHtml = False
'send the message
Dim smtp As New SmtpClient(strMailSMTP)
smtp.DeliveryMethod = SmtpDeliveryMethod.Network
smtp.EnableSsl = True
'smtp.UseDefaultCredentials = True
smtp.Credentials = basicCredential
smtp.Port = MailPort
Dim AttachmentFile As String() = AttachmentFiles.Split("*")
For Each bestand In AttachmentFile
If System.IO.File.Exists(bestand) Then
mail.Attachments.Add(New Attachment(bestand))
Else
Call MessageBox.Show("File can't be found")
End If
Next
'Dim userState As Object = mail
'smtp.SendAsync(mail, userState)
'AddHandler smtp.SendCompleted, AddressOf SendCompletedCallback
smtp.Send(mail)
mailSent = True
smtp.Dispose()
Catch ex As Exception
mailSent = False
Call MessageBox.Show(ex.Message & vbCrLf & "Didn't sent to: " & strTo & vbCrLf & " with extra error message:" & vbCrLf & ex.ToString)
Finally
End Try
Return mailSent
End Function
This function is used in a program which reads a text file, with the parameters on one line, and is called as many lines there are. (in a loop)
This is working fine.
Now when the text file has a wrong email adress the function doesn't trow a error it just sent the email to nobody.
example: sent an mail to joe#gmail.com works, send an email to joe#hmail.com doesn't sent but doesn't give an error either.
I have googled but the examples said that I should use 'smtp.SendAsync(mail, userState)'
But then the program doesn't follow the loop anymore and no mails are being sent. I can't use the debugger and step through the code. It just jumps from one place to the other.
This is the other function:
Private Sub SendCompletedCallback(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
Dim mail As MailMessage = CType(e.UserState, MailMessage)
'write out the subject
Dim subject As String = mail.Subject
'If e.Cancelled Then
' Call MessageBox.Show("Send canceled: " & Now & " token " & subject)
' MailLog &= "Send canceled" & vbCrLf
'End If
If Not e.Error Is Nothing Then
Call MessageBox.Show("Foutmelding op: " & Now & " onderwerp " & subject & " met error: " & e.Error.ToString())
MailLog = MailLog & "Niet verstuurd met als fout melding: " & e.Error.ToString() & vbCrLf
Else
'Call MessageBox.Show("Message sent at: " & Now)
MailLog = MailLog & "Bericht verstuurd op: " & Now & vbCrLf
End If
mailSent = True
End Sub
Thanks in advance. I hope somebody can put me in the right direction.
Brian
This is a data issue, not an issue with the actual mechanism to send email. The best you can do is to use a regular expression to make sure the email address is valid per the rules of RFC 2822, like this:
string email = txtemail.Text;
Regex regex = new Regex(#"^([\w\.\-]+)#([\w\-]+)((\.(\w){2,3})+)$");
Match match = regex.Match(email);
if (match.Success)
{
Response.Write(email + " is valid.");
}
else
{
Response.Write(email + " is invalid.");
}
Unfortunately for you, joe#hmail.com is a valid email address by the above logic, but is is not the intended joe#gmail.com address so it ends up in the wrong place. When it is discovered that it is the wrong email address, then changing the data to the right value is the only correct course of action.
Note: Generally, you verify someone's email address when they register for a website, thus the system "knows" the email address is legitimate/correct because they successfully received an email and entered a verification code or clicked on a link that verified with the website that they did get the email. This solves most data issues (misspellings, incorrectly entered values, etc.).
After two full days of testing and searching I have found that when using:
Dim userState As Object = mail
smtp.SendAsync(mail, userState)
AddHandler smtp.SendCompleted, AddressOf SendCompletedCallback
you should not close the smtpClient with smtp.Dispose()
The callback function kept getting the cancel error.
Also I used the backgroundworker for sending the many mails but the async is, in a way, a backgroundworker. So I had two backgroundworkers and that didn't work at all.
It took me two days.....
Brian

Getting User Count From IRC

I am making IRC chat client and I am wanting to grab the user list or simply the user count, how can I go about doing this. This is the method I'm using to connect to the IRC:
Private Sub IRCConnect()
Dim stream As NetworkStream
Dim irc As TcpClient
Dim reader As StreamReader
Try
irc = New TcpClient(SERVER, PORT)
stream = irc.GetStream()
reader = New StreamReader(stream)
writer = New StreamWriter(stream)
' Start PingSender thread
Dim ping As New PingSender
ping.Start()
writer.WriteLine(USER)
writer.Flush()
writer.WriteLine("NICK " & Config.Nickname)
writer.Flush()
writer.WriteLine("JOIN " & Config.Channel & " " & Config.ChanPass)
writer.Flush()
txtView.Text = txtView.Text & ">Connected successfully." & vbNewLine
HighlightPhrase(txtView, "Connected successfully.", Color.Lime)
Thread.Sleep(2000)
Catch Ex As Exception
' Show the exception, sleep for a while and try to establish a new connection to irc server
txtView.Text = txtView.Text & ">ERROR: Unexpected error occured: " & Ex.ToString & vbNewLine
HighlightPhrase(txtView, "Unexpected error occured: " & Ex.ToString, Color.Red)
End Try
End Sub
I have no idea where to start, any help would be much appreciated.
The IRC-protocol is defined in RFC2812: https://www.rfc-editor.org/rfc/rfc2812
Send the "NAMES #currentchannel" - command ( https://www.rfc-editor.org/rfc/rfc2812#section-3.2.5 ) and you will receive a list of all visible users. This list can be counted and voilĂ  - there you got your user-count
Start by reading the the specification for IRC, it is RFC 2812.
You'll want to use the NAMES message. Here is the appropriate section from the RFC.