API自動化 Python

Pythonでnoteの下書きを自動作成・保存する

投稿の自動化

エディタで書いて、コピーして、貼り付けて、体裁を直す。この往復は自動化できる。

下書き作成は2段階。仕組みを理解すれば実装は短く済みます

📋 この記事でわかること

  • 下書き作成が2段階に分かれている理由
  • 返ってくる id と key の違いと使い分け
  • 本文をHTMLで渡すときの注意点
  • ローカルの原稿を一括で下書き化する処理
  • 下書きの一覧取得・重複チェック・削除
  • publish系のフィールドが無視される仕様

記事をどこで書くかは人それぞれですが、テキストエディタやMarkdownで書いてからnoteに移す人は少なくありません。この移す作業が地味に面倒です。コピーして貼り付けると体裁が崩れ、見出しを付け直し、改行を整える——記事1本ごとにこれをやると、書く時間より整える時間のほうが長くなることさえあります。noteの下書き作成はAPIから実行できます。ローカルの原稿ファイルを読み込んで、そのままnoteの下書きとして流し込めるようになります。この記事では、その実装を解説します。認証が必要な処理なので、Cookieの準備を先に済ませてください。

この記事の前提

  1. 認証が必須です。Cookie認証の記事note_auth_client.py を使います
  2. 扱うのは自分のアカウントの下書きのみです
  3. 非公式APIのため、仕様は予告なく変更される可能性があります
  4. 大量の下書きを短時間に作成するのは避けてください

下書き作成は2段階に分かれている

noteの下書き作成は、1回のリクエストで完結しません。まず空の下書きを作り、次にそこへ本文を保存するという2段階の構造になっています。

  • 1
    空の下書きを作る——POST /api/v1/text_notes。ここで記事の枠が作られ、idkey が返ります。
  • 2
    本文を保存する——POST /api/v1/text_notes/draft_save?id={id}。1で得た数値idを指定して、タイトルと本文を送ります。

この構造は、noteのエディタの挙動を考えると理解しやすくなります。「新規note作成」を押した瞬間に空の記事が作られ、その後の入力が自動保存されていく——ブラウザ上の動きと同じことを、APIから行っているだけです。

ステップ エンドポイント 送るもの 返るもの
1. 枠を作る POST /api/v1/text_notes なし(空でよい) id(数値)と key(n形式)
2. 本文を保存 POST /api/v1/text_notes/draft_save?id={id} name(タイトル)、body(HTML) 保存結果

idとkeyの使い分け

ステップ1のレスポンスには2種類の識別子が含まれます。これを取り違えると404が返るため、最初に整理しておきます。

識別子 形式 使う場面
id 数値(例: 12345678) 下書き保存・公開・削除
key n + 英数字(例: nabcd1234) 記事の取得・URL生成

覚え方としては、「書き込む操作はid、読み取る操作はkey」と考えると整理しやすくなります。例外もありますが、大枠はこの理解で困りません。

最小の実装:下書きを1本作る

まずは動く最小コードです。note_auth_client.py認証の記事で作成したものを使います。

01_create_draft.py
"""
下書きを1本作成して本文を保存する、最小の実装。
"""
from note_auth_client import NoteAuthClient, CookieExpiredError


def create_empty_draft(client: NoteAuthClient) -> dict:
    """空の下書きを作成し、id と key を返す"""
    data = client.post_json("/api/v1/text_notes", payload={})

    note_id = data.get("id")
    note_key = data.get("key")

    if not note_id:
        raise RuntimeError(f"下書きの作成に失敗しました: {data}")

    print(f"下書きを作成しました(id={note_id} / key={note_key})")
    return {"id": note_id, "key": note_key}


def save_draft(client: NoteAuthClient, note_id: int,
               title: str, body_html: str) -> bool:
    """作成済みの下書きにタイトルと本文を保存する"""
    payload = {
        "name": title,
        "body": body_html,
    }

    res = client.request(
        "POST",
        "/api/v1/text_notes/draft_save",
        params={"id": note_id},
        json=payload,
    )

    if res.status_code not in (200, 201):
        print(f"保存に失敗しました: HTTP {res.status_code}")
        print(res.text[:300])
        return False

    print("本文を保存しました")
    return True


if __name__ == "__main__":
    try:
        client = NoteAuthClient()
        client.verify()

        draft = create_empty_draft(client)

        title = "APIから作成したテスト記事"
        body = (
            "<p>これはPythonから作成した下書きです。</p>"
            "<h2>見出しのテスト</h2>"
            "<p>本文には<strong>強調</strong>も使えます。</p>"
        )

        if save_draft(client, draft["id"], title, body):
            print(f"確認: https://note.com/notes/{draft['key']}/edit")

    except CookieExpiredError as e:
        print("認証エラー:", e)

実行後、noteの「下書き」一覧を開くと記事が増えているはずです。編集画面のURLは https://note.com/notes/{key}/edit という形式なので、作成直後に確認リンクを出力しておくと便利です。

publish系のフィールドは無視される

draft_save のペイロードに status: "published"price を含めても、エラーにはならず黙って無視されます。「エラーが出なかったから公開されたはず」と考えると混乱します。公開処理は別のエンドポイント(PUT /api/v1/text_notes/{id})で行う必要があり、これは公開の記事で解説します。

下書き作成をクラスにまとめる

2段階の処理を毎回書くのは冗長です。1つのメソッドで完結する形にまとめます。

note_draft.py
"""
noteの下書き操作をまとめたクラス。
以降の記事でもこのモジュールを使う。
"""
import logging

from note_auth_client import NoteAuthClient

logger = logging.getLogger(__name__)


class NoteDraft:

    def __init__(self, client: NoteAuthClient):
        self.client = client

    # ---- 作成 ----

    def create(self, title: str, body_html: str) -> dict:
        """
        下書きを作成して本文まで保存する。
        成功したら {"id":..., "key":..., "title":...} を返す。
        """
        data = self.client.post_json("/api/v1/text_notes", payload={})
        note_id = data.get("id")
        note_key = data.get("key")

        if not note_id:
            raise RuntimeError(f"下書き枠の作成に失敗: {data}")

        ok = self.save(note_id, title, body_html)
        if not ok:
            logger.warning("枠は作成されましたが本文の保存に失敗しました "
                           "(id=%s)", note_id)

        return {
            "id": note_id,
            "key": note_key,
            "title": title,
            "saved": ok,
            "edit_url": f"https://note.com/notes/{note_key}/edit",
        }

    def save(self, note_id: int, title: str, body_html: str) -> bool:
        """既存の下書きを上書き保存する"""
        res = self.client.request(
            "POST",
            "/api/v1/text_notes/draft_save",
            params={"id": note_id},
            json={"name": title, "body": body_html},
        )

        if res.status_code not in (200, 201):
            logger.error("draft_save 失敗 HTTP %s: %s",
                         res.status_code, res.text[:200])
            return False
        return True

    # ---- 取得 ----

    def list_drafts(self, max_pages: int = 20) -> list:
        """下書きの一覧を取得する"""
        drafts = []

        for page in range(1, max_pages + 1):
            data = self.client.get_json(
                "/api/v3/notes",
                params={"kind": "note", "status": "draft", "page": page},
            )
            notes = data.get("notes", data.get("contents", []))
            if not notes:
                break

            drafts.extend(notes)

            if data.get("isLastPage") or data.get("is_last_page"):
                break

        return drafts

    def find_by_title(self, title: str) -> dict:
        """同じタイトルの下書きがあるか探す(重複防止用)"""
        for d in self.list_drafts():
            if (d.get("name") or "").strip() == title.strip():
                return d
        return {}

    # ---- 削除 ----

    def delete(self, note_id: int) -> bool:
        """下書きを削除する"""
        res = self.client.request(
            "DELETE",
            "/api/v1/text_notes/draft_delete",
            params={"id": note_id},
        )

        if res.status_code not in (200, 204):
            logger.error("削除失敗 HTTP %s", res.status_code)
            return False

        logger.info("下書きを削除しました (id=%s)", note_id)
        return True


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)

    client = NoteAuthClient()
    client.verify()

    draft = NoteDraft(client)
    result = draft.create(
        "クラス経由で作成したテスト",
        "<p>NoteDraft クラスから作成しました。</p>",
    )
    print(result)

本文HTMLで使えるタグの制限

本文はHTMLで渡しますが、すべてのタグが通るわけではありません。特にインライン要素は厳しく制限されており、対応していないタグは保存時に取り除かれます。

タグ 扱い 備考
p 使える 段落の基本
h2 / h3 使える 見出し
ul / ol / li 使える リスト
blockquote 使える 引用
strong 使える 太字
em 使える 斜体
s 使える 打ち消し線
code 使える インラインコード
a 使える リンク
span / div 削除される 装飾目的のタグは通らない
style属性 削除される 色やサイズの指定は不可
table 非対応 noteに表機能がないため

この制限があるため、外部で作ったHTMLをそのまま流し込むと、意図した見た目にならないことがあります。送る前にサニタイズする関数を通しておくと安全です。

sanitize.py
"""
noteが受け付けるタグだけを残すサニタイザ。
標準ライブラリの HTMLParser を使うので追加インストール不要。
"""
from html.parser import HTMLParser
from html import escape

ALLOWED_TAGS = {
    "p", "h2", "h3", "ul", "ol", "li",
    "blockquote", "strong", "em", "s", "code", "a", "br",
}
ALLOWED_ATTRS = {"a": {"href"}}


class NoteSanitizer(HTMLParser):

    def __init__(self):
        super().__init__(convert_charrefs=True)
        self.parts = []
        self.removed = set()

    def handle_starttag(self, tag, attrs):
        if tag not in ALLOWED_TAGS:
            self.removed.add(tag)
            return

        allowed = ALLOWED_ATTRS.get(tag, set())
        kept = [
            f'{k}="{escape(v or "")}"'
            for k, v in attrs if k in allowed
        ]

        if kept:
            self.parts.append(f"<{tag} {' '.join(kept)}>")
        else:
            self.parts.append(f"<{tag}>")

    def handle_endtag(self, tag):
        if tag in ALLOWED_TAGS and tag != "br":
            self.parts.append(f"</{tag}>")

    def handle_data(self, data):
        self.parts.append(escape(data))

    def result(self) -> str:
        return "".join(self.parts)


def sanitize(html: str, verbose: bool = True) -> str:
    """note用にHTMLを整形する"""
    parser = NoteSanitizer()
    parser.feed(html)
    parser.close()

    if verbose and parser.removed:
        print("除去したタグ:", ", ".join(sorted(parser.removed)))

    return parser.result()


if __name__ == "__main__":
    dirty = (
        '<div class="wrap"><p style="color:red">赤い文字</p>'
        '<span>スパン</span><h2>見出し</h2>'
        '<p><a href="https://example.com" target="_blank">リンク</a>'
        '</p><table><tr><td>表</td></tr></table></div>'
    )
    print(sanitize(dirty))

▶ Markdownで書いた原稿をnote用に変換する処理は、別途まとめています。
見出し・リスト・引用の変換まで対応した実装です。

Markdown変換を見る

テキストファイルから一括で下書き化する

実用的な使い方として、ローカルにある原稿ファイルをまとめて下書きにするスクリプトを作ります。

bulk_draft.py
"""
drafts/ フォルダ内のテキストファイルを、noteの下書きとして一括作成する。

ファイル形式:
    1行目 = タイトル
    2行目以降 = 本文(空行で段落を区切る)

処理済みのファイルは done/ へ移動する。
"""
import os
import shutil
import time
from html import escape

from note_auth_client import NoteAuthClient, CookieExpiredError
from note_draft import NoteDraft

SOURCE_DIR = "drafts"
DONE_DIR = "drafts_done"
SLEEP_SEC = 3.0        # 下書き作成の間隔(余裕をもって)
MAX_PER_RUN = 10       # 1回の実行で作る上限


def text_to_html(text: str) -> str:
    """
    プレーンテキストをnote用のHTMLに変換する。
    - 空行で段落を分ける
    - 行頭の ## を見出しにする
    - 行頭の - をリストにする
    """
    blocks = [b.strip() for b in text.split("\n\n") if b.strip()]
    html_parts = []

    for block in blocks:
        lines = block.split("\n")

        # リストブロック
        if all(l.strip().startswith("- ") for l in lines):
            items = "".join(
                f"<li>{escape(l.strip()[2:])}</li>" for l in lines
            )
            html_parts.append(f"<ul>{items}</ul>")
            continue

        # 見出し
        if block.startswith("## "):
            html_parts.append(f"<h2>{escape(block[3:].strip())}</h2>")
            continue
        if block.startswith("### "):
            html_parts.append(f"<h3>{escape(block[4:].strip())}</h3>")
            continue

        # 引用
        if block.startswith("> "):
            body = escape(block[2:].strip())
            html_parts.append(f"<blockquote>{body}</blockquote>")
            continue

        # 通常の段落(内部の改行は br に)
        para = "<br>".join(escape(l) for l in lines)
        html_parts.append(f"<p>{para}</p>")

    return "".join(html_parts)


def read_file(path: str) -> tuple:
    """ファイルを読んで (タイトル, 本文HTML) を返す"""
    with open(path, encoding="utf-8") as f:
        content = f.read()

    lines = content.split("\n")
    title = lines[0].strip().lstrip("# ").strip()
    body_text = "\n".join(lines[1:]).strip()

    if not title:
        title = os.path.splitext(os.path.basename(path))[0]

    return title, text_to_html(body_text)


def main():
    if not os.path.isdir(SOURCE_DIR):
        print(f"{SOURCE_DIR}/ フォルダを作って、原稿を置いてください")
        return

    files = sorted(
        f for f in os.listdir(SOURCE_DIR)
        if f.endswith((".txt", ".md"))
    )

    if not files:
        print("処理対象のファイルがありません")
        return

    try:
        client = NoteAuthClient()
        client.verify()
    except CookieExpiredError as e:
        print("認証エラー:", e)
        return

    draft = NoteDraft(client)
    os.makedirs(DONE_DIR, exist_ok=True)

    created = 0

    for filename in files[:MAX_PER_RUN]:
        path = os.path.join(SOURCE_DIR, filename)
        title, body = read_file(path)

        # 同名の下書きがあればスキップ(二重投稿の防止)
        existing = draft.find_by_title(title)
        if existing:
            print(f"スキップ(既存): {title}")
            continue

        print(f"作成中: {title}")
        try:
            result = draft.create(title, body)
            print(f"  → {result['edit_url']}")
            created += 1

            shutil.move(path, os.path.join(DONE_DIR, filename))

        except Exception as e:
            print(f"  エラー: {e}")

        time.sleep(SLEEP_SEC)

    print(f"\n完了: {created} 件の下書きを作成しました")


if __name__ == "__main__":
    main()

重要なのは重複チェックと処理済みファイルの退避です。この2つが無いと、実行するたびに同じ記事が下書きに積み上がります。同名の下書きを探してスキップし、成功したファイルは別フォルダへ移動する——この設計で二重作成を防いでいます。

実行間隔を3秒にしている理由

下書き作成は1本あたり2回のリクエスト(枠の作成+保存)を行います。さらに重複チェックで一覧取得も走るため、実質的には1本で3回以上のリクエストが発生します。取得系より重い処理なので、間隔は広めに取ってください。1回の実行で作る本数にも上限を設けています。

下書きの棚卸しをする

下書きは溜まりやすく、放置されがちです。一覧を取得して状態を確認するスクリプトを用意しておくと管理が楽になります。

draft_report.py
"""
下書きの一覧を取得して、状態を報告する。
- タイトル未設定のもの
- 本文が極端に短いもの
- 古いまま放置されているもの
"""
from datetime import datetime, timezone

from note_auth_client import NoteAuthClient, CookieExpiredError
from note_draft import NoteDraft

STALE_DAYS = 60


def parse_date(value: str):
    if not value:
        return None
    try:
        return datetime.fromisoformat(value.replace("Z", "+00:00"))
    except ValueError:
        return None


def report(drafts: list):
    if not drafts:
        print("下書きはありません")
        return

    now = datetime.now(timezone.utc)
    untitled = []
    short = []
    stale = []

    print(f"=== 下書き {len(drafts)} 件 ===\n")

    for d in drafts:
        title = (d.get("name") or "").strip()
        body = d.get("body") or ""
        updated = parse_date(
            d.get("updatedAt") or d.get("updated_at") or ""
        )

        label = title or "(無題)"
        age = ""
        if updated:
            days = (now - updated).days
            age = f"{days}日前"
            if days > STALE_DAYS:
                stale.append(label)

        print(f"  {label[:44]:<46}{len(body):>7}文字  {age}")

        if not title:
            untitled.append(d.get("id"))
        if len(body) < 300:
            short.append(label)

    print("\n=== 気になるもの ===")
    print(f"  タイトル未設定 : {len(untitled)} 件")
    print(f"  本文300文字未満: {len(short)} 件")
    print(f"  {STALE_DAYS}日以上放置  : {len(stale)} 件")

    if stale:
        print("\n  放置されている下書き:")
        for s in stale[:10]:
            print(f"    - {s[:50]}")
        print("\n  → 仕上げて公開するか、削除するか決めてください")


if __name__ == "__main__":
    try:
        client = NoteAuthClient()
        client.verify()

        draft = NoteDraft(client)
        report(draft.list_drafts())

    except CookieExpiredError as e:
        print("認証エラー:", e)

放置されている下書きが見えると、次にやることが具体的になります。新しく書き始めるより、あと少しで完成する下書きを仕上げるほうが早く1本増やせます

▼ RECOMMENDATION ▼

投稿を仕組み化しても、読者は自動では増えない

下書き作成を自動化すれば、書いてから公開までの手間は減ります。ただし、記事を読む人を増やす作業は別に必要です。アメブロであれば、アメプレスProがいいね・フォロー・アクセス獲得を自動で回します。コードを書く必要はなく、設定するだけで24時間動きます。noteと違ってASPアフィリエイトも使えるため、収益化の選択肢も広がります。月額2,980円、365日LINEサポート付きです。

✦ プログラミング不要 ✦ 自動いいね・フォロー ✦ ASPアフィリOK ✦ 365日LINEサポート
アメプレスPro 公式ページを確認する →

※ 当サイトはアフィリエイト広告を含みます。

不要な下書きを整理する

テストで作った下書きや、書き直しで不要になったものを削除する処理です。削除は取り消せないため、確認を挟む実装にします。

clean_drafts.py
"""
条件に合う下書きを削除する。
実行前に必ず対象を表示し、確認を取る。
"""
import time

from note_auth_client import NoteAuthClient, CookieExpiredError
from note_draft import NoteDraft

# 削除対象の条件
TITLE_KEYWORDS = ["テスト", "test", "APIから作成"]
MIN_BODY_CHARS = 50


def find_targets(drafts: list) -> list:
    """削除候補を絞り込む"""
    targets = []

    for d in drafts:
        title = (d.get("name") or "").strip()
        body = d.get("body") or ""

        # テスト用のタイトルを含む
        if any(k.lower() in title.lower() for k in TITLE_KEYWORDS):
            targets.append((d, "テスト用タイトル"))
            continue

        # 中身がほぼ無い
        if len(body) < MIN_BODY_CHARS and title:
            targets.append((d, "本文がほぼ空"))

    return targets


def main():
    try:
        client = NoteAuthClient()
        client.verify()
    except CookieExpiredError as e:
        print("認証エラー:", e)
        return

    draft = NoteDraft(client)
    drafts = draft.list_drafts()
    targets = find_targets(drafts)

    if not targets:
        print("削除対象はありません")
        return

    print(f"=== 削除候補 {len(targets)} 件 ===")
    for d, reason in targets:
        title = (d.get("name") or "(無題)")[:44]
        print(f"  [{reason}] {title}")

    answer = input("\nこれらを削除しますか? (yes / no): ").strip().lower()
    if answer != "yes":
        print("中止しました")
        return

    deleted = 0
    for d, _ in targets:
        note_id = d.get("id")
        if not note_id:
            continue

        if draft.delete(note_id):
            deleted += 1
        time.sleep(1.5)

    print(f"\n{deleted} 件を削除しました")


if __name__ == "__main__":
    main()

削除は元に戻せない

下書きの削除にゴミ箱のような猶予はありません。実行すると即座に消えます。この記事のコードで input() による確認を挟んでいるのはそのためです。自動実行するスクリプトに削除処理を組み込むのは、条件が明確に限定できる場合を除いて避けてください。

つまずきやすいポイント

症状 原因 対処
401が返る Cookieが無効 ブラウザで取り直す
404が返る idとkeyの取り違え draft_saveには数値idを使う
保存されるが本文が空 bodyのキー名が違う ペイロードを確認する
装飾が消える 非対応のタグを送っている サニタイザを通す
改行が反映されない テキストをそのまま送っている pタグやbrで囲む
公開されない draft_saveでは公開できない PUTのエンドポイントを使う
同じ記事が量産される 重複チェックが無い タイトルで既存を確認する

まとめ:枠を作ってから中身を入れる

noteの下書き作成は、空の枠を作ってから本文を保存する2段階の構造です。この構造さえ理解すれば、実装自体は難しくありません。

この記事の要点

  1. 下書き作成は POST /api/v1/text_notesdraft_save の2段階
  2. 返る id(数値)と key(n形式)は用途が違う
  3. 本文はHTML。使えるタグは限られている
  4. span・div・style属性は削除される
  5. publish系のフィールドは黙って無視される
  6. 一括作成には重複チェックと処理済みファイルの退避が必須
  7. 下書きの棚卸しをすると、公開できる記事が見つかる
  8. 削除は取り消せない。確認を挟む

下書きまで自動化できれば、書く場所を自由に選べるようになります。エディタでもMarkdownでも、書きやすい環境で書いて、あとはスクリプトに任せる。この分業ができると、書くこと自体に集中しやすくなります。

FAQ|noteの下書きAPIについてよくある質問

Q. なぜ2段階に分かれているのですか?

noteのエディタが自動保存方式であるためと考えられます。ブラウザで「新規note作成」を押した時点で空の記事が作られ、その後の入力が随時保存されていきます。APIもその構造をそのまま踏襲しているだけです。1回のリクエストで完結させたい場合は、この記事の NoteDraft.create() のように内部で2回呼ぶメソッドを用意すれば実用上は問題ありません。

Q. 下書きから公開まで自動化できますか?

できます。ただし公開は PUT /api/v1/text_notes/{id} という別のエンドポイントで、しかも全フィールドを送る必要があります。差分更新ができないため、現在の値を取得してマージしてから送る、という手順が必要です。この処理は公開の記事で詳しく解説しています。まずは下書き作成だけを自動化し、公開は画面から行うという段階的な進め方をおすすめします。

Q. 本文に画像を入れられますか?

画像を先にアップロードしてURLを取得し、そのURLを含むimgタグを本文に埋め込む形になります。アップロードには専用のエンドポイントを使い、S3への2段階アップロードという手順を踏みます。下書き作成とは別の処理になるため、画像を含む記事を自動生成したい場合は画像アップロードの記事も参照してください。

Q. 何本まで下書きを作れますか?

上限は公開されていませんが、実用上問題になる制限は確認されていません。ただし、短時間に大量作成するとサーバー負荷の観点で問題があります。この記事のスクリプトでは1回の実行で10本までという上限を設けています。原稿が大量にある場合は、日を分けて処理してください。

Q. 装飾したいのですがspanが使えません

noteは意図的に装飾の自由度を制限しています。文字色やフォントサイズを個別に変えることはできません。使えるのは太字・斜体・打ち消し線・引用・見出しといった基本的な要素だけです。これは制約ではありますが、記事の見た目が統一されるという利点もあります。装飾で強調するのではなく、構成と言葉で伝える設計にするのが、noteでの書き方に合っています。

Q. 既存の下書きを更新できますか?

できます。draft_save に既存の下書きのidを渡せば上書きされます。この記事の NoteDraft.save() がそれにあたります。注意点として、上書き保存は元の内容を復元できません。ローカルの原稿を正としてnote側へ反映する運用にすると、誤って上書きしても手元のファイルから戻せます。

Q. 同じ記事が何本も作られてしまいました

重複チェックを入れていない状態で複数回実行したケースです。この記事の find_by_title() のように、作成前に同名の下書きが無いかを確認してください。すでに大量に作ってしまった場合は、clean_drafts.py のようなスクリプトでタイトル一致のものをまとめて削除できます。削除は取り消せないため、対象の確認は慎重に行ってください。

Q. Markdownをそのまま渡せますか?

渡せません。本文はHTMLとして解釈されるため、Markdown記法はそのまま文字として表示されます。この記事の text_to_html() は簡易的な変換ですが、見出し・リスト・引用には対応しています。より本格的な変換が必要な場合は、Markdown変換の記事で扱っている実装を使ってください。

Q. 下書きの状態でも他人に見られますか?

見られません。下書きは自分だけが閲覧できる状態です。ただし、公開設定を誤って操作すると意図せず公開されることはあります。APIで下書きを扱う際は、draft_save が公開処理を行わない仕様であることが安全側に働きます。公開は明示的に別のエンドポイントを呼ばない限り発生しません。

Q. スクリプトが途中で止まりました

この記事の一括作成スクリプトは、成功したファイルだけを処理済みフォルダへ移動します。そのため、途中で止まっても再実行すれば残りのファイルから続行されます。また重複チェックがあるため、同じ記事が二重に作られることもありません。エラーの内容を確認する場合は、認証切れ(401)か、ペイロードの問題(422)かをステータスコードで切り分けてください。

アメプレスラボ編集部

AMEPRESS LAB EDITORIAL TEAM

アメブロ・note・WordPressを実際に運営し、それぞれの収益構造を数字で検証しているチーム。プラットフォームごとの得意・不得意を踏まえた、宣伝色に偏らない実践情報の発信を続けています。