I want to send a message and photo to a channel with my bot in c# 2013. Message and photo should be sent in one box. Photo in above the message .

i can send a message to the channel successfully but there are 2 problems:

  1. when send photo , this error shows:

The remote server returned an error: (400) Bad Request.

  1. I cannot send a text and photo together in only 1 send.

code :

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using Telegram.Bot;
    using Telegram.Bot.Types;
    using System.Net;

    namespace SendTxt-Photo
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
         string  Token = "adasdsadsadsadasds";
          string  channel_id = "@BestLaptop";

            private void Form1_Load(object sender, EventArgs e)
            {

            }


  private void button1_Click(object sender, EventArgs e)
        {

         using (var stream = File.Open(@"image/1.jpg", FileMode.Open))
          {
           WebRequest req = WebRequest.Create("https://api.telegram.org/bot" + Token + "/sendMessage?chat_id=" + channel_id + "&text=" + textbox1.text);
                       req.UseDefaultCredentials = true;
          WebRequest req1 = WebRequest.Create("https://api.telegram.org/bot" + Token + "/sendPhoto?chat_id=" + channel_id + "&Photo=" + stream );
                       req.UseDefaultCredentials = true;
                       req1.UseDefaultCredentials = true;

                        var result = req.GetResponse();
                        req.Abort();

                         var result1 = req1.GetResponse();
                        req1.Abort();


                }

            }
        }
    }
2

There are 2 answers

2
anatol On BEST ANSWER

At first you must know that you send ...&photo=Sistem.IO.FileStream instead your file. It's root cause of bad request. Take a look in debug.

At second as you can see in api documentation sendPhoto method provide three types of photo parameter:

Pass a file_id as String to send a photo that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a photo from the Internet, or upload a new photo using multipart/form-data.

So using multipart/form-data required in your case. It can be simplified by using RestSharp for example like (code was generated by Postman, haven't tested):

var client = new RestClient("https://api.telegram.org/botadasdsadsadsadasds/sendPhoto");
        var request = new RestRequest(Method.POST);
        request.AddHeader("cache-control", "no-cache");
        request.AddHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
        request.AddParameter("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"chat_id\"\r\n\r\n@BestLaptop\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"photo\"; filename=\"1.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--", ParameterType.RequestBody);
        IRestResponse response = client.Execute(request);

At third you can't sent photo above text in one message. For sending text and photo in one message use caption parameter of sendPhoto method. It provide 200 symbols length.

PS Why not using the Telegram.Bot nuget package?

0
Danil On

This function is helper to upload file:

        public static string UploadFilesToRemoteUrl(HttpWebRequest request, string[] files, NameValueCollection formFields = null)
    {
        string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");

        request.ContentType = "multipart/form-data; boundary=" + boundary;
        request.Method = "POST";
        request.KeepAlive = true;

        Stream memStream = new System.IO.MemoryStream();

        var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
                                                                boundary + "\r\n");
        var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
                                                                    boundary + "--");


        string formdataTemplate = "\r\n--" + boundary +
                                    "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";

        if (formFields != null)
        {
            foreach (string key in formFields.Keys)
            {
                string formitem = string.Format(formdataTemplate, key, formFields[key]);
                byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                memStream.Write(formitembytes, 0, formitembytes.Length);
            }
        }

        string headerTemplate =
            "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
            "Content-Type: application/octet-stream\r\n\r\n";

        for (int i = 0; i < files.Length; i++)
        {
            memStream.Write(boundarybytes, 0, boundarybytes.Length);
            var header = string.Format(headerTemplate, "photo", files[i]);
            var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);

            memStream.Write(headerbytes, 0, headerbytes.Length);

            using (var fileStream = new FileStream(files[i], FileMode.Open, FileAccess.Read))
            {
                var buffer = new byte[1024];
                var bytesRead = 0;
                while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    memStream.Write(buffer, 0, bytesRead);
                }
            }
        }

        memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
        request.ContentLength = memStream.Length;

        using (Stream requestStream = request.GetRequestStream())
        {
            memStream.Position = 0;
            byte[] tempBuffer = new byte[memStream.Length];
            memStream.Read(tempBuffer, 0, tempBuffer.Length);
            memStream.Close();
            requestStream.Write(tempBuffer, 0, tempBuffer.Length);
        }

        using (var response = request.GetResponse())
        {
            Stream stream2 = response.GetResponseStream();
            StreamReader reader2 = new StreamReader(stream2);
            return reader2.ReadToEnd();
        }
    }

Here the code to send file (proxy used for Roscomnadzor) Use your variables instead of msg.GetParam({""}) you'll need chat_id, bot_id,photo and caption. And "proxy" if you need it.

                string filePath = msg.GetParam("photo");
            string URL = "https://api.telegram.org/bot" + msg.GetParam("bot_id") + "/sendPhoto";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
            WebProxy myProxy = new WebProxy(msg.GetParam("proxy"));
            myProxy.UseDefaultCredentials = true;
            request.Proxy = myProxy;

            string[] variable_name = {filePath};
            NameValueCollection form = new NameValueCollection();
            form["chat_id"] = msg.GetParam("chat_id");
            form["caption"] = msg.GetParam("caption");
            UploadFilesToRemoteUrl(request, variable_name, form);