【告知】MakeYourDayは近日中にサービス停止します。
ご好評いただいてきました MakeYourDay ですが、物理的な事情によりサービスを停止します。
サービス停止日は10/19頃を予定しています。
10/18分をもって停止しました。
700人を越えるユーザ様にご利用いただいていますが、Twitterとはてなブックマーク等を合わせて毎日1000通を越えるはてなダイアリー投稿メールを連続して送っており、さくらインターネットレンタルサーバのメールサーバにスパム扱いされて送信を拒否されています。*1
はてなダイアリーAtomPubを使う*2・Gmailなど他のSMTPサーバを使う*3・新規登録を中止して既存ユーザだけで続ける・自分のfollowing/follower関係だけ救済する*4などを考えましたが、いずれも明朗な解決策とはいえず、サービスを停止することに決めました。
Twitterのログを投稿する部分のスクリプト(一部修正済み)を下記に掲載します。
SMTP認証周りはさくらのレンタルサーバ スタンダードでの仕様です。cronで毎日午前3時頃に動かしていました。
require 'net/smtp' require 'net/http' require 'nkf' mailserver="さくらID.sakura.ne.jp" maildomain="さくらID.sakura.ne.jp" mailid="さくらメールID@さくらID.sakura.ne.jp" mailpass="さくらメールIDパスワード" mail="さくらメールID@さくらID.sakura.ne.jp" backupmail="バックアップ送信用メールアドレス" hatenad={"はてなID" => "はてなダイアリー投稿用アドレス"} #"@d.hatena.ne.jp"と".g.hatena.ne.jp"は省く twitter={"はてなID" => "ツイッターID"} twittertitle={"はてなID" => "はてなダイアリー投稿時のタイトル"} #"[ライフログ]今日のツイッター"とか t=Time.now-60*60*24 $yesterday=Time::mktime(t.year,t.month,t.day,3,0,0) #午前3時から現在までのログを投稿 ### スクレイピング def fetch(p,id) rt=0 begin body = Net::HTTP.get( "twitter.com" , "/"+id+"?page="+p.to_s ) rescue Exception => err sleep 10 rt+=1 retry if rt<3 $stderr.print err,":",id,"\n" $yesterday else $stderr.print "404:That page doesn't exist!:",id,"\n" if /That page doesn't exist!/=~body body.split(/<\/ul>|<\/td>/).each{|line| if p==1 && /<p class="entry-title entry-content">\s*(.+)\s*<\/p>\s*(<a href="http:\/\/twitter\.com\/[^\/]+\/statuses\/\d+">\.\.\.<\/a>|)<div style="float:right;margin-top:-5px;"><div id="status_actions_\d+" class="status_actions">\s*<\/div>\s*<\/div>\s*<p class="meta entry-meta">\s*<a href="http:\/\/twitter\.com\/[^\/]+\/statuses\/(\d+)" class="entry-date" rel="bookmark"><abbr class="published" title="(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d)\:(\d\d)\:\d\d\+00\:00">/=~line $comment << $1 $link << $3 $date << Time::mktime($4.to_i,$5.to_i,$6.to_i,$7.to_i,$8.to_i)+60*60*9 elsif /<span class="entry-content">\s*(.+)\s*<\/span>\s*(<a href="http:\/\/twitter\.com\/[^\/]+\/statuses\/\d+">\.\.\.<\/a>\s*|\s*)<span class="meta entry-meta">\s*<a href="http:\/\/twitter\.com\/[^\/]+\/statuses\/(\d+)" class="entry-date" rel="bookmark"><span class="published" title="(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d)\:(\d\d)\:\d\d\+00\:00">/=~line $comment << $1 $link << $3 $date << Time::mktime($4.to_i,$5.to_i,$6.to_i,$7.to_i,$8.to_i)+60*60*9 end } $date[-1] ? $date[-1] : $yesterday end end ### メイン hatenad.each{|user,mailto| next if mailto.to_s=="" || twitter[user].to_s=="" $mailout="" page=1 $last="" $comment=[] $link=[] $date=[] while page<11 && fetch(page,twitter[user])>$yesterday #11ページから先のpostは破棄 page+=1 end $comment.each_with_index{|c,i| mailbody="" if $date[i]>$yesterday mailbody << "[http://twitter.com/"+twitter[user]+"/statuses/"+$link[i]+":title="+("0"+$date[i].hour.to_s).slice(-2,2)+":"+("0"+$date[i].min.to_s).slice(-2,2)+"] " mailbody << c.gsub(/<a href="([^\/][^"]+)"[^>]*>[^<]*<\/a>/,'\1').gsub(/<[^>]*>/,'').gsub(">",">").gsub("<","<").gsub(""",'"').gsub("&","&") mailbody << "\n" end $mailout=mailbody+$mailout } ### メール送信 if $mailout!="" retry_count=0 begin address=mailto+'@d.hatena.ne.jp' address=mailto+'.g.hatena.ne.jp' if mailto=~/@/ Net::SMTP.start( mailserver, 25, maildomain, mailid, mailpass, :login ) {|smtp| smtp.send_mail <<EOM, mail, address, backupmail From: #{mail} To: #{address} Subject: =?iso-2022-jp?B?#{NKF.nkf('-EjMB',twittertitle[user])}?= Content-Transfer-Encoding: 7bit Content-Type: Text/Plain; charset=iso-2022-jp #{NKF.nkf('-Wj',$mailout)} EOM } #↑はてなダイアリー投稿時のタイトルがEUCなので'-EjMB' rescue => err $stderr.print user,":",address,":",err,"\n" retry_count+=1 if retry_count<2 sleep 10 retry end end end }
*1:「550 5.7.1 Command rejected, Your sent mails reached the limit.」というエラーですが、送信済みメールはサーバに蓄積されておらず、毎日途中までは送信成功しており、スパムと見做されて拒否されていると考えていいと思います。
*2:新たにはてなダイアリーのパスワードを預かる必要があります(追記:LoudTwitterというサービスがあるようです)。現状はてなダイアリー投稿用メールアドレスを預かっているのも充分危険ですが、ダイアリー投稿しかできませんし、ユーザー側で再設定できるので。
*3:結局スパム扱いされることになるでしょう(追記:Gmailは500通/日らしい)。自前でメールサーバを立てるのはメンテナンス負担が大きい。
*4:不公平。