Quantcast
Channel: Baeldung
Viewing all articles
Browse latest Browse all 3550

Post a Link to the Reddit API

$
0
0

I usually post about Security on Twitter - you can follow me there:

1. Overview

In this article, we’ll build some simple functionality to post on Reddit from our application, via their API.

2. Necessary Security

First – let’s get the security aspect out of the way.

In order to Submit a Link to Reddit, we need to define an OAuth protected Resource with the scope of “submit“:

@Bean
public OAuth2ProtectedResourceDetails reddit() {
    AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
    details.setId("reddit");
    details.setClientId(clientID);
    details.setClientSecret(clientSecret);
    details.setAccessTokenUri(accessTokenUri);
    details.setUserAuthorizationUri(userAuthorizationUri);
    details.setTokenName("oauth_token");
    details.setScope(Arrays.asList("identity", "submit"));
    details.setGrantType("authorization_code");
    return details;
}

Note that we’re also specifying the scopeidentity” because we also need access the user account information.

3. Is Captcha Needed?

Users that are new to Reddit have to fill in a Captcha in order to submit; that is before they pass a certain karma threshold within Reddit.

For these users, we first need to check if the Captcha is needed:

private String needsCaptcha() {
    String result = redditRestTemplate.getForObject(
      "https://oauth.reddit.com/api/needs_captcha.json", String.class);
    return result;
}

private String getNewCaptcha() {
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    HttpEntity req = new HttpEntity(headers);

    Map<String, String> param = new HashMap<String, String>();
    param.put("api_type", "json");

    ResponseEntity<String> result = redditRestTemplate.postForEntity(
      "https://oauth.reddit.com/api/new_captcha", req, String.class, param);
    String[] split = result.getBody().split("\""); 
    return split[split.length - 2];
}

4. The “Submit Post” Form

Next, let’s create the main form for submitting new posts to Reddit. Submitting a Link requires the following details:

  • title – the title of the article
  • url – the URL of the article
  • subreddit – the sub-reddit to submit the link to

So let’s see how we can display this simple submission page:

@RequestMapping("/post")
public String showSubmissionForm(Model model) throws JsonProcessingException, IOException {
    String needsCaptchaResult = needsCaptcha();
    if (needsCaptchaResult.equalsIgnoreCase("true")) {
        String iden = getNewCaptcha();
        model.addAttribute("iden", iden);
    }
    return "submissionForm";
}

And of course the basic  submissionForm.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Spring Security OAuth</title>
    <link rel="stylesheet" 
      href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Submit to Reddit</h1>
<form action="submit" method="post">
<div class="row">
<div class="form-group">
    <label class="col-sm-3">Title</label>
    <span class="col-sm-9">
        <input name="title" placeholder="title" class="form-control" />
    </span>
</div>
<br><br>
<div class="form-group">
    <label class="col-sm-3">Url</label>
    <span class="col-sm-9">
        <input name="url" placeholder="url" class="form-control" />
    </span>
</div>
<br><br>  
<div class="form-group">
    <label class="col-sm-3">Subreddit</label>
    <span class="col-sm-9">
        <input name="sr" placeholder="Subreddit" class="form-control" />
    </span>
</div>
<br><br>
    <c:if test="${iden != null}">
    <input type="hidden" name="iden" value="${iden}"/>
	<div class="form-group">   
	    <label class="col-sm-3">Captcha</label>
	    <span class="col-sm-9">
                <input name="captcha" placeholder="captcha" class="form-control"/>
            </span>
	</div>
	<br><br>
    <img src="http://www.reddit.com/captcha/${iden}" alt="captcha" width="200"/>
    </c:if>
    <br><br>
    <button type="submit" class="btn btn-primary">Post</button>
   </div>
</form>
</div>
</body>
</html>

5. Submit a Link to Reddit

Now – let’s take a look at the final step – submitting the actual link via the Reddit API.

We’ll post a submit request to Reddit using the parameters from our submissionForm:

@RequestMapping("/submit")
public String submit(Model model, @RequestParam Map<String, String> formParams) {
    MultiValueMap<String, String> param = new LinkedMultiValueMap<String, String>();
    param.add("api_type", "json");
    param.add("kind", "link");
    param.add("resubmit", "true");
    param.add("sendreplies", "false");
    param.add("then", "comments");
    for (Map.Entry<String, String> entry : formParams.entrySet()) {
        param.add(entry.getKey(), entry.getValue());
    }

    logger.info("Submitting Link with these parameters: " + formParams.entrySet());
    String result = redditRestTemplate.postForObject(
      "https://oauth.reddit.com/api/submit", param, String.class);
    logger.info("Submitted Link - Full Response from Reddit" + result);
    
    String responseMsg = parseResponseMessage(result);
    model.addAttribute("msg", responseMsg);
    
    return "submissionResponse";
}

And the simple parseResponse() logic:

private String parseResponse(String responseBody) throws JsonProcessingException, IOException {
    String result = "";
    JsonNode node = new ObjectMapper().readTree(responseBody);
    JsonNode errorNode = node.get("json").get("errors").get(0);
    for (JsonNode child : errorNode) {
        result = result + child.toString().replaceAll("\"|null", "") + "<br>";
    }
    if (result.length() == 0) {
        if (node.get("json").get("data") != null && node.get("json").get("data").get("url") != null) {
            return "Post submitted successfully 
              <a href=\"" + node.get("json").get("data").get("url").asText() + "\"> check it out </a>";
        }
        else {
            return "Error Occurred";
        }
    }
    return result;
}

Finally – the submissionResponse.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Spring Security OAuth</title>
    <link rel="stylesheet" href=
      "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
</head>
<body>
    <div class="container">
        <h1>${msg}</h1>
        <a href="post" class="btn btn-primary">Submit another link to Reddit</a>
    </div>
</body>
</html>

6. Conclusion

In this quick tutorial we implemented some basic Submit to Reddit functionality – simplistic but fully functional.

In the next part of this case study, we’ll implement a Schedule Post for Later functionality into our app.

The full implementation of this tutorial can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.

I usually post about Security on Twitter - you can follow me there:



Viewing all articles
Browse latest Browse all 3550

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>