httr2 multipart body with unnames list elements does not accept unnamed list

I am currently writing an r package so that one can send signal text messages from R.
I am planning to make this open source.
It is based on the rest specification from GitHub - bbernhard/signal-cli-rest-api: Dockerized Signal Messenger REST API

Sofar I have been using httr2 to make the rest calls and this works very well as long as I don't include attachments.

for example the following curl command works very well as follows:

`curl -X POST -H "Content-Type: application/json" -d '{"message": "Hello World!", "number": 
"+431212131491291", "recipients": ["+4354546464654", "+4912812812121"]}' 'http://127.0.0.1:8080/v2/send'`
Request_url <- "http://127.0.0.1:8080/v2/send"

Request_body <-  list( 'message' = "Hello World!"
                                             , 'number' =  "+431212131491291"
                                             , "recipients" = list("+4354546464654", "+4912812812121")
                                             )

query <- httr2::request(base_url = Request_url) |>
               httr2::req_headers('Content-Type' = 'application/json') |>
               httr2::req_timeout(60) |>
               httr2::req_body_json(body)|>
               httr2::req_perform()

 query
<httr2_response>
POST http://127.0.0.1:8080/v2/send
Status: 201 Created
Content-Type: application/json
Body: In memory (29 bytes)

and I also receive the message in Signal.

However if I try to add an attachment it suddenly does not want to work anymore.
The curl specification is as follows:

curl -X POST -H "Content-Type: application/json" -d '{"message": "<message>", "base64_attachments": ["<base64 encoded attachment>"], "number": "<number>", "recipients": ["<recipient1>", "<recipient2>"]}' 'http://127.0.0.1:8080/v2/send'

as it can observed the recipients are required as a list without named list elements:

However if I change my code than as follows:

base64_attachments <- "C:\\somefile.pdf"

 query <- httr2::request(base_url = Request_url) |>
               httr2::req_headers('Content-Type' = 'application/json') |>
               httr2::req_user_agent("RSignalApi") |>
               httr2::req_timeout(60) |>
               httr2::req_body_json(Request_body ) |>
               httr2::req_body_multipart(base64_attachments = curl::form_file(base64_attachments))|>
               httr2::req_dry_run()

I then get the following error:

Error in curl::handle_setform(handle, .list = req$fields) : 
  Unsupported value type for form field 'recipients'.
Called from: curl::handle_setform(handle, .list = req$fields)

if I only use one recipient as character (so not a list anymore) I get the following error:

Error in `httr2::req_perform()` at package/R/hello.R:53:7:
! HTTP 400 Bad Request.

Meaning that the rest server really expects the unnamed list for receipients.

Does somebody have any advice how to tackle this?

I'm afraid you can't mix req_body_json() & req_body_multipart() like this. Besides, from curl example, it doesn't look like a multipart request, just a base64-coded content in JSON payload.
I'd try with something like this:

base64_attachments <- "foo.txt"
Request_url <- "http://127.0.0.1:8080/v2/send"
Request_body <- list(
  message            = "Hello World!",
  base64_attachments = list(base64enc::base64encode(base64_attachments)),
  number             = "+431212131491291",
  recipients         = list("+4354546464654", "+4912812812121")
)

httr2::request(base_url = Request_url) |>
  httr2::req_headers('Content-Type' = 'application/json') |>
  httr2::req_user_agent("RSignalApi") |>
  httr2::req_timeout(60) |>
  httr2::req_body_json(Request_body ) |>
  httr2::req_dry_run()
#> POST /v2/send HTTP/1.1
#> Host: 127.0.0.1:8080
#> User-Agent: RSignalApi
#> Accept: */*
#> Accept-Encoding: deflate, gzip
#> Content-Type: application/json
#> Content-Length: 137
#> 
#> {"message":"Hello World!","base64_attachments":["YmFyDQo="],"number":"+431212131491291","recipients":["+4354546464654","+4912812812121"]}

Created on 2024-03-17 with reprex v2.1.0

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.