
ãGASããµã€ãã®æ°çãã§ãã¯ïœRSSãããŒã¯ãŒãã§çµãã5ä»¶ã ãã¹ãã¬ããã·ãŒãã«äžŠã¹ãïŒã³ãŒãå šæïŒ
å ¥ææ å ±ã®ããŒãžãåå·¥äŒè°æã圹æã®ãç¥ãããæ¥çãã¥ãŒã¹ãæ°ãããã®ãåºãŠããªãããæ¯æããã€ãã®ããŒãžãéããŠäžããèªããã»ãšãã©ã¯èªåã«é¢ä¿ããªããé¢ä¿ããããã®ã¯æ°ä»¶ã ããããã§ãèŠèœãšãã®ãæãã®ã§ãæ¯æ¥å šéšã«ç®ãéããŠããŸãã
ç§ã坿¥ã®æ¡ä»¶æ¢ãã§ãä»äºããåž°ã£ãŠããæ¯æ©ããã€ãã®ãµã€ããèŠåã£ãŠããŸãããèŠçµããããã«ã¯ç²ããŠããŠãèå¿ã®å¿åæãæžãæ°åãæ®ã£ãŠããªãããã®ãèŠåããããæ±ºãŸã£ãæ¡ä»¶ã§æ©æ¢°ã«å ã«ãµããã«ãããŠããããšã人ãèªãã®ã¯æ°ä»¶ã§æžã¿ãŸãã
ãã®èšäºã§ã¯ããµã€ãã®æ°çïŒRSSïŒãèªãã§ãæ¡ä»¶ã«åããã®ã ããç¹æ°é ã«5ä»¶ãGoogleã¹ãã¬ããã·ãŒãã«äžŠã¹ãGASïŒGoogle Apps ScriptãGoogleã®ãµãŒãã¹ã«ä»ããŠãããç¡æã§ããã°ã©ã ãåãããä»çµã¿ïŒã®ã³ãŒããå šéšèŒããŠããŸãã貌ãä»ããŠããèšå®ãã·ãŒãã«URLãšèšèãæžãã°åããæå»ã決ããŠæ¯æåããããšãã§ããŸãã
äŸã«äœ¿ã£ãã®ã¯æ¶ç©ºã®ãµã€ã3ã€ã§ãå°åã®å°ããªãã¶ã€ã³äºåæãæ¡ä»¶ã»è£å©éã»å ¥æã®æ°çãèŠåãæ³å®ã®èŠæ¬ã§ãã
ã§ãããã
ã³ãŒãã®äžã® pickToday ãšãã颿°ïŒã²ãšãŸãšãŸãã®åŠçã®ååïŒãåãããšãã仿¥ã®åè£ãã·ãŒãã«ãã䞊ã³ãŸãã

ç¹ã®ä»ãæ¹ã¯åçŽã§ãããæŸãèšèãã1ã€èŠã€ããããšã«10ç¹ãæ²èŒãæ°ããã»ã©æå€§5ç¹ïŒä»åºãã°ããã§5ç¹ã3æ¥ãã€ãš0ç¹ïŒãäžã®1è¡ç®ã¯ãããŒã ããŒãžããšããã©ã·ãã®2ã€ãèŠã€ãã£ãã®ã§20ç¹ã12æéåã®æ²èŒãªã®ã§çŽ4ç¹ãåãããŠ24ç¹ã§ãã人ãèŠãã®ã¯ãã®5è¡ãšãæ°ã«ãªãè¡ã®ãªã³ã¯ã ãã§ãã
æžãã®ã¯ãèšå®ãã·ãŒãã ã
ã³ãŒãã®äžã¯è§Šããã«æžãããã«ãæ¡ä»¶ã¯ã·ãŒãã«æžã圢ã«ããŸããã

Aåã«èŠããµã€ãã®RSSã®URLãBåã«ãå«ãã§ãããæŸãèšèããCåã«ãå«ãã§ãããå€ãèšèããã1ãã¹ã«1ã€ãã€æžããŸããåããšã®è¡ã®æ°ã¯ããã£ãŠããªããŠããŸããŸããïŒç©ºã®ãã¹ã¯é£ã°ããŸãïŒã
RSSã¯ããµã€ããæ°çã®äžèŠ§ãæ©æ¢°ãèªãã圢ã§åºããŠãããã®ã§ãããRSSãã®ããŒã¯ããURLã /feedã.rdfã.xmlã.atom ã§çµãããªã³ã¯ãããã§ããèŠã€ãããªããã°ããµã€ãå RSSãã§æ€çŽ¢ããŸãã
15ä»¶ãã©ãçµãããã
æ¶ç©ºã®3ã€ã®ãµã€ãã®æ°çãåãããŠ15ä»¶ããããããã©ããªã£ããã§ãïŒãã®è¡šã¯èª¬æã®ããã«å¥ã«äœã£ããã®ã§ãã³ãŒããæžã蟌ãã®ã¯äžã®ã仿¥ã®åè£ãã ãã§ãïŒã

å€ãæ¹ã¯4éãã§ãã
å€ãèšèãå«ãïŒãåžžé§ããåéçµäºããç· åæžãïŒ
3æ¥ããå€ã
æŸãèšèã1ã€ãç¡ã
åããªã³ã¯ããã§ã«åºãŠãã
æåŸã®è¡ã¯ãåžåœ¹æã®RSSã«æ··ãã£ãŠãã転èŒã§ãããªã³ã¯ã1è¡ç®ãšåããªã®ã§å€ããŸãïŒãã®è¡ã®ãã©ãã®æ°çããã¯ãæåãA æ¡ä»¶ããšåºãã®ã§æã§çŽããŸããïŒããããŒã ããŒãžã®æŽæ°äœæ¥ãã¯æŸãèšèããã£ãŠã6äœã§ãå ¥ããŸããã§ããã
ã³ãŒãå šæ
/** @OnlyCurrentDoc */
/**
* èŠåã£ãŠãããµã€ãã®æ°çïŒRSSïŒãèªãã§ãæ¡ä»¶ã«åããã®ãã仿¥ã®åè£ãã«5ä»¶ã ã䞊ã¹ã
*
* äœ¿ãæ¹
* 1. ã¹ãã¬ããã·ãŒãã«ãèšå®ããšããã·ãŒããäœãã1è¡ç®ã«èŠåºãã2è¡ç®ãã
* AåïŒèŠãRSSã®URLãBåïŒå«ãã§ãããæŸãèšèãCåïŒå«ãã§ãããå€ãèšèãã1ã€ãã€æžã
* 2. ãã®ã³ãŒãããæ¡åŒµæ©èœãâãApps Scriptãã«è²Œã£ãŠä¿åããpickToday ãå®è¡ãã
*/
const MAX_ITEMS = 5; // 仿¥ã®åè£ã«åºãä»¶æ°
const MAX_DAYS = 3; // ããããå€ãèšäºã¯åºããªã
function pickToday(ss) {
ss = (ss && ss.getSheetByName) ? ss : SpreadsheetApp.getActiveSpreadsheet();
const cond = readSettings_(ss);
const items = [];
cond.feeds.forEach(url => {
try {
items.push(...parseFeed_(UrlFetchApp.fetch(url).getContentText()));
} catch (e) {
Logger.log('èªããªãã£ãURLïŒ' + url + 'ïŒ' + e.message + 'ïŒ');
}
});
const top = pickTop_(items, cond, new Date());
writeToday_(ss, top);
Logger.log('èªãã èšäº ' + items.length + 'ä»¶ â 仿¥ã®åè£ ' + top.length + 'ä»¶');
return { read: items.length, picked: top.length };
}
/** ãèšå®ãã·ãŒãã®AãCåãèªãïŒç©ºã®ã»ã«ã¯é£ã°ãïŒ */
function readSettings_(ss) {
const sh = ss.getSheetByName('èšå®');
if (!sh) throw new Error('ãèšå®ããšããååã®ã·ãŒããèŠã€ãããŸãããã·ãŒãã®ååã確ãããŠãã ãã');
const rows = sh.getDataRange().getValues().slice(1);
const col = i => rows.map(r => String(r[i]).trim()).filter(v => v);
return { feeds: col(0), want: col(1), ng: col(2) };
}
/** RSSã®3ã€ã®åœ¢ïŒRSS 2.0ïŒRSS 1.0ïŒAtomïŒããåã圢ã®äžèЧã«ãã */
function parseFeed_(text) {
const root = XmlService.parse(text).getRootElement();
const atom = XmlService.getNamespace('http://www.w3.org/2005/Atom');
const rss1 = XmlService.getNamespace('http://purl.org/rss/1.0/');
const dc = XmlService.getNamespace('dc', 'http://purl.org/dc/elements/1.1/');
if (root.getName() === 'feed') {
return root.getChildren('entry', atom).map(e => {
// link ãè€æ°ãããšãã¯ãèšäºãã®ãã®ã®ãªã³ã¯ïŒrel ãç¡ãã alternateïŒãéžã¶
const links = e.getChildren('link', atom);
const link = links.find(l => !l.getAttribute('rel') || l.getAttribute('rel').getValue() === 'alternate') || links[0];
return item_(e.getChildText('title', atom), link ? link.getAttribute('href').getValue() : '',
e.getChildText('updated', atom) || e.getChildText('published', atom), e.getChildText('summary', atom));
});
}
const isRss1 = root.getName() === 'RDF';
const ns = isRss1 ? rss1 : XmlService.getNoNamespace();
const list = isRss1 ? root.getChildren('item', rss1) : root.getChild('channel').getChildren('item');
return list.map(e => item_(e.getChildText('title', ns), e.getChildText('link', ns),
e.getChildText('pubDate', ns) || e.getChildText('date', dc), e.getChildText('description', ns)));
}
function item_(title, link, date, desc) {
const d = date ? new Date(date) : null; // èªããªãæ¥ä»ã¯ãæ¥ä»ãªãããšããŠæ±ã
return {
title: (title || '').trim(),
link: (link || '').trim(),
date: d && !isNaN(d) ? d : null,
desc: (desc || '').replace(/<[^>]*>/g, '').trim()
};
}
/** å€ãèšèãå«ããã®ã»å€ããã®ã»åããªã³ã¯ãå€ããæŸãèšèã®æ°ãšæ°ããã§ç¹ãã€ããŠäžãã䞊ã¹ã */
function pickTop_(items, cond, now) {
const seen = {};
return items
.filter(it => {
const text = it.title + ' ' + it.desc;
if (cond.ng.some(w => text.includes(w))) return false;
if (it.date && (now - it.date) / 86400000 > MAX_DAYS) return false;
if (it.link && seen[it.link]) return false; // ãªã³ã¯ã®ç¡ãèšäºã¯éè€ãšã¿ãªããªã
seen[it.link] = true;
return true;
})
.map(it => {
const hits = cond.want.filter(w => (it.title + ' ' + it.desc).includes(w));
const hours = it.date ? (now - it.date) / 3600000 : 72;
const fresh = Math.max(0, 72 - hours) / 72 * 5; // æ°ããã»ã©æå€§5ç¹
return Object.assign({}, it, { hits: hits, score: hits.length * 10 + fresh });
})
.filter(it => it.hits.length > 0)
.sort((a, b) => b.score - a.score)
.slice(0, MAX_ITEMS);
}
/** ã仿¥ã®åè£ãã·ãŒããæ¯åãŸã£ããã«ããŠæžã */
function writeToday_(ss, top) {
const sh = ss.getSheetByName('仿¥ã®åè£') || ss.insertSheet('仿¥ã®åè£');
sh.clear();
const rows = [['ç¹', 'èŠã€ãã£ãèšè', 'ã¿ã€ãã«', 'æ²èŒ', 'ãªã³ã¯']].concat(top.map(it => [
Math.round(it.score), it.hits.join('ã»'), it.title,
it.date ? Utilities.formatDate(it.date, 'Asia/Tokyo', 'M/d HH:mm') : '', it.link
]));
sh.getRange(1, 1, rows.length, rows[0].length).setValues(rows);
return rows;
}è²Œãæ¹
1. ã¹ãã¬ããã·ãŒããæ°ããäœããç»é¢äžã®ã·ãŒãã®ã¿ãïŒæåã¯ãã·ãŒã1ãïŒã®ååããèšå®ãã«å€ããŠãäžã®è¡šãšåã圢ã§URLãšèšèãæžã
2. ã¡ãã¥ãŒã®ãæ¡åŒµæ©èœãâãApps Scriptããéããæåããå
¥ã£ãŠããã³ãŒããæ¶ããŠãäžã®ã³ãŒãã貌ãä»ããŠä¿åãã
3. ç»é¢äžéšã®ã颿°åã衚瀺ãããŠããæ¬ã§ pickToday ãéžã³ããå®è¡ããæŒã
4. ååã ããGoogleã¢ã«ãŠã³ãã®æš©éãèš±å¯ããç»é¢ãåºãŸããå€éšã®ããŒãžãèªãããšãšãã¹ãã¬ããã·ãŒãã®èªã¿æžãã®èš±å¯ã§ã
5. ãGoogle ã§ç¢ºèªãããŠããŸããããšåºãããã詳现ãããå
ã«é²ãã§èš±å¯ããŸããèªåã§äœã£ãã¹ã¯ãªãããªã®ã§åºã衚瀺ã§ã
ã³ãŒãã®1è¡ç®ã® @OnlyCurrentDoc ã¯ãèªã¿æžãããã®ã¹ãã¬ããã·ãŒãã ãã«çµãå°ã§ãã
æ¯æèªåã§åãããšãã¯ãApps Script ã®ç»é¢ã®å·Šã«ããæèšã®ããŒã¯ïŒããªã¬ãŒïŒâãããªã¬ãŒã远å ãã§ãå®è¡ãã颿°ã pickTodayãã€ãã³ãã®ãœãŒã¹ããæéäž»å°åããçš®é¡ããæ¥ä»ããŒã¹ã®ã¿ã€ããŒãã«ããŠãæå»ïŒäŸïŒåå6æã7æïŒãéžãã§ä¿åããŸããããªã¬ãŒããåŒã°ãããšãã¯ãpickToday ã®1è¡ç®ã§ãã®ã¹ãã¬ããã·ãŒãã䜿ãããã«åãæ¿ããäœãã«ããŠãããŸãïŒããªã¬ãŒã§ã®å®è¡ã¯æªç¢ºèªïŒã
ã€ãŸããæ
RSSãç¡ããµã€ãã¯èªããªãã æ€çŽ¢çµæã®RSSãåºããŠããªãåéãµã€ãããããŸãããã®å Žåã¯ããµã€ãã®ãæ°çãã¡ãŒã«ã§ç¥ããããæ©èœãäœ¿ãæ¹ã確å®ã§ãã
ãµã€ãã«ãã£ãŠã¯ãæ©æ¢°ããã®èªã¿èŸŒã¿ãæãããã æ¬ç©ã§è©ŠããšãNHKã®ãã¥ãŒã¹ïŒ7ä»¶ïŒãGitHubã®æŽæ°æ å ±ïŒ10ä»¶ïŒãITç³»ãã¥ãŒã¹ãµã€ãïŒ20ä»¶ïŒã¯èªããŸããããçµæžç£æ¥çã®RSSã¯ããšã©ãŒ: 403ãïŒèªã¿èŸŒã¿ã®æåŠïŒã§èªããŸããã§ããã
ã·ãŒãã®ååãéããšæ¢ãŸãã ãèšå®ãã·ãŒãã®ååããã·ãŒã1ãã®ãŸãŸã ãšãããèšå®ããšããååã®ã·ãŒããèŠã€ãããŸããããšãããšã©ãŒã§æ¢ãŸããŸããã·ãŒãã®ååã確ãããŠãã ããã
èªããªãURLããã£ãŠãæ¢ãŸããªãã ååšããªãURLã1ã€æ··ããŠåããããšããããã®URLã¯å®è¡ãã°ã«ãèªããªãã£ãURLããšåºãŠé£ã°ããããã1ã€ã®NHKã®RSSïŒ7ä»¶ïŒã¯èªããŠãåŠçã¯æåŸãŸã§çµãããŸããïŒãã®ãšãã¯æŸãèšèã«åãèšäºãç¡ããåè£ã¯0ä»¶ïŒãæ°çãæ¥ã«åºãªããªã£ããããŸãå®è¡ãã°ïŒåãããèšé²ãApps Script ã®å·Šã®ãå®è¡æ°ãïŒãèŠãŠãã ããã
RSSã®åœ¢ã¯3çš®é¡ãããäžèº«ãæ¬ ããŠããããšãããã ãRSS 2.0ããRSS 1.0ããAtomãã®3ã€ã parseFeed_ ãèªã¿åããŸãããªã³ã¯ã®ç¡ãèšäºããäžæãã®ãããªæ¥ä»ããæ¶ç©ºã®RSSã§ã¯æ¢ãŸããã«æ±ããŸããïŒèªããªãæ¥ä»ã¯æ°ãã0ç¹ïŒã
ãŸãã«ãå€ããµã€ãã¯æååãããã æåã³ãŒãïŒæåãèšé²ããæ¹åŒïŒã Shift_JIS ãšããå€ãæ¹åŒã®RSSã¯ãæååãããŠèšèãäžèŽããªãããšããããŸãããã®å Žå㯠getContentText() ã getContentText('Shift_JIS') ã«å€ããŸããRSSã®äžã« ïŒç©ºçœã衚ãèšå·ïŒãæ··ãã£ãŠãããšèªã¿èŸŒã¿ã«å€±æãããã®ãµã€ãã¯äžžããšé£ã°ãããŸããã©ã¡ããä»åã¯è©ŠããŠããŸããã
èšèã¯æåã©ããã«ããäžèŽããªãã ãHPããšãããŒã ããŒãžããå šè§ãšåè§ã¯å¥ã®èšèãšããŠæ±ããŸããæŸãããã®ã«åºãŠããªããã®ããã£ãããèšãæããBåã«è¶³ããŸãã
æšæ¥èŠããã®ãããŸãåºãã åãããã³ã«æžãçŽãã®ã§ã3æ¥ä»¥å ãªãæšæ¥èŠããã®ãç¹æ°ãã ãã§ãŸã䞊ã³ãŸããç°¡æçãªã®ã§å²ãåã£ãŠããŸããé¿ããããªããååã®ææ°ã®æ²èŒæ¥æãã»ã«ã«æ®ããããããæ°ãããã®ã ã䞊ã¹ã圢ã«çŽããŸãã
ã©ããŸã§è©Šããã
æ¶ç©ºã®15ä»¶ã¯ãURLããèªã代ããã«RSSã®äžèº«ãçŽæ¥æž¡ããŠãçµã蟌ã¿ãšæžã蟌ã¿ã確ãããŸãããURLããèªãæã¯ãæ¬ç©ã®NHKã®RSSã§ pickToday ãéããŠç¢ºãããŸãããã¹ãã¬ããã·ãŒãããéããŠå®è¡ããæµããšãããªã¬ãŒã§ã®å®è¡ã¯è©ŠããŠããŸããïŒã©ã¡ãã Apps Script ã®ãµã ãã®äœ¿ãæ¹ã§ãïŒã
è²»çš
ããããŸãããGoogleã¢ã«ãŠã³ããããã°ãã¹ãã¬ããã·ãŒããApps Scriptãç¡æã§äœ¿ããŸããå€éšãèªãåæ°ã«ã¯1æ¥ã®äžéããããŸãããæ¯ææ°åã®RSSãªãå±ããŸããã