PythonとAIでブログ執筆を加速!Gemini APIとWordPress APIを連携させるGUIツールのコードを徹底解説
ブログ運営は楽しい一方で、記事のネタ探しから執筆、そして投稿まで、多くの時間と労力を必要とします。特に複数の記事を作成している方にとって、このプロセスをいかに効率化するかが大きな課題です。
そこで注目されているのが、AIを活用したブログ記事の生成支援です。GoogleのGeminiのような強力な言語モデルを使えば、アイデア出しやドラフト作成を大幅に短縮できます。さらに、WordPressのREST APIを使えば、生成した記事を直接ブログに投稿することも可能です。
この記事では、Pythonを使ってGoogle Gemini APIでブログ記事(タイトル、メタディスクリプション、本文)を生成し、それを簡単なGUI上で編集・確認し、最終的にWordPressへ自動投稿するツールを実現したコードを深掘りして解説します。
このコードを理解し、カスタマイズすることで、あなたのブログ運営ワークフローを劇的に改善できる可能性があります。
1. はじめに:このコードが解決することと使用技術
まず初めに、今回解説するPythonコードの目的と全体像を把握しましょう。
このコードは、ユーザーが提供するテキスト(記事の元ネタやアイデア)を基に、以下のタスクを自動化または半自動化するためのデスクトップGUIアプリケーションです。
- AI (Gemini) による記事コンテンツ生成: 入力テキストから、SEOに強いブログ記事のタイトル案、魅力的なメタディスクリプション、そして本文のドラフトを生成します。
- GUI上でのコンテンツ確認・編集: 生成されたタイトル、メタディスクリプション、本文(Markdown形式)をGUI上で確認し、必要に応じて手動で編集できます。
- WordPressへの自動投稿: 編集・確認済みの記事を、WordPress REST APIを使ってあなたのブログに新規記事として投稿します。メタディスクリプションは、特定のSEOプラグイン(例: All in One SEO Pack)のカスタムフィールドに対応可能です。
このツールは、完全に自動で記事を量産するものではなく、「AIが得意なドラフト生成」と「人間が行うべき最終確認・編集・判断」を組み合わせることで、効率的なブログ記事作成プロセスを実現することを目指しています。
使用されている主な技術は以下の通りです。
- Python: 全体のプログラミング言語。
- Tkinter: Python標準のGUIライブラリ。シンプルながらデスクトップアプリケーションを構築できます。
- Google Generative AI (gemini): Google Gemini APIを利用するためのPythonライブラリ。テキスト生成を担当します。
- requests: HTTPリクエストを送信するためのライブラリ。WordPress REST APIとの通信に使用します。
- python-dotenv: 環境変数ファイルを読み込むためのライブラリ。APIキーやWordPress接続情報などの機密情報をコードと分離します。
- markdown, Pygments: Markdown形式で書かれた本文をHTMLに変換するために使用します。(Pygmentsはコードハイライトに必要)
これらの技術を組み合わせることで、デスクトップ上の操作でAIを活用したブログ投稿が完結する仕組みが作られています。
2. コード徹底解説:各部分の役割と仕組み
それでは、提供されたコードをセクションごとに詳しく見ていきましょう。
2.1. ライブラリのインポートと設定読み込み
import os
import json
import time
from datetime import datetime
import requests
from dotenv import load_dotenv
# GUIライブラリ
import tkinter as tk
from tkinter import scrolledtext, messagebox, ttk, font
# Gemini APIライブラリ
import google.generativeai as genai
# Markdown to HTML
try:
import markdown
from markdown.extensions.codehilite import CodeHiliteExtension
from markdown.extensions.fenced_code import FencedCodeExtension
MARKDOWN_AVAILABLE = True
except ImportError:
MARKDOWN_AVAILABLE = False
# --- 設定項目 ---
load_dotenv(dotenv_path="apikey.env")
WP_URL = os.getenv("WP_URL")
WP_USERNAME = os.getenv("WP_USERNAME")
WP_APP_PASSWORD = os.getenv("WP_APP_PASSWORD")
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
# All in One SEO Pack のメタディスクリプション用カスタムフィールドキーをデフォルトに
META_DESCRIPTION_FIELD_KEY = os.getenv("META_DESCRIPTION_FIELD_KEY", "_aioseo_description")
GEMINI_MODEL_NAME = os.getenv("GEMINI_MODEL_NAME", 'gemini-1.5-flash-latest')
LOG_FILE = "gemini_wp_poster_v0.4.1_aioseo.log"
- 標準ライブラリ:
os
(環境変数),json
(データ処理),time
,datetime
(時刻・日付) など、基本的な処理に必要なモジュールをインポートしています。 - 外部ライブラリ:
requests
: WordPress APIとの通信に必須です。dotenv
(load_dotenv
): プロジェクトルートに置かれたapikey.env
ファイルからWP_URL
,GEMINI_API_KEY
などの設定値を読み込み、環境変数として利用可能にします。これにより、機密情報をコード内に直接書かずに済みます。tkinter
モジュール群: GUI部品(ウィンドウ、ボタン、テキストエリアなど)を提供します。scrolledtext
はスクロール可能なテキストエリア、messagebox
は警告やエラーダイアログ、ttk
はよりモダンなウィジェットを提供します。google.generativeai
: Gemini APIをPythonから簡単に呼び出すための公式ライブラリです。markdown
,markdown.extensions.*
: Markdown形式のテキストをHTMLに変換するためのライブラリです。コードハイライト機能 (CodeHiliteExtension
) やフェンス付きコードブロック (FencedCodeExtension
) といった拡張機能も利用しています。try...except ImportError
ブロックでインポートしているのは、これらのライブラリがインストールされていなくても基本的な機能(Markdown→HTML変換を除く)は動作するようにするためです。
- 設定項目:
load_dotenv()
で.env
ファイルの内容を読み込んだ後、os.getenv()
で各設定値を変数に代入しています。WP_URL
,WP_USERNAME
,WP_APP_PASSWORD
: WordPressサイトのURL、API接続用ユーザー名、アプリケーションパスワードです。GEMINI_API_KEY
: Gemini APIを利用するためのAPIキーです。META_DESCRIPTION_FIELD_KEY
: ここが重要なポイントです。WordPressでSEOプラグイン(例: AIOSEO, Yoast SEO)を使っている場合、メタディスクリプションは記事の標準フィールドではなく、カスタムフィールドとして管理されることが多いです。この変数にそのカスタムフィールドのキー名を指定することで、生成したメタディスクリプションを正しく設定できます。デフォルト値としてAIOSEOのキー_aioseo_description
が指定されていますが、お使いの環境に合わせて変更可能です。GEMINI_MODEL_NAME
: 使用するGeminiモデルの名前を指定します。デフォルトはgemini-1.5-flash-latest
です。
2.2. ログ出力関数 (log_message
)
# グローバル変数
app_instance = None
gemini_model = None
# --- ユーティリティ関数 (ログ) ---
def log_message(message):
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_entry = f"[{timestamp}] {message}\n"
print(log_entry.strip())
if app_instance and hasattr(app_instance, 'log_to_gui') and app_instance.root and app_instance.root.winfo_exists():
app_instance.log_to_gui(log_entry)
try:
with open(LOG_FILE, "a", encoding="utf-8") as f:
f.write(log_entry)
except Exception as e:
print(f"ログファイル書き込みエラー: {e}")
if app_instance and hasattr(app_instance, 'log_to_gui') and app_instance.root and app_instance.root.winfo_exists():
app_instance.log_to_gui(f"ログファイル書き込みエラー: {e}\n")
log_message
関数は、プログラムの実行状況や発生したエラーを記録するために使われます。
– タイムスタンプを付加し、コンソールに出力します。
– app_instance
が存在し、かつGUIのログ表示エリアが利用可能であれば、そこにもメッセージを表示します。これにより、GUI上でリアルタイムに処理の進行やエラーを確認できます。
– 指定されたログファイル (LOG_FILE
) にも追記書き込みを行います。これにより、GUIを閉じてもログを後から確認できます。
– ログファイル書き込み自体でエラーが発生した場合も、それを捕捉して報告します。
2.3. Gemini API連携関数
AIによるコンテンツ生成の中核部分です。
# --- Gemini API連携関数 ---
def configure_gemini():
global gemini_model
if not GEMINI_API_KEY:
log_message("エラー: Gemini APIキーが設定されていません。apikey.envを確認してください。")
return False
try:
genai.configure(api_key=GEMINI_API_KEY)
model_name_to_use = GEMINI_MODEL_NAME # グローバル設定から取得
gemini_model = genai.GenerativeModel(model_name_to_use)
log_message(f"Gemini APIの初期化成功 (モデル: {model_name_to_use})。")
return True
except Exception as e:
log_message(f"エラー: Gemini APIの初期化に失敗: {e}")
gemini_model = None
return False
def generate_title_with_gemini(text_input):
# ... タイトル生成ロジック ...
def generate_metadesc_with_gemini(text_input, article_title=""):
# ... メタディスクリプション生成ロジック ...
def generate_content_with_gemini(text_input, input_type="general"):
# ... 本文生成ロジック ...
configure_gemini()
:GEMINI_API_KEY
を使用してGemini APIクライアントを初期化します。指定されたモデル名 (GEMINI_MODEL_NAME
) でGenerativeModel
オブジェクトを作成し、グローバル変数gemini_model
に格納します。APIキーが設定されていない場合や、初期化に失敗した場合はログを出力し、後続処理に知らせます。generate_title_with_gemini(text_input)
:- 入力テキスト (
text_input
) を基に、タイトル生成のためのプロンプトを作成します。プロンプトには、AIの役割(プロブロガー、SEOエキスパート)、目的(魅力的なタイトル案5個)、制約事項(日付なし、簡潔さ、フォーマット)が具体的に記述されています。 gemini_model.generate_content()
を呼び出し、APIにテキスト生成をリクエストします。レスポンスから生成されたタイトル候補を抽出し、リスト形式で返します。余分な記号(-
や*
)を除去する処理も含まれています。
- 入力テキスト (
generate_metadesc_with_gemini(text_input, article_title="")
:- 入力テキストと(もしあれば)生成済みタイトルを基に、メタディスクリプション生成のためのプロンプトを作成します。プロンプトでは、AIの役割(SEOコンテンツライター)、目的(クリックを促すメタディスクリプション)、制約事項(文字数範囲、要約内容、キーワード)が指定されています。
- APIにリクエストし、生成されたメタディスクリプションのテキストを返します。
generate_content_with_gemini(text_input, input_type="general")
:- これが最も重要な関数です。入力テキストと入力タイプ(”question”, “code”, “general”)を基に、ブログ記事本文生成のための詳細なプロンプトを構築します。
- ベースプロンプト: 全ての入力タイプに共通する指示(プロブロガー/テクニカルライターの役割、SEO配慮、Markdown形式、構造化、平易な言葉遣い、専門用語解説、構成、深掘り、つなぎ言葉、参考情報)が含まれています。
- 入力タイプ別指示:
input_type
に応じて、記事の構成案を具体的に指示するプロンプトが追加されます。これにより、質問には質問への回答、コードにはコード解説というように、内容に合わせた構成の本文が生成されるよう促します。 - APIにリクエストし、生成されたMarkdown形式の本文テキストを返します。
各API連携関数には、API呼び出し中に発生しうる様々な例外 (Exception
) を捕捉し、エラーメッセージをログに出力する仕組みが実装されています。
2.4. WordPress連携関数 (create_wordpress_post
)
生成・編集した記事コンテンツをWordPressに投稿する部分です。
# --- WordPress連携関数 (新規作成のみ) ---
def create_wordpress_post(title, content_html, metadescription=None):
if not all([WP_URL, WP_USERNAME, WP_APP_PASSWORD]):
log_message("エラー: WordPressの接続情報が設定されていません。")
return None, None
api_url = f"{WP_URL.rstrip('/')}/wp-json/wp/v2/posts"
headers = {"Content-Type": "application/json"}
post_data = {
"title": title,
"content": content_html,
"status": "publish", # デフォルトで公開
}
if metadescription and META_DESCRIPTION_FIELD_KEY:
post_data["meta"] = {
META_DESCRIPTION_FIELD_KEY: metadescription
}
log_message(f"投稿データにメタディスクリプションを追加 (キー: {META_DESCRIPTION_FIELD_KEY}): 「{metadescription[:50]}...」")
elif metadescription:
log_message(f"警告: メタディスクリプション「{metadesc[:50]}...」がありますが、META_DESCRIPTION_FIELD_KEYが設定されていません。投稿されません。")
log_message(f"WordPress記事 新規作成試行: 「{title[:50]}...」")
try:
response = requests.post(api_url, headers=headers, auth=(WP_USERNAME, WP_APP_PASSWORD), json=post_data, timeout=90)
response.raise_for_status() # ステータスコードがエラーの場合は例外発生
response_json = response.json()
wp_post_id = response_json.get('id')
wp_post_link = response_json.get('link')
log_message(f"WordPress記事 新規作成成功: 「{title[:50]}...」(記事ID: {wp_post_id}, URL: {wp_post_link})")
return wp_post_id, wp_post_link
except requests.exceptions.RequestException as e:
# ... エラーハンドリングとログ出力 ...
messagebox.showerror("WordPress投稿エラー", f"WordPressへの投稿に失敗しました。\n詳細はログを確認してください。\n{error_detail.splitlines()[0] if error_detail else str(e)}")
return None, None
- この関数は、
requests
ライブラリを使ってWordPressのREST APIエンドポイント (/wp-json/wp/v2/posts
) に対してPOSTリクエストを送信します。 - 認証には、WordPressで生成したアプリケーションパスワードを使用します(Basic認証形式)。
- リクエストボディには、記事のタイトル (
title
)、HTML形式の本文 (content_html
)、そして記事の状態 (status
– デフォルトは “publish” で公開) をJSON形式で含めます。 - メタディスクリプション:
metadescription
が提供され、かつMETA_DESCRIPTION_FIELD_KEY
が設定されている場合、"meta"
フィールドの中にカスタムフィールドとしてメタディスクリプションのデータを含めます。これにより、AIOSEOなどのプラグインがその値を認識し、適切に処理できるようになります。 response.raise_for_status()
は、HTTPステータスコードが4xxや5xxの場合にrequests.exceptions.HTTPError
を発生させ、エラーを捕捉しやすくします。- 成功した場合、レスポンスJSONから投稿された記事のIDとパーマリンクを取得して返します。
- 失敗した場合は、詳細なエラー情報をログに出力し、GUIにエラーメッセージを表示します。
2.5. GUIアプリケーションクラス (GeminiWordPressPosterApp
)
Tkinterを使ってユーザーインターフェースを構築し、上記の関数群を連携させます。
# --- GUIアプリケーション ---
class GeminiWordPressPosterApp:
def __init__(self, root_tk):
global app_instance
app_instance = self # グローバル変数にインスタンスを格納 (ログ関数からアクセスするため)
self.root = root_tk
# ... GUIの基本設定、スタイル設定 ...
if not configure_gemini():
# Gemini初期化失敗時の処理
messagebox.showerror("API初期化エラー", "...")
# self.root.destroy() # 必要なら終了
notebook = ttk.Notebook(self.root) # タブUI
# ... タブとフレームの作成 ...
# メインタブのUI要素配置
# ... input_frame (入力テキストエリア) ...
# ... type_frame (入力タイプ選択ラジオボタン) ...
# ... ai_action_frame (生成ボタン) ...
# ... title_frame (タイトル編集エントリー) ...
# ... metadesc_frame (メタディスクリプション編集エントリーと文字数ラベル) ...
# ... content_frame (本文編集スクロールテキストエリアと文字数ラベル) ...
# ... post_action_frame (投稿ボタン) ...
# ログタブのUI要素配置
# ... log_text_area (ログ表示用スクロールテキストエリア) ...
# 各種UIイベントのバインド
self.metadesc_var.trace_add("write", self.update_metadesc_char_count) # メタディスクリプション文字数カウント
self.generated_content_text.bind("<<Modified>>", self._text_modified_flag) # 本文文字数カウントトリガー
# ボタンのcommand設定は__init__内で行われている
log_message("GUIアプリケーションを開始しました。")
self.check_initial_configs() # 設定チェック
def _text_modified_flag(self, event): # 本文変更フラグをリセットし、文字数カウントを更新
# ...
def update_metadesc_char_count(self, *args): # メタディスクリプション文字数カウント更新
# ... 文字数表示と色分けロジック ...
def update_content_char_count(self, *args): # 本文文字数カウント更新
# ... 文字数表示と色分けロジック ...
def check_initial_configs(self): # 初期設定チェックと警告表示
# ... WP, Gemini, Markdownライブラリの設定不足をチェックし、メッセージボックスで警告 ...
def log_to_gui(self, message): # ログメッセージをGUIに表示
# ... log_text_areaにメッセージを追記し、スクロール ...
def _toggle_buttons_state(self, state="disabled"): # ボタンの有効/無効切り替え
# ... 生成・投稿ボタンの状態を変更 ...
def generate_all_action(self): # 「タイトル・メタ・本文を生成」ボタンの処理
# ... 入力テキスト取得、バリデーション、ボタン無効化 ...
# ... generate_title_with_gemini() 呼び出しと結果のUI反映 ...
# ... generate_metadesc_with_gemini() 呼び出しと結果のUI反映 ...
# ... generate_content_with_gemini() 呼び出しと結果のUI反映 ...
# ... ボタン有効化、完了メッセージ ...
def post_to_wordpress_action(self): # 「WordPressに投稿」ボタンの処理
# ... タイトル、メタディスクリプション、本文取得、バリデーション ...
# ... WordPress設定チェック ...
# ... MarkdownからHTMLへの変換 (markdownライブラリを使用、なければ簡易変換) ...
# ... ボタン無効化 ...
# ... create_wordpress_post() 呼び出し ...
# ... 成功時のメッセージボックス表示とクリア確認 ...
# ... 失敗時のエラーメッセージボックス表示 ...
# ... ボタン有効化 ...
if __name__ == "__main__":
root = tk.Tk() # Tkinterアプリケーションのルートウィンドウを作成
app = GeminiWordPressPosterApp(root) # アプリケーションインスタンスを作成
root.mainloop() # GUIイベントループを開始
log_message("GUIアプリケーションを終了しました。")
__init__(self, root_tk)
: アプリケーションの初期化を行い、GUIコンポーネントを配置します。app_instance = self
:log_message
関数からインスタンスメソッド (log_to_gui
) を呼び出せるように、自身のインスタンスをグローバル変数に設定します。- ウィンドウタイトル、サイズ、スタイルの設定。
- Gemini APIの初期化 (
configure_gemini()
) を行い、失敗した場合はメッセージボックスで警告します。 ttk.Notebook
を使用して、「記事生成」と「ログ」のタブを作成します。- 各タブ内にフレームを作成し、その中にユーザーが操作する各種ウィジェット(テキストエリア、ボタン、エントリーフィールドなど)を配置します。
ttk.LabelFrame
を使うことで、関連するウィジェットをグループ化し、ラベルを付けることができます。 - 入力テキストエリア (
self.input_text
)、生成された本文エリア (self.generated_content_text
) はscrolledtext.ScrolledText
を使うことで、内容が多くてもスクロールして確認できます。 - タイトル (
self.title_var
) やメタディスクリプション (self.metadesc_var
) の入力にはtk.StringVar
とttk.Entry
を使用し、変数と入力フィールドを連携させています。 - メタディスクリプションと本文の文字数をリアルタイムで表示するラベル (
self.metadesc_char_count_label
,self.content_char_count_label
) を設置し、指定範囲内外で色が変わるようにしています。 - 各種ボタン (
self.generate_all_button
,self.post_button
) に、クリック時に実行されるメソッド (command
) を割り当てています。 - メタディスクリプションの文字数カウントは
metadesc_var.trace_add("write", ...)
で変数への書き込みイベントを監視して更新します。本文は<<Modified>>
イベントを監視し、フラグをリセットしながら更新する方式を取っています。 - 初期設定 (
apikey.env
の内容など) を確認し、不足している場合は警告メッセージを表示します。
log_to_gui(self, message)
:log_message
関数から呼ばれ、GUI上のログエリアにメッセージを追加・表示する役割を担います。generate_all_action()
: AIによる生成処理を実行するメソッドです。入力テキストを取得し、バリデーション後、generate_title_with_gemini
,generate_metadesc_with_gemini
,generate_content_with_gemini
各関数を呼び出し、結果を対応するGUI要素にセットします。処理中はボタンを無効化し、終了後に有効化します。post_to_wordpress_action()
: WordPressへの投稿処理を実行するメソッドです。GUI上のタイトル、メタディスクリプション、本文を取得し、バリデーション後、Markdown形式の本文をHTMLに変換します。この際、markdown
ライブラリが利用可能であれば高度な変換(コードブロック対応など)を行い、なければ単純なHTMLタグ置換による変換を行います。その後、create_wordpress_post
関数を呼び出し、投稿結果に応じてメッセージを表示し、必要であれば入力内容をクリアします。処理中はボタンを無効化します。if __name__ == "__main__":
: スクリプトが直接実行された場合に、Tkinterのルートウィンドウを作成し、GeminiWordPressPosterApp
クラスのインスタンスを生成、そしてroot.mainloop()
でGUIイベントループを開始します。これにより、GUIアプリケーションとして実行されます。
3. 実行方法と使用例
このツールをローカル環境で実行するための手順と、簡単な使用例を示します。
3.1. 事前準備
- Pythonのインストール: Python 3.7以上がインストールされていることを確認してください。
-
必要なライブラリのインストール: ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行します。
bash
pip install requests python-dotenv google-generativeai markdown Pygments tkinter ttkthemes
(tkinter
とttkthemes
はPythonに標準で含まれていることがありますが、明示的にインストールしても問題ありません。ttkthemes
はコードには直接使用されていませんが、Tkinterのテーマを試すのに便利です。)
3..env
ファイルの作成: スクリプトファイルと同じディレクトリにapikey.env
という名前のテキストファイルを作成し、以下の形式で必要な情報を記述します。“`env
Google Gemini API Key
GEMINI_API_KEY=’YOUR_GEMINI_API_KEY’
WordPress Connection Info (Requires Application Passwords)
See: https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/#application-passwords
WP_URL=’YOUR_WORDPRESS_URL’ # e.g., https://yourblog.com/
WP_USERNAME=’YOUR_WP_API_USERNAME’ # An existing WP username
WP_APP_PASSWORD=’YOUR_WP_APPLICATION_PASSWORD’ # Generate in WP admin -> Users -> Your Profile -> Application PasswordsOptional: All in One SEO Pack Meta Description Custom Field Key (Default: _aioseo_description)
Check your SEO plugin’s documentation or inspect post meta
META_DESCRIPTION_FIELD_KEY=’_aioseo_description’
Optional: Gemini Model Name (Default: gemini-1.5-flash-latest)
GEMINI_MODEL_NAME=’gemini-1.5-flash-latest’ # Or ‘gemini-1.5-pro-latest’ etc.
“`YOUR_GEMINI_API_KEY
: Google AI Studioなどで取得したGemini APIキーに置き換えてください。YOUR_WORDPRESS_URL
: あなたのWordPressサイトのURLに置き換えてください(末尾にスラッシュ/
を含めるかどうかはAPI仕様によるが、通常は含めなくてOK)。YOUR_WP_API_USERNAME
: WordPressでAPI接続に使用するユーザーのログイン名に置き換えてください。このユーザーには投稿権限が必要です。YOUR_WP_APPLICATION_PASSWORD
: WordPress管理画面で、API接続に使用するユーザーのプロフィールページに行き、「アプリケーションパスワード」セクションで新規パスワードを生成し、その生成されたパスワードをここに貼り付けてください。このパスワードは一度しか表示されないので、必ず控えてください。META_DESCRIPTION_FIELD_KEY
: お使いのSEOプラグインのメタディスクリプション用カスタムフィールドキーがAIOSEOと異なる場合は、適切なキー名に変更してください。不明な場合はデフォルトのままでも動作しますが、メタディスクリプションは投稿されません。この設定を空にしても、メタディスクリプションは投稿されません。GEMINI_MODEL_NAME
: 使用したいGeminiモデル名を指定します。利用可能なモデルはGemini APIのドキュメントで確認してください。
.env
ファイルは機密情報を含むため、Gitなどで管理する場合は必ず.gitignore
に追加し、誤って公開しないように注意してください。
-
WordPress側の設定:
- REST APIが有効になっていることを確認します(通常はデフォルトで有効です)。
- API接続に使用するユーザーに投稿権限があることを確認します。
- 上記3.で説明した手順でアプリケーションパスワードを生成します。
- SEOプラグイン(AIOSEOなど)を使用しており、メタディスクリプションをカスタムフィールドで管理している場合は、そのフィールドキーが
.env
で設定したMETA_DESCRIPTION_FIELD_KEY
と一致していることを確認します。
3.2. 実行手順
- 上記のPythonコードを
gemini_wp_poster.py
のような名前で保存します。 .env
ファイルが同じディレクトリにあることを確認します。- ターミナルまたはコマンドプロンプトを開き、保存したディレクトリに移動します。
-
以下のコマンドを実行します。
bash
python gemini_wp_poster.py
5. GUIウィンドウが表示されます。
3.3. 使用例
- GUIウィンドウの「記事生成」タブが開いていることを確認します。
- 左側の「1. 入力テキスト (記事の元ネタ)」エリアに、ブログ記事の元となるテキストを貼り付けます。例えば、ある技術に関する調査結果や、書きたい記事の概要などを書きます。
- 「2. 入力タイプ」で、入力テキストが「一般的な内容」「質問・疑問」「プログラムコード」のいずれに該当するかを選択します。この選択が、AIへの指示(プロンプト)の内容に影響し、生成される記事の構成が変わります。コードの解説記事を生成したい場合は、「プログラムコード」を選択します。
- 「3. AIで一括生成」の「タイトル・メタ・本文を生成」ボタンをクリックします。
- しばらく待つと、右側のエリアにAIが生成した「4. タイトル案」(最初の候補が入力済み)、「5. メタディスクリプション」、「6. 本文 (Markdown)」が表示されます。ログタブには、API通信などの詳細が表示されます。
- 生成された内容を確認し、必要に応じて各入力フィールドやテキストエリアで編集を行います。タイトルやメタディスクリプションの文字数カウンターを参考に調整しましょう。本文はMarkdown形式なので、見出しやリスト、コードブロックなどが適切に整形されているか確認します。
- 内容に問題がなければ、右下の「WordPressに投稿」ボタンをクリックします。
- 投稿が成功すると、成功メッセージと投稿された記事のID、URLが表示されます。入力内容をクリアするかどうかも選択できます。失敗した場合は、エラーメッセージが表示され、詳細はログタブで確認できます。
- WordPressの管理画面で、新しく投稿された記事を確認します。タイトル、本文、そしてメタディスクリプションが正しく反映されていることを確認しましょう。
4. 応用と改善のヒント
提供されたコードは、あくまで基本的な機能を持つツールです。これをベースに、さらに便利にするための応用や改善のアイデアは数多く考えられます。
4.1. 機能拡張のアイデア
- タイトル候補リスト: 現在は生成されたタイトル候補の最初の1つがエントリーに設定されるだけですが、生成された候補リストを表示し、ユーザーが選択できるようにすることで、より適切なタイトルを選びやすくなります。
- カテゴリ・タグ設定: WordPress APIを利用して、記事にカテゴリやタグを設定する機能を追加します。APIドキュメントを参照し、投稿データに
categories
やtags
フィールドを追加できるようにします。 - 画像アップロード: 記事に関連する画像をAIに生成させたり、ローカルから画像をアップロードしてWordPressのメディアライブラリに登録し、記事本文に挿入する機能は、視覚的な記事作成において非常に有効です。これはWordPress REST APIのメディアエンドポイント (
/wp/v2/media
) を利用することで実現できます。 - 予約投稿: 投稿ステータスを
"publish"
ではなく"future"
に設定し、公開日時を指定することで、記事を予約投稿できるようにします。 - 既存記事の更新: 記事IDを指定して、既存の記事の内容やタイトルを更新する機能も考えられます。これはWordPress REST APIのPUTメソッドを利用します。
- 他のAIモデル・APIとの連携: Geminiだけでなく、OpenAI (ChatGPT) やClaudeなど、他の言語モデルAPIを選択して利用できるように機能を拡張することで、生成されるコンテンツのバリエーションを増やせます。
- 他のブログプラットフォームへの対応: WordPressだけでなく、Qiita、note、Bloggerなど、他のブログプラットフォームやCMSのAPIに対応することで、活用の幅が広がります。
- バッチ処理: 複数の入力テキストファイルを用意し、それらを一括で処理して記事を生成・投稿するバッチ処理機能を追加すれば、さらに大量の記事作成が効率化できます。
- プロンプトのカスタマイズUI: 現在、生成プロンプトはコード内に直接記述されていますが、GUI上でプロンプトのテンプレートを編集したり、詳細な指示(文体、ターゲット読者など)を追加できるUIを設けることで、AIによる生成結果をより細かくコントロールできるようになります。
4.2. パフォーマンス改善と堅牢性向上
- 非同期処理: 現在のコードはAPI呼び出し中にGUIが応答しなくなる(フリーズする)可能性があります。
asyncio
やthreading
を利用してAPI呼び出しをバックグラウンドで行うようにすることで、GUIの応答性を維持できます。 - API呼び出しのリトライ: ネットワークの一時的な問題などでAPI呼び出しが失敗した場合に、数回リトライする仕組みを追加することで、処理の中断を防ぎ、堅牢性を高められます。
- エラーハンドリングの強化: 各種API呼び出しやファイル操作などにおいて、考えられる様々なエラーケース(APIレート制限、不正なAPIキー、WordPress接続失敗、権限不足など)に対するより詳細なエラー処理と、ユーザーへの分かりやすいフィードバックを実装します。
4.3. セキュリティに関する考慮事項
- .envファイルの管理:
apikey.env
ファイルにはAPIキーやWordPressの認証情報といった機密情報が含まれています。このファイルが誤って外部に公開されないよう、Gitなどで管理する場合は必ず.gitignore
に追加してください。 - WordPressアプリケーションパスワード: アプリケーションパスワードは、特定のアプリケーションにWordPressへのアクセス権限を与える強力な認証情報です。このパスワードが漏洩すると、サイトに不正アクセスされるリスクがあります。不要になったパスワードは速やかにWordPress管理画面から削除し、安全な場所に保管してください。また、API接続に使用するWordPressユーザーの権限は、必要最低限に絞ることを推奨します。
- APIキーの保護: Gemini APIキーも同様に機密情報です。第三者に知られないように厳重に管理してください。
5. おわりに:AIと自動化で変わるブログ運営
この記事では、PythonとTkinterを用いて、Google Gemini APIによる記事コンテンツ生成とWordPress REST APIによる自動投稿を連携させたGUIツールのコードを詳細に解説しました。
このツールは、ブログ記事の企画・執筆・投稿という一連のワークフローにおいて、AIが強力なアシスタントとなりうる可能性を示しています。単に自動で記事を作るだけでなく、AIが生成したドラフトを人間が確認・編集するというプロセスをGUI上でスムーズに行えるのがポイントです。
もちろん、AIが生成したコンテンツには事実誤認や不自然な表現が含まれる可能性があるため、人間による最終的な校正や推敲は欠かせません。しかし、ゼロから記事を書き始めるのと比較すれば、AIによるドラフト生成は大幅な時間短縮と効率化をもたらすでしょう。
このコードはあくまで出発点です。今回紹介した応用や改善のヒントを参考に、ぜひご自身のブログ運営スタイルに合わせてコードをカスタマイズし、より強力で便利なツールへと発展させてみてください。Pythonのスキルを磨きながら、ブログ運営をさらに効率化する、素晴らしい機会となるはずです。
Happy Blogging with AI!
参考情報:
- Google for Developers Japan Blog: Gemini API が利用可能になりました (Gemini APIの概要)
- WordPress Developer Resources: REST API Handbook (WordPress REST APIの公式ドキュメント)