Telegram API

di il
13 risposte

Telegram API

Ho bisogno di implementare le API di Telegram e in particolare mi sto basando sulla documentazione ufficiale che presenta un esempio di bot scritto in c# per console. Ho bisogno di convertirlo in vb.net per WinForms. Non conoscendo il c#, mi sono basato su multipli servizi online che convertono c# to vb.net.
Questo è il codice che sono riuscito a convertire:
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
Il codice ha bisogno del package Telegram.Bot da NuGet. Sfortunatamente il progetto su github non supporta più richiesta di aiuto se non tramite telegram stesso.

Qualcuno può darmi una mano per convertire il codice?
Grazie

13 Risposte

  • Re: Telegram API

    matty95srk ha scritto:


    Qualcuno può darmi una mano per convertire il codice?
    Cosa non riesci a convertire? E che errore ti da?
  • Re: Telegram API

    Non riesco a trasformare un pò tutto il codice. Sono riuscito a scrivere questo
    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
    ma ottengo due errori:

    'StartReceiving' is not a member of 'TelegramBotClient'.
    Type 'ReceiverOptions' is not defined. Ho notato comunque che quel package per .net core, mentre io sto lavorando per .net framework. Ho provato a creare un app winforms per .net6.0 ma ottengo lo stesso entrambi gli errori.
  • Re: Telegram API

    matty95srk ha scritto:


    Ho notato comunque che quel package per .net core, mentre io sto lavorando per .net framework. Ho provato a creare un app winforms per .net6.0 ma ottengo lo stesso entrambi gli errori.
    Stai traducendo un esempio che probabilmente non è più aggiornato rispetto alla libreria client che stai utilizzando.

    Secondo me, meglio leggere la documentazione della libreria e prendere quell'esempio come mero spunto, ma cercando di seguire appunto la documentazione piuttosto che tradurre da linguaggio a linguaggio senza ragionamenti o formazione su quello che si sta facendo.
  • Re: Telegram API

    Perdonami Alka, ho omesso il link alla documentazione ufficiale . Ho risolto gli errori precedenti installando il package Telegram.Bot.Extensions.Polling e importando Imports Telegram.Bot.Extensions.Polling . Non ottengo più quegli errori, per cui ora il codice completo privo di errori è :
    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
    
    Public Class Form1
        Sub Main(args As String())
            DoWork().Wait()
        End Sub
    
        Private Async Function DoWork() As Task
            Dim botClient = New TelegramBotClient("Il mio token id personale")
            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 Class
    Come potrei convertirlo per win forms app? MI servirebbe usare dei bottoni per sfruttare le funzioni. Ti Ringrazio
  • Re: Telegram API

    matty95srk ha scritto:


    Come potrei convertirlo per win forms app? MI servirebbe usare dei bottoni per sfruttare le funzioni. Ti Ringrazio
    In che senso "convertirlo"? Nel codice si fa già riferimento a un Form.

    Se devi usare dei pulsanti, basta che li posizioni sulla finestra e gestisci gli eventi legati al click andando poi a chiamare la funzione che ti serve. Non capisco la difficoltà.
  • Re: Telegram API

    La funzione DoWork la posso inserire in un button
     Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim botClient = New TelegramBotClient("5113735396:AAFwJxh0rBQDwiJAcefukGRoCvhQcH5-NRQ")
            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 Sub
    ma come potrei chiamare la funzione HandleUpdateAsync da un altro pulsante avendo
    ByVal botClient As ITelegramBotClient, ByVal update As Update, ByVal cancellationToken As CancellationToken
    nella funzione stessa?
  • Re: Telegram API

    matty95srk ha scritto:


    ma come potrei chiamare la funzione HandleUpdateAsync da un altro pulsante avendo
    ByVal botClient As ITelegramBotClient, ByVal update As Update, ByVal cancellationToken As CancellationToken
    nella funzione stessa?
    La funzione HandleUpdateAsync non la devi chiamare tu: è l'API a invocarla quando ha bisogno di segnalarti un aggiornamento.

    Sta di fatto cercando di scrivere senza aver ancora imparato a leggere: se scrivi del codice, è fondamentale che tu sappia qual è il significato di quello che scrivi, e se lo fai passivamente copiando/incollando codice altrui senza documentarti su quello che fa e sulla sintassi di base, è inutile chiedere aiuto... tanto vale che mi chiedi di farlo al posto tuo, perché in caso contrario il risultato sarebbe un dubbio da spiegare su ogni singola riga del codice.
  • Re: Telegram API

    In primis vorrei dire che ha completamente ragione. Prima di cimentarmi nel codice dovrei capire cosa fa ogni singola linea. Partendo da questo fatto, vorrei precisare che ci sto mettendo tutta la mia buona volontà e impegno nel capire cosa fa quel codice. Inoltre vorrei aggiungere che oltre a quello da lei già citato, la mia inesperienza su console è notevole, in quanto non mi sono mai cimentato per console ma solo per WinForm, per cui la mia necessità di usare controlli è quasi un must..
    Vorrei sbatterci la testa perchè quello di cui ho bisogno è inviare un semplice messaggio, per cui il mio scopo è capire il codice e riuscire ad implementarlo nella maniera di cui più ho bisogno.
    Lei ha dichiarato :
    Se devi usare dei pulsanti, basta che li posizioni sulla finestra e gestisci gli eventi legati al click andando poi a chiamare la funzione che ti serve. Non capisco la difficoltà.
    dunque mi sono messo compilatore alla mano e, dopo aver letto nuovamente la documentazione per inviare un messaggio https://telegrambots.github.io/book/2/send-msg/index.html ho provato ad implementare il tutto:

    Sull'evento click di button1 ho chiamato la funzione DoWork con il codice:
     DoWork()
    e ora devo usare un altro button per inviare il messaggio. Il codice convertito in vb.net dovrebbe essere:
    
    Dim Message = Await botClient.SendTextMessageAsync(ChatId, "hello world", CancellationToken)
    Dunque ora ho 3 errori:

    'ChatId' is a class type and cannot be used as an expression.
    'CancellationToken' is a structure type and cannot be used as an expression.
    'botClient' is not declared. It may be inaccessible due to its protection level.

    Dunque mi fa capire che devo dichiarare ChatID, CancellationToken e botClient pubblici. Cosa faccio?
    li estraggo dalle loro funzioni, taglio, e incollo sotto Public Class Form1.
    Il codice completo ora è
    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
    
    Public Class Form1
        Dim chatId As String = Update.Message.Chat.Id
        Dim messageText As String = Update.Message.Text
        Dim botClient = New TelegramBotClient("Il mio token id personale")
        Dim cts = New CancellationTokenSource()
    
    
        Sub Main(args As String())
            DoWork().Wait()
        End Sub
    
        Private Async Function DoWork() As Task
            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
    
            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
    
        Private Async Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
            Dim Message = Await botClient.SendTextMessageAsync(chatId, "hello world", cts)
        End Sub
    End Class
    Ora dunque ho risolto quei 3 errori, ma ottengo 4 nuovi errori:

    Expression does not produce a value. sulla linea Dim chatId As String = Update.Message.Chat.Id
    Expression does not produce a value. sulla linea Dim messageText As String = Update.Message.Text
    'AddressOf' expression cannot be converted to 'Object' because 'Object' is not a delegate type.
    'AddressOf' expression cannot be converted to 'Object' because 'Object' is not a delegate type.
    entrambi su
    botClient.StartReceiving(AddressOf HandleUpdateAsync, AddressOf HandleErrorAsync, receiverOptions, cts.Token)
    Ora passo alla parte da nabbo: rimuovo (ByVal botClient As ITelegramBotClient, ByVal exception As Exception, ByVal cancellationToken As CancellationToken) dalla funzione HandleErrorAsync perchè li sto già dichiarando pubblici..
    e nella funzione DoWork rimuovo gli AddressOf da botClient.StartReceiving(receiverOptions, cts.Token). In teoria ora non ho più quei due ultimi errori . I problemi persistenti restano i primi due.

    @Alka perdonami il lungo post, ma è per farti capire che io non voglio la pappa pronta. Ho trascritto ciò che sto provando a fare e nonostante tutto, mi ritrovo bloccato ancora in questa situazione. Spero tu capisca la mia posizione, non ho bisogno della pappa pronta, vorrei cucinarmi del cibo da solo. Ho solo bisogno di uno chef come te che mi indirizzi sugli ingredienti giusti.
    Ti ringrazio.
    Mattia
  • Re: Telegram API

    matty95srk ha scritto:


    Prima di cimentarmi nel codice dovrei capire cosa fa ogni singola linea.
    Non solo. Ho precisato anche che dovresti capire ciò che scrivi.

    Prendiamo anche solo questa riga:
    
    Dim messageText As String = Update.Message.Text
    
    Cosa significa per te?
    Se l'hai scritta, e non vai a caso come dici, suppongo che tu sappia perché l'hai scritta e quello che fa.
  • Re: Telegram API

    Direi che prende la stringa da update.message.text e la mette in una variabile a parte quale messagetext
  • Re: Telegram API

    matty95srk ha scritto:


    Direi che prende la stringa da update.message.text e la mette in una variabile a parte quale messagetext
    Esattamente.

    Da questo dovrebbero scaturirti altre domande, ad esempio...
    a che serve?
    perché metterla?
    che valore sta finendo in quella variabile?

    Io non lo so, onestamente.
    Infatti, credo che quell'istruzione non abbia senso, ma se c'è una motivazione... ben venga.
  • Re: Telegram API

    Secondo la documentazione , essa serve per ricevere i messaggi dal client e risponderli. In realtà non proprio quello di cui avevo bisogno, ma ormai l'ho già tradotto in vb.net e me lo tengo. Devo aggiungere solo https://telegrambots.github.io/book/2/send-msg/index.html
    Ho inoltre usato variabili globali quale

    Public Class Form1
     Public chatId As String
        Public messageText As String
        Public botClient = New TelegramBotClient("Il mio token id personale")
        Public cts = New CancellationTokenSource()
    per cui la variabile HandleUpdateAsync diventa
    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)
        End Function
    Ritorna il problema che ho descritto prima.. Come richiamo la funzione HandleUpdateAsync da bottone?
  • Re: Telegram API

    matty95srk ha scritto:


    Secondo la documentazione , essa serve per ricevere i messaggi dal client e risponderli.
    Scusa, ma l'esempio che riporti è completamente diverso dal codice che hai scritto tu.

    Tu hai dichiarato un campo nel Form a cui assegni, in fase di costruzione, il valore ottenuto da Update.Message.Text, dove Update è una classe, Message è il nome di una proprietà di una istanza della classe Update, che dovrà quindi essere creata e probabilmente è il framework a farlo, quando riceve un aggiornamento, per veicolarti le informazioni relative, mentre Text infine è a sua volta una proprietà dell'oggetto Message.

    Nel codice di esempio corretto, infatti, un oggetto di tipo Update viene passato come parametro (con nome update, maiuscole e minuscole sono cose diverse!) al metodo HandleUpdateAsync che NON è una funzione da richiamare su qualche click, come stai cercando di fare tu, ma è la funzione che affidata al client Telegram (passata chiamando StartReceiving per iniziare a ricevere) viene richiamata dal client stesso quando riceve un aggiornamento e vuole notificartelo, indicandoti tutti i parametri necessari.

    matty95srk ha scritto:


    Ho inoltre usato variabili globali quale [...]
    NON sono variabili globali!

    matty95srk ha scritto:


    [...] per cui la variabile HandleUpdateAsync diventa [...]
    HandleUpdateAsync NON è una variabile!

    E' ovvio che se non distingui un campo da una variabile, una variabile da un parametro, un oggetto da una classe, ecc. e - ripeto - scrivi codice a caso senza sapere quello che stai realmente facendo, non ne uscirai mai fuori.

    Prima studia, almeno i rudimenti della OOP e del linguaggio che stai usando, poi programmi.

    matty95srk ha scritto:


    Ritorna il problema che ho descritto prima.. Come richiamo la funzione HandleUpdateAsync da bottone?
    Ritorna la risposta che ti ho già dato più volte: il metodo (e non variabile) HandleUpdateAsync NON devi chiamarlo tu: ti viene richiamato dal client Telegram!
Devi accedere o registrarti per scrivere nel forum
13 risposte