重投 Reddit 帖子,爭取獲得足夠的關注

REST,Spring
Remote
1
06:35 PM · Dec 01 ,2025

1. 概述

發佈到Reddit是一場投機行為。

一篇帖子可能大受歡迎並獲得大量關注,而另一篇可能更好的帖子卻一無所獲。 密切關注這些帖子,並在它們沒有獲得足夠的關注時,迅速刪除並重新提交

在本文中,我們將繼續研究Reddit案例,實現一個有趣的特性——如果帖子沒有立即獲得足夠的關注,則刪除並重新提交

目標很簡單:允許用户配置多少個Reddit上的投票足以認為帖子獲得了足夠的關注以保留它——在一定的時間間隔內。

2. 更多 Reddit 權限首先,我們需要從 Reddit API 請求額外的權限——具體來説,我們需要編輯帖子。

因此,我們將向 Reddit Resource 添加 “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 上用於檢查分數和刪除帖子的 Post ID
  • noOfAttempts :最大重提交嘗試次數(刪除並重新提交 Post)
  • timeInterval :檢查帖子是否獲得足夠關注的時間間隔
  • minScoreRequired :為了認為它足夠成功而保留的最低分數

接下來 – 讓我們為我們的 PostRepository 接口添加一些新的操作 – 以便在需要檢查時輕鬆檢索帖子:

public interface PostRepository extends JpaRepository<Post, Long> {

    List<Post> findBySubmissionDateBeforeAndIsSent(Date date, boolean sent);

    List<Post> findByUser(User user);

    List<Post> findByRedditIDNotNullAndNoOfAttemptsGreaterThan(int attempts);
}

4. 新的計劃任務

現在,讓我們將新的任務——重新提交任務——定義到調度器中:

@Scheduled(fixedRate = 3 * 60 * 1000)
public void checkAndReSubmitPosts() {
    List<Post> 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("檢查帖子 " + 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("尚未發送");
    postReopsitory.save(post);
}

我們還需要在首次提交時跟蹤 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”權限
  • 我們在 Reddit ID 中添加“t3_”以獲取帖子的完整名稱

6. 刪除 Reddit 帖子

接下來,讓我們看看如何使用其 ID 刪除 Reddit 帖子:

private void deletePost(String redditId) {
    MultiValueMap<String, String> param = new LinkedMultiValueMap<String, String>();
    param.add("id", "t3_" + redditId);
    redditRestTemplate.postForObject(
      "https://oauth.reddit.com/api/del.json", param, JsonNode.class);
}

8. 用户界面 – 配置規則

最後,讓我們修改我們的非常簡單的日程表表單,以添加重新提交新設置:

<label class="col-sm-3">重新提交設置</label>

<label>嘗試次數</label>
<select name="attempt">
    <option value="0" selected>無</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
</select>

<label>時間間隔</label>
<select name="interval">
    <option value="0" selected >無</option>
    <option value="45">45 分鐘</option>
    <option value="60">1 小時</option>
    <option value="120">2 小時</option>
</select>

<label>最小分數</label>
<input type="number"value="0" name="score" required/>
</code>

9. 結論

我們正在不斷改進這個簡單的應用程序的功能——現在我們可以將內容發佈到Reddit,並且——如果內容發佈後沒有迅速獲得足夠的關注——系統可以刪除並重新發布以提高其表現的機會。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.