Domanda Convertire Telegram API da c# console a vb.net WinForms

Matty80

Utente Bronze
18 Settembre 2020
45
11
0
25
Ultima modifica:
Salve, sto cercando di implementare le api di telegram in particolare sono interessato ad inviare un messaggio. Dalla documentazione ufficiale in c# ho trovato Questo esempio ma è in c# per console e vorrei convertirlo in vb.net WinForms. Il codice ha bisogno del package Telegram.Bot scaricabile da NuGet. Ho già provato ad usare tools online per la conversione, ma questa non avviene come previsto.
Questo è il codice che sono riuscito a convertire per il momento:

Codice:
 Imports Telegram.Bot
  Imports Telegram.Bot.Exceptions
  Imports Telegram.Bot.Extensions.Polling
  Imports Telegram.Bot.Types
  Imports Telegram.Bot.Types.Enums
       
 Private Async Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
         Dim botClient As New TelegramBotClient("My token ID")
         Dim bot = Await botClient.GetMeAsync()
         MessageBox.Show($"Hello, World! I am user {bot.Id} and my name is {bot.FirstName}.")
         Message sentMessage = Await botClient.SendTextMessageAsync()
   
     End Sub    
  Imports var cts = New CancellationTokenSource()
       
  ' StartReceiving does not block the caller thread. Receiving is done on the ThreadPool.
  var receiverOptions = New ReceiverOptions
  {
      AllowedUpdates =
      {
             
      }
   ' receive all update types
       
  }
       
  botClient.StartReceiving(
      HandleUpdateAsync,
      HandleErrorAsync,
      receiverOptions,
      Dim cts.Token) As cancellationToken:
       
       
  Dim me As var =  await botClient.GetMeAsync()
       
  MsgBox($"Start listening for @{me.Username}")
   
       
  ' Send cancellation request to stop bot
  cts.Cancel()
       
  async Function HandleUpdateAsync(ByVal botClient As ITelegramBotClient, ByVal update As Update, ByVal cancellationToken As CancellationToken) As Task
      ' Only process Message updates: https://core.telegram.org/bots/api#message
      If update.Type <> UpdateType.Message Then
          Return
      End If
      ' Only process text messages
      If update.MessageNot .Type <> MessageType.Text Then
          Return
      End If
       
      Dim chatId As String =  update.Message.Chat.Id
      Dim messageText As String =  update.Message.Text
       
     MsgBox($"Received a '{messageText}' message in chat {chatId}.")
       
      ' Echo received message text
      Message sentMessage = await botClient.SendTextMessageAsync(
          chatId: chatId,
          text: "You said:\n" + messageText,
          Dim cancellationToken) As cancellationToken:
  End Function
       
  Private Function HandleErrorAsync(ByVal botClient As ITelegramBotClient, ByVal exception As Exception, ByVal cancellationToken As CancellationToken) As Task
      var ErrorMessage = exception switch
      {
          ApiRequestException apiRequestException
              => $"Telegram API Error:\n[{apiRequestException.ErrorCode}]\n{apiRequestException.Message}",
          _ => exception.ToString()
      }
       
       
     MsgBox(ErrorMessage)
      Return Task.CompletedTask
  End Function

Qualcuno potrebbe aiutarmi? Vi ringrazio
 
Il convertitore falliva per diversi motivi, alcuni per feature C# assenti in VB, altri per keyword riservate in VB (ad esempio me) quindi andava fatto a mano.
Ti posto qui l'esempio ma non so come tu possa fare con i WinForms, da quello che vedo quel package per telegram è per .NET Core. Non l'ho provato.

Codice:
Imports System
Imports System.Threading
Imports Telegram.Bot
Imports Telegram.Bot.Exceptions
Imports Telegram.Bot.Extensions.Polling
Imports Telegram.Bot.Types
Imports Telegram.Bot.Types.Enums

Module Program
    Sub Main(args As String())
        DoWork().Wait()
    End Sub

    Private Async Function DoWork() As Task
        Dim botClient = New TelegramBotClient("{YOUR_ACCESS_TOKEN_HERE}")
        Dim cts = New CancellationTokenSource()
        Dim receiverOptions = New ReceiverOptions()

        botClient.StartReceiving(AddressOf HandleUpdateAsync, AddressOf HandleErrorAsync, receiverOptions, cts.Token)

        Dim _me = Await botClient.GetMeAsync()
        Console.WriteLine($"Start listening for @{_me.Username}")
        Console.ReadLine()
        ' Send cancellation request to stop bot
        cts.Cancel()
    End Function

    Private Function HandleErrorAsync(ByVal botClient As ITelegramBotClient, ByVal exception As Exception, ByVal cancellationToken As CancellationToken) As Task
        Dim ErrorMessage = exception.ToString()
        Console.WriteLine(ErrorMessage)
        Return Task.CompletedTask
    End Function

    Async Function HandleUpdateAsync(ByVal botClient As ITelegramBotClient, ByVal update As Update, ByVal cancellationToken As CancellationToken) As Task
        ' Only process Message updates: https://core.telegram.org/bots/api#message
        If update.Type <> UpdateType.Message Then
            Return
        End If
        ' Only process text messages
        If update.Message.Type <> MessageType.Text Then
            Return
        End If

        Dim chatId As String = update.Message.Chat.Id
        Dim messageText As String = update.Message.Text

        Console.WriteLine($"Received a '{messageText}' message in chat {chatId}.")

        ' Echo received message text
        Dim msg = "You said:" & vbLf & messageText
        Dim sentMessage = Await botClient.SendTextMessageAsync(chatId, msg, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, cancellationToken)
    End Function
End Module
 
Ho provato il tuo codice su una nuova app winforms .net 6.0 ma ottengo li stessi errori della versione .net framework ovvero:-

Codice:
'StartReceiving' is not a member of 'TelegramBotClient'.
Type 'ReceiverOptions' is not defined.
 
Se ti da questi due errori le cose sono due:
  1. Non hai inserito Imports Telegram.Bot.Extensions.Polling
  2. Hai installato il package Telegram.Bot senza anche il package Telegram.Bot.Extensions.Polling
 
Ultima modifica da un moderatore:
Ah ok grazie, intellisense non mi indicava di scaricare pure quel package.. Sto provando ora a splittare le funzioni che posso mettere dentro a dei bottoni. Per cui sto provando con :
Nell'evento Load del form


Codice:
 Dim botClient = New TelegramBotClient("-ACCESS TOKEN REDACTED-")
        Dim cts = New CancellationTokenSource()
        Dim receiverOptions = New ReceiverOptions()

        botClient.StartReceiving(AddressOf HandleUpdateAsync, AddressOf HandleErrorAsync, receiverOptions, cts.Token)

        Dim _me = Await botClient.GetMeAsync()
        Console.WriteLine($"Start listening for @{_me.Username}")
        Console.ReadLine()
        ' Send cancellation request to stop bot
        cts.Cancel()

inoltre suppongo che il seguente codice possa essere messo dentro ad un button per inviare e / o ascoltare i messaggi da telegram

Codice:
If update.Type <> UpdateType.Message Then
            Return
        End If
        ' Only process text messages
        If update.Message.Type <> MessageType.Text Then
            Return
        End If

        Dim chatId As String = update.Message.Chat.Id
        Dim messageText As String = update.Message.Text
        messageText = TextBox1.Text
        Console.WriteLine($"Received a '{messageText}' message in chat {chatId}.")

        ' Echo received message text
        Dim msg = "You said:" & vbLf & messageText
        Dim sentMessage = Await botClient.SendTextMessageAsync(chatId, msg, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, cancellationToken)

Ma ci sono i parametri (ByVal botClient As ITelegramBotClient, ByVal update As Update, ByVal cancellationToken As CancellationToken nella funzione HandleUpdateAsync . Come pensi li possa passare per usarlo sotto un button? Grazie
 
Ultima modifica da un moderatore:
Ciao Code, nella tua attesa sono andato avanti col codice e mi ritrovo con il seguente

Codice:
Imports System
Imports System.Threading
Imports Telegram.Bot
Imports Telegram.Bot.Exceptions
Imports Telegram.Bot.Extensions.Polling
Imports Telegram.Bot.Types
Imports Telegram.Bot.Types.Enums
Imports Telegram.Bot.Types.ReplyMarkups
Public Class Form1
    Public chatId As String
    Public messageText As String
    Public botClient = New TelegramBotClient("-ACCESS TOKEN REDACTED-")
    Public cts = New CancellationTokenSource()
    Public update As Update

    Sub Main(args As String())
        DoWork().Wait()
    End Sub

    Private Async Function DoWork() As Task
        Dim receiverOptions = New ReceiverOptions()

        botClient.StartReceiving(receiverOptions, cts.Token)

        Dim _me = Await botClient.GetMeAsync()
        Console.WriteLine($"Start listening for @{_me.Username}")
        Console.ReadLine()

        ' Send cancellation request to stop bot
        cts.Cancel()
    End Function

    Private Function HandleErrorAsync(ByVal botClient As ITelegramBotClient, ByVal exception As Exception, ByVal cancellationToken As CancellationToken) As Task
        Dim ErrorMessage = exception.ToString()
        Console.WriteLine(ErrorMessage)
        Return Task.CompletedTask
    End Function

    Async Function HandleUpdateAsync(ByVal botClient As ITelegramBotClient, ByVal update As Update, ByVal cancellationToken As CancellationToken) As Task
        ' Only process Message updates: https://core.telegram.org/bots/api#message
        If update.Type <> UpdateType.Message Then
            Return
        End If
        ' Only process text messages
        If update.Message.Type <> MessageType.Text Then
            Return
        End If
        chatId = update.Message.Chat.Id
        messageText = update.Message.Text

        Console.WriteLine($"Received a '{messageText}' message in chat {chatId}.")

        ' Echo received message text
        Dim msg = "You said:" & vbLf & messageText
        Dim sentMessage = Await botClient.SendTextMessageAsync(ChatId, msg, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, cancellationToken)
        Dim Message = Await botClient.SendTextMessageAsync(chatId, "hello world", cts)
    End Function

    Private Async Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
        'ascolto messaggi in entrata

        HandleUpdateAsync(botClient, Update, cts)
        '
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ' mi connetto a telegram

        DoWork()
    End Sub

    Private Async Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
        'invio un messaggio

        chatId = update.Message.Chat.Id
        Dim Message = Await botClient.SendTextMessageAsync(chatId, "hello world", cts)
    End Sub
End Class

Mi sto basando su due api:
1) riceve i messaggi, ma del quale non sto dando tanta priorità https://telegrambots.github.io/book/1/example-bot.html
2) inviare un messaggio, che dalla documentazione https://telegrambots.github.io/book/2/send-msg/index.html ho convertito in vb.net e lo sto usando nel button 6

Durante il debug sto avendo due errori:
1) Cast non valido su HandleUpdateAsync(botClient, Update, cts) nel button 5
2) System.NullReferenceException: 'Riferimento a un oggetto non impostato su un'istanza di oggetto.' nel codice del button 6 quando tento di inviare un messaggio.

Non so se hai mai utilizzato questa api, perciò non sentirti in obbligo di rispondermi. Se invece l'hai già utilizzata, cosa sto sbagliando? Grazie
 
Non l'ho mai utilizzata, ma vedo comunque che non va usata così.
Il button5 è sbagliato, la funzione HandleUpdateAsync non va chiamata direttamente, viene chiamata in automatico quando il bot riceve un update (per quello l'ho passata a StartReceiving).
Il button6 ti dà errore perché stai usando la variabile di classe update tuttavia non viene mai settata e quindi è null (Nothing in VB). Non ho indagato quale sia il modo corretto per inviare un messaggio ma sicuramente non è quello, soprattutto se consideri che un bot può gestire molte chat e tu dovresti specificare il chatId interessato e non è detto che sia l'ultimo da cui hai ricevuto il messaggio visto che lo invii solo al click del bottone.

PS: ho modificato i tuoi post per rimuovere l'access token, non devi mai pubblicare chiavi e token privati per API.
 
Non l'ho mai utilizzata, ma vedo comunque che non va usata così.
Il button5 è sbagliato, la funzione HandleUpdateAsync non va chiamata direttamente, viene chiamata in automatico quando il bot riceve un update (per quello l'ho passata a StartReceiving).
Il button6 ti dà errore perché stai usando la variabile di classe update tuttavia non viene mai settata e quindi è null (Nothing in VB). Non ho indagato quale sia il modo corretto per inviare un messaggio ma sicuramente non è quello, soprattutto se consideri che un bot può gestire molte chat e tu dovresti specificare il chatId interessato e non è detto che sia l'ultimo da cui hai ricevuto il messaggio visto che lo invii solo al click del bottone.

PS: ho modificato i tuoi post per rimuovere l'access token, non devi mai pubblicare chiavi e token privati per API.
Grazie Junk, cosa intendi per " per quello l'ho passata a StartReceiving"? Noto che il codice è rimasto così come l'ho postato io. Sbaglio? Saresti così cortese di mostrarmi il codice corretto che intendi?
Dalla documentazione https://telegrambots.github.io/book/2/send-msg/index.html, un semplice messaggio di testo viene passato con ChatId, testo, cancellationToken.
Ti ringrazio per aver rimosso il token id, ma quello è solo un token che fa riferimento ad un bot appena creato. per cui per il mio utilizzo futuro ne avrei creato un'altro.
Il ChatId penso che si riferisca alla prima parte numerica del token come descritto qui https://telegrambots.github.io/book/1/quickstart.html
 
Grazie Junk, cosa intendi per " per quello l'ho passata a StartReceiving"? Noto che il codice è rimasto così come l'ho postato io. Sbaglio? Saresti così cortese di mostrarmi il codice corretto che intendi?
Dalla documentazione https://telegrambots.github.io/book/2/send-msg/index.html, un semplice messaggio di testo viene passato con ChatId, testo, cancellationToken.
Ti ringrazio per aver rimosso il token id, ma quello è solo un token che fa riferimento ad un bot appena creato. per cui per il mio utilizzo futuro ne avrei creato un'altro.
Il ChatId penso che si riferisca alla prima parte numerica del token come descritto qui https://telegrambots.github.io/book/1/quickstart.html

La prima parte numerica del token è lo user id, come dice nel link che hai postato. Un singolo bot è come fosse un utente e può chattare con diversi utenti. Immagino che visto che sono gli utenti umani ad iniziare la chat dovresti salvere il chatId che ricevi in HandleUpdateAsync tramite il parametro update ed usarlo in seguito se vuoi rispondergli.

Per StartReceiving mi riferisco al cambio che hai fatto:
Codice:
' Hai sostituito
botClient.StartReceiving(AddressOf HandleUpdateAsync, AddressOf HandleErrorAsync, receiverOptions, cts.Token)
' Con:
botClient.StartReceiving(receiverOptions, cts.Token)
 
Ultima modifica:
In realtà la faccenda è più semplice.. Il bot serve solo ed unicamente a me, per ricevere del testo dal mio programma, per cui il chat id sarà solo il mio, singolarmente quello del token.. correggimi se sbaglio..
cmq usando
Codice:
botClient.StartReceiving(AddressOf HandleUpdateAsync, AddressOf HandleErrorAsync, receiverOptions, cts.Token)
ricevo due errori sull stessa linea
'AddressOf' expression cannot be converted to 'Object' because 'Object' is not a delegate type.

Grazie