Publique um link na API do Reddit

Publique um link na API do Reddit

1. Visão geral

Neste segundo artigo dethe series, vamos construir algumas funcionalidades simples para postar no Reddit de nosso aplicativo, por meio de sua API.

2. Segurança Necessária

Primeiro - vamos tirar o aspecto da segurança do caminho.

ParaSubmit a Link to Reddit, precisamos definir um recurso protegido OAuth comscope de “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;
}

Observe que também estamos especificandoscopeidentity” porque também precisamos acessar as informações da conta do usuário.

3. O Captcha é necessário?

Usuários que são novos no Reddithave to fill in a Captcha para enviar; isto é, antes de ultrapassarem um certo limite de carma no Reddit.

Para esses usuários, primeiro precisamos verificar se o Captcha é necessário:

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 param = new HashMap();
    param.put("api_type", "json");

    ResponseEntity 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.html:

captcha

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:

@Controller
@RequestMapping(value = "/api/posts")
public class RedditPostRestController {

    @Autowired
    private RedditService service;

    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public List submit(@Valid @RequestBody PostDto postDto) {
        return service.submitPost(postDto);
    }
}

Here’s the actual method implementation:

public List submitPost(PostDto postDto) {
    MultiValueMap param1 = constructParams(postDto);
    JsonNode node = redditTemplate.submitPost(param1);
    return parseResponse(node);
}

private MultiValueMap constructParams(PostDto postDto) {
    MultiValueMap param = new LinkedMultiValueMap();
    param.add("title", postDto.getTitle());
    param.add("sr", postDto.getSubreddit());
    param.add("url", postDto.getUrl());
    param.add("iden", postDto.getIden());
    param.add("captcha", postDto.getCaptcha());
    if (postDto.isSendReplies()) {
        param.add("sendReplies", "true");
    }

    param.add("api_type", "json");
    param.add("kind", "link");
    param.add("resubmit", "true");
    param.add("then", "comments");
    return param;
}

And the simple parsing logic, handling the response from the Reddit API:

private List parseResponse(JsonNode node) {
    String result = "";
    JsonNode errorNode = node.get("json").get("errors").get(0);
    if (errorNode != null) {
        for (JsonNode child : errorNode) {
            result = result + child.toString().replaceAll("\"|null", "") + "
"; } return Arrays.asList(result); } else { if ((node.get("json").get("data") != null) && (node.get("json").get("data").get("url") != null)) { return Arrays.asList("Post submitted successfully", node.get("json").get("data").get("url").asText()); } else { return Arrays.asList("Error Occurred while parsing Response"); } } }

All of this is working with a basic DTO:

public class PostDto {
    @NotNull
    private String title;

    @NotNull
    private String url;

    @NotNull
    private String subreddit;

    private boolean sendReplies;

    private String iden;
    private String captcha;
}

Finally – the submissionResponse.html:



    

Hello

Hello

Here

6. Conclusão

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.

Ofull implementation deste tutorial pode ser encontrado emthe github project - este é um projeto baseado em Eclipse, portanto, deve ser fácil de importar e executar como está.