Vue.js初心者がWP REST APIとGA Reporting APIを使ってスワブロランキングアプリを作ったよ

2020.04.01

vue.js初心者がWP Rest APIとGoogle Analytics APIを使ってスワブロランキングアプリを作ったよ

 

ども、むったんです。

 

コロナ騒ぎで、ライブ&イベントが軒並み中止になってとても辛い。
えぇ、分かってます。
ウイルスを蔓延させないためって分かってます。
分かってる…けどさぁーーー!推しに会いたいよーーー😭

 

 

ちなみに3月に開催予定だったライヴは中止となり、払い戻しが始まりました😭
ライブが開催できていれば、リアル推し×画面の中にいた2D推しが3Dになってステージで歌って、踊っていたと思うと…是非もう一度企画していただきたいと思う所存!
むったんが行きたかったライブはこちら

 

 

 

そして、そんな悶々とした気持ちをぶつけながら作ったのが、今回のアプリですww

 

 

スワブロランキングアプリを作った

作り始めた経緯

みなさんが見てくれているこのスワローブログ(略してスワブロ)ですが、運用が始まったのは2018年10月。
そこから月ごと&四半期ごとに、中村さんがGoogleアナリティクスからフィルターかけたりしてランキングを発表してくれていました。

 

正直この作業簡略化できそうだし、アプリにできたら中村さんの仕事の負担ちょっとは減るよなー…と思っていました。
なので、リーダー千に「中村さんの仕事の負担を減らすために、WPとアナリティクスからデータ引っ張ってきてスワブロランキングアプリ作ってええ?( ´ ▽ ` )ノ」とノリで言ったらOKをもらいました!
ということで、ざっくり書いていくよ😆

 

環境

  • WordPress 5.3.2
  • GoogleアナリティクスReporting API v4
  • Vue.js 2.6.10
  • vuex 3.1.0
  • vuetify 2.1.0

 

取得したいもの

GoogleアナリティクスReporting API v4

  • URL
  • PV数

 

WP REST API

  • URL
  • 投稿日
  • ブログタイトル
  • 投稿者

 

投稿者情報が不要であれば、GoogleアナリティクスReporting APIのみで行けたのですが…そりゃそうね、複数人で運用しているブログだもの。
投稿者は知りたいよね。

 

 

インストールしたもの

  • vuetify

詳しい導入方法は以前むつたくが紹介しているので、そちらをご覧ください。
やっぱりフレームワーク使うとラクだわ(諦めれば、cssとの戦いも放棄できると最近踏ん切りがついたw

Vue-CLI3から始めるUIフレームワーク 〜Vuetify〜

 

  • moment.js

インストール方法は以下の記事が分かりやすいです。

Vue.jsで日付処理ライブラリMoment.jsを使う|WEB PIXEL

 

  • vue-monthly-picker

年月だけ指定したかったので、以下のものを使用させていただきました🙏

vue-monthly-picker

 

  • vue-google-api

Google ApiとGoogle認証を使用して、クライアント側の操作を行うのに必要なもの。

vue-google-api

 

ざっくり流れはこんな感じ

スワブロランキング流れ

 

WP REST APIは投稿順で情報をくれるっぽい。
GA Reporting APIは好きなようにソートできるっぽいので、PV昇順に指定。

 

for文で回して、GA Reporting APIから来た内容を基準にWP REST APIの情報もまとめて、ランキングを表示しました。

 

準備(WordPress)

WordPress4.7以上であれば、プラグインなどを使用せずに下記URLから記事情報等がjson形式で取得できます。

[cc_html5] http://[ドメイン]/wp-json/wp/v2/[slug] [/cc_html5]

 

ちなみに、今回はスワブロの情報を取得したいので、こんな感じになります。

[cc_html5] https://swallow-incubate.com/wp-json/wp/v2/blog [/cc_html5]

 

取得件数の初期値は10件です。

 

 

準備(Google API)

設定が面倒だったのはこっちだった…orz
そして未だちゃんと理解してないけど、動いてるから大丈夫なのかな😅

 

ざっくり説明すると、こんな感じ。

  1. Google API ConsoleからGoogle  Analytics Reporting APIを選択
  2. プロジェクトを作成
  3. 認証情報を作成
  4. Google Analyticsにサービスアカウントを追加
  5. APIキーを発行
  6. OAuth2.0クライアントIDを発行(むったんはhttp://localhost:8080を許可、状況に応じて変更してください)

 

詳しいやり方はSAKI Web Design様のブログに書いてありますので、参考にしてみてください🙏

Google Analytics Reporting API V4 を使う①|SAKI Web Design

コード

※コードが長くなるので、CSSは書きません。

src/main.js

[cc_javascript]
import Vue from ‘vue’
import App from ‘./App.vue’
import router from ‘./router’
import store from ‘./store/index’
import vuetify from ‘./plugins/vuetify’
import VueGoogleApi from ‘vue-google-api’

const config = {
clientId: ‘[clientId]’,
scope: ‘https://www.googleapis.com/auth/analytics’,
apiKey: ‘[apiKey]’,
discoveryDocs: [‘https://analyticsreporting.googleapis.com/$discovery/rest?version=v4’]
}

Vue.config.productionTip = false

Vue.use(VueGoogleApi, config)

new Vue({
router,
store,
vuetify,
render: h => h(App)
}).$mount(‘#app’)
[/cc_javascript]

 

src/App.vue

[cc_javascript]


[/cc_javascript]

 

src/components/BaseLine.vue

[cc_javascript height=”600″]


[/cc_javascript]

 

src/views/Home.vue

[cc_javascript height=”600″]


[/cc_javascript]

 

src/store/index.js

[cc_javascript]
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
{
path: '/',
name: 'home',
component: () => import('../views/Home.vue')
},
{
path: '/three-months',
name: 'threeMonths',
component: () => import('../views/ThreeMonths.vue')
}
]

const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})

export default router
[/cc_javascript]

 

src/store/modules/blog.js

[cc_javascript height="600"]
import axios from 'axios'

export const blog = {
namespaced: true,
state: {
url: 'https://swallow-incubate.com/wp-json/wp/v2/blog?'
},
actions: {
async getBlog (state, obj) {
const ApiURL = state.state.url + 'after=' + obj.params.after + '&before=' + obj.params.before + '&per_page=' + obj.params.perPage
const result = await axios.get(ApiURL)
.then(res => {
if (res.status === 200) {
return {
result: true,
data: res.data
}
} else {
return {
result: false,
code: res.code,
data: []
}
}

})
.catch(error => {
if(error.message) {
if (Array.isArray(error.message)) {
let message = []
for (let err of error.message) {
message.push(err.msg)
}
return {
result: false,
data: message.join(',')
}
} else {
return {
result: false,
data: error.message
}
}
} else {
return {
result: false,
data: error
}
}
})
return result
}
}
}
[/cc_javascript]

 

src/store/modules/gAnalytics.js

[cc_javascript height="600"]
export const gAnalytics = {
namespaced: true,
state: {
url:'https://analyticsreporting.googleapis.com/v4/reports:batchGet',
viewId: '[viewId]'
},
actions: {
async getGAnalytics ({state}, obj) {
const requestParams = {
reportRequests: [
{
viewId: state.viewId,
dateRanges: [
{
startDate: obj.params.start,
endDate: obj.params.end,
}
],
metrics: [
{
expression: 'ga:pageviews'
}
],
dimensions: [
{
name: 'ga:pageTitle'
},
{
name: 'ga:pagePath'
}
],
dimensionFilterClauses: [{
filters: [{
dimensionName: 'ga:pagePath',
expressions: [
obj.params.selectedMonth
]
},
{
dimensionName: 'ga:pagePath',
expressions: [
obj.params.conditions
]
}
]
}],
orderBys: [{
fieldName: "ga:pageviews",
sortOrder: "DESCENDING"
}]
}
]
}
const result = await obj.gapi.request({
path: state.url,
method: 'POST',
body: requestParams,
headers: {
'content-Type': 'application/json'
}
})
.then(res => {
if (res.status === 200) {
return {
result: true,
data: res.result.reports[0].data.rows
}
} else {
return {
result: false,
code: res.code,
data: []
}
}

})
.catch(err => {
console.log('gAnalytics', err)
})
return result
}
}
}
[/cc_javascript]

 

完成イメージ

cssもちゃんと設定してあげて、こんな感じになりました。

 

スワブロランキング

 

これは、2月1日〜2月29日までに公開されたブログで、かつ2月1日〜2月29日までのPV数をカウントした1ヶ月のランキング画面になっております!
1ヶ月単位で見ると、そんな大した数字ではないのですが...3ヶ月ごとになると、トップ5くらいが爆発的な数字になってるんですよね。

 

1位は大体あの方がさらっと取っていくのですが、2&3位争いはいつも熾烈を極めているスワブロです。

コードの説明

さてさて、垂れ流しで紹介したコードですが...ざっくり説明しますね!

 

src/main.js

インストールしたvue google apiをimportして、作成したGoogle APIの情報を入れます。
clientId = OAuth2.0クライアントIDから作成したクライアントID
apiKey = APIキーから作成したキー

 

 

src/App.vue

外枠を作ってあげてます。
コンポーネンツにBaseLine.vueを作っているので、そちらの読み込みをしています。

 

 

src/components/BaseLine.vue

vuetifyのナビゲーションドロワーを使っています。
ここでは、1ヶ月と3ヶ月のランキングへのメニューを作っていますが、今回は1ヶ月ランキングのみ紹介します。

 

 

src/views/Home.vue

html部分ではtop3をvuetifyのcardでレイアウトしています。
テーブルはvuetifyのData tableを使用しています(手動ソートにも対応しているため、超便利!)

 

script部分は細かいものはコメントで説明しましたが、ざっくり説明するとこんな感じ。

  1. セレクトボックスに今月を代入
  2. WPからデータを取得
  3. GA Reporting APIからデータを取得
  4. 上記で集計して、ソートがおかしければ再集計

 

ちなみに、セレクトボックスは年月のみの選択となっていますが、script内ではこんな感じになっています。

〜今月(今日が2020年4月03日11時00分00秒の場合)〜
集計開始日:2020-04-01
集計終了日:2020-04-03
集計開始日(秒まで):2020-04-01T00:00:00
集計終了日(秒まで):2020-04-03T11:00:00

 

〜今月以外(2月を選択した場合)〜
集計開始日:2020-02-01
集計終了日:2020-02-29
集計開始日(秒まで):2020-02-01T00:00:00
集計終了日(秒まで):2020-02-29T23:59:59

 

今月以外だったら1ヶ月分をごっそり集計しちゃえばいいのですが、今月の場合は今日のなうタイムまでのデータしか作成されていないので...今月以外と同じ処理でデータをgetすると「んなデータねぇーよ!この野郎!」と怒られますww
そのためにwatchのif部分は細かく設定してあげてます。

 

あと268行でPVでソートし直しとありますが...
ここは、恐らくやらなくても大丈夫なんです。

 

ただ、弊社の場合ちょっと前にサーバー移管とかなんやらやって、数ページだけGAで取得している情報が同じURLなのに別れてる...という珍事象がありまして(原因がこれかは分かりませんが...
GA上では合体しているんですが、APIから取得してくると別れてるんです。

 

archives/blog/xxxxxxxx/:500pv
archives/blog/xxxxxxxx/:2pv

 

みたいな?
中村さんから月間発表されて「たくやが1位になったのに、こっちのアプリではたくや3位なんですけどwwwあれ?分裂してるwww」っていうね。

 

 

 

src/store/index.js

コードがゴチャゴチャしてくるため、modules/blog.js, modules/gAnalytics.jsというモジュールを作って管理しています。

 

 

src/store/modules/blog.js

Home.vueでまとめたparams(after, before, perPage)を受け取り、それをWP Rest APIに投げて、statusが200だったらdataに格納して、Home.vueに値をぶん投げてます。

 

参照:WP REST API

 

 

src/store/modules/gAnalytics.js

Home.vueでまとめたparams(start, end, selectedMonth, conditions)を受け取り、reportRequestsに条件を当てはめていきGA Reporting APIに投げて、statusが200だったらdataに格納して、Home.vueに値をぶん投げてます。

 

参照:リファレンスガイドQuery Explorer

 

まとめ

いかがでしたでしょうか?
超ローングな内容だったので、大分はしょっちゃいました😋
一応私のローカルでは動いてるんですが...だ、大丈夫かな(ひやひや

 

 

次の問題は、社内サーバーにあげようとしたらGoogle APIが「IPアドレスじゃ受け付けませんぜ!」と弾くんで、そこで頭を抱えています。
中村さんに使ってもらえなかったら、作った意味がーーー😭

 

ちなみに、このアプリはGAで見る権限がないと見れないのも注意!
(多分誰でも見られる方法もある気はするが...とりあえず、社内で見られればでこんな感じにしています)

 

 

無事、スワローメンバーに見てもらえる日が来ることを祈って...このブログを締めたいと思います!

 

 

 

ではっ!

 

 


Top