Publier un lien vers l'API Reddit
1. Vue d'ensemble
Dans ce deuxième article dethe series, nous allons créer des fonctionnalités simples à publier sur Reddit à partir de notre application, via leur API.
2. Sécurité nécessaire
Tout d’abord, éliminons l’aspect sécurité.
PourSubmit a Link to Reddit, nous devons définir une ressource protégée OAuth avec lesscope 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;
}
Notez que nous spécifions également lesscope «identity», car nous devons également accéder aux informations du compte utilisateur.
3. Le captcha est-il nécessaire?
Les utilisateurs qui sont nouveaux sur Reddithave to fill in a Captcha afin de soumettre; c'est avant qu'ils ne passent un certain seuil de karma dans Reddit.
Pour ces utilisateurs, nous devons d’abord vérifier si le Captcha est nécessaire:
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:
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:
@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. 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.
Lesfull implementation de ce didacticiel se trouvent dansthe github project - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.