Nginx Helper 2.0.1でコメント時にパージが動かない。

Nginx Helperで個別記事のキャッシュをパージできない。 – return $lock;
これとは別の問題です。2.0.1の段階でコメントがついた時に個別記事のパージが動かなくなりました。前回とは異なり、個別記事のURLは正しいようです。

バージョンアップの度に動かなくなることが多いプラグインのため、以下から適当に1.9系のバージョンを持ってきたところ動作しました。やはり2.0.x系に問題がありそうです。修正されるまでバージョンアップはなしで運用かなと思います。
Releases · rtCamp/nginx-helper · GitHub

調べてみると同じ問題に当たっている方がいて、やはり1.9系に戻してるようです。
Nginx-Helper で上手いことキャッシュのパージが行われない問題 | ぶっちろぐ

カービィカフェのキャンセルを通知するLINE botをPython3で作る。

書こうかやめとくか迷ったネタだったのですが、以下みたいな記事があって、「あ、こういうの書いていいんだ」と思ったので書くことにしました。
年末年始の新幹線をPythonで予約する - ふしみのブログ


カービィカフェ | トレタかんたんウェブ予約をChrome DevToolsで開くと、空き確認用のAPIが存在している事がわかるので、それをそのまま実行してLINE Botで通知すればいいです。

DevToolsのNetwork

準備

LINE Developersから適当にBotを発行してアクセストークンを取得します。For Developerプランだと(友達に登録できる人数に制限がありますが、)無料でメッセージのPushができます。自分用のBotならDeveloperプランで十分でしょう。

チャネル基本設定画面から自分のUserIDとBotのアクセストークンを確認します。今回はCallbackが必要ないのでCallback URLの準備は不要です。

トークンの取得

必要なライブラリをpipで導入します。今回は公式のLINE Bot用のSDKを使いました。
line/line-bot-sdk-python: SDK of the LINE Messaging API for Python.

sudo python3 -m pip install line-bot-sdk

以下のコードをDoS攻撃にならない間隔(2分に1回とか)で定期的に回します。ちなみにコード自体は別のところで公開したやつの改良版です。

import sys
import json
import urllib.request
from linebot import LineBotApi
from linebot.models import TextSendMessage
from linebot.exceptions import LineBotApiError

LINE_ACCESS_TOKEN = '取得したアクセストークン'
LINE_USER_ID = '自分のUser ID'
line_bot_api = LineBotApi(LINE_ACCESS_TOKEN)

restaurant_id = 'jta9560wTJF-1OGWHJwGdFyX1A3dE4wjK4ChQ2pe6kM'
year = '2019' # 空きを確認したい年
month = '1' # 空きを確認したい月
seats = '2' # 席数

url = 'https://yoyaku.toreta.in/web/v1/web_reservations/{}/days.json?year={}&month={}&seats={}'.format(restaurant_id, year, month, seats)

try:
    req = urllib.request.Request(url)
    res = urllib.request.urlopen(req)
    body = json.loads(res.read().decode('utf-8'))
except urllib.error.HTTPError as err:
    print(err.code)
    sys.exit(1)
except urllib.error.URLError as err:
    print(err.reason)
    sys.exit(1)

days = body['result']['days']

day = 1
message = ""

for results in days:
    if results is not None:
        for result in results:
            if result['label'] is not None:
                message += month + '/' + str(day) + ' ' + result['label'] + '\n'
    day+=1

if message != "":
    #print(message)
    try:
        line_bot_api.push_message(LINE_USER_ID, TextSendMessage(text=message.rstrip()))
    except LineBotApiError as err:
        print(err)

空きが通知された。

稼働中のmetabaseを他のサーバに移行する。

本当はAlexa Skillの記事を書きたかったのですが、スクショとか取るのめんどくさくなってしまった。

あらまし

このブログと同じサーバでmetabase(0.31.2)を動かしていたのですが、-Xmxで指定してるヒープ領域を食いつぶす+Full GCが発生しまくる+他のサービスに影響が出そうなので引っ越すことにしました。(チューニング用のパラメータは以下を参考にしています。)

移動先はRaspberry Pi 3 Model Bしかなかったのでそこにしました。動くのか。

移行方法

metabase.db.mv.dbのSETTINGのurlを移行先のものにしたあと、metabase.db.mv.dbとmetabase.db.trace.dbをmetabase.jarと同じ場所において起動したところ、問題なく動作しました。ダッシュボードや管理者の設定も正しく生きています。
urlは移行先のものにしなくても起動できそうな気がします。多分。
Dockerの場合は試していませんが、おそらくdbファイルをホストからマウントすればいけるんじゃないでしょうか。

問題点(未解決)

起動がめちゃくちゃ遅いです。移行前はおよそ3分で起動していたのですが、移行後は7分程度かかるようになりました。ダッシュボードにあるグラフの描画も、移行前と比べて明らかにLoading状態が長いです。
チューニングの問題なのか、ラズパイのスペックが足りてないのか、問題の切り分けができていないので調査して改善できそうならどうにかしたいです。

コンタクトフォームにreCAPTCHA v3を導入した。

コンタクトフォームからのスパムメールが2日に10通くらいのペースで来ていて、困るほどの数でもないけどどうにかしたいレベルにはなってきたので、reCAPTCHA v3を導入してみました。

「私はロボットではありません」選ぶ必要なし 新「reCAPTCHA」Googleが公開、ユーザーは何もしなくてOK – ITmedia NEWS
reCAPTCHA v3 | reCAPTCHA | Google Developers

Akismetでもよかったのですが、今までコメントフォームに使ってみて誤検知が結構多い印象だったのと、公開されたばかりなので試してみたいこともあり、こっちにしてみました。
判定の流れとしては以下のとおりです。

  1. クライアントサイドでtokenを取得
  2. 取得したtokenを元にサーバサイドでverify用のAPIを呼び出す
  3. APIから返ってきた結果をもとに、ページにアクセスしてきたのが人間かロボットかを判定する

クライアントサイドの導入方法

  1. 管理ページでAPI実行用のキーを発行する。
  2. 管理ページにjsロード用のscriptタグのスニペットが表示されるので、reCAPTCHAしたいページのhead内に埋め込む。
  3. 管理ページにreCAPTCHAのexecute用のscriptタグのスニペットが表示されるので、reCAPTCHAしたいページのどこかしらに埋め込む
<script>
  grecaptcha.ready(function() {
    grecaptcha.execute('Site key', {action: 'action_name'}) // action_nameはサーバサイドの処理で使用する
      .then(function(token) {
        // Verify the token on the server.
    });
  });
</script>

サーバサイドの導入方法

  1. クライアントからtokenを受け取る。
  2. Secret keyとtokenを使用してスコアの問い合わせを行う。APIからのレスポンスの形式はドキュメントを参照
curl https://www.google.com/recaptcha/api/siteverify  -X POST -d "secret=secret&amp;response=token"
{
    "success": true,
    "score": 0.9,
    "action": "contact_form", // クライアントサイドで決めたaction_name
    ...
}

しきい値を決めて、それを下回るならエラーを返す等の処理をサーバサイドに書きます。

コンタクトフォームはContact Form 7を使用しているのですが、そのうちプラグイン側がv3に対応しそうなのと、自分で改造するのが面倒なので、reCAPTCHA用のエンドポイントを設置して、「エンドポイントからのレスポンスが200以外だったら、送信ボタンのDOMをremoveした上でsubmitイベントを無効化する」とかいう意味があるんだかないんだかわからない処理を入れておきました。
DOMの処理終わる前に送信されたら意味ないし、そもそもスパムの送信元がJS無効化してたら詰むんだけどまぁものは試しなので…。
reCAPTCHA用のjsも本当は全ページに読み込ませないといけないのですが、スパムの送信元はどうせコンタクトフォームに直接アクセスしてきてるので、コンタクトフォームのページにだけ読み込ませています。

設置してから4日くらい経ちますが、スパムが3通くらいしか届いていないのである程度効果はあるのかなと思っています。

追記 2018/12/15

Contact Form 7がv3に対応したので用済みになりました。

だから私はQiitaに投稿しない。

最近のQiitaの記事の質が下がってきている事への考察 – Qiita
これ読んでいろいろ思うことがあったのでポエム。

メールで問い合わせ受けたときに何回か「この記事Qiitaに投稿してほしかった(Qiitaに投稿してくれたらもっと早く見つけられた)」と言われたことがあるんですが、私は多分Qiitaには行かないと思います。

ポエムとかJAVAの人の記事は論外として、何かしら記事書いても「質の高い記事を投稿しろ」って言われてしまうなら、じゃあQiitaには投稿しないわ、ってなっちゃう。
今までQiitaに投稿された色々な記事に助けられてきたけど、私の書く記事がそうなれるかって言ったらなれないんですよね。多分。

Qiitaって技術ブログのInstagramみたいだとずっと感じてて、見る分にはほんとに楽しいしすごいなぁって思うんですが、私は投稿するのきついです。
意識高い人やいけてる人がめっちゃキラキラした写真を投稿するように、いけてるベンチャーの人やバリバリのフリーランスの人やレベルの高いエンジニアがレベルの高い記事を投稿するのがQiitaで、Qiitaには質の高いものばっかりなきゃいけない、みたいな感じになってる気がします。(でもそれってほんとにQiitaと、Qiitaを見に来る人にとっていいことなんですかね?)
「質の高い記事だけ探して読むわ」って人が集まるんじゃなくて「質の高い記事だけ投稿しろ」っていう人が集まってるところに記事投稿しても自分が悲しくなるだけだなぁって。

ポエムも書きたいし自分の好きな言語だけで好きなものだけ作りたいので、私はこのブログでいいです。