【2023-8-10更新】ニュース収集の代替が見つかるまで
Tweetdeckさんも使えなくってえ〜
でもまだRSSリーダーとか準備していなくってえ〜
そんならユーザースタイルシート書けばええやんみたいな気持ちになったので
@-moz-document domain("twitter.com") { aside[aria-label="認証を受ける"], aside[aria-label="おすすめユーザー"], div[data-testid="UserCell"], section[aria-labelledby="accessible-list-10"] h2, *[data-testid="left-impression-pixel"] + article { display:none; } .r-a023e6 { font-size:14px; line-height: 1.4; } .r-kzbkwu { padding-bottom: 4px; } .r-ttdzmv { padding-top: 8px; } .r-zl2h9q { margin-bottom: 0; } .css-1dbjc4n div[role="group"] { margin-top: 2px; } /*投稿部分*/ .DraftEditor-root { font-size: 14px; } }
2023-8-10 : 広告の出され方が変わってたので更新
TogglのログをGoogleカレンダーにぶちこみたい(GASで)
社内を工数をGoogleカレンダー上で管理したいというお達しが届き
chatGPT先生に相談しながら作った。
もしGASが初めての人はできればテスト用のカレンダーを作って、試してからのがいいかもしれない。
※2023/7/7 重複しまくったので改修
トリガーで1日1回で回す用
最初全部取得で重複を見るようにしたかったが日時のフォーマットを比較するのがだるすぎて諦め。
実行から24時間だけ遡って反映するようにした。
トリガーは一番仕事してなさそうな時間に指定するのがよい。
実行の段階でタイマーが動いてると最新の時間エントリがエラーになるので悲しくなると思う。
function syncTogglToCalendar() { var togglApiKey = 'YOUR_TOGGL_API_KEY'; // https://track.toggl.com/profile の API Tokenから取得 var calendarId = 'YOUR_CALENDAR_ID'; // 該当のカレンダーのID var togglTimeEntries = fetchTogglTimeEntries(togglApiKey); var calendarEvents = getCalendarEvents(calendarId); var now = new Date(); var pastStartTime = new Date(now.getTime() - (24 * 60 * 60 * 1000)); // Togglの時間エントリをカレンダーに反映 for (var i = 0; i < togglTimeEntries.length; i++) { var timeEntry = togglTimeEntries[i]; var timeEntryStartTime = new Date(timeEntry.start); var timeEntryEndTime = new Date(timeEntryStartTime.getTime() + timeEntry.duration * 1000); // タイムエントリの開始時間が24時間前よりも後の場合にのみカレンダーに新しいイベントを作成 if (timeEntryStartTime > pastStartTime && timeEntryStartTime <= now) { // カレンダーに新しいイベントを作成 var event = createCalendarEvent(calendarId, timeEntry.description, timeEntryStartTime, timeEntry.duration); // イベントの詳細情報を設定 event.setDescription(timeEntry.description); event.setLocation(timeEntry.project); Logger.log('Created event: ' + event.getTitle()); } } } // Togglから時間エントリを取得 function fetchTogglTimeEntries(apiKey) { var url = 'https://api.track.toggl.com/api/v8/time_entries'; var headers = { 'Authorization': 'Basic ' + Utilities.base64Encode(apiKey + ':api_token') }; var options = { 'headers': headers, 'method': 'GET' }; var response = UrlFetchApp.fetch(url, options); var data = JSON.parse(response.getContentText()); return data; } // カレンダーからイベントを取得 function getCalendarEvents(calendarId) { var calendar = CalendarApp.getCalendarById(calendarId); var today = new Date(); var tomorrow = new Date(); tomorrow.setDate(today.getDate() + 1); // 現在の日付から1日後の日付を取得 var events = calendar.getEvents(today, tomorrow); return events; } // カレンダーに新しいイベントを作成 function createCalendarEvent(calendarId, title, startTime, duration) { var calendar = CalendarApp.getCalendarById(calendarId); var end = new Date(startTime.getTime() + duration * 1000); // 秒をミリ秒に変換して終了時間を計算 var event = calendar.createEvent(title, startTime, end); return event; }
まるごと全部取得して反映する用
今までTogglで取得してたけど、全部遡って反映したい時用。*1
これを1日1回ずつトリガーで実行しちゃうと、ポケット叩いたビスケットみたいにどんどん増えるので注意。
function syncTogglToCalendar() { var togglApiKey = 'YOUR_TOGGL_API_KEY'; // https://track.toggl.com/profile の API Tokenから取得 var calendarId = 'YOUR_CALENDAR_ID'; // 該当のカレンダーのID var togglTimeEntries = fetchTogglTimeEntries(togglApiKey); var calendarEvents = getCalendarEvents(calendarId); // Togglの時間エントリをカレンダーに反映 for (var i = 0; i < togglTimeEntries.length; i++) { var timeEntry = togglTimeEntries[i]; // 同じタイトルと開始時間を持つカレンダーイベントが存在するか確認 var existingEvent = findExistingEvent(calendarEvents, timeEntry.description, timeEntry.start); if (existingEvent) { // 既存のイベントが見つかった場合はスキップ continue; } // カレンダーに新しいイベントを作成 var event = createCalendarEvent(calendarId, timeEntry.description, timeEntry.start, timeEntry.duration); // イベントの詳細情報を設定 event.setDescription(timeEntry.description); event.setLocation(timeEntry.project); Logger.log('Created event: ' + event.getTitle()); } } // Togglから時間エントリを取得 function fetchTogglTimeEntries(apiKey) { var url = 'https://api.track.toggl.com/api/v8/time_entries'; var headers = { 'Authorization': 'Basic ' + Utilities.base64Encode(apiKey + ':api_token') }; var options = { 'headers': headers, 'method': 'GET' }; var response = UrlFetchApp.fetch(url, options); var data = JSON.parse(response.getContentText()); return data; } // カレンダーからイベントを取得 function getCalendarEvents(calendarId) { var calendar = CalendarApp.getCalendarById(calendarId); var today = new Date(); var tomorrow = new Date(); tomorrow.setDate(today.getDate() + 1); // 現在の日付から1日後の日付を取得 var events = calendar.getEvents(today, tomorrow); return events; } // 既存のイベントを検索 function findExistingEvent(events, title, startTime) { for (var i = 0; i < events.length; i++) { var event = events[i]; if (event.getTitle() === title && event.getStartTime().getTime() === startTime) { return event; } } return null; } // カレンダーに新しいイベントを作成 function createCalendarEvent(calendarId, title, startTime, duration) { var calendar = CalendarApp.getCalendarById(calendarId); var start = new Date(startTime); // 開始時間をDateオブジェクトとしてパース var end = new Date(start.getTime() + duration * 1000); // 秒をミリ秒に変換して終了時間を計算 var event = calendar.createEvent(title, start, end); return event; }
工数管理はたいへんだと思うけど
部署によって仕事の細切れ具合も、ブロック化する塩梅も違うから
社内で共通の言語で語ることは難しいね
楽できるところは楽をしながら
お互い様でやっていきたいものです
*1:たぶんこれは全部は遡らないはず