3

Anyone tried to use the POST command from R to upload an image to wordpress through the REST API.

I thought this would do it but no cigar.

POST(paste0(site,"wp/v2/media"),              
add_headers(
          'Authorization' = paste("Bearer", token, sep = " "), 
          'cache-control' = "no-cache", 
          'content-disposition' = "attachment; filename=test.png",
          'content-type' = "image/png"), 
      body = list(
        title = "page_title", 
        status = "published", 
      encode = "json") 
)
Yusef Maali
  • 2,201
  • 2
  • 23
  • 29
Charles Stangor
  • 292
  • 7
  • 21
  • Hello, I'm struggling with this... did you ever get it to go? – Charles Stangor Dec 08 '20 at 18:37
  • I can do this through postman by selectiong a binary file. – Charles Stangor Feb 21 '21 at 13:02
  • This one is close. Returns a 500 error. Somehow I haven't specified the file properly. POST("https://example.org/wp-json/wp/v2/media", add_headers( 'Authorization' = paste("Bearer", token, sep = " "), 'cache-control' = "no-cache", 'content-disposition' = "form-data; filename=Capture.png", 'content-type' = "image/png"), #body = list(y = upload_file(system.file("c:/users/Capture.png"))) body=list(name="new_file", filedata=upload_file("c:/users/cases.png", "image/png")) ) – Charles Stangor Feb 21 '21 at 13:04
  • I can see the issue is related to the R post request generation. Here is a PHP sample code to upload image via WordPress REST API https://gist.github.com/ahmadawais/0ccb8a32ea795ffac4adfae84797c19a#file-upload-a-file-md-readme You can check the code and mimic the same curl header and body data with R – Intelligent Web Solution Feb 23 '21 at 14:23

2 Answers2

3

Creating a new attachment via the POST /wp/v2/media endpoint can be done in two ways:

  1. Set the Content-Disposition header to attachment; filename=<file name> and the Content-Type header to the correct MIME type such as image/jpeg, and then set the request body to the binary file content.

  2. Set the Content-Type header to multipart/form-data; boundary=<boundary> and then set the request body to the multi-part data like you can see here which begins with ---------------------------<boundary> and ends with ---------------------------<boundary>--.

    And in specific to WordPress, the advantage of using this option is that you can set custom attachment post data like the post title and slug. But make sure the form data name for the media file is exactly file — and not filedata, file_content or something else.

And in R, you could easily do the above like so with the Authorization header set to Bearer <token>, and that we're uploading a JPEG image:

Example based on the option 1 above

r <- POST(
    'https://example.com/wp-json/wp/v2/media',
    add_headers(
        'Authorization' = paste('Bearer', token, sep = ' '),
        'Content-Disposition' = 'attachment; filename="test-using-R-4.0.4.jpg"',
        'Content-Type' = 'image/jpeg'
    ),
    body = upload_file('test.jpg', 'image/jpeg')
)
d <- content(r)

cat( ifelse(! is.null(d[['id']]),
    paste('success - id:', d['id']),
    paste('error:', d['message']))
)

Example based on the option 2 above

r <- POST(
    'https://example.com/wp-json/wp/v2/media',
    add_headers(
        'Authorization' = paste('Bearer', token, sep = ' '),
    ),
    body = list(
        file = upload_file('test.jpg', 'image/jpeg'),
        title = 'custom title',
        slug = 'custom-slug'
    )
)
d <- content(r)

cat( ifelse(! is.null(d[['id']]),
    paste('success - id:', d['id']),
    paste('error:', d['message']))
)

And if you're using the default Application Password feature introduced in WordPress 5.6, then you would want to use authenticate() instead of the add_headers() in Option 2 above:

# Replace this:
add_headers(
    'Authorization' = paste('Bearer', token, sep = ' '),
),

# with this one:
authenticate('<your WordPress username>', '<your WordPress Application Password>'),

So I hope the examples, which were tried & tested working with R-4.0.4, also work for you.

Sally CJ
  • 15,362
  • 2
  • 16
  • 34
  • 1
    This was exactly what I needed! Note that you may have to disable or reconfigure Modsecurity on your site to get the REST API to do anything. – jafelds May 31 '21 at 21:56
1

I have the same question..did you manage to have it worked out?

There is a package called wordpressr being developed..however uploading media is not yet incorporated: wordpressr

So currently Im trying out some settings but am a bit lost too.

But what I see is you have to authenticate somewhere in your code to be able to upload media. That can be done via the Application Password Plugin . That should be incorportaed in your code something like:

user = "yourusername"
password = "XXXX XXXX XXXX XXXX XXXX XXXX" (generated with the plugin)

Than add it to your code: (and exclude 'Authorization' = paste("Bearer", token, sep = " " I guess?)

POST(paste0(site,"wp/v2/media"),
authenticate(user, password, type = "basic"),              
add_headers(
           
          'cache-control' = "no-cache", 
          'content-disposition' = "attachment; filename=test.png",
          'content-type' = "image/png"), 
      body = list(
        title = "page_title", 
        status = "published", 
      encode = "json") 
)

Moreover there is a "upload_file("path/") in the body which I assume should be determined too right?

H. berg
  • 471
  • 1
  • 3
  • 11