Declaration of VAR

and some other stuff

C# / .NET Core, publish to Telegram channel

2018-03-31 14:20:57 +0200

2018-03-31 14:20:57 +0200 | Comments

I can’t believe I haven’t wrote about publishing to Telegram yet. I have articles about Twitter, Facebook and VK, but I should have started with Telegram as it is the easiest among them all.

We have a .NET Core MVC website and we want to publish our content to a Telegram channel. The result should look like this:

So it is a picture and a post in two separate messages. We can have the post as a picture’s description, but that doesn’t feel right.

Okay, how to do this. First you need to have:

  1. Telegram channel;
  2. Telegram bot (just his token). Here’s how to create one;
  3. This bot has to be an administrator at your channel.

When you have all that, the only thing you need to do is to send a HTTP request to Telegram API. Actually, two requests:

  1. Send a picture to your channel. We’ll go the easy way - by sending an URL of the picture, because we have it at our website;
  2. Send the text of your post.

Basically, here’s what it takes to send a text message:

string token = "YOUR-BOT-TOKEN",
       channel = "@YOUR-CHANNEL";

using (var httpClient = new HttpClient())
{
    var res = httpClient.GetAsync(
        $"https://api.telegram.org/bot{token}/sendMessage?chat_id={channel}&text=ololo"
        ).Result;
    if (res.StatusCode == HttpStatusCode.OK)
    { /* done, go check your channel */ }
    else
    { /* something went wrong */ }
}

If you need to send a complex text, like more than one word, with some symbols and newlines, then use StringBuilder and Environment.NewLine. Also don’t forget to encode it with WebUtility.UrlEncode() before sending.

Here’s a C# class that I’ve created for my .NET Core MVC project:

public class Telegram
{
    IConfiguration _configuration;
    ILogger _logger;

    readonly string _telegramAPI;
    readonly string _botToken;
    readonly string _channel;
    
    public Telegram(IConfiguration configuration, ILogger logger)
    {
        _configuration = configuration;
        _logger = logger;

        _telegramAPI = _configuration.GetSection("Telegram:API").Value;
        _botToken = _configuration.GetSection("Telegram:BotToken").Value;
        _channel = _configuration.GetSection("Telegram:Channel").Value;
    }

    /// <summary>
    /// Publish to Telegram channel.
    /// </summary>
    /// <returns>0 - successful posting, 1 - published only picture, 2 - nothing has been published</returns>
    /// <param name="post">post to publish</param>
    /// <param name="picture">URL of the image to publish</param>
    public int PublishToTelegramChannel(string post, string picture)
    {
        if(!SendPicture(picture, _channel))
        {
            return 2;
        }

        if(!SendMessage(post, _channel))
        {
            return 1;
        }
        return 0;
    }

    /// <summary>
    /// Send a message to a Telegram chat/channel
    /// </summary>
    /// <param name="msg">Message text</param>
    /// <param name="sendTo">Recepient</param>
    public bool SendMessage(string msg, string sendTo)
    {
        try
        {
            msg = WebUtility.UrlEncode(msg);

            using (var httpClient = new HttpClient())
            {
                var res = httpClient.GetAsync($"{_telegramAPI}{_botToken}/sendMessage?chat_id={sendTo}&text={msg}&parse_mode=HTML&disable_web_page_preview=true").Result;
                if (res.StatusCode != HttpStatusCode.OK)
                {
                    //string content = res.Content.ReadAsStringAsync().Result;
                    //string status = res.StatusCode.ToString();
                    throw new Exception($"Couldn't send a message via Telegram. Response from Telegram API: {res.Content.ReadAsStringAsync().Result}");
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex.Message);
            return false;
        }
        return true;
    }

    /// <summary>
    /// Send a picture to a Telegram chat/channel
    /// </summary>
    /// <param name="picture">URL of the image to send</param>
    /// <param name="sendTo">Recepient</param>
    public bool SendPicture(string picture, string sendTo)
    {
        try
        {
            picture = WebUtility.UrlEncode(picture);
            
            using (var httpClient = new HttpClient())
            {
                var res = httpClient.GetAsync($"{_telegramAPI}{_botToken}/sendPhoto?chat_id={sendTo}&photo={picture}").Result;
                if (res.StatusCode != HttpStatusCode.OK)
                {
                    //string content = res.Content.ReadAsStringAsync().Result;
                    //string status = res.StatusCode.ToString();
                    throw new Exception($"Couldn't send a picture to Telegram. Response from Telegram API: {res.Content.ReadAsStringAsync().Result}");
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex.Message);
            return false;
        }
        return true;
    }
}

The easiest SoMe integration in human history.