やったこと
MATLAB の新着記事無いかな~と Qiita をチェックする回数を減らすために、MATLAB タグのついた記事を自動でお知らせする bot を作ったのでコード公開します。
アカウントはこちら -> @Qiita_MATLAB
2023/08/15 追記
ThingSpeak からの Tweet が現在機能していないので今は GitHub Actions と Twitter API v2 を使っています。GitHub:minoue-xx/Qiita-what-was-posted-on-this-day
本投稿のポイント
タイムゾーンを加味した処理が楽な datetime
型変数の TimeZone
プロパティが見どころです。
簡単な例だと、
t1 = datetime();
t1.TimeZone = 'Asia/Shanghai'
t2 = t1;
t2.TimeZone = 'Europe/London'
と実行すると
t1 =
datetime
2019/10/26 07:00:14
t2 =
datetime
2019/10/26 00:00:14
と表示は異なりますが、以下のように時間情報としては同値です。
>> isequal(t1,t2)
ans =
logical
1
関連記事、ページ
ThingSpeak 自体や、Twitter で呟くのに必要な設定やコードは以下で紹介していますので、良ければ参考にしてください。
実際の Channel は こちら で確認できますが、一応以下の2つの情報もトラックしています。
- total_items: MATLAB タグが付いた記事の合計数
- total_followers: MATLAB タグのフォロワー数
本題の MATLAB Analysis
コード全文は最後に纏めて再掲しますので、ここでは要所だけ解説します。ThingSpeak の Time Control 設定によって1時間に1回実行され、
- 新着チェック
- 新着情報を Tweet
する仕組みとしています。
まず、Qiita API を使って最新20件のリストを作ります。
% ここから新着記事のチェック(最新20個取ればOKでしょう・・)
url = "https://qiita.com/api/v2/tags/matlab/items?page=1&per_page=20";
tmp = webread(url,opts);
% 投稿時刻をチェック(TimeZone は日本時間に設定)
created_at = datetime(vertcat(tmp.created_at),...
'InputFormat', "uuuu-MM-dd'T'HH:mm:ss'+09:00",'TimeZone','Asia/Tokyo');
titles = string({tmp.title}');
urls = string({tmp.url}');
item_list = timetable(titles, urls, 'RowTimes', created_at,...
'VariableNames',{'titles', 'urls'})
この時、時間情報は TimeZone
, Asia/Tokyo
と設定して timetable
型変数:item_list
としてまとめます。
現時刻から1時間以内に投稿されていればそれは新着記事。現時刻から過去1時間の間に投稿されたものだけを、item_list
から抜き出します。
% 新着かどうかのチェック
% このスクリプトは 1時間に1回実行する設定にします。(ThingSpeak の Time Control 設定)
interval = duration(1,0,0);
tnow = datetime;
% ThingSpeak が動いているところでは TimeZone が UTC であるところに注意
tnow.TimeZone = 'UTC';
trange = timerange(tnow-interval,tnow) % 過去一時間以内の投稿だけを抽出
newitem_list = item_list(trange,:);
trange
変数につかう時間情報は TimeZone
, UTC
に設定しています。
まとめ
ThingSpeak を使って @Qiita_MATLAB bot を作りました。
ThingSpeak 上の時間設定は UTC
ですが、Qiita API からとれる投稿時間は JST
ということで時間情報に時差がありましたが、datetime
型変数の TimeZone
プロパティで対処しています。
MATLAB タグのついた投稿頻度はまだ高くないので、bot としては少し寂しいですね。。こんなこと呟いてみたら?など提案ありましたら何なりと。
MATLAB コード全文
各 APIKey だけ設定すればそのまま機能するはず。
% アクセストークン使用
% accessToken = 'Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
% opts = weboptions('HeaderFields',{'Authorization',accessToken});
% アクセストークン使用しない場合
opts = weboptions;
% ThingSpeak ログ用:記事合計数、フォロワー数の取得
url = "https://qiita.com/api/v2/tags/matlab";
tmp = webread(url,opts);
items_count = tmp.items_count;
followers_count = tmp.followers_count;
channelID = 890134;
writeAPIKey = 'XXXXXXXXXXXXXXXX'; % それぞれの Channel に固有の APIKey
readAPIKey = 'XXXXXXXXXXXXXXXX'; % それぞれの Channel に固有の APIKey
% Fields:
% 1: total_items
% 2: total_followers
% Channel に情報送信
data = {items_count, followers_count};
thingSpeakWrite(channelID, data , 'WriteKey', writeAPIKey);
% ここから新着記事のチェック(最新20個取ればOKでしょう・・)
url = "https://qiita.com/api/v2/tags/matlab/items?page=1&per_page=20";
tmp = webread(url,opts);
% 投稿時刻をチェック(TimeZone は日本時間に設定)
created_at = datetime(vertcat(tmp.created_at),...
'InputFormat', "uuuu-MM-dd'T'HH:mm:ss'+09:00",'TimeZone','Asia/Tokyo');
titles = string({tmp.title}');
urls = string({tmp.url}');
item_list = timetable(titles, urls, 'RowTimes', created_at,...
'VariableNames',{'titles', 'urls'})
% 新着かどうかのチェック
% このスクリプトは 1時間に1回実行する設定にします。(ThingSpeak の Time Control 設定)
% なので、、現時刻から1時間以内に投稿されていればそれは新着記事とします。
interval = duration(1,0,0);
tnow = datetime;
% ThingSpeak が動いているところでは TimeZone が UTC であるところに注意
tnow.TimeZone = 'UTC';
trange = timerange(tnow-interval,tnow) % 過去一時間以内の投稿だけを抽出
newitem_list = item_list(trange,:);
% ThingTweet 設定
tturl='https://api.thingspeak.com/apps/thingtweet/1/statuses/update';
api_key = 'XXXXXXXXXXXXXX'; % Twitterをリンクして APIKey を取得してください。
options = weboptions('MediaType','application/x-www-form-urlencoded');
options.Timeout = 10;
tweetFlag = true;
% 新着の数だけ呟きます(無ければ呟かない)
for ii=1:height(newitem_list)
% 投稿文
status = "#Qiita #MATLAB" + newline;
status = status + newitem_list.titles(ii);
status = status + newitem_list.urls(ii);
disp(status);
if tweetFlag
try
webwrite(tturl, 'api_key', api_key, 'status', status, options);
catch ME
disp(ME)
end
end
end