十分なトラクションなしで投稿をRedditに送信しようとする
1. 概要
Posting to Reddit is a crap shoot.ある投稿はうまく機能し、多くの注目を集めるかもしれませんが、別の投稿は、おそらくまったく愛されないでしょう。 これらの投稿を早い段階で監視し、十分な牽引力が得られない場合はdeleting them quickly and resubmitting themについてはどうでしょうか。
この簡単な記事では、興味深い機能であるdelete and resubmit a post if it’s not getting enough attention immediatlyを実装することにより、the Reddit case studyを継続しています。
単純な目標は、ユーザーがRedditの投票数を設定して、特定の時間間隔内に投稿がそれを残すのに十分な牽引力を得ていると見なすことです。
2. その他のReddit権限
まず、Reddit APIからask for additional permissionsを実行する必要があります。具体的には、投稿を編集する必要があります。
そこで、RedditResourceに「edit」スコープを追加します。
@Bean
public OAuth2ProtectedResourceDetails reddit() {
AuthorizationCodeResourceDetails details =
new AuthorizationCodeResourceDetails();
details.setScope(Arrays.asList("identity", "read", "submit", "edit"));
...
}
3. エンティティとリポジトリ
それでは、Postエンティティに追加情報を追加しましょう。
@Entity
public class Post {
...
private String redditID;
private int noOfAttempts;
private int timeInterval;
private int minScoreRequired;
}
フィールド:
-
redditID:Redditの投稿ID。スコアを確認するときや投稿を削除するときに使用されます
-
noOfAttempts:再送信の最大試行回数(投稿を削除して再送信)
-
timeInterval:投稿が十分な牽引力を得ているかどうかを確認する時間間隔
-
minScoreRequired:それが十分に成功したと見なすために必要な最小スコア
次に、PostRepositoryインターフェースにいくつかの新しい操作を追加して、チェックチェックが必要なときに投稿を簡単に取得できるようにします。
public interface PostRepository extends JpaRepository {
List findBySubmissionDateBeforeAndIsSent(Date date, boolean sent);
List findByUser(User user);
List findByRedditIDNotNullAndNoOfAttemptsGreaterThan(int attempts);
}
4. 新しいスケジュールされたタスク
それでは、新しいタスク(再送信タスク)をスケジューラーに定義しましょう。
@Scheduled(fixedRate = 3 * 60 * 1000)
public void checkAndReSubmitPosts() {
List submitted =
postReopsitory.findByRedditIDNotNullAndNoOfAttemptsGreaterThan(0);
for (Post post : submitted) {
checkAndReSubmit(post);
}
}
数分ごとに、これはまだ再生中の投稿を繰り返し処理するだけです。十分な牽引力が得られない場合は、投稿を削除して再送信します。
そしてここにcheckAndReSubmit()メソッドがあります:
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);
}
また、最初にRedditに送信するときに、redditIDを追跡する必要があります。
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);
...
}
ここのロジックも非常に単純です。IDを保存して、試行回数を減らすだけです。
5. Reddit投稿スコアを取得する
では、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;
}
ご了承ください:
-
Redditから投稿情報を取得するときは、「read」スコープが必要です
-
投稿のfull nameを取得するために、reddit IDに「t3_」を追加します
6. Reddit投稿を削除する
次へ–IDを使用してRedditの投稿を削除する方法を見てみましょう。
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. RedditController
それでは、新しい情報をコントローラーに追加しましょう。
@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. UI –ルールの構成
最後に、非常に単純なスケジュールフォームを変更して、新しい設定を再送信します。
9. 結論
このシンプルなアプリでできることを継続的に改善しています。Redditに投稿できるようになりました。投稿がすぐに十分な牽引力を得られない場合は、システムに削除して再投稿して、より良いチャンスを与えることができます。実行します。