Réessayer de soumettre pour reddit une publication sans traction suffisante
1. Vue d'ensemble
Posting to Reddit is a crap shoot. Un message peut faire très bien et attirer beaucoup d'attention, tandis qu'un autre, peut-être meilleur, ne recevra aucun amour. Que diriez-vous de garder un œil sur ces messages dès le début et - s'ils ne reçoivent pas assez de traction -deleting them quickly and resubmitting them.
Dans cet article rapide, nous poursuivonsthe Reddit case study en implémentant une fonctionnalité intéressante -delete and resubmit a post if it’s not getting enough attention immediatly.
L’objectif simple est de permettre à l’utilisateur de configurer le nombre de votes sur Reddit pour qu’il soit suffisant de considérer que la poste reçoit suffisamment d’attrait pour le laisser en suspens - dans un certain intervalle de temps.
2. Plus d'autorisations Reddit
Premièrement, nous aurons besoin deask for additional permissions de l'API Reddit - en particulier, nous devons modifier les messages.
Nous allons donc ajouter la portée «edit» à notre RedditResource:
@Bean
public OAuth2ProtectedResourceDetails reddit() {
AuthorizationCodeResourceDetails details =
new AuthorizationCodeResourceDetails();
details.setScope(Arrays.asList("identity", "read", "submit", "edit"));
...
}
3. L'entité et le référentiel
Maintenant, ajoutons les informations supplémentaires dans notre entitéPost:
@Entity
public class Post {
...
private String redditID;
private int noOfAttempts;
private int timeInterval;
private int minScoreRequired;
}
Les champs:
-
redditID: ID de publication sur Reddit, à utiliser lors de la vérification du score et lors de la suppression de la publication
-
noOfAttempts: nombre maximum d'essais de nouvelle soumission (supprimer le message et le renvoyer)
-
timeInterval: Intervalle de temps pour vérifier si le poteau obtient suffisamment de traction
-
minScoreRequired: score minimum requis pour le considérer comme suffisamment réussi pour quitter
Ensuite - ajoutons de nouvelles opérations dans notre interfacePostRepository - afin de récupérer facilement les messages lorsque nous devons les vérifier:
public interface PostRepository extends JpaRepository {
List findBySubmissionDateBeforeAndIsSent(Date date, boolean sent);
List findByUser(User user);
List findByRedditIDNotNullAndNoOfAttemptsGreaterThan(int attempts);
}
4. Une nouvelle tâche planifiée
Maintenant, définissons une nouvelle tâche - la tâche de re-soumission - dans le planificateur:
@Scheduled(fixedRate = 3 * 60 * 1000)
public void checkAndReSubmitPosts() {
List submitted =
postReopsitory.findByRedditIDNotNullAndNoOfAttemptsGreaterThan(0);
for (Post post : submitted) {
checkAndReSubmit(post);
}
}
Toutes les quelques minutes, il s'agit simplement d'itérer les messages qui sont encore en jeu - et, s'ils ne reçoivent pas assez de traction, cela les supprime et les soumet à nouveau.
Et voici la méthodecheckAndReSubmit():
private void checkAndReSubmit(Post post) {
try {
checkAndReSubmitInternal(post);
} catch (final Exception e) {
logger.error("Error occurred while check post " + post.toString(), e);
}
}
private void checkAndReSubmitInternal(Post post) {
if (didIntervalPassed(post.getSubmissionDate(), post.getTimeInterval())) {
int score = getPostScore(post.getRedditID());
if (score < post.getMinScoreRequired()) {
deletePost(post.getRedditID());
resetPost(post);
} else {
post.setNoOfAttempts(0);
postReopsitory.save(post);
}
}
}
private boolean didIntervalPassed(Date submissonDate, int postInterval) {
long currentTime = new Date().getTime();
long interval = currentTime - submissonDate.getTime();
long intervalInMinutes = TimeUnit.MINUTES.convert(interval, TimeUnit.MILLISECONDS);
return intervalInMinutes > postInterval;
}
private void resetPost(Post post) {
long time = new Date().getTime();
time += TimeUnit.MILLISECONDS.convert(post.getTimeInterval(), TimeUnit.MINUTES);
post.setRedditID(null);
post.setSubmissionDate(new Date(time));
post.setSent(false);
post.setSubmissionResponse("Not sent yet");
postReopsitory.save(post);
}
Nous devrons également garder une trace desredditID lors de leur première soumission à Reddit:
private void submitPostInternal(Post post) {
...
JsonNode node = redditRestTemplate.postForObject(
"https://oauth.reddit.com/api/submit", param, JsonNode.class);
JsonNode errorNode = node.get("json").get("errors").get(0);
if (errorNode == null) {
post.setRedditID(node.get("json").get("data").get("id").asText());
post.setNoOfAttempts(post.getNoOfAttempts() - 1);
...
}
La logique est également simple: il suffit de sauvegarder l’id et de diminuer le nombre de tentatives.
5. Obtenez le score de publication Reddit
Voyons maintenant comment nous pouvons obtenir le score actuel du message à partir de Reddit:
private int getPostScore(String redditId) {
JsonNode node = redditRestTemplate.getForObject(
"https://oauth.reddit.com/api/info?id=t3_" + redditId, JsonNode.class);
int score = node.get("data").get("children").get(0).get("data").get("score").asInt();
return score;
}
Notez que:
-
Nous avons besoin de la portée «read» lors de la récupération des informations de publication depuis Reddit
-
Nous ajoutons «t3_» à l'identifiant reddit pour obtenirfull name du message
6. Supprimer le post Reddit
Ensuite, voyons comment supprimer le post Reddit en utilisant son identifiant:
private void deletePost(String redditId) {
MultiValueMap param = new LinkedMultiValueMap();
param.add("id", "t3_" + redditId);
redditRestTemplate.postForObject(
"https://oauth.reddit.com/api/del.json", param, JsonNode.class);
}
7. LesRedditController
Maintenant, ajoutons les nouvelles informations au contrôleur:
@RequestMapping(value = "/schedule", method = RequestMethod.POST)
public String schedule(Model model,
@RequestParam Map formParams) throws ParseException {
Post post = new Post();
post.setTitle(formParams.get("title"));
post.setSubreddit(formParams.get("sr"));
post.setUrl(formParams.get("url"));
post.setNoOfAttempts(Integer.parseInt(formParams.get("attempt")));
post.setTimeInterval(Integer.parseInt(formParams.get("interval")));
post.setMinScoreRequired(Integer.parseInt(formParams.get("score")));
....
}
8. L'interface utilisateur - Configurer les règles
Enfin, modifions notre formulaire de planification très simple pour ajouter de nouveau les nouveaux paramètres:
9. Conclusion
Nous continuons à améliorer ce que cette application simple peut faire - nous pouvons maintenant publier sur Reddit et - si la publication ne reçoit pas assez de traction rapidement - nous pouvons demander au système de la supprimer et de la re-publier pour lui donner une meilleure chance de performant.