2016-06-25 5 views
0

저는 텔레 그램 봇에서 일하고 있습니다. 최근에는 거의 민감한 부분을 다 처리 했으므로 이제는 웹 훅을 활성화하고 싶습니다. ,하지만 webhook은 인증서 파일을 전보에 보내야 활성화됩니다. 나중에 클라이언트에 파일을 보내거나 파일로 회신을 보내고 싶을 수도 있습니다. (우리는 웹 사이트 기능을 전보). HttpClient를 통해 https://core.telegram.org/bots/api#inputfilePOCO를 사용하여 텔레 그램에서 파일을 전송하는 방법 (어떤 미들웨어도 사용하고 싶지 않습니다)

I, 나 자신, 다 내 모든 API 호출 클래스, 그리고 난 그것이로 계속 하시겠습니까 : 여기

는 전보 봇 API에 대한 참조입니다. 전보는 인증서 정확한 유형을 정의하지 않았다 때문에, 내가 이것 좀보세요 : https://github.com/MrRoundRobin/telegram.bot 그것을 생성

public static Exception SetWebhook(SetWebhook webhook) 
    { 
     try 
     { 
      using (var hc = new HttpClient()) 
      { 
       HttpContent requestContent = new ObjectContent(typeof(SetWebhook), webhook, 
        new JsonMediaTypeFormatter 
        { 
         SerializerSettings = new JsonSerializerSettings 
         { 
          ContractResolver = new CustomPropertyNamesContractResolver 
          { 
           Case = IdentifierCase.UnderscoreSeparator 
          }, 
          NullValueHandling = NullValueHandling.Ignore 
         }, 
         SupportedEncodings = {Encoding.UTF8} 
        }, "multipart/form-data"); 

       var responseMessage = 
        hc.PostAsync("https://api.telegram.org/bot" + AppSetting.Token + "/setWebhook", 
         requestContent).Result; 

       if (responseMessage.IsSuccessStatusCode) 
       { 
        return null; 
       } 
       else 
       { 
        return new Exception("Status Code: " + responseMessage.StatusCode + "\n\nRequest" + responseMessage.RequestMessage.ToString() + "\n\nResponse" + responseMessage.ToString()); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      return ex; 
     } 
    } 

그리고 여기 내 모델입니다 : 여기 내 실패 방법이다. 여기

public class SetWebhook 
{ 
    /// <summary> 
    /// Optional<br/> 
    /// If empty remove webhook 
    /// </summary> 
    public string Url { get; set; } 

    /// <summary> 
    /// Optional<br/> 
    /// Upload your public key certificate so that the root certificate in use can be checked. See our self-signed guide for details. 
    /// </summary> 
    public InputFile Certificate { get; set; } 
} 

/// <summary> 
/// Represents information for a file to be sent 
/// </summary> 
public class InputFile 
{ 
    /// <summary> 
    /// Required <b/> 
    /// Gets or sets the filename. 
    /// </summary> 
    public string Filename { get; set; } 

    /// <summary> 
    /// Required <b/> 
    /// Gets or sets the content. 
    /// </summary> 
    public Stream Content { get; set; } 

    public InputFile() 
    { 
    } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="InputFile"/> class. 
    /// </summary> 
    /// <param name="filename">The <see cref="Filename"/>.</param> 
    /// <param name="content">The <see cref="Content"/>.</param> 
    public InputFile(string filename, Stream content) 
    { 
     Filename = filename; 
     Content = content; 
    } 
} 

내가 그것을 호출하는 방법입니다 :

public ActionResult SetWebhook() 
    { 
     var result = true; 
     var text = "-"; 

     try 
     { 
      WebHook.SetWebhook("http://ravis.ir:444/Data/Message", Server.MapPath("~/Files/ravis.ir-PEM.cer")); 
     } 
     catch(Exception ex) 
     { 

      result = false; 
      text = ex.Message; 
     } 

     return View(new WebhookResult 
     { 
      Result = result, 
      Text = text 
     }); 
    } 

이 마지막 방법, 오류 :

((ex.InnerException).InnerException).Message -> 제한 시간이 스트림에서 지원되지 않습니다.

(ex.InnerException).Message -> 오류 'System.IO.FileStream'에 'ReadTimeout'에서 값을 받고.

ex.Message -> 하나 이상의 오류가 발생했습니다.

어떻게 파일을 보내야합니까? 어떻게 받아야합니까? 어떤 종류의 개체를 더 정확하게 정의해야합니까? 얻기 위하여

답변

1

이 당신이 내부 StreamContent (아닌 ObjectContent)와 MultipartFormDataContent을 구성해야합니다 작업 :

using (var httpClient = new HttpClient()) 
using (var form = new MultipartFormDataContent()) 
{ 
    var content = new StreamContent(setWebhook.Certificate.Content); 
    form.Add(content, "certificate", setWebhook.Certificate.Filename); 
    form.Add(new StringContent(setWebhook.Url, Encoding.UTF8), "url"); 

    var response = await httpClient.PostAsync(uri, form); 
} 

파일을 수신하는 경우 - 먼저 다음 file_path 등을 포함하는 "정보 파일"가야 그것은 다운로드 할 수 있습니다 : 솜을 볼 것이다

var fileId = "fileId"; 

using (var httpClient = new HttpClient()) 
{ 
    var responseMessage = await httpClient.PostAsJsonAsync("https://api.telegram.org/bot" + token + "/getFile", new { file_id = fileId }); 
    responseMessage.EnsureSuccessStatusCode(); 
    var fileInfoResponse = await responseMessage.Content.ReadAsAsync<TelegramResponse<FileInfo>>(); 

    var fileUri = new Uri("https://api.telegram.org/file/bot" + token + "/" + fileInfoResponse.result.file_path); 
    var fileStreamResponse = await httpClient.GetAsync(fileUri, HttpCompletionOption.ResponseHeadersRead); 
    //and here's downloaded file 
    var stream = await fileStreamResponse.Content.ReadAsStreamAsync(); 
} 
다음

TelegramResponseFileInfo을 이런 식으로 (* C#은 아니지만 원하는 경우 수정할 수 있습니다.)

class TelegramResponse<T> 
{ 
    public bool ok { get; set; } 
    public T result { get; set; } 
} 
class FileInfo 
{ 
    public string file_path { get; set; } 
} 
+0

고마워요. 파일을받는 것은 어떨까요? 내가 말했듯이 나는 보내고받을 필요가있다. – deadManN

+0

당신은 무엇을 시도하고 일하지 않았습니까? –

+0

지금은 파일을 전송하거나 전송할 필요가 없지만 곧 필요할 것입니다. 이제는 webhook을 위해 전송하기 만하면되어 작동하지 않았습니다. (당신의 코드, 나는 아직 테스트하지 않았고, 오늘 아침에 할 일이 있었고, 지금 시도 할 것입니다.) – deadManN