はじめに
技術記事を書くのが趣味の たま と申します。
Qiitaの週間レポートを送ってくれるアプリを作りました!
※サービスとして公開はしていませんが、コードは公開します。
完成品
Qiita公式のweekly reportと比較し、以下の点が長所です。
- 投稿した記事一覧の表示
- 記事ごとにいいね・ストック数を表示
- コメント・ビュー数の表示機能
きっかけ
きっかけは「しずかなインターネット」の月間振り返りレポートです。
振り返りと、ちょっとした達成感を得られるのが推しポイントです。
環境
環境 | 具体名称 |
---|---|
動作環境 | Google Apps Script |
言語 | JS / HTML / CSS |
API | Qiita API |
以下の理由により、GAS(Google Apps Script)で開発しました。
- 手軽
- 経験がある
- 無料
- 定期タスクの実行が容易
- Gmailで送信するのが容易
GASとは?という方はこちら
かんたんな解説
コード一覧はこちら
※GAS上でないと動作しません
1. Qiita APIを使用し、週間の記事一覧を取得する
Qiita APIの概要は以下です。
-
https://qiita.com/api/v2/users/${ユーザーネーム}/items
にて取得可能 - JSON形式
- tokenがあると、view数も確認することができる
コード上では、tokenがない場合も動作するようにしています。
tokenはsecretに保存しています。
該当コード
function get_weekly_qiita_posts(username, qiita_api_token) {
const api_url = `https://qiita.com/api/v2/users/${username}/items`;
const week_ago = new Date();
week_ago.setDate(week_ago.getDate() - 7);
const options = {
method: 'get',
muteHttpExceptions: true,
headers: {}
};
// If the qiita_api_token is provided, add the Authorization header
if (qiita_api_token) {
options.headers['Authorization'] = `Bearer ${qiita_api_token}`;
}
const response = UrlFetchApp.fetch(api_url, options);
const articles = JSON.parse(response.getContentText());
const weekly_articles = articles.filter(article => {
const created_at = new Date(article.created_at);
return created_at >= week_ago;
});
const formatted_articles = weekly_articles.map(article => {
return {
title: article.title,
date: new Date(article.created_at).toLocaleDateString(),
likes: article.likes_count,
stocks: article.stocks_count,
comments: article.comments_count || 0,
views: article.page_views_count,
url: article.url
};
});
return formatted_articles;
}
2. メール送信用HTMLを作成する
ポイントは以下です。
- GASではCSSファイルの作成ができないため、styleタグで規定する
-
<? script ?>
/<?= output ?>
を使用し、スクリプトを埋め込む
(erb
のようなイメージ)
CSS部分
<head>
<style>
body {
font-family: 'Arial', sans-serif;
color: #333;
line-height: 1.6;
}
.header {
font-size: 18px;
color: #444;
margin-bottom: 20px;
}
.article {
margin-bottom: 15px;
padding: 10px;
border: 1px solid #ddd;
}
.article-title {
font-size: 18px;
color: #007BFF;
}
.article-title a {
text-decoration: none;
color: #007BFF;
}
.article-meta {
font-size: 14px;
color: #555;
}
.summary {
margin-top: 20px;
font-size: 16px;
}
.summary-item {
font-size: 14px;
color: #666;
}
.footer {
margin-top: 30px;
font-size: 12px;
color: #999;
}
a:hover {
opacity: 0.8
}
</style>
</head>
HTML部分
<body>
<h2><?= username ?> さん、今週の振り返りをお送りします</h2>
<div class="header">今週(<?= startDate ?> 〜 <?= endDate ?>)に投稿された記事の一覧です</div><br>
<? for (var i = 0; i < articles.length; i++) { ?>
<div class="article">
<div class="article-title">
<a href="<?= articles[i].url ?>" target="_blank"><?= articles[i].title ?></a>
</div>
<div class="article-meta">
<p>投稿日: <?= articles[i].date ?></p>
いいね数: <?= articles[i].likes ?> | ストック数: <?= articles[i].stocks ?> | コメント数: <?= articles[i].comments ?> | ビュー数: <?= articles[i].views ?>
</div>
</div>
<br>
<? } ?>
<div class="summary">
<div class="summary-item">総合いいね数: <?= totalLikes ?></div>
<div class="summary-item">総合ストック数: <?= totalStocks ?></div>
<div class="summary-item">総合コメント数: <?= totalComments ?></div>
<div class="summary-item">総合ビュー数:<?= totalViews ?></div>
</div>
<div class="footer">
これからも、素晴らしい記事の投稿をお待ちしています!<br>
Qiita Weekly Report Bot
</div>
</body>
3. HTMLを呼び出し、演算を行う関数を作成する
MVCモデルのControllerに当たるものを作成します。
先程のHTMLに全て書いても動くのですが、分けることで可読性が上がります。
該当コード
function create_report(username, articles) {
const totalLikes = articles.reduce((sum, article) => sum + article.likes, 0);
const totalStocks = articles.reduce((sum, article) => sum + article.stocks, 0);
const totalComments = articles.reduce((sum, article) => sum + article.comments, 0);
const totalViews = articles.reduce((sum, article) => sum + article.views, 0);
const startDate = new Date();
startDate.setDate(startDate.getDate() - 7);
const endDate = new Date();
const template = HtmlService.createTemplateFromFile('report_template');
template.username = username;
template.startDate = startDate.toLocaleDateString();
template.endDate = endDate.toLocaleDateString();
template.articles = articles;
template.totalLikes = totalLikes;
template.totalStocks = totalStocks;
template.totalComments = totalComments;
template.totalViews = totalViews;
const reportHtml = template.evaluate().getContent();
return reportHtml;
}
4. メール送信関数を作成する
-
MailApp.sendEmail
でメールを送信できます - htmlBodyとして指定することで、HTMLとして解釈されます
該当コード
function send_mail(email, subject, htmlBody) {
// メール送信部分
try {
MailApp.sendEmail({
to: email,
subject: subject,
htmlBody: htmlBody
});
console.log("Success:",`sent mail to ${email}`)
} catch (error) {
console.log("Error:", error)
}
}
5. トリガーを設定し毎週実行する
おわりに
以上、Qiitaの週間レポートアプリについてでした。
サービス化するには非公式である点と、tokenの登録をしてもらう点がネックですね。
次はZennやnoteなどでも作りたいですね。
参考