cybozu developer networkでもGitHubの活用シーンが増えてきました。
リポジトリを公開すると気になるのは訪問数です。
GitHubではリポジトリの訪問数を取得できますが、直近2週間しか取得できません。
そこでkintoneとAWS Lambdaを使って、GitHubリポジトリの訪問数をkintoneに定期的に記録するサンプルを作りました。
定期的に実行するためにAWS Lambdaを利用します。
また、Lambda関数の作成にNode.js環境が必要ですのでご注意ください。
大きな処理の流れは以下のとおりです。
ではさっそく準備に取り掛かりましょう。
1. kintone設定
固定リンクがコピーされました
kintoneアプリの作成
固定リンクがコピーされました
フィールド名 |
フィールドタイプ |
フィールドコード |
プロジェクト |
文字列(1行) |
project |
年月日 |
日付 |
date |
訪問数 |
数値 |
count |
ユニーク訪問数 |
数値 |
uniques |
APIトークンの発行
固定リンクがコピーされました
「アプリの設定 > APIトークン」で、レコード閲覧、レコード追加が可能なAPIトークンを発行します。
kintoneに追加するデータが重複しないようにレコード閲覧権限も必要です。
2. GitHub設定
固定リンクがコピーされました
GitHubアカウントの作成
固定リンクがコピーされました
github.com
から、GitHubアカウントを作成します。
GitHubアカウントを取得済みの方はログインしてください。
Personal access tokenの作成
固定リンクがコピーされました
AWS LambdaからGitHub APIを利用するために必要な作業です。
Personal access tokens
にアクセスして新しいPersonal access tokenを作成します。
「Token description」には適当な値を、「Select scopes」には「public_repo」を設定します。
Tokenとなるキーは作成時にしか確認できませんので忘れずにメモしてください。
3. Lambda関数の実行ファイル作成
固定リンクがコピーされました
Node.jsをインストールした環境での作業になります。
以下のサンプルコードをファイル名「index.js」で保存します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
/*
* kinone x GitHub sample program
* Copyright (c) 2017 Cybozu
*
* Licensed under the MIT License
* https://opensource.org/license/mit/
*/
const GitHubApi = require('github');
const moment = require('moment');
const https = require('https');
const querystring = require('querystring');
const bluebird = require('bluebird');
const async = require('async');
// kintone接続設定
const DOMAIN = 'subdomain.cybozu.com';
const APP_ID = 1;
const API_TOKEN = 'your_api_token';
// GitHub接続設定
const OWNER = 'owner_name';
const REPO = 'repository_name';
const PERSONAL_ACCESS_TOKEN = 'your_personal_access_token';
const github = new GitHubApi({
protocol: 'https',
host: 'api.github.com',
Promise: bluebird
});
github.authenticate({
type: 'token',
token: PERSONAL_ACCESS_TOKEN
});
const getOptions = (apiPath, method) => {
'use strict';
return {
hostname: DOMAIN,
port: 443,
path: apiPath,
method: method,
headers: {
'X-Cybozu-API-Token': API_TOKEN
}
};
};
// kintoneから一番直近に登録したデータの年月日を取得
const getRecord = (project, callback) => {
'use strict';
console.log('[START] get kintone record');
const params = {
app: APP_ID,
query: `project = "${project}" order by date desc limit 1 offset 0`,
fields: ['date']
};
const query = querystring.stringify(params);
const options = getOptions('/k/v1/records.json?' + query, 'GET');
const req = https.request(options, (res) => {
res.setEncoding('utf-8');
res.on('data', (chunk) => {
if (res.statusCode === 200) {
callback(null, JSON.parse(chunk).records);
} else {
callback(res.statusMessage);
}
});
});
req.on('error', (err) => {
callback(err.message);
});
req.end();
};
// kintoneに訪問数などを登録
const postRecord = (project, date, count, uniques, callback) => {
'use strict';
console.log(`[START] post kintone record: ${date}`);
const params = {
app: APP_ID,
record: {
project: {
value: project
},
date: {
value: date
},
count: {
value: count
},
uniques: {
value: uniques
}
}
};
const options = getOptions('/k/v1/record.json', 'POST');
options.headers['Content-Type'] = 'application/json';
const req = https.request(options, (res) => {
res.setEncoding('utf-8');
res.on('data', (chunk) => {
if (res.statusCode === 200) {
const body = JSON.parse(chunk);
callback(null, body.id);
} else {
callback(res.statusMessage);
}
});
});
req.on('error', (err) => {
callback(err.message);
});
req.write(JSON.stringify(params));
req.end();
};
exports.handler = (event, context, callback) => {
'use strict';
const project = `${OWNER}/${REPO}`;
getRecord(project, (err, records) => {
'use strict';
if (err !== null) {
callback(err);
return false;
}
const currentDate = moment();
let lastDate = '';
try {
lastDate = moment(records[0].date.value);
} catch (_) {
lastDate = moment('2000-01-01');
}
github.repos.getViews({
owner: OWNER,
repo: REPO
}).then((res, err2) => {
if (err2 !== undefined) {
callback(err2);
return false;
}
const views = res.data.views;
const postRecordHandlers = [];
for (let i = 0; i < views.length; i++) {
const view = views[i];
const timestamp = view.timestamp;
const count = view.count;
const uniques = view.uniques;
const date = moment(timestamp);
// 一番直近に登録したデータの年月日以前の場合はスキップ
if (date.isSameOrBefore(lastDate, 'day')) {
continue;
}
// 実行日と同じ年月日もスキップ
if (date.isSame(currentDate, 'day')) {
continue;
}
postRecordHandlers.push(postRecord.bind(this, project, date.format('YYYY-MM-DD'), count, uniques));
}
if (postRecordHandlers.length === 0) {
console.log('[COMPLETE] nothing to do');
callback(null, '[COMPLETE] nothing to do');
return false;
}
async.series(postRecordHandlers, (err3, rid) => {
if (err3 !== null) {
callback(err3);
return false;
}
console.log('[COMPLETE] record id: ' + rid.join(', '));
callback(null, '[COMPLETE] record id: ' + rid.join(', '));
});
});
});
};
|
17~19行目にkintoneのドメイン、アプリID、APIトークンを設定します。
16
17
18
19
|
// kintone接続設定
const DOMAIN = 'subdomain.cybozu.com';
const APP_ID = 1;
const API_TOKEN = 'your_api_token';
|
訪問数を取得するにはそのリポジトリの管理者権限が必要になります。
22~24行目に訪問数を取得したいリポジトリのオーナー名、リポジトリ名、先ほど作成したPersonal access tokenを設定します。
リポジトリのURLが
https://github.com/kintone-labs/kintoneUtility
の場合、オーナー名は「kintone-labs」、リポジトリ名は「kintoneUtility」になります。
21
22
23
24
|
// GitHub接続設定
const OWNER = 'owner_name';
const REPO = 'repository_name';
const PERSONAL_ACCESS_TOKEN = 'your_personal_access_token';
|
以下のコマンドを実行して、モジュールのインストール、ZIPファイル(Lambda関数の実行ファイル)を作成します。
zip
コマンドでエラーが発生した場合は、階層にファイル「index.js」とディレクトリ「node_modules」が存在するか確認してください。
1
2
|
npm install github moment https querystring bluebird async
zip -rq github-to-kintone.zip index.js node_modules
|
AWSアカウントの作成
固定リンクがコピーされました
Lambdaの開始方法
を参考にAWSアカウントと管理者ユーザーを作成します。
AWSアカウントを取得済みの方はログインしてください。
Lambda実行ロール
を参考にLambdaを実行するロールを作成します。
例として、今回はロール名を「AWSLambdaExecute」で作成しました。
新規関数を作成します。
設計図は「ブランク関数」を選択します。
トリガーにはCloudWatchを設定します。
「ルール名」、「ルールの説明」は適当な値を、「スケジュール式」には「rate(1 day)」を設定します。
「名前」は適当な値を設定します。
「ランタイム」は「Node.js 6.10」を選択します。
「関数パッケージ」には先ほど作成した「GitHub-to-kintone.zip(Lambda関数の実行ファイル)」をアップロードします。
「ハンドラー」は「index.handler」を、「ロール」は先ほど作成したロールを設定します。
詳細設定の「タイムアウト」には少し余裕をみて20秒を設定します。
実行するとkintoneにデータが登録されました。
また、AWS Lambdaの機能で毎日データが登録されるので過去の訪問数も確認できますね。
GitHub非常に楽しいですね。
訪問数の増加が確認できればコード更新のモチベーションにもつながりそうです。