skip to Main Content

I looked at the messenger documentation at https://developers.facebook.com/docs/messenger-platform/send-messages/#file to try and figure out how to send local attachments. However, when I try it out with a httpclient I get an error saying that the message body can not be empty must provide a valid attachment or message. Below is my code

string fileType = ImageExtensions.Contains(Path.GetExtension(url).ToUpper()) ? "image" : "file";

var multipartContent = new MultipartFormDataContent();

var content = new StringContent($"{{"attachment":{{"type":"{fileType}", "payload":{{"is_reusable"=true}}}}");

multipartContent.Add(new StringContent($"{{"id":"{long.Parse(recipient)}"}}"), "recipient");
multipartContent.Add(new StringContent($"{{"attachment":{{"type":"{fileType}", "payload":{{"is_reusable"=true}}}}"), "message");

var file1 = File.ReadAllBytes(url);
var file2 = new ByteArrayContent(file1);

file2.Headers.Add("Content-Type", GetMimeType(Path.GetExtension(url)));

multipartContent.Add(file2,"filedata", Path.GetFileName(url));
request.Content = multipartContent;

The file type is image and the mime type is image/jpeg. I know the url exists as I checked File.exists

2

Answers


  1. Welcome to Stack Overflow!

    From the code sample provided it’s quite hard to work out what’s going wrong as it’s not runnable in isolation.

    That said, I’d first verify that the image you’re consuming by url exists in the format you expect. If you download the .jpeg from the url can you open it on your machine? Assuming it’s well structured I’d then try and work out if it’s the HttpClient that’s malformed – or if there’s something wrong with the values you’re providing to the Facebook API.

    You can do this by creating a simple C# Web API project that listens for a multipart upload on a specific route. See this answer for some sample code on how to do this.

    Assuming that you’re able to send the .jpeg in question between a local client and a local endpoint accepting a multipart/form-data header then the issue must be with how you’re using the Facebook API itself.

    In your sample I don’t see you using the value of the content variable anywhere. Is this intentional?

    If that missing variable is a red-herring then you could try running something along the lines of (making sure to swap the values out as necessary for the ones you’re having problems with):

    using (var httpClient = new HttpClient())
    using (var formDataContent = new MultipartFormDataContent()) 
    {
        // Read the file in from a local path first to verify that the image
        // exists in the format you're expecting.
        var fileStream = File.OpenRead("/some/path/image.jpeg");
        using (var streamContent = new StreamContent(fileStream)) 
        {
            // Don't actually call `.Result` you should await this, but for ease of
            // demonstration.
            var imageContent = new ByteArrayContent(streamContent.ReadAsByteArrayAsync().Result);
            imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
    
            formDataContent.Add(imageContent, "image", "your-file-name-here");
            formDataContent.Add(new StringContent ($"{{"id":"{long.Parse("your-recipient-here")}"}}"), "recipient");
            formDataContent.Add(new StringContent($"{{"attachment":{{"type":"{"image"}", "payload":{{"is_reusable"=true}}}}"), "message");
    
            // Again don't call `.Result` - await it.
            var response = httpClient.PostAsync("https://some-url-here.com", formDataContent).Result;
        }    
    }
    

    If you run the above do you still get an empty message body error?

    Login or Signup to reply.
  2. If you stumble upon this and you’re using the FacebookClient from Nuget. This is how I finally managed to upload files to the messages api using vb.net.

    Dim Client = New FacebookClient(GetPageAccessToken(PageID))
    Dim TmpParams As New Dictionary(Of String, Object)
    
    TmpParams.Add("recipient", "{""id"":""RECIPIENT_ID""}")
    TmpParams.Add("message", "{""attachment"":{""type"":""image"", ""payload"":{""url"":"""", ""is_reusable"":false}}}")
    TmpParams.Add("messaging_type", "RESPONSE")
    
    Dim Med As New FacebookMediaObject()
    Med.FileName = YourFile.FileName
    Med.ContentType = YourFile.ContentType
    Med.SetValue(YourFile.InputStream.ToBytes())
    
    TmpParams.Add(YourFile.FileName, Med)
    
    Client.Post("me/messages", TmpParams)
    

    Using a Dictionary(of string,object), manually add the params for recipient,message,messaging_type and the file bytes.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search