Search code examples
dartfacebook-graph-apiwhatsapp

Trying to upload media to the Meta Whatsapp API but running into errors


Context: I need to send media templates in which I need to send local files. Thus I need to upload the files to the WhatsApp API to get the Media Id, which I can then use to send the message templates.
The issue: I am running into errors while sending the post request to the server through DART. However the same call is working when sent through postman. I have tried sending the data both as a JSON and as form-data, but both are returning errors. I am attaching the code below, as well as the errors I am facing. Any help is really appreciated.

Getting the file path

upload() async{
    if(await Permission.storage.isGranted){
      FilePickerResult? choice = await FilePicker.platform.pickFiles(allowMultiple: false);
      String? path = choice?.files.single.path;
      if(path != null){
        uploadJson(path);
        // uploadFormData(path);
      }
    }else{
      Permission.storage.request();
    }
  }

Uploading JSON

uploadJson(String path) async{
    File imgfile = File(path);
    Uint8List imgbytes = await imgfile.readAsBytes();
    String bs4str = base64.encode(imgbytes);
    print(bs4str);
    var headers = {
      'Authorization': variables.authorizationToken,
      "Content-Type": 'application/json',
    };
    var body = jsonEncode({
      'file': '$bs4str;type=image/jpeg',
      'messaging_product':'whatsapp'
    });
    Response response = await post(Uri.parse('${variables.baseURL}${variables.phoneNumberId}/media'), headers: headers, body: body);
    print(response.body);
  }

Uploading as Form-data

uploadFormData(String path) async {
    var headers = {
      'Authorization': 'Bearer EAAGtvNhUHUIBANf5KvyxnZCUKcRn3jTJgPZBR2AbbVhZBZBO7GjoDCnS26FQT6Nr6qdRV993ZCJEbGwiqZCdQ7TZBJX8S6KXQdOTgmSf9ue7GCEN1IL3yqfAUEIN1bw0nyvptHeZBFCsdfwpxZAcS1ZCbCdmqArZC81orVbYRkzJy1h7ChOAygmrchfFtJAapykZAadruFqOWwcVvtudMezse94zENBNVZA0k7pAZD',
    };
    var request = MultipartRequest('POST', Uri.parse('https://graph.facebook.com/v14.0/106822672107550/media'));
    request.fields.addAll({
      'messaging_product': 'whatsapp'
    });
    request.files.add(await MultipartFile.fromPath('file', path));
    request.headers.addAll(headers);

    Response response = await Response.fromStream(await request.send());
    print(response.body);
  }

Error for JSON:

    flutter: {"error":{"message":"An unknown error has occurred.","type":"OAuthException","code":1,"fbtrace_id":"AE72st2KT8wJFQ_wYvrcJY6"}}

Error for Form-Data:

flutter: {"error":{"message":"(#100) Param file must be a file with one of the following types: audio\/aac, audio\/mp4, audio\/mpeg, audio\/amr, audio\/ogg, audio\/opus, application\/vnd.ms-powerpoint, application\/msword, application\/vnd.openxmlformats-officedocument.wordprocessingml.document, application\/vnd.openxmlformats-officedocument.presentationml.presentation, application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application\/pdf, text\/plain, application\/vnd.ms-excel, image\/jpeg, image\/png, image\/webp, video\/mp4, video\/3gpp. Received file of type 'application\/octet-stream'.","type":"OAuthException","code":100,"fbtrace_id":"AfsxKl38CW7hUF_ixMzNha9"}}

Solution

  • The problem was with the Mime-type of the file. The Multi-Part file class needed the mime-type of the file to be declared while uploading the file, or the file was automatically being uploaded as an octlet-stream. The code to the working request is posted below.

            var request = http.MultipartRequest('POST', Uri.parse('https://graph.facebook.com/v14.0/${variables.phoneNumberId}/media'));
        request.headers.addAll({
          'Authorization': variables.authorizationToken,
          'Content-Type': 'multipart/form-data'
        });
        request.fields.addAll({
          'messaging_product': 'whatsapp',
          'type': 'application/pdf'     
        });
    
        // The MIME type of the image or file
        const mimeType = 'application/pdf';
        // Open the image file
        var file = File(path);
    
        // Create a MultipartFile from the File object
        final multipartFile = await http.MultipartFile.fromPath(
          'file',
          file.path,
          contentType: MediaType.parse(mimeType),
        );
    
        // Create a request body containing the multipart file
        request.files.add(multipartFile);
    
        // Send the request
        final response = await request.send();
    
        // Check the response status code
        if (response.statusCode == 200) {
          String body = await response.stream.bytesToString();
          var json = jsonDecode(body);
          print(json['id']);
        } else {
          print(response.reasonPhrase);
        }