update currently message by inline keyboard Telegram VB.NET - telegram

hello i try to updating Message by inline keyboard.
telegram OnMessageReceived function:
Dim ID As String = e.Message.From.Id.ToString ' it is your id
Select Case e.Message.Text
Case "/ts"
Await bot.SendTextMessageAsync(ID, "Hello", replyMarkup:=CreateInLineMainMenuMarkup)
Return
End Select
Inline Keyboard function's
Public Shared Function CreateInLineMainMenuMarkup() As IReplyMarkup
Dim buttonsList As Dictionary(Of String, String) = New Dictionary(Of String, String)()
buttonsList.Add("Refresh", "test")
Return CreateInlineKeyboardButton(buttonsList, 1)
End Function
Public Shared Function CreateInlineKeyboardButton(ByVal buttonList As Dictionary(Of String, String), ByVal columns As Integer) As IReplyMarkup
Dim rows As Integer = CInt(Math.Ceiling(CDbl(buttonList.Count) / CDbl(columns)))
Dim buttons As InlineKeyboardButton()() = New InlineKeyboardButton(rows - 1)() {}
For i As Integer = 0 To buttons.Length - 1
buttons(i) = buttonList.Skip(i * columns).Take(columns).[Select](Function(direction) TryCast(New InlineKeyboardCallbackButton(direction.Key, direction.Value), InlineKeyboardCallbackButton)).ToArray()
Next
Return New InlineKeyboardMarkup(buttons)
End Function
Image To explain
Question here,can i update text message from "Hello", To be "Done". using inline keyboard click.

you will need handle OnCallbackQuery event.
first :
AddHandler bot.OnCallbackQuery, AddressOf OnCallbackQuery
then add function OnCallbackQuery (that to handle any action of callback inline keyboard)
Private Async Sub OnCallbackQuery(sender As Object, e As CallbackQueryEventArgs)
Dim call_data As String = e.CallbackQuery().Message.Text
Dim message_id As Long = e.CallbackQuery().Message.MessageId
Dim chat_id As Long = e.CallbackQuery().Message.Chat.Id
Dim callback As Long = e.CallbackQuery.Id
If call_data.Equals("Hello") Then
Dim answer As String = "Done"
Dim r As Telegram.Bot.Types.Message = Await bot.EditMessageTextAsync(chat_id, message_id, (answer))
Dim r2 As Boolean = Await bot.AnswerCallbackQueryAsync(callbackQueryId:=callback, text:=answer)
End If
End Sub
Notice that, it gonna update inline keyboard message to normal text message.
Hope it help.

Related

How can I send an email with my vb.net code?

I am using asp.net / vb.net. I want to send an email. My code does not send an email as it is. I am wondering what I am doing wrong here.
I created a file called email.text that holds the email template. The rest of the code to send the email is below. I removed personal information from my code.
I setup the SMTP connection as such:
Private SMTPClientConnection As SmtpClient
Sub New()
SMTPClientConnection = New SmtpClient
SMTPClientConnection.Host = "HOSTHERE"
SMTPClientConnection.Port = PORTHERE
SMTPClientConnection.DeliveryMethod = SmtpDeliveryMethod.Network
End Sub
Then I created a function to send the email:
Private Shared Function SendEmail(ByVal emailUser As String, ByVal bodyMessage As List(Of String), ByVal priority As MailPriority) As Boolean
Dim functionReturnValue As Boolean = False
Try
If Not String.IsNullOrWhiteSpace(emailUser) Then
If Regex.IsMatch(emailUser, "^([a-zA-Z0-9]+([\.+_-][a-zA-Z0-9]+)*)#(([a-zA-Z0-9]+((\.|[-]{1,2})[a-zA-Z0-9]+)*)\.[a-zA-Z]{2,6})$") Then
Using SMTPClientConnection
Dim smtpMessage As MailMessage = New MailMessage()
Dim _with1 = smtpMessage
_with1.[To].Add(New MailAddress(emailUser))
_with1.From = New MailAddress("Test Email" & " <email#email.com>")
_with1.ReplyToList.Add(New MailAddress("email#email.com"))
_with1.Subject = "Test Email"
_with1.Priority = priority
Dim htmlView As AlternateView = AlternateView.CreateAlternateViewFromString(bodyMessage(0), Nothing, "text/html")
Dim plainView As AlternateView = AlternateView.CreateAlternateViewFromString(bodyMessage(1), Nothing, "text/plain")
_with1.AlternateViews.Add(plainView)
_with1.AlternateViews.Add(htmlView)
SMTPClientConnection.Send(smtpMessage)
Return True
End Using
Else
Throw New SmtpException("Invalid email.")
End If
End If
Catch ex As Exception
End Try
Return functionReturnValue
End Function
I use the function on my code here:
Dim plainBody As String = File.ReadAllText(HttpContext.Current.Server.MapPath("email.txt"))
plainBody = plainBody.Replace("%Name%", emailName)
Dim emailBody As List(Of String) = New List(Of String)(New String() {plainBody})
SendEmail("email#email.com", emailBody, MailPriority.Normal)
The compiler error message is clear. The variable SmtpClientConnection is an instance variable (it exists as a different entity in any class instance where is declared) but you are trying to use inside a Shared method (a method that exists without a class instance). Inside this kind of methods you cannot use instance variables because you don't have an instance from which the method could pick the variable value and use it.
The solution could be to remove the Shared keyword from the method and then, whenever you want to call the method you need to create an instance of the class where the instance variable SmtpClientConnection is initialized and ready to be used in the following call to the SendMail method.
However, you could still use the Shared method but should remove the instance variable and create it inside the SmtpClient method:
Private Shared Function SendEmail(ByVal emailUser As String, ByVal bodyMessage As List(Of String), ByVal priority As MailPriority) As Boolean
Dim functionReturnValue As Boolean = False
Try
If Not String.IsNullOrWhiteSpace(emailUser) Then
If Regex.IsMatch(emailUser, "^([a-zA-Z0-9]+([\.+_-][a-zA-Z0-9]+)*)#(([a-zA-Z0-9]+((\.|[-]{1,2})[a-zA-Z0-9]+)*)\.[a-zA-Z]{2,6})$") Then
Dim SMTPClientConnection As SmtpClient = New SmtpClient
SMTPClientConnection.Host = "HOSTHERE"
SMTPClientConnection.Port = PORTHERE
SMTPClientConnection.DeliveryMethod = SmtpDeliveryMethod.Network
Using SMTPClientConnection
Dim smtpMessage As MailMessage = New MailMessage()
......
SMTPClientConnection.Send(smtpMessage)
Return True
End Using
Else
Throw New SmtpException("Invalid email.")
End If
End If
Catch ex As Exception
' No point in catching an exception and doing nothing here.
' You can log the exception somewhere and then throw it again
LogException(ex)
Throw
' or just remove the try/catch block.
End Try
Return functionReturnValue
End Function
In this way the variable is created only when needed and destroyed as well when the using statement ends. Take also note of the comments relative to the Try/Catch block.

Stackoverflow exception - Recursive Treeview ASP.Net

I am trying to build a treeview recursively using VB.Net this is my code so far
.... Code to get the data table
For Each row As DataRow In dt.Rows
Dim oName As String = Nothing
Dim pId As String = Nothing
Dim cId As String = Nothing
Dim cmts As String = Nothing
Dim lvl As String = Nothing
oName = row(0)
pId = row(4)
cId = row(5)
If Not String.IsNullOrEmpty(row(3).ToString()) Then
cmts = row(3)
End If
lvl = row(2)
list.Add(New MyObject() With { _
.ObjectName = oName,
.ParentId = pId,
.ChildId = cId,
.Comments = cmts,
.level = lvl
})
Next
BindTree(list, Nothing)
End Sub
Private Sub BindTree(list As IEnumerable(Of MyObject), parentNode As TreeNode)
Dim nodes = list.Where(Function(x) If(parentNode Is Nothing, x.ParentId = "[Transform].[(Root)]", x.ParentId = parentNode.Value))
For Each node As MyObject In nodes
Dim newNode As New TreeNode(node.ObjectName, node.ParentId.ToString())
If parentNode Is Nothing Then
TreeView1.Nodes.Add(newNode)
Else
parentNode.ChildNodes.Add(newNode)
End If
BindTree(list, newNode)
Next
End Sub
also the new class
Public Class MyObject
Public ObjectName As String
Public ParentId As String
Public ChildId As String
Public Comments As String
Public level As Integer
End Class
The issue I am having is that when this goes so far through the recursion I get a System.StackOverFlowException. When looking at the exception snapshot every thing says "unable to evaluate expression" The error is coming from this line
Dim nodes = list.Where(Function(x) If(parentNode Is Nothing, x.ParentId = "[Transform].[(Root)]", x.ParentId = parentNode.Value)) but Ive no idea why or how to resolve it.
Any help would be very much appreciated.
Thanks
Simon
A StackOverflowException isn't thrown by a particular line of code, that's just the first line of code in the method being called which is overflowing the stack. And there isn't any more information that can really be given, because no further code can be executed. (Because the stack is full.)
Your method is recursive:
Private Sub BindTree(list As IEnumerable(Of MyObject), parentNode As TreeNode)
' ...
BindTree(list, newNode)
End Sub
Which is ok, except that you're not modifying the list variable anywhere. So every time you call the method, you call it with the same list. Therefore it will continue to perform the same logic, recursively, indefinitely, with no terminating condition.
Generally, you should think of a recursive method with the following structure (in VB-ish pseudo-code):
Method(ByVal something As SomeType)
' Check if the recursion should end
If SomeTerminatingCondition Then
Return
End If
' Perform the logic for this step of the recursion
DoSomething()
' Recurse again
Method(somethingModified)
End Method
It's not entirely clear to me from the code how list should be modified. But presumably when you call BindTree(list, newNode) at that point list should be some subset of the original list.

combining two textbox values

i called a field from mysql into a readonly textarea and i made another textbox to allow users to add fields into the textarea. how do I combine the values from the textbox into the textarea?
an example of what i want to do is:
textarea
15/12: Nothing special today
16/12: another day
17/12: and so on
textbox
this is a new input
Result
15/12: Nothing special today
16/12: another day
17/12: and so on
18/12: this is a new input
The textarea is "log1" and the textbox is "txb1". I'm currently using
log = trim(request.form("log1"))
how do I do something like
log = trim(request.form("log1")) <br> date ": " trim(request.form("txb1"))
assuming date is a string variable, You would want to do the following:
log = trim(request.form("log1")) & "<br>" & [date] & ": " & trim(request.form("txb1"))
also, if date is a DateTime variable, you would want to use date.ToShortDateString() and instead of <br/> i would recommend using Environment.NewLine
and even better, you should use StringBuilder:
Dim SB As New StringBuilder()
SB.AppendLine(trim(request.form("log1")))
SB.AppendLine([date] & ": " & trim(request.form("txb1")))
log = SB.ToString()
UPDATE:
if you want to store the entire log in one record rather than a separate table, you better off saving it as a list of logs into a varbinary(MAX) column.
here is a full example of how to do it:
1. we start by creating a <div> element that will hold our pretty logs and will be handled by the server, and a text box for new logs:
<asp:TextBox ID="txb1" runat="server"></asp:TextBox>
<div id="Text_Div1" runat="server"></div>
2. now in the code behind, we create a class to hold 1 single line of log:
'create a log class and state that it serializable
<Serializable> _
Public Class MyLogRecord
Public Sub New(_msg As String)
[Date] = DateTime.Now
Message = _msg
End Sub
Public Property [Date]() As DateTime
Get
Return m_Date
End Get
Set
m_Date = Value
End Set
End Property
Private m_Date As DateTime
Public Property Message() As [String]
Get
Return m_Message
End Get
Set
m_Message = Value
End Set
End Property
Private m_Message As [String]
Public Function ToText() As String
Return [Date].ToShortDateString() & ": " & Convert.ToString(Message)
End Function
End Class
3. wherever you update the logs, whether its button_click or textbox_keydown, you do the following:
' create a list of logs
Dim MyLogs As List(Of MyLogRecord)
'check if we stored the logs already in the session,
'if yes, retrieve it from the session var,
'if not then create a new one.
If Session("MyLogs") IsNot Nothing Then
MyLogs = DirectCast(Session("MyLogs"), List(Of MyLogRecord))
Else
MyLogs = New List(Of MyLogRecord)()
End If
' create a new log record from the new textbox value
Dim _tempLog As New MyLogRecord(txb1.Text)
'add the new log to the list
MyLogs.Add(_tempLog)
'save it back in a session var:
Session("MyLogs") = MyLogs
4. in the part where you save the logs to the mysql db, you do it this way: first convert the list to a byte array and store it in a varbinary(MAX) column
'create a new binary formatter, include System.Runtime.Serialization.Formatters.Binary;
Dim formatter As New BinaryFormatter()
'create a byte array to store our logs list
Dim _logsBinary As Byte()
'create a memory stream to write the logs list into
Using _logStream As New MemoryStream()
'use the formatter to serialize the list in to an array of bytes
'directly into the memory stream
formatter.Serialize(_logStream, MyLogs)
'dump the memory stream into the byte array
_logsBinary = _logStream.ToArray()
End Using
' ... save the _logsBinary into mysql as a 'varbinary(max)' ...
5. in the place where you retrieve the logs from the mysql db, you de-serialize the byte array back to a logs list:
Dim MyLogs As New List(Of MyLogRecord)()
Dim formatter As New BinaryFormatter()
Using _logStream As New MemoryStream()
_logStream.Write(_logsBinary, 0, _logsBinary.Length)
_logStream.Position = 0
' de-serialize the byte array back into a logs list
MyLogs = DirectCast(formatter.Deserialize(_logStream), List(Of MyLogRecord))
End Using
6. in the place where you write the logs in your page, you do it this way:
Dim SB As New StringBuilder()
' create a temp date to compare against all the records,
' and initialize it with the first value or else you will have
' a orizontal line before the first row
Dim _prevDate As DateTime = MyLogs.First().[Date]
For Each _logRec As MyLogRecord In MyLogs
'take the date of the currently iterrated item and
'compare against the temp date, note that comparing months is not enough,
'month might be same/earlier but year can be higher
Dim _currentDate As DateTime = _logRec.[Date]
If _currentDate.Month > _prevDate.Month OrElse _currentDate.Year > _prevDate.Year Then
'append horizontal line
SB.AppendLine("<hr/>")
'update temp value
_prevDate = _currentDate
End If
'finally append the log: ToText() is the class custom
'function that we created above
SB.AppendLine(_logRec.ToText())
Next
'dump the logs into the server managed div:
Text_Div1.InnerHtml = SB.ToString()

PDFs missing EOF section on customer's server

Folks- I'm relatively new to ASP.NET, and have a question that has stumped my peers-- folks much more experienced than myself.
My company created a website that uses iTextSharp to build and stream PDFs. The functionality works perfectly on my company's development and staging/test servers. The customer's functionality isn't working well, however. The customer's server streams a file where the PDF is missing the last block of data representing the EOF section. The PDF seems to build correctly, streams correctly, but when users open the PDF, the following error displays: 'There was an error opening this document. The file is damaged and could not be repaired.'
By comparing the PDFs in a text viewer (comparing the PDFs from my server vice the customer's server), I can see that the EOF section is missing from the customer's PDF. I'll also note that no errors are thrown during PDF creation, if that's helpful. To make matters more difficult, I have no access to the customer's servers, so I won't be able to interact with the systems directly.
The asp.net version is 3.5. Both of our servers (my company and the customer) are: running IIS7.5 on Server 2008R2; using iTextSharp is 5.1.2; and are configured for FIPS compatibility.
I've read dozens and dozens of posts detailing why a PDF isn't created properly, why it may not be streaming, and all things related, but I haven't seen this particular issue before. I guess what I need to know in the short-term is: 1) what can I provide to help diagnose the issue, 2) where is a good place to start looking for areas of concern?
Also, I updated to revision 5.5.3 last night; same results-- it works fine on my servers, but produces broken PDFs on the customer's server.
Code added:
Public Function BuildReport(ByVal tblReport As DataTable, _
ByRef memStream As MemoryStream, _
ByRef strErrMsg As String) As Boolean
Dim booOK As Boolean = True
strErrMsg = String.Empty
' Create document
Try
' Create writer (listens to the document and directs PDF stream)
memStream = New MemoryStream()
Dim msWriter As PdfWriter = PdfWriter.GetInstance(_document, memStream)
msWriter.CloseStream = False
'Create header
Dim ev As New itsEvents
msWriter.PageEvent = ev
' Set document metadata
_document.AddTitle(_strMetaTitle)
_document.AddSubject(_strMetaSubject)
_document.AddCreator(_strMetaApplication)
_document.AddAuthor(_strMetaAuthor)
' Open document, add document content, close document
_document.Open()
AddReportContent(tblReport)
_document.Close()
Catch ex As Exception
booOK = False
strErrMsg = ex.Message
End Try
Return booOK
End Function
Private Sub AddReportContent(ByVal tblReport As DataTable)
' Count report columns
Dim intReportColumns As Integer = 0
For Each col As DataColumn In tblReport.Columns
If ContainedInColumnMask(col.ColumnName) Then
intReportColumns += 1
End If
Next
' Build table
Dim table As PdfPTable
Dim cell As PdfPCell
Dim phrase As Phrase
If intReportColumns >= 1 Then
' Init table
table = New PdfPTable(intReportColumns)
' Add title to table
'phrase = New Phrase(_strMetaTitle, _fontLarge)
'cell = New PdfPCell(phrase)
'cell.Colspan = intReportColumns
'cell.HorizontalAlignment = 1 ' 0=Left, 1=Centre, 2=Right
'table.AddCell(cell)
' Add column headers to table
Dim i As Integer = 0
Dim intColWidth As Integer
Dim intColWidths As Integer() = New Integer(intReportColumns - 1) {}
Dim intColWidthTotal As Integer = 0
Dim strColName As String
For Each col As DataColumn In tblReport.Columns
If ContainedInColumnMask(col.ColumnName) Then
strColName = col.ColumnName
If (col.ExtendedProperties.Item("NOTEXTEXPORT") <> True) Then
If col.ExtendedProperties.Contains("FRIENDLYNAME") Then
strColName = col.ExtendedProperties.Item("FRIENDLYNAME")
End If
End If
phrase = New Phrase(strColName, _fontMedium)
cell = New PdfPCell(phrase)
cell.BorderWidth = 1
cell.BackgroundColor = iTextSharp.text.BaseColor.LIGHT_GRAY
'cell.BackgroundColor = iTextSharp.text.Color.LIGHT_GRAY
table.AddCell(cell)
intColWidth = GetColumnWidth(col, strColName, _fontMedium.Size, _fontSmall.Size)
intColWidths(i) = intColWidth
intColWidthTotal += intColWidth
i += 1
End If
Next
table.TotalWidth = intColWidthTotal
table.SetWidths(intColWidths)
' Add rows to table
For Each row As DataRow In tblReport.Rows
For Each col As DataColumn In tblReport.Columns
If ContainedInColumnMask(col.ColumnName) Then
phrase = New Phrase(SetBlankIfNothing(row.Item(col.ColumnName).ToString()), _fontSmall)
cell = New PdfPCell(phrase)
cell.BorderWidth = 0.5
table.AddCell(cell)
End If
Next
Next
Else
' Init table
table = New PdfPTable(1)
' Nothing to add to table
table.AddCell(String.Empty)
End If
' Add table to document
_document.Add(table)
End Sub
Public Sub New(ByVal strMetaTitle As String, _
ByVal strMetaSubject As String, _
ByVal strMetaApplication As String, _
ByVal strMetaAuthor As String, _
Optional ByVal strColumnMask As String = "")
GetStaticInfo()
_strMetaTitle = strMetaTitle
_strMetaSubject = strMetaSubject
_strMetaApplication = strMetaApplication
_strMetaAuthor = strMetaAuthor
_document = New iTextSharp.text.Document(_itsPage, _itsMarginLeft, _itsMarginRight, _itsMarginTop, _itsMarginBottom)
If strColumnMask <> "" And Not strColumnMask Is Nothing Then
_strColumnMask = strColumnMask
End If
End Sub
Public Sub New(ByVal strMetaTitle As String, _
ByVal strMetaSubject As String, _
ByVal strMetaApplication As String, _
ByVal strMetaAuthor As String, _
Optional ByVal strColumnMask As String = "")
GetStaticInfo()
_strMetaTitle = strMetaTitle
_strMetaSubject = strMetaSubject
_strMetaApplication = strMetaApplication
_strMetaAuthor = strMetaAuthor
_document = New iTextSharp.text.Document(_itsPage, _itsMarginLeft, _itsMarginRight, _itsMarginTop, _itsMarginBottom)
If strColumnMask <> "" And Not strColumnMask Is Nothing Then
_strColumnMask = strColumnMask
End If
End Sub

How to test a controller which updates what was posted to it

This seems really simple, but I can't seem to get it to work. I want to unit test my controller's assign action. It takes a IEnumerable(Of Integer) which represent the ID's of all the objects to assign.
Here's the code I've written, I'm getting an error on the Do statement (I copied the code from Ayende's blog here http://ayende.com/blog/3397/rhino-mocks-3-5-a-feature-to-be-proud-of-seamless-do).
<Test()> _
Public Sub Assign_Post_Should_Assign_All_Audits_Provided()
Dim auditsToAssign As IEnumerable(Of HvacAudit) = HvacAuditsGenerator.GenerateAudits() _
.Unassigned()
Dim auditIDs As IEnumerable(Of Integer) = auditsToAssign.Select(Function(audit, index) audit.HvacAuditID)
Dim hvacAuditRepo As IHvacAuditRepository = MockRepository.GenerateMock(Of IHvacAuditRepository)()
hvacAuditRepo.Stub(Sub(repo) repo.GetAuditByID(1)) _
.Do(Function(invocation) invocation.ReturnValue = auditsToAssign.Single(Function(audit) audit.HvacAuditID = invocation.Arguments(0)))
Dim controller As New HvacAuditController(hvacAuditRepo)
Dim r As ViewResult = controller.Assign(auditIDs).AssertViewRendered()
r.AssertAssignedAuditCount(auditsToAssign.Count)
auditsToAssign.AssertAreAssigned()
hvacAuditRepo.AssertWasCalled(Sub(h) h.SaveChanges())
End Sub
I was able to fix this by changing the code to use a function lambda instead of a sub lambda and return the value directly. I'm not sure what Ayende's blog was referring to.
<Test()> _
Public Sub Assign_Post_Should_Assign_All_Audits_Provided()
Dim auditsToAssign As IEnumerable(Of HvacAudit) = HvacAuditsGenerator.GenerateAudits() _
.Unassigned()
Dim auditIDs As IEnumerable(Of Integer) = auditsToAssign.Select(Function(audit, index) audit.HvacAuditID)
Dim hvacAuditRepo As IHvacAuditRepository = MockRepository.GenerateMock(Of IHvacAuditRepository)()
hvacAuditRepo.Stub(Sub(repo) repo.GetAuditByID(1)) _
.Do(Function(auditID as Integer) Return auditsToAssign.Single(Function(audit) audit.HvacAuditID = auditID))
Dim controller As New HvacAuditController(hvacAuditRepo)
Dim r As ViewResult = controller.Assign(auditIDs).AssertViewRendered()
r.AssertAssignedAuditCount(auditsToAssign.Count)
auditsToAssign.AssertAreAssigned()
hvacAuditRepo.AssertWasCalled(Sub(h) h.SaveChanges())
End Sub

Resources