1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

Qiita Advent Calendar 2024 楽しかったですね!
さて、本イベントの中でしれっと予約投稿機能が実装されておりました。
image.png
この機能、普段から欲しくない?…ということで、以前公開した記事から機能を大幅アップデートして、Qiita予約投稿機能のChrome拡張ver2.0を作成してみました。

使い方

拡張機能は下記リンクから入手してください。

本ツールは予約投稿画面、設定画面の2画面で構成されています。
<予約投稿画面>
image.png
<設定画面>
image.png

事前準備

  1. 設定画面に移動して、アクセストークンの入手方法を参考にAPIのアクセストークンを入力します。
  2. Organizationに紐づけて記事を投稿する場合は、組織のURI(https://qiita.com/organizations/xxxx の末尾xxxx)を入力します。
    image.png
  3. 保存ボタンを押すと、次回以降は設定不要でAPIへのアクセス・組織紐づけが行われます。

投稿予約

  1. 投稿予約したい記事を限定共有記事として公開します。
  2. 限定共有記事のページにアクセスして本ツールを開きます。URLが自動入力されていることを確認します。
    image.png
  3. 予約日時を選択して予約ボタンを押すと投稿予約完了です。ポップアップで予約日時が確認できます。
    image.png

中身について

ソースコードは以下で公開しています。
まだまだ2年目の駆け出しエンジニアなので初心者感丸出しかもしれませんがご容赦ください(^^;

予約の仕組み

予約ボタンを押すと、予約日時をローカルストレージに保存します。

popup.js
document.getElementById("publishButton").addEventListener("click", async () => {
  //~~~//
    // スケジュールをlocalStorageに保存
    chrome.storage.local.get({ publishSchedules: [] }, (result) => {
      const schedules = result.publishSchedules;
      schedules.push(scheduleData);
      chrome.storage.local.set({ publishSchedules: schedules }, () => {
        // 最新のスケジュール情報を取得
        chrome.storage.local.get({ publishSchedules: [] }, (latestResult) => {
          const latestSchedule =
            latestResult.publishSchedules[
              latestResult.publishSchedules.length - 1
            ];

          if (latestSchedule && latestSchedule.scheduledDate) {
            alert(
              `予約投稿を次の日時に設定しました: ${latestSchedule.scheduledDate}`
            );
          } else {
            alert("スケジュールが設定されていません");
          }

          window.close();
        });
      });
    });
//~~~//

このとき、Qiita API v2のGETリクエストを叩いて限定共有記事の内容を保存します。

popup.js
    const articleData = await getArticle(itemId, accessToken);
popup.js
async function getArticle(itemId, accessToken) {
  const response = await fetch(`https://qiita.com/api/v2/items/${itemId}`, {
    method: "GET",
    headers: {
      Authorization: `Bearer ${accessToken}`,
    },
  });
  //~~~//
  return await response.json();
}

公開の仕組み

バックグラウンドで毎分チェックを行い、投稿の予約があるか確認します。

background.js
setInterval(() => {
  chrome.storage.local.get({ publishSchedules: [] }, async (result) => {
    //~~~//
  });
}, 60000);

予約投稿時刻を過ぎた記事は、Qiita API v2のPATCHリクエストにより公開記事に変更されます。

background.js
      if (scheduledTime <= currentTime) {
        try {
          await updateArticleToPublic(
            schedule.itemId,
            schedule.accessToken,
            schedule.organization,
            schedule.articleData
          );
        } catch (error) {
        //~~~//
        }
      //~~~//
      }
background.js
async function updateArticleToPublic(
  itemId,
  accessToken,
  organization,
  articleData
) {
  const response = await fetch(`https://qiita.com/api/v2/items/${itemId}`, {
    method: "PATCH",
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      title: articleData.title,
      body: articleData.body,
      tags: articleData.tags,
      organization_url_name: organization,
      private: false, // 公開状態にする
    }),
  });
  //~~~//
  return await response.json();
}

今後の改修予定

Qiita公式からリリースがあった場合はSTOPします。

予約機能強化(優先度:★★★)

現状ではブラウザを落とすと機能停止してしまうので、対策を調査中です。

CSSの整備(優先度:★★)

操作画面が生のHTMLのままなのでQiitaのデザインに寄せていく予定です。

組織紐づけ機能の強化(優先度:★★)

組織を複数登録可能にし、紐づけの有無を選択できるようにする予定です。

リファクタリング(優先度:★)

現状各プログラムに処理を直書きしてしまっているので、APIを使用する関数は1か所にまとめる等整理したいです。

おわりに

上にあげた改修予定以外にもここをこうしてほしいという要望や先輩方からのアドバイスがありましたらコメントお願いします!反応いただけるととても嬉しいです。
もちろんGitHubの共同編集も大歓迎です(^^)

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?