【GAS】teratailから任意の質問を取得する
概要
今回はGoogle Apps Script
(以下GAS
)を使ってteratailから任意の質問を取得したいと思います。
よくteratail
で回答をしているのですが、Javascript
などの人気ジャンルの質問はすぐに回答されてしまうため、ベストアンサーにたどり着くのが難しいです。
そこで私は、自分が得意なタグの質問を自動取得して通知するような仕組みを自作していますが、その際にポイントになるのが「質問の取得方法」です。
特定タグだけならteratail
にはRSS
が用意されているので、それを使えばオッケーですが、「まだ誰も回答していない質問」や「投稿されて長い間回答がついていない質問」など細々とした条件をカスタマイズする場合はteratail API
を使うといいです。
※今回は「通知する」部分については記載しません
前提条件
以下のものは準備できている想定とします。
-
teratail
のアカウント -
GAS
プロジェクトの作成
teratail APIを使用する
teratail
にはAPI
が用意されています。
上記のページによると、以下のことが可能です。
teratail APIでは以下のようなことが可能です。
- 質問一覧の取得
- 質問詳細とその回答の取得
- ユーザー詳細の取得
- ユーザーのクリップしている質問の取得
- タグ一覧の取得
- タグを持つ質問の一覧の取得
今回は「質問一覧の取得」の機能を使います。
前準備「アクセストークンの取得」
API
を使用するためにはアクセストークンが必要になってくるので、取得します。
teratail
にログインした状態で設定ページを開きます。
そしてメニューから 「アクセストークン管理」 を押下します。
下図のような表示になるので、「新規作成する」ボタンを押下します。
すると、「トークン名」を聞かれるので入力し生成します。
下記のようにトークンが表示されたら成功です。
この文字列をコピーしておきます。
APIの実行
利用するAPIの詳細仕様は以下のページに記載してあります。
質問一覧を取得するエンドポイントはhttps://teratail.com/api/v1/questions
で、以下のようなJSON
形式のレスポンスが返ります。
※実際にはquestions
にはmeta.hit_num
の中の最新20件が含まれています。
※ページングしたい場合はパラメータを切り替えながらリクエストを投げていきます。
{
"meta": {
"message": "success",
"total_page": 16433,
"page": 1,
"limit": 20,
"hit_num": 328653
},
"questions": [
{
"id": 999999,
"title": "質問さんぷる",
"created": "2021-04-16 13:33:29",
"modified": "2021-04-16 13:33:29",
"count_reply": 0,
"count_clip": 0,
"count_pv": 4,
"is_beginner": false,
"is_accepted": false,
"is_presentation": false,
"tags": [
"Javascript",
"MySQL"
],
"user": {
"display_name": "test",
"photo": "test.jpg",
"score": 28
}
}
]
}
GASでリクエストを叩く
上記のエンドポイントをGAS
で叩くコードを記載します。
ポイントは取得したいタグを自身で設定している点です。
実際はハードコーディングでなく、ある程度自由に追加・削除できる形で運用しています。
// teratailで発行したアクセストークン
const token = '【teratailのアクセストークン】';
// 取得したいタグ
const targetTags = ['Javascript', 'HTML'];
// 質問URLの雛形部分
const urlBase = 'https://teratail.com/questions/';
/**
* 対象となる質問を取得
*/
function getTargetQuestions() {
let result = [];
// Teratail API
const uri = 'https://teratail.com/api/v1/questions';
const headers = {
'Authorization' : 'Bearer ' + token,
};
const option = {
'method': 'get',
'contentType': 'application/json',
'headers' : headers
}
// API実行
const response = UrlFetchApp.fetch(uri, option);
// JSONに整形
const result = JSON.parse(response.getContentText());
// 対象の質問リスト
var targetList = [];
if(result.questions) {
const questions = result.questions;
for(var i = 0; i< questions.length; i++){
const question = questions[i];
const modified = new Date(question.modified)
const isTargetTag = question.tags.some(function(t){ return targetTags.indexOf(t) >= 0 })
// 対象タグだったら
if(isTargetTag) {
// targetListに投稿に必要なデータをまとめてpush
// ここではURL,件名,回答数を取得している
targetList.push({ url : urlBase + question.id, title : question.title, countReply : question.count_reply })
}
}
}
return targetList;
}
また、既に回答がついているかどうかを重視したい場合はquestion.count_reply
を参照して条件付けをするといいかなと思います。
使ってみて実際どうか
かれこれ1年近くこのスクリプトを運用していますが、自動で自分が回答できそうな質問を拾ってきてくれるため使用感は上々です。
基本数分間隔でこの処理を走らせて通知を受けていますが、それでも先を超されるケースがあるので、同じような事をしている方も一定数いるのかもしれません。
※リクエストは1時間に300件までという制約があるので、その範囲内で利用しましょう
まとめ
今回はteratail
の質問をAPI
から取得する方法についてGAS
を用いたケースを紹介しました。
なぜGAS
かというと時間起動のトリガを使うことで、特に環境を用意しなくてもスケジュール実行してくれるからです。
当然Google
系のサービスとは相性がいいので、スプレッドシートに収集内容を保持して解析に使ったりもできます。
リクエストを叩く箇所については一番オーソドックスな形にしてあるので、そのまま他サービスのAPI
を叩くコードに置き換えるのもそれほど難しくないと思います。
今回の内容が少しでも役立てば幸いです。
Discussion