バックアップは、ウェブサイトに「災難」が発生した場合にセーフティネットの役割を果たします。KinstaのWordPress専用マネージドクラウドサーバーサービスには、6種類のバックアップ性能が付帯します。毎日自動でバックアップが作成され、任意で毎時バックアップに変更することも可能です。その他にも、手動でバックアップを取ることができ、重要な操作の前には自動でシステム生成バックアップが実行されます。ダウンロード用にバックアップを作成することも、任意でAmazon S3やGoogleクラウドストレージと統合することも可能です。
このようなバックアップの管理はKinsta自社開発のコントロールパネル「MyKinsta」で簡単に行えます。さらに、Kinsta APIのリリースにより、WordPressサイトとそのバックアップを扱う方法にさらなる柔軟性がもたらされました。何百ものサイトを管理する代行業者の方々、Slackのような生産性ツールを活用するチームまで、Kinsta APIはあらゆる効率化を助けます。
こちらの記事では、APIを通じて利用可能なさまざまなバックアップエンドポイントとその可能性、そしてSlack環境でバックアップを管理する方法をご紹介します。
Kinsta APIを理解する
Kinsta APIは、WordPressサイトとKinstaサービスとの遠隔操作といったシステムを確立する便利な機能です。サイトの作成、サイト情報の取得、サイトのステータスの取得、バックアップの参照や復元など、WordPressの管理に関連するさまざまなタスクを自動化することができます。
KinstaのAPIを使用するには、MyKinstaに少なくとも1つのWordPressサイト、アプリケーション、またはデータベースのアカウントを保有する必要があります。また、アカウント認証のためにAPIキーの生成が必要になります。
APIキーを生成する方法は以下の通りです。
- MyKinstaにアクセス
- 「APIキー」ページに移動((アカウント名)>「企業の設定」>「APIキー」)
- 「APIキーを作成」をクリック
- 有効期限を選択する(開始日と期間を指定可能)
- キーに一意の名前を付ける
- 「生成」をクリック
APIキーを生成したら、コピーして安全な場所に保管してください(パスワードマネージャーを使用することをお勧めします)。複数のAPIキーを生成することができ、「APIキー」ページに一覧表示されます。APIキーの取り消しが必要になった場合は、名前と有効期限の横にある「アクセス取り消し」ボタンをクリックします。
Kinsta APIでWordPressサイトのバックアップを管理する
Kinsta APIには、バックアップ関連の操作のためのエンドポイントが用意されています。
- 手動、スケジュール、およびシステム生成バックアップの一覧表示
- ダウンロード可能なバックアップの一覧表示
- 日時指定、手動、またはシステム生成バックアップの復元
- 特定の環境の手動バックアップを作成
- WordPressサイト環境のバックアップを削除
これらのエンドポイントとやり取りするには、先ほど生成したAPIキーが必要です。エンドポイントの仕組みを理解しながら、後でSlackbotに統合して、Slackのスラッシュコマンドを使ってKinsta APIとやり取りできるようにしましょう。
Kinsta APIで手動、自動、システム生成バックアップを取得する方法
MyKinsta内の特定のWordPressサイトに移動し、「バックアップ」タブをクリックすると、毎日、毎時(有効になっている場合のみ)、手動、およびシステム生成バックアップといったバックアップの一覧が表示されます。
Kinsta APIを使用して、このデータにアクセスしたり、外部のアプリケーションやプラットフォームから簡単に操作を実行したりすることができます。
ID、名前、タイプ、作成時間などのバックアップ情報をプログラムを介して取得できます。独自のツールからAPIを使用することで、この情報が必要なときにいつでも(コントロールパネルにアクセスすることなく)実行可能です。
このエンドポイントにアクセスするには、まずはget site environmentエンドポイントを使用して、サイトの環境IDをプログラム経由で取得します。
{
  "site": {
    "environments": [
      {
        "id": "54fb80af-576c-4fdc-ba4f-b596c83f15a1",
        "name": "first-site",
        "display_name": "First site",
        "is_blocked": false,
        "id_edge_cache": "54fb80af-576c-4fdc-ba4f-b596c83f15a1",
        "cdn_cache_id": "54fb80af-576c-4fdc-ba4f-b596c83f15a1",
        "is_premium": false,
        "domains": [
          {
            "id": "54fb80af-576c-4fdc-ba4f-b596c83f15a1",
            "name": "example.com",
            "type": "live"
          }
        ],
        "primaryDomain": {
          "id": "54fb80af-576c-4fdc-ba4f-b596c83f15a1",
          "name": "example.com",
          "type": "live"
        },
        "ssh_connection": {
          "ssh_port": "808080",
          "ssh_ip": {
            "external_ip": "1xx.1xx.1xx.1xx"
          }
        },
        "container_info": {
          "id": "54fb80af-576c-4fdc-ba4f-b596c83f15a1",
          "php_engine_version": "php8.0"
        }
      }
    ]
  }
}サイトの環境 IDがわかったら、https://api.kinsta.com/v2/sites/environments/${envId}/backupsにGETリクエストを送り、サイトのすべてのバックアップの配列を取得することができます。
curl -i -X GET \
  'https://api.kinsta.com/v2/sites/environments/{env_id}/backups' \
  -H 'Authorization: Bearer 'バックアップの配列を持つオブジェクトが返されるため、クライアントにループさせてデータを操作することが可能です。
{
  "environment": {
    "display_name": "MyEnvironment",
    "backups": [
      {
        "id": 123456789,
        "name": "mySiteName-1234567890-backupType",
        "note": "Daily Auto Backup",
        "type": "manual",
        "created_at": 1665382600770
      }
    ]
  }
}Kinsta APIで手動、自動、システム生成バックアップを復元する方法
Kinsta APIでは、POSTリクエストを使用して、生成された一覧から特定のバックアップを環境に復元することもできます。
必要なのはバックアップID、ターゲット環境ID、バックアップの環境名だけです。この操作により、バックアップ復元作業のためにMyKinstaを都度開く必要がなくなります。
curl -i -X POST \
  'https://api.kinsta.com/v2/sites/environments/{target_env_id}/backups/restore' \
  -H 'Authorization: Bearer ' \
  -H 'Content-Type: application/json' \
  -d '{
    "backup_id": 123456789,
    "env_display_name_of_backup": "my-env"
  }'このリクエストに対する応答には、操作ステータスと操作IDが含まれるため、操作ステータスのエンドポイントを使用して、プログラムを介して復元の進捗状況を追跡可能です。
{
  "operation_id": "backups:restore-54fb80af-576c-4fdc-ba4f-b596c83f15a1",
  "message": "Restoring a backup to environment in progress",
  "status": 202
}Kinsta APIでダウンロード可能バックアップを取得する方法
https://api.kinsta.com/v2/sites/environments/{env_id}/downloadable-backupsにGETリクエストを送信し、サイトのすべてのダウンロード可能バックアップの配列を取得することで、既存のダウンロード可能バックアップとそのダウンロードリンクにアクセスできます。
curl -i -X GET \
  'https://api.kinsta.com/v2/sites/environments/{env_id}/downloadable-backups' \
  -H 'Authorization: Bearer '配列内の各ダウンロード可能バックアップには、ID、作成タイミングを示すタイムスタンプ、ダウンロードリンク、有効期限のタイムスタンプ、および生成プロセスが進行中かどうかを示すステータスが含まれます。
{
  "environment": {
    "display_name": "MyEnvironment",
    "downloadable_backups": [
      {
        "id": "1915fa3a-7ef4-4766-806d-71104be7deb0",
        "created_at": 1665382600770,
        "download_link": "https://example.com",
        "expires_at": 1665382600770,
        "is_generation_in_progress": true
      }
    ]
  }
}ダウンロードリンクをクリックすると、バックアップZIPファイルのダウンロードが始まり、アプリケーションにリンクを埋め込むことができます。
Kinsta APIで環境に手動バックアップを追加する方法
WordPressサイトの手動バックアップはMyKinstaでも簡単に作成できますが、Kinsta APIでさらに効率的に実行可能です。
手動バックアップを行うには、エンドポイントhttps://api.kinsta.com/v2/sites/environments/{env_id}/manual-backupsでKinsta APIにPOSTリクエストを送信します。このリクエストには、バックアップを追加する環境IDとメッセージ本文のタグが必要になります。タグはメモがわりになり、後でバックアップを特定しやすくなります。
curl -i -X POST \
  'https://api.kinsta.com/v2/sites/environments/{env_id}/manual-backups' \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>' \
  -H 'Content-Type: application/json' \
  -d '{
    "tag": "my-awesome-backup"
  }'リクエストの実行に成功すると、APIが操作ステータスとIDを返します。これにより、手動バックアップ操作の進行状況を追跡することができます。
Kinsta APIでWordPressサイトの環境バックアップを削除する方法
Kinsta APIでは、バックアップの追加だけでなく、削除することもできるため、完全に自動管理可能です。
バックアップを削除するには、特定のバックアップIDを含むDELETEリクエストを送信します。以下は、curlを使用してこのリクエストを構成する方法です。
curl -i -X DELETE \
  'https://api.kinsta.com/v2/sites/environments/backups/{backup_id}' \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>'このリクエストを実行すると、操作状況、ID、メッセージが表示されます。
Kinsta APIでバックアップを管理するためのSlackスラッシュコマンドの実装
最近公開した別の記事では、Node.jsとKinsta APIを利用してサイト管理Slackbotを作成する方法をご紹介しました。そこでは、Slackbotを作成し、KinstaのウェブアプリケーションサーバープラットフォームでホストしたNode.jsアプリケーションを介してKinsta APIとの相互作用を確立する方法を解説しています。
一方で今回は、3つのバックアップエンドポイント用の別のSlackスラッシュコマンドの作成に焦点を当てます。この説明を読み進める前に、Node.jsアプリケーションとパーソナライズ型Slackbotの設定について、以前の記事をご確認ください。
完了したら、Gitを使ってスタータープロジェクトを複製します。
- コードを保存するお好みのディレクトリに移動し、ターミナルで以下のコマンドを実行します。
git clone -b tutorial-1 --single-branch https://github.com/olawanlejoel/SlackBot-KinstaAPI.git
- プロジェクトフォルダに移動し、必要な依存関係をすべてインストールします。
cd SlackBot-KinstaAPI npm install
Slackでバックアップを処理するスラッシュコマンドの作成
前回の記事では、以下の5つのスラッシュコマンドを作成しました。
- /site_id [site name]:サイトIDを取得
- /environment_id [site name]:環境IDを取得
- /clear_site_cache [environment id]:サイトキャッシュをクリア
- /restart_php_engine [environment id]:PHPエンジンを再起動
- /operation_status [operation id]:操作状況を確認するために使用
今回の記事では、3つの新しいコマンドを追加することにします。Slackでスラッシュコマンドを作成するには、Slackアプリケーションに移動し、左サイドバーの「Slash Commands」メニューをクリックし、「Create New Command」ボタンをクリックします。以下の情報を使ってコマンドを作成します。
| コマンド | 説明 | 使い方のヒント | 
| /get_backups | サイトのすべてのバックアップとその関連情報を取得 | [環境ID] | 
| /get_downloadable_backups | サイトのダウンロード可能なバックアップを、関連する情報とリンクと共に取得 | [環境ID] | 
| /restore_backup | スケジュールに基づき、手動で、またはシステムで生成したバックアップを環境に復元 | [対象環境ID] [バックアップID] [環境名] | 
| /add_manual_backup | サイト環境の手動バックアップを作成 | [対象環境ID] [タグ] | 
| /delete_backup | サイトの環境から特定のバックアップを削除 | [バックアップID] | 
これらのコマンドを作成したら、/と入力してSlackで確認してみましょう。コマンドが追加されていることがわかります。
次のステップとして、Kinsta APIとのインタラクションを実装し、Slackから渡されたデータを受信し、特定のAPIエンドポイントにクエリできるようにします。
バックアップ操作のためのNode.js Fetchリクエストの実装
必要なスラッシュコマンドを作成したら、次はそれに応答するようにNode.jsアプリを調整します。各エンドポイントとやり取りする非同期関数を作成することから始めましょう。
app.jsファイルに5つの関数を定義します。
- getBackups(environmentId):特定の環境のバックアップ情報を取得
- getDownloadableBackups(environmentId):指定した環境のダウンロード可能なバックアップを取得
- restoreBackup(targetEnvironmentId, backupId, environmentName):指定された環境への特定のバックアップの復元処理を開始
- addManualBackup(environmentId, tag):指定した環境の手動バックアップを作成し、簡単に識別できるようにオプションのタグを付ける
- deleteBackup(backupId):指定したバックアップを環境のバックアップリストから削除
以下は各機能のFetchリクエストです。
async function getBackups(environmentId) {
    const resp = await fetch(
        `${KinstaAPIUrl}/sites/environments/${environmentId}/backups`,
        {
            method: 'GET',
            headers: getHeaders,
        }
    );
    const data = await resp.json();
    return data;
}
async function getDownloadableBackups(environmentId) {
    const resp = await fetch(
        `${KinstaAPIUrl}/sites/environments/${environmentId}/downloadable-backups`,
        {
            method: 'GET',
            headers: getHeaders,
        }
    );
    const data = await resp.json();
    return data;
}
async function restoreBackup(targetEnvironmentId, backupId, environmentName) {
    const resp = await fetch(
        `${KinstaAPIUrl}/sites/environments/${targetEnvironmentId}/backups/restore`,
        {
            method: 'POST',
            headers: postHeaders,
            body: JSON.stringify({
                backup_id: backupId,
                env_display_name_of_backup: environmentName,
            }),
        }
    );
    const data = await resp.json();
    return data;
}各関数はJavaScriptのFetch APIを利用してKinsta APIと通信するように構築されています。環境ID、バックアップID、および環境名のパラメータの入力が想定されています。これらをSlackコマンドから受信し、実行のために関数へと渡します。
基本API URLとGET、POSTリクエスト用のヘッダーという重要な要素を格納するために3つの変数が使用されていることがわかります。これはコードを効率化し、繰り返しを防ぐための施策です。
const KinstaAPIUrl = 'https://api.kinsta.com/v2';
const getHeaders = {
    Authorization: `Bearer ${process.env.KINSTA_API_KEY}`,
};
const postHeaders = {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.KINSTA_API_KEY}`,
};さらに、Slackのシークレットキー(Signing secrets)、ボットトークン、アプリトークン、企業ID、APIキーなどの機密キーやトークンは、.envファイル内に安全に保存することができます。
SLACK_SIGNING_SECRET="YOUR_SIGNING_SECRET"
SLACK_BOT_TOKEN="xoxb-YOUR_BOT_TOKEN"
APP_TOKEN="xapp-YOUR_APP_TOKEN"
KINSTA_COMPANY_ID = "YOUR_COMPANY_ID" 
KINSTA_API_KEY = "YOUR_API_KEY"これらの関数とキーの設定を終え、次のステップではSlackコマンドを設定します。具体的には、Slackから入力値を受け取り、この入力に基づいて関連するメソッドを起動し、特定のレスポンスをSlackに送り返します。
バックアップ管理のためのNode.jsでのスラッシュコマンドの設定
スラッシュコマンドを設定するには、JavaScriptのイベントリスナーに似た機能を持つapp.command()関数を使用します。リッスンしたいコマンドを指定し、目的のアクションを定義する非同期コールバック関数を作成することになります。この関数は以下の3つのパラメータを受け取ります。
- command:ユーザーにより送信されたスラッシュコマンド情報
- ack:スラッシュコマンドの受信を確認
- say:Slackチャンネルにメッセージを送り返す
以下、5つのコマンドの設定を行います。
app.command('/get_backups', async ({ command, ack, say }) => {
    await ack();
    let environmentId = command.text;
    let response = await getBackups(environmentId);
    let backups = response.environment.backups;
    let backupDetails = backups
        .map((backup) => {
            return `バックアップID:${backup.id}\n名前:${backup.name}\nメモ:${
                backup.note
            }\n種類:${backup.type}\n作成日時:${new Date(backup.created_at)}\n\n`;
        })
        .join('');
    if (backupDetails) {
        say(
            `こんにちは👋 次の環境IDのバックアップ情報は以下の通りです─${environmentId}:\n\n${backupDetails}`
        );
    } else {
        say(`次の環境IDに関連するバックアップが見つかりませんでした─${environmentId}`);
    }
});
app.command('/get_downloadable_backups', async ({ command, ack, say }) => {
    await ack();
    let environmentId = command.text;
    let response = await getDownloadableBackups(environmentId);
    let backups = response.environment.downloadable_backups;
    let downloadable_backupDetails = backups
        .map((backup) => {
            return `バックアップID:${backup.id}\nダウンロードリンク:${
                backup.download_link
            }\n作成日時:${new Date(backup.created_at)}\n有効期限:${new Date(
                backup.expires_at
            )}\n生成実行中:${backup.is_generation_in_progress}\n\n`;
        })
        .join('');
    if (downloadable_backupDetails) {
        say(
            `こんにちは👋 次の環境IDのダウンロード型バックアップの詳細情報は以下の通りです─${environmentId}:\n\n${downloadable_backupDetails}`
        );
    } else {
        say(`次の環境IDに関連するダウンロード型バックアップが見つかりませんでした─${environmentId}`);
    }
});
app.command('/restore_backup', async ({ command, ack, say }) => {
    await ack();
    const [targetEnvironmentId, backupId, environmentName] =
        command.text.split(' ');
    let response = await restoreBackup(
        targetEnvironmentId,
        backupId,
        environmentName
    );
    if (response) {
        say(
            `こんにちは👋 \n\n${response.message} このOperation IDのステータスを確認するには、/operation_status Slackコマンドを使用してください─${response.operation_id}`
        );
    }
});
app.command('/add_manual_backup', async ({ command, ack, say }) => {
    await ack();
    const [environmentId, tag] = command.text.split(' ');
    let response = await addManualBackup(environmentId, tag);
    if (response) {
        say(
            `こんにちは👋 \n\n${response.message} このOperation IDのステータスを確認するには、/operation_status Slackコマンドを使用してください─${response.operation_id}`
        );
    }
});
app.command('/delete_backup', async ({ command, ack, say }) => {
    await ack();
    let backupId = command.text;
    let response = await deleteBackup(backupId);
    if (response) {
        say(`こんにちは👋 \n\n${response.message}`);
    }
});上記のスラッシュコマンドは、さまざまなバックアップ関連のタスクを管理することができます。/get_backupsは環境固有のバックアップ情報を取得し、/get_downloadable_backupsはダウンロード可能なバックアップ情報を取得し、/restore_backupは指定されたパラメータに基づき復元を開始します。/add_manual_backup は簡単に識別できるようにオプションでタグ付けされた手動バックアップの作成を可能にし、/delete_backupは指定されたバックアップの削除を容易にします。
各コマンドは受信を確認し、入力を処理し、それぞれの機能 (getBackups()、getDownloadableBackups()、restoreBackup()、addManualBackup()、deleteBackup())をトリガーし、レスポンスのフォーマットを整えた上で、結果をSlackに通信します。結果、バックアップ操作に便利なインターフェースが確保できます。
アプリケーションをデプロイし、Slackにアクセスして様々なコマンドをテストしてみてください。
このプロジェクトのコードはこちらのGitHubリポジトリで公開しています。
まとめ
今回の記事では、Kinsta APIを統合し最新のバックアップエンドポイントを活用する一例をご紹介しました。このエンドポイントを利用することで、バックアップ操作をフロントエンドのアプリケーションにシームレスに組み込んだり、パイプラインを確立したり、プログラムを介してサイト管理を簡素化したりできます。
Kinsta APIにはこれ以外にも多くの機能があります。その他のエンドポイントをプロジェクトに活用する方法を模索してみることをおすすめします。
Kinsta APIは活用されていますか?どのような有効活用をされているでしょうか。また、将来的に導入をご希望の機能はありますか?コメント欄でお気軽にお聞かせください。