Skip to content

Commit 9e01eb0

Browse files
committed
init gsc-report and use run.sh for auto-moderator
1 parent 793993f commit 9e01eb0

File tree

9 files changed

+1099
-6
lines changed

9 files changed

+1099
-6
lines changed

bots/auto-moderator/run.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
bun install --frozen-lockfile || {
5+
echo 'auto-moderator: Failed to bun install --frozen-lockfile. falling back to bun install...' 2>&1
6+
bun install
7+
}
8+
9+
bun start
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: gsc-report
2+
on:
3+
workflow_dispatch:
4+
jobs:
5+
build:
6+
runs-on: ubuntu-latest
7+
steps:
8+
- uses: actions/checkout@v4
9+
- uses: actions/setup-node@v4
10+
- run: npm ci
11+
- env:
12+
GOOGLE_CLIENT_EMAIL: ${{ secrets.GOOGLE_CLIENT_EMAIL }}
13+
GOOGLE_PRIVATE_KEY: ${{ secrets.GOOGLE_PRIVATE_KEY }}
14+
WEBHOOK_ID: ${{ secrets.DISCORD_WEBHOOK_ID }}
15+
WEBHOOK_TOKEN: ${{ secrets.DISCORD_WEBHOOK_TOKEN }}
16+
run: node main.js

bots/gsc-report/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# gsc-reports

bots/gsc-report/main.js

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
const { google } = require('googleapis');
2+
const { WebhookClient } = require('discord.js');
3+
const dayjs = require('dayjs');
4+
const dotenv = require('dotenv')
5+
dotenv.config({path: process.env.ENV_FILE});
6+
7+
const auth = new google.auth.GoogleAuth({
8+
scopes: ['https://www.googleapis.com/auth/webmasters.readonly'],
9+
credentials: {
10+
client_email: process.env.GOOGLE_CLIENT_EMAIL,
11+
private_key: process.env.GOOGLE_PRIVATE_KEY,
12+
}
13+
});
14+
15+
const endDate = dayjs().format('YYYY-MM-DD');
16+
const startDate = dayjs().subtract(7, 'day').format('YYYY-MM-DD');
17+
18+
async function getSearchPerformance() {
19+
const client = await auth.getClient();
20+
const searchconsole = google.searchconsole({ version: 'v1', auth: client });
21+
22+
const res = await searchconsole.searchanalytics.query({
23+
siteUrl: "sc-domain:utcode.net",
24+
requestBody: {
25+
startDate,
26+
endDate,
27+
dimensions: ['page'],
28+
rowLimit: 25000,
29+
},
30+
});
31+
32+
const grouped = {};
33+
34+
for (const row of res.data.rows || []) {
35+
const url = row.keys[0];
36+
const subdomain = new URL(url).hostname.split('.').slice(0, -2).join('.') || 'utcode.net';
37+
38+
if (!grouped[subdomain]) {
39+
grouped[subdomain] = { clicks: 0, impressions: 0 };
40+
}
41+
42+
grouped[subdomain].clicks += row.clicks;
43+
grouped[subdomain].impressions += row.impressions;
44+
}
45+
46+
return grouped;
47+
}
48+
49+
async function sendToDiscord(data) {
50+
const webhook = new WebhookClient({ url: process.env.WEBHOOK_URL });
51+
52+
const fields = Object.entries(data)
53+
.filter(([sub, stats]) => stats.clicks > 0)
54+
.sort(([sub1, stats1], [sub2, stats2]) => stats2.clicks - stats1.clicks)
55+
.slice(0, 10)
56+
.map(([sub, stats], i) => {
57+
let name;
58+
if (sub.startsWith("kf")) {
59+
name = `${sub} (駒場祭${2000 + parseInt(sub.slice(2)) - 51})`;
60+
} else if (sub.startsWith("mf")) {
61+
name = `${sub} (五月祭${2000 + parseInt(sub.slice(2)) - 73})`;
62+
} else if (channelIds[sub]) {
63+
name = `${sub} ${channelIds[sub]}`;
64+
} else {
65+
name = sub;
66+
}
67+
return {
68+
name: `${i + 1}: ${name}`,
69+
value: `クリック数: ${stats.clicks}`,
70+
inline: true,
71+
};
72+
});
73+
74+
await webhook.send({
75+
embeds: [{
76+
title: "1週間の検索パフォーマンス",
77+
description: `${startDate}${endDate}`,
78+
fields
79+
}],
80+
});
81+
}
82+
83+
const channelIds = {
84+
"utcode.net": "<#1347510096044883988>",
85+
"syllabus": "<#1356879628907712572>",
86+
"create-cpu": "<#1354435873323876462>",
87+
"coursemate": "<#1352695487056052366>",
88+
"learn": "<#1368523267911974912>",
89+
"ut-bridge": "<#1346690984217677864>",
90+
"extra": "<#1353557111052828716>",
91+
"itsuhima": "<#1356806556297072793>",
92+
"shortcut-game": "<#1364040140850462741>",
93+
"mf98": "<#1353342238477783172>",
94+
"kf76": "<#1373908089794985984>",
95+
};
96+
97+
(async () => {
98+
const data = await getSearchPerformance();
99+
await sendToDiscord(data);
100+
})();

0 commit comments

Comments
 (0)