外部サービスとの連携

目次

別のシステムと同居させる

ここでは、a-blog cmsを使っているサイトで、特定フォルダ以下に別のサービス(プログラム)を設置したい場合の設定方法について説明します。

a-blog cmsはURLの偽装を行っており、実際のフォルダ・ファイル構造と、エントリーのURLが一致しない仕組みになっています。 a-blog cmsがインストールされている領域内で、特定のフォルダに別のシステムを入れたいケースもあります。通常では方法では、その特定のフォルダ内にもa-blog cmsの偽装処理(htaccessを使ったURL書き換え)が影響を与えるため、別のシステムが意図しない動作になることがあります。

対処方法

a-blog cms が設置されているルートディレクトリの.htaccessに記述を追加します。この例では /other/ ディレクトリをa-blog cmsから切り離しています。
※ver1.6.2以降は追記する内容はコメントアウトで記載されています。

RewriteCond %{REQUEST_URI} !^/?other/
RewriteRule ((\.(html|htm|php|xml|txt|js|json|css|yaml|csv))|/)$index.php [L]

通常は文末2行の記述を利用することで特定ディレクトリを除外できます。
特定ディレクトリ内が動的なサイトの場合は上記の記述が必要になるケースがあります。

Custom Search API との連携

JSON形式のデータを表示させることができるビルトインモジュール Json_2Tpl とGoogleの検索結果をJSON形式で取得することができるCustom Search API を連携させて Google の検索結果を使用するサイト内検索を実装することができます。

a-blog cms標準のサイト内検索機能はエントリー単位の検索ですが、 Custom Search API を連携させることで、一覧ページやトップページなどのページも検索対象に含めることができます。また、検索結果自動的に関連度順に表示されるため、普段Googleで検索するときのような検索体験を実現することができます。

Googleのサイト内検索を実装するためには以下の情報が必要になります。

  • GoogleのAPIキー
  • Googleカスタム検索エンジンの検索エンジンID

準備1: APIキーを用意する

Google Cloud Platform の管理画面からAPIキーを作成してください。 https://console.cloud.google.com/

必要であればIP アドレス(ウェブサーバー、cron ジョブなど)でAPIキーを使用できるウェブサイト、IP アドレス、アプリケーションを制御してください。

※Json_2Tpl ではwebサーバー側でHTTPリクエストを送信するため、HTTPリファラー(URL)による制限はできません。


HTTPリファラー(ウェブサイト)や、IP アドレス(ウェブサーバー、cron ジョブなど)でAPIキーを使用できるウェブサイト、IP アドレス、アプリケーションの制御を設定する画面

また、APIの制限も行いましょう。


APIの制限をする

準備2: 検索エンジンの設定

Google カスタム検索エンジンにログインして、検索エンジンの作成と検索エンジンIDの取得をします。
https://programmablesearchengine.google.com/

1. 検索エンジンの作成

検索対象のドメインと任意の名前を設定して検索エンジンを作成します。
注意点として検索できるサイトでないといけないので、ablogcms.ioなどではなく、ご自身のサイトなどを設定ください。


検索エンジンの作成

2. 検索エンジンIDの取得

コントロールパネルの「基本」タブ内、検索エンジン IDをコピーします。


検索エンジンIDの取得

サイト内検索の実装

APIキーと検索エンジンIDがそろったらa-blog cmsのカスタマイズを行い、Googleの検索結果を使用したサイト内検索を実装します。

1. モジュールIDの作成・設定

Json_2Tpl モジュールのモジュールIDを作成し、表示設定のJSONファイルに以下のURLを設定します。

https://www.googleapis.com/customsearch/v1?key=認証キー&cx=検索エンジンID&q=%{KEYWORD}&hl=ja&start=%{start}

&start=%{start} の部分はページャー機能を実装する場合に必要になります。



2. テンプレートの記述

Json_2Tplのテンプレートを書くためには、jsonの中身を確認する必要がありますが、例えばキーワードを "api" としたとき、検索結果のデータを1件目から取得したい場合は下記のURLをブラウザのアドレスバーに入力して検索すると、jsonの中身を確認することができます。 https://www.googleapis.com/customsearch/v1?key=認証キー&cx=検索エンジンID&q=api&hl=ja&start=1

jsonデータの中身が確認できたら、Json_2Tpl の テンプレートの書き方 を参考に検索結果を表示するテンプレートを記述します。

<!-- BEGIN_MODULE Json_2Tpl id="google_custom_search" -->
<div class="google-search clearfix">
	<!-- BEGIN items:loop -->
	<div class="search-item clearfix">
		<h2>
			<a href="{link}">{htmlTitle}[raw]</a>
		</h2>
		<p class="link">{link}[trim(100, '...')]</p>
		<div class="acms-col-md-10">
			<p>{snippet}</p>
		</div>
		<div class="acms-col-md-2 acms-sp-hide">
			<!-- BEGIN pagemap -->
			<!-- BEGEN metatags:loop -->
			<img src="{og:image}[resizeImg(130)]" width="130">
			<!-- END metatags:loop -->
			<!-- END pagemap -->
		</div>
	</div>
	<!-- END items:loop -->

  <ul class="search-pager">
		<!-- BEGIN queries -->
		<!-- BEGIN previousPage:loop -->
		<li class="link-item">
			<a href="search.html?keyword=%{KEYWORD}&start={startIndex}" class="btn">前</a>
		</li>
		<!-- END previousPage:loop -->

		<!-- BEGIN nextPage:loop -->
		<li class="link-item">
			<a href="search.html?keyword=%{KEYWORD}&start={startIndex}" class="btn">次</a>
		</li>
		<!-- END nextPage:loop -->
		<!-- END queries -->
  </ul>
</div>
<!-- END_MODULE Json_2Tpl -->

ページャーは、a-blog cms標準機能であるクエリストリングの値をグローバル変数として取得するを利用して実装しています。
具体的には、{startIndex} の値をクエリストリングに渡すことで、Json_2Tpl モジュールの表示設定、JSONファイルで設定したURLの %{start}のグローバル変数が {startIndex}を参照するようになります。

次にキーワード検索をするためのフォームを設置します。

<form action="/search.html" class="search-form" method="post" role="search" aria-label="検索フォーム">
	<input type="hidden" name="tpl" value="/search.html">
	<input type="hidden" name="query[]" value="keyword">
	<input type="hidden" name="query[]" value="start">
	<input type="hidden" name="bid" value="%{BID}">
        <input type="hidden" name="start" value="1">
	<input type="text" name="keyword" class="search-form-text" value="%{KEYWORD}" size="15" placeholder="検索キーワード">
	<span class="search-form-btn-wrap">
		<button type="submit" name="ACMS_POST_2GET" class="search-form-btn"><span class="acms-icon-search"></span>
		</button>
	</span>
</form>

完成


完成形

検索フォームに適当な検索ワードを入力し、検索ボタンをクリックした時に、画像のような検索画面が表示されていれば完成です。スタイルやHTMLの構造を変えることで、オリジナルのレイアウトにすることも可能です。

追記:複数ワード対応

上記の実装で検索はヒットするようになりましたが、複数ワードをスペースで区切って検索すると検索結果が出てきません。

方法としては、半角スペース&全角スペースを半角カンマに置き換えたグローバル変数 %{API_KEYWORD} を作成し、利用する事で複数ワードでの検索に対応できるようになります。

config.server.php

define('HOOK_ENABLE', 1);

extension/acms/Hook.php

    /**
     * グローバル変数の拡張
     *
     * @param array $globalVars
     */
    public function extendsGlobalVars(&$globalVars)
    {
        // $globalVars->set('key', 'var');
        $globalVars->set('API_KEYWORD', str_replace(' ', ',', mb_convert_kana(KEYWORD,'s','utf-8')));

    }
  1. モジュールIDの作成・設定 の Json_2Tpl の設定画面で %{KEYWORD} と設定していた部分を %{API_KEYWORD} と修正ください。

Googleアカウントを使ったログイン・サインアップ

GoogleのAPIを使用してログインするログイン機能があります。この機能を利用することで簡単にa-blog cmsへログインすることができる様になります。またサインアップ機能(読者登録)も対応していますので、読者登録を実装されている場合は有効なカスタマイズになります。

Google API Consoleでの設定

Googleアカウントを使ったログインのための準備として、a-blog cms の管理ページ>コンフィグ>ログイン設定 にあるGoogleの「Client ID」と「Secret Key」の2つの情報が必要になります。この2つの情報は、GoogleのOAuth クライアント IDを作成することで入手できます。


Google API 「Client ID」「Secret Key」設定画面

Google API 「Client ID」「Secret Key」設定画面

この手順は2023年10月現在のものです。Google側の仕様変更がされる場合がありますのでご注意ください。

1.Google API Console( https://console.developers.google.com/ )から、申請を行う必要があります。この時点でログインしているアカウントに関連づけられます。はじめにヘッダーの「プロジェクトを選択してください」から「プロジェクトの作成...」から新しいプロジェクトを作成を行います。


プロジェクトの作成

プロジェクトの作成


2.認証情報から認証情報作成を行います。左のAPI Managerから「認証情報」を選択します。「認証情報を作成」から「OAuth クライアント ID」を選択します。

  • アプリケーションの種類: ウェブアプリケーション
  • 承認済みの JavaScript 生成元: Googleアカウントでログインを行うサイトURL(http://www.example.com)を入力
  • 承認済みのリダイレクト URI: 対象となるa-blog cmsのブログURL/callback/signin/google.html

作成すると、クライアントIDクライアントシークレット が表示されます。後で使うのでメモしておきましょう。また認証情報になりますので、外部にもれないように気をつけて下さい。


認証情報の作成

認証情報の作成


3.同意画面を設定します。認証情報 > OAuth同意画面から設定してください。サービス名は必須項目です。


OAuth同意画面の設定

OAuth同意画面の設定


a-blog cms 側の設定

Googleログインのためのa-blog cms側での設定は大きく3つあります。

1. 認証情報を登録

管理ページ > コンフィグ > ログイン設定 から設定できます。先ほどメモした「Client ID」 を Client IDに 「Client Secret」を Secret Keyに入力してください。


Google API 「Client ID」「Secret Key」設定画面

Google API 「Client ID」「Secret Key」設定画面

2. Googleログインのための設定

ブログ全体でのSNSログイン機能と対象についての設定は 管理ページ > コンフィグ > ログイン設定 から行います。

SNSログイン機能のチェックで該当ブログでの機能を有効化します。SNSログイン使用権限では、SNSログイン機能が使えるユーザー権限を設定します。


SNSログインの有効化

SNSログインの有効化

3. ユーザーごとの設定

「2. SNSログインのための設定」でブログでのSNSログイン機能を有効にすることで、該当ブログに所属する各ユーザーのプロフィール変更画面にSNSログインのための項目が表示されるようになります。

https://example.com/mypage/update-profile/

ログインした状態で認証(または認証解除)することで、ログイン情報とこのユーザーが関連づけされます。ログイン状態がユーザーに関連づけされますので、この設定は管理者が設定するのではなく、各ユーザーが個別に行うものとなります。


ユーザー管理でSNSと関連づけます

ユーザー管理でSNSと関連づけます


ログイン

ここまでの設定が行われていれば、ユーザーID、パスワードを入力しなくても、Googleのログインボタンからログインできるようになります。ログイン画面を表示すると、通常のユーザーID、パスワードの入力欄の下に、Googleのログインボタンが表示されます。


管理ログイン画面の場合

管理ログイン画面の場合


一般サインイン画面の場合

一般サインイン画面の場合

X(旧Twitter)アカウントを使ったログイン・サインアップ

X(旧Twitter) APIを使用してログイン・サインアップする機能があります。この機能を利用することで簡単にa-blog cmsへログインできる様になります。またサインアップ機能(読者登録)も対応していますので、読者登録を実装されている場合は有効なカスタマイズになります。

X(旧Twitter)APIの設定

Xアカウントを使ったSNSログインのための準備として、a-blog cms の 管理ページ>コンフィグ>ログイン設定 にあるX(旧Twitter)欄の「Consumer Key」と「Consumer Secret」の2つの情報が必要になります。この2つの情報は、 独自のTwitterアプリを作成することで入手できます。


API Keyと API Secretの設定画面

API Keyと API Secretの設定画面

アプリの作成手順

この手順は2016年05月現在のものです。Twitter側の仕様変更がされる場合がありますのでご注意ください。

  1. Twitter のアプリケーション登録ページ( https://apps.twitter.com )から、申請を行う必要があります。この時点でログインしているアカウントが表示や投稿に関連づけられます。画面右側の「Create New App」から新しいアプリケーションの作成を行います。

Twitter Application Managementの画面

Twitter Application Managementの画面


2.Application Detail の各欄を入力します。 Name、Descriptionにはわかりやすい名前と概要を入力し、Websiteには対象となるa-blog cmsのブログURLを入力してください。 Callback URLには以下の内容を入力してください。

対象となるa-blog cmsのブログURL/callback/signin/twitter.html

画面下部の規約に同意して登録を完了してください。


アプリケーション作成画面

アプリケーション作成画面


3.アプリケーションの作成が完了すると、情報の確認や設定の変更ができます。以下の内容を変更してください。

Application Settings内「Access level」

基本のアクセス形式です。 (modify app permissions)のリンクからデフォルトは「Read & Write」ですが、SNSログインは「Read only」で実行できます。


SNSログインは「Read only」で実行できます

SNSログインは「Read only」で実行できます


Keys and Access Tokens

a-blog cmsとの連携には、このタブで表示される「Consumer Key (API Key)」と「Consumer Secret (API Secret)」が必要になりますのでメモをしておいてください。


Keys and Access Tokensの画面

Keys and Access Tokensの画面


a-blog cms 側の設定

SNSログインのためのa-blog cms側での設定は大きく3つあります。

  • APIキーの設定
  • SNSログインのための設定
  • ユーザーごとの設定

1. APIキーを設定

APIキーは 管理ページ>コンフィグ>ログイン設定 から設定できます。


APIキーの設定画面

APIキーの設定画面


2. SNSログインのための設定

ブログ全体でのSNSログイン機能と対象についての設定は 管理ページ>コンフィグ>ログイン設定 から行います。

SNSログイン機能 のチェックで該当ブログでの機能を有効化します。SNSログイン使用権限 では、SNSログイン機能が使えるユーザー権限を設定します。


機能設定画面

機能設定画面


3. ユーザーごとの設定

「2. SNSログインのための設定」でブログでのSNSログイン機能を有効にすることで、 該当ブログに所属する各ユーザーのプロフィール変更画面 にSNSログインのための項目が表示されるようになります。

https://example.com/mypage/update-profile/

SNSで認証(または認証解除)することで、ログイン情報とこのユーザーが関連づけされます。ログイン状態がユーザーに関連づけされますので、この設定は管理者が変更するのではなく、各ユーザーが個別に行うものとなります。


プロフィール変更画面でSNSと関連づけます

プロフィール変更画面でSNSと関連づけます


認証がされている場合は「認証」ボタンが「認証解除」に変わって表示されます。各サービスの認証ボタンを押した時、サービスにログインしていない場合は、各サービスの認証画面が表示されます。ここでログインすることで、このユーザーでのa-blog cmsのSNSログインが有効になります。

ログインするには

ここまでの設定が行われていれば、ユーザーID、パスワードを入力しなくても、SNSログインボタンからログインできるようになります。ログイン画面を表示すると、通常のユーザーID、パスワードの入力欄の下に、Xのログインボタンが表示されます。


管理ログイン画面の場合

管理ログイン画面の場合


一般サインイン画面の場合

一般サインイン画面の場合

Webhook機能

外部サービスとの連携を強化するWebhook機能についてご紹介します。Ver.3.0から追加された機能です。

Webhook機能を使えば、Webhookとの連携に対応したツールとa-blog cms を連携できます。
例えばサイトの通知を受け取りたい場合、更新したら通知するという指示を与えておき、更新されるたびに外部サービスに通知する仕組みを作れるようになります。

具体的には、a-blog cms で記事が更新されたら、Slackに通知をしたり、IFTTTなどのWebサービスを経由してTwitterやFacebookなどのSNSに自動で投稿できます。

a-blog cms がサポートしているイベント

  • エントリー(作成・更新・削除・公開)
  • ユーザー(作成・更新・削除・退会・ログイン・会員登録)
  • フォーム(送信)

a-blog cms では送信側のみ対応しています。
例えば、a-blog cms でエントリーを更新したら通知したり、a-blog cms のフォームに投稿されたら外部ツールにデータを投稿するといったa-blog cmsが起点となった仕組みを作成できます。

Webhook機能の使い方

Webhook機能を有効化する

ルートディレクトリにあるconfig.server.phpの HOOK_ENABLE1 にし、Webhookを有効化します。

define('HOOK_ENABLE', 1);

Webhookの設定を作成する

管理画面 > Webhookの順にページを移動して作成します。

設定

以下はWebhook機能の基本的な設定です。

セキュリティアップデートにより「Ver. 3.1.12」と「Ver. 3.0.32」から「Webhook URL」に設定するURLのホストを「.env」ファイルに設定する必要があります。

WEBHOOK_WHITE_LIST=hooks.slack.com,xxxxxx.com # Webhookでリクエスト可能なホストをカンマ区切りで指定ください。

ステータス チェックするとWebhookの設定が有効になります
タイプ イベントをフックするタイプを指定します
イベント フックするイベントを指定します
Webhook URL WebhookのPOST先のURLを指定します
リクエスト履歴 チェックをすると、リクエスト履歴を残します
グローバル チェックをすると、このWebhookが下の階層のブログも対象になります

ペイロード

ペイロードをカスタマイズする際には下記の設定を使用します。


カスタム ペイロードをカスタムする際にチェックをつけて「テンプレート」の項目を有効化します。
テンプレート ペイロードをテンプレートを使って組み立てます。「カスタム」にチェックが付けられている場合、テンプレートに入力された値が適用されます。

Webhookのリクエスト履歴を確認する

セキュリティアップデートにより「Ver. 3.1.12」と「Ver. 3.0.32」から デフォルトでレスポンス情報が閲覧できないようになっております。閲覧する場合は「.env」ファイルで以下項目を変更ください。 また閲覧が終わりましたら設定は元に戻してください

WEBHOOK_RESPONSE_VIEW=disabled # (disabled|enable) WebhookのログにHTTPレスポンス情報を表示するかどうか設定します。セキュリティのため、確認する時のみ「enable」に設定ください。

リクエスト履歴にチェックをつけて、ログを記録します。一度でも機能が動作していたら、管理画面>Wehook>ログの順にページを移動し、リクエスト履歴を確認できます。

ステータスコードの状態を確認できます。もしエラーになっていたら、エラーのステータスコードが表示されます。
(HTTPレスポンスステータスコードについての詳細はMDNのドキュメントをご確認ください)


Webhookの設定とリクエスト履歴が掲載されている

Webhook履歴のページ


ペイロードのテンプレートをカスタマイズする

ペイロードのテンプレートをカスタマイズするには、使用できる変数を確認するため、一度リクエスト履歴で成功レスポンス(200~299)以外のステータスコードを記録しなければなりません。一度、ペイロードの「カスタム」のチェックを外してWebhookを動作させ、エラーを出してください。

エラーのステータスコードを出したリクエスト履歴の詳細を開くと、下図のようなRequest Bodyが値として返ってきます。そうすると、使用できる変数が確認できます。

以下の場合は、タイプが「エントリー」、イベントが「公開」に設定した状態です。



セキュリティアップデートにより「Ver. 3.1.12」と「Ver. 3.0.32」からペイロードをカスタマイズするテンプレートエンジンが変更され、Twig が利用できるようになりました。テンプレート記法がかわっているため、CMSをアップデートされた場合はテンプレートの修正が必要な可能性があります。

第一階層の値を取得する

第一階層の値を取得したい場合は、{{変数名}}とペイロードのテンプレート欄に記述します。
たとえば、エントリーのURLを取得したい場合は、{{url}}になります。

第二階層以下の値を取得する

第二階層以下の値を取得したい場合は、->でつなぎます。実際には{{ 変数名.変数名2.変数名3 }}のような記述をペイロードのテンプレート欄におこないます。
たとえば、エントリータイトルを取得したい場合は{{ contents.entry.title }}になります。

テンプレートの記入例

ペイロードのテンプレート欄に下記のように記入すると出力できます。 { "value1" : "{{ url }}", "value2" : "{{ contents.entry.title }}" }

以下は、a-blog cms と Slack を連携し、Slackに通知を送るための記述です。
JSON形式の記述が採用されているため、「\n」で改行できます。

{
  "text": "ページを更新しました!\n「{{ contents.entry.title }}」\n{{ url }}",
  "username": "更新情報bot",
  "icon_emoji": ":dog:"
}

テンプレートにはカスタムフィールドの値を使用することも可能です。

{
    "webhook_id": "2",
    "webhook_name": "Slack\u901a\u77e5",
    "type": "entry",
    "event": "entry:created,entry:opened",
    "actor": {
        "uid": 1,
        "name": "admin"
    },
    "url": "http:\/\/acms.org\/entry-322.html",
    "contents": {
      ...(省略)...
      "field": {
            "message": "ここにmessageカスタムフィールドに登録された内容が入ります"
        }
    }
}

ペイロードのテンプレート欄には下記のように記入すると出力できます。

{
  "value1" : "{{ contents.field.message }}",
}

トラブルシューティング

リクエスト履歴のステータスコードがエラーになっていて動かない その1

ペイロードの「カスタム」のチェックが外れたままになっていないでしょうか?
テンプレートの変数を確認するために、カスタマイズしている最中は「カスタム」のチェックが外れた状態なので、Webhookの動作を確認したい時は「カスタム」にチェックをつけることを忘れないようにしましょう。

リクエスト履歴のステータスコードがエラーになっていて動かない その2

もしステータスコードがエラーになっていて、ログ>Response Bodyの項目で missing_text_or_fallback_or_attachmentsと表示されていたら、ペイロードの書き方が悪いかもしれません。見直してみてください。


missing_text_or_fallback_or_attachmentsと表示されている様子


ハンズオン記事

以下の記事では、Slackと連携する方法とIFTTTと連携してGoogle Driveにデータを保存する方法を紹介しています。動画もあるので、ぜひご覧ください。