エンジニアになりたい人募集!X(旧Twitter)からフォローしたらリプライで質問常時OK!

【AI ブロガー開発】WordPress REST API を使った記事投稿機能の実装

この記事はで読むことができます。

はじめに

前回の記事では、Claude APIを使用して記事を自動生成する機能を実装しました。今回は、生成された記事をWordPressに自動投稿する機能を開発します。この機能により、AIが生成したコンテンツを直接ブログに公開することが可能になります。

【AI ブロガー開発】Claude API を使った記事生成機能の実装

この記事を通じて、以下のスキルと知識を習得することができます。

  1. WordPress REST APIの基本的な使い方
  2. GolangでのREST APIクライアントの実装
  3. 認証処理とセキュリティ考慮事項
  4. エラーハンドリングと例外処理

それでは、実装に入っていきましょう。

WordPress REST APIの概要

WordPress REST APIは、WordPressの機能にプログラムからアクセスするためのインターフェースを提供します。これを使用することで、投稿の作成、更新、削除などの操作をリモートから行うことができます。

主な特徴は以下の通りです。

  1. RESTful な設計
  2. JSON形式でのデータのやり取り
  3. 認証機能による安全なアクセス制御

WordPress API クライアントの実装

まず、WordPress REST APIとやり取りするためのクライアントを実装します。internal/wordpress/client.goファイルを以下のように作成します:

go
package wordpress

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"

    "github.com/yourusername/ai-blogger-golang/internal/models"
)

type Client struct {
    BaseURL  string
    Username string
    Password string
}

func NewClient(baseURL, username, password string) *Client {
    return &Client{
        BaseURL:  baseURL,
        Username: username,
        Password: password,
    }
}

func (c *Client) CreatePost(article *models.Article) (int, error) {
    endpoint := fmt.Sprintf("%s/wp-json/wp/v2/posts", c.BaseURL)

    postData := map[string]interface{}{
        "title":   article.Title,
        "content": article.Content,
        "status":  "draft", // または "publish" としてすぐに公開することもできます
    }

    jsonData, err := json.Marshal(postData)
    if err != nil {
        return 0, fmt.Errorf("error marshaling post data: %v", err)
    }

    req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonData))
    if err != nil {
        return 0, fmt.Errorf("error creating request: %v", err)
    }

    req.SetBasicAuth(c.Username, c.Password)
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return 0, fmt.Errorf("error sending request: %v", err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusCreated {
        return 0, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
    }

    var result map[string]interface{}
    if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
        return 0, fmt.Errorf("error decoding response: %v", err)
    }

    postID, ok := result["id"].(float64)
    if !ok {
        return 0, fmt.Errorf("could not extract post ID from response")
    }

    return int(postID), nil
}

このコードでは、以下の主要な機能を実装しています。

  1. WordPress APIクライアントの構造体定義
  2. クライアントの初期化関数
  3. 記事投稿関数(HTTP POSTリクエストの送信と応答の処理)

カテゴリ指定機能の追加

記事をカテゴリに分類することも重要です。カテゴリを指定して投稿する機能を追加しましょう。internal/wordpress/client.goに以下の関数を追加します。

go
func (c *Client) GetCategories() ([]Category, error) {
    endpoint := fmt.Sprintf("%s/wp-json/wp/v2/categories", c.BaseURL)

    req, err := http.NewRequest("GET", endpoint, nil)
    if err != nil {
        return nil, fmt.Errorf("error creating request: %v", err)
    }

    req.SetBasicAuth(c.Username, c.Password)

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, fmt.Errorf("error sending request: %v", err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
    }

    var categories []Category
    if err := json.NewDecoder(resp.Body).Decode(&categories); err != nil {
        return nil, fmt.Errorf("error decoding response: %v", err)
    }

    return categories, nil
}

func (c *Client) CreatePost(article *models.Article, categoryIDs []int) (int, error) {
    // ... (前半部分は変更なし)

    postData := map[string]interface{}{
        "title":      article.Title,
        "content":    article.Content,
        "status":     "draft",
        "categories": categoryIDs,
    }

    // ... (後半部分は変更なし)
}

これにより、カテゴリ一覧の取得と、カテゴリを指定しての投稿が可能になります。

main.go の更新

次に、cmd/main.goファイルを更新して、WordPress投稿機能を利用できるようにします。

go
package main

import (
    "fmt"
    "log"

    "github.com/yourusername/ai-blogger-golang/config"
    "github.com/yourusername/ai-blogger-golang/internal/claude"
    "github.com/yourusername/ai-blogger-golang/internal/content"
    "github.com/yourusername/ai-blogger-golang/internal/wordpress"
)

func main() {
    cfg, err := config.Load()
    if err != nil {
        log.Fatalf("Error loading config: %v", err)
    }

    claudeClient := claude.NewClient(cfg.ClaudeAPIKey)
    generator := content.NewGenerator(claudeClient)
    wpClient := wordpress.NewClient(cfg.WordPressBaseURL, cfg.WordPressUsername, cfg.WordPressPassword)

    keyword := "人工知能" // この部分は後でユーザー入力に変更できます
    categoryName := "技術" // この部分も後でユーザー入力に変更できます

    article, err := generator.GenerateArticle(keyword)
    if err != nil {
        log.Fatalf("Error generating article: %v", err)
    }

    categories, err := wpClient.GetCategories()
    if err != nil {
        log.Fatalf("Error getting categories: %v", err)
    }

    var categoryID int
    for _, category := range categories {
        if category.Name == categoryName {
            categoryID = category.ID
            break
        }
    }

    if categoryID == 0 {
        log.Fatalf("Category not found: %s", categoryName)
    }

    postID, err := wpClient.CreatePost(article, []int{categoryID})
    if err != nil {
        log.Fatalf("Error posting to WordPress: %v", err)
    }

    fmt.Printf("Article successfully posted to WordPress with ID: %d\n", postID)
}

セキュリティ考慮事項

WordPress REST APIを使用する際は、以下のセキュリティ考慮事項に注意してください。

  1. HTTPS の使用: API通信は必ずHTTPS経由で行ってください。
  2. 適切な認証: Basic認証の代わりに、Application PasswordsやOAuth認証の使用を検討してください。
  3. 最小限の権限: 投稿作成に必要な最小限の権限のみを持つユーザーアカウントを使用してください。
  4. API キーの保護: .envファイルやシステム環境変数を使用して、APIキーを安全に管理してください。

エラーハンドリングの改善

実際の運用では、より堅牢なエラーハンドリングが必要です。以下のような改善を検討してください。

  1. リトライメカニズム: 一時的なネットワークエラーに対処するため、リトライロジックを実装します。
  2. エラーログ: 詳細なエラー情報をログに記録し、トラブルシューティングを容易にします。
  3. ユーザーフレンドリーなエラーメッセージ: エンドユーザーに分かりやすいエラーメッセージを提供します。

例えば、internal/wordpress/client.goCreatePost関数に以下のようなリトライロジックを追加できます:

go
func (c *Client) CreatePost(article *models.Article, categoryIDs []int) (int, error) {
    var err error
    var postID int

    for retries := 0; retries < 3; retries++ {
        postID, err = c.createPostOnce(article, categoryIDs)
        if err == nil {
            return postID, nil
        }
        log.Printf("Error posting to WordPress (attempt %d): %v", retries+1, err)
        time.Sleep(time.Second * time.Duration(retries+1))
    }

    return 0, fmt.Errorf("failed to post after 3 attempts: %v", err)
}

func (c *Client) createPostOnce(article *models.Article, categoryIDs []int) (int, error) {
    // 既存のCreatePost関数の内容をここに移動
}

パフォーマンスの最適化

大量の記事を投稿する場合、以下のような最適化を検討してください。

  1. 並行処理: ゴルーチンを使用して複数の記事を同時に投稿します。
  2. バッチ処理: 複数の記事をまとめて投稿するバッチ処理を実装します。
  3. キャッシュ: カテゴリ情報などをキャッシュし、API呼び出しを減らします。

まとめ

この記事では、WordPress REST APIを使用して自動生成された記事を投稿する機能の実装について解説しました。主な実装ポイントは以下の通りです。

  1. WordPress APIクライアントの実装
  2. 記事投稿機能の構築
  3. カテゴリ指定機能の追加
  4. メインプログラムの更新
  5. セキュリティ考慮事項の検討
  6. エラーハンドリングとパフォーマンス最適化の考慮

これらの実装により、AIが生成した記事を自動的にWordPressブログに投稿することが可能になりました。

次のステップ

このAIブロガーシステムをさらに改善するために、以下のような機能追加を検討できます。

  1. ユーザーインターフェースの改善(WebUIやCLIの実装)
  2. 投稿スケジューリング機能の追加
  3. SEO最適化(メタデータの自動生成など)
  4. 画像生成AIとの連携による、記事用イメージの自動生成
  5. 投稿後の統計情報収集と分析機能の実装

AIとプログラミングを組み合わせることで、ブログ運営を大幅に効率化できることがお分かりいただけたかと思います。この技術を応用することで、さまざまな分野でコンテンツ生成の自動化が可能になります。

次回の記事では、このシステムの最適化とエラーハンドリングについてより詳細に解説する予定です。AIブロガーシステムの信頼性と効率性をさらに高めていく方法を探っていきましょう。お楽しみに!

【AI ブロガー開発】最適化とエラーハンドリング

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)