LINE Messaging APIでオウム返しbotを作りながらRuby on Railsをかじる

前回の記事でherokuを導入した目的は、LINE botを作ってみようと思ったからです。
さっそく下記の記事を参照して、もっとも基本的なオウム返しbotを作成してみました。
qiita.com
これを教材にRuby on Railsの言語仕様やLINE Messaging APIの仕組みについて学んだことを書き残しておきます。
コードは上記記事からの切り貼りなので、単純に作り進めたい人は元記事を参照してください。

はじめる前に

LINE Messaging APIには前身となるLINE botと呼ばれていたバージョンがあり、使い方がかなり違います*1
情報を探すときにはどちらのバージョンを使っている記事なのか注意しましょう。

routes.rbとController

RailsにおけるMVC(モデル/ビュー/コントローラ) - Ruby on Rails入門
サーバーにURLのリクエストが来たとき、何を返すかをroutes.rbに記述する。
今回の場合は(コメント部筆者追記)

Rails.application.routes.draw do
  post '/callback' => 'linebot#callback'   #post '/URI' => 'コントローラ名#メソッド'
end

ここでlinebotはapp/controllers/linebot_controller.rbを暗黙的に意味している*2
コントローラを生成するときは、Terminalから

$rails generate controller linebot

を叩く*3
これで、/callbackのリクエストはlinebot_controller.rb内の

class LinebotController < ApplicationController
…中略…
  def callback

と紐つけられた。

linebot#client

    def client
      @client ||= Line::Bot::Client.new { |config|
        config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
        config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
      }
    end

def callback ~ endがメソッドの定義範囲。
@で始まるのはインスタンス変数(Javaでいうフィールド)*4

a ||= xxx

この記法は自己代入。aがFalseか未定義ならxxxを代入。

newでインスタンスを生成しているっぽいが、引数は|config|ととらえて、引数を渡す前の処理をブロックの部分に追記できると理解するのが良さそう*5

オブジェクト.メソッド{|ブロックパラメータ|
  # ブロック
}

ブロックパラメータというらしい。

戻り値がないじゃん、と思うのだが、Rubyは最後に評価した値が戻るらしい。つまりここでの戻り値は@client*6

linebot#callback

      body = request.body.read

突如出てくるrequestオブジェクトは親クラスであるActionControllerで定義されていて、ブラウザからのリクエストに含まれる情報を持っているオブジェクトを取得できる*7

      signature = request.env['HTTP_X_LINE_SIGNATURE']
      unless client.validate_signature(body, signature)
        error 400 do 'Bad Request' end
      end

request.envは指定されたヘッダ情報を返す。request.headersと同義?*8ここではlinebot#clientで意図したLine Botからのリクエストかどうかを判定している。
unlessはif notと同義。

      events = client.parse_events_from(body)
  
      events.each { |event|
        case event
        when Line::Bot::Event::Message
          case event.type
          when Line::Bot::Event::MessageType::Text
            message = {
              type: 'text',
              text: event.message['text']
            }
            client.reply_message(event['replyToken'], message)
          end
        end
      }

parse_events_fromでbodyに含まれているイベントのコレクションが返ってくるので、ひとつずつ調べて(each)、テキストメッセージの場合のみメッセージを作成する。
このときeventsの要素がeach内で変数eventに展開されているのだが、前述のブロックパラメータの挙動とはちょっと違っている。こちらはイテレータと呼ばれているらしいが、記法が同じだけで実装が違うのか、やはり同じ実装によるのか?
なお、この分岐はifで良いような気がするが、別のイベントを拾いたくなったときのためにcaseになっているのだろう。

messageの右辺はハッシュの記法で、キー:値。

{ a:"aaa", b:"bbb" }

感想

なんだか暗黙のルールや記号が多くて読みにくい…文章的に書けそうな気はするけども。
次はデータベースを使ってみよう。

Rubyド素人がherokuをGetting Startedするよ(Mac)

元旦から暇人なのでherokuをはじめてみました。
Rubyもサーバーサイドも一切いじったことない私が、Getting startedを完走するまでにつまづいたところの備忘録です。
Let's get started!
devcenter.heroku.com

環境とか

Introduction

Heroku accountを取得する。
Heroku | Sign up
送られてくるメールにあるURLからアクティベートする。
RubyとBundlerのインストールが指示されているが、一旦これをすっ飛ばす。

Set up

Download the Heroku CLI for...でMac OS Xを選択して、ダウンロードしたapkを実行。
ターミナルを起動して、

$ heroku login
Enter your Heroku credentials.
Email: 登録メールアドレス
Password: 登録パスワード
...

ここまでいってから、Rubyを入れていきます。こちらを参考に。
[Ruby入門] 01.導入(Macに最新版のRubyを入れる) - Qiita

$ brew install rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

次にPATHを通します。こちらを参考に。
MacでPATHを通す - Qiita

$ vi ~/.bash_profile

Vimが開きます。Insertモードにして

i

PATHを入力

export PATH="$HOME/.rbenv/bin:$PATH"
if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi

Insertモードから出て、上書きして終了*1

esc
:w
:q

ターミナルに戻ったら、変更を反映させます。反映されたかどうかはechoで確認。

source ~/.bash_profile
echo $PATH

まず、herokuのRubyバージョンを調べる*2

heroku run "ruby -v"

表示されたバージョンのRubyをインストールする。執筆時点では2.3.5だったので、この表記で進めます。
インストールが成功したら、デフォルトではSystemバージョンになっているので変更しておく。

$ rbenv install 2.3.5
$ rbenv global 2.3.5

次にBundlerとPostgreSQLをインストール。
bundle installのpgインストールでエラー | EasyRamble

$ gem install bundler
$ brew install postgresql

Declare app dependencies

実際には、上の手順を踏まなかったために、ここでbundle installが失敗した。
食らったエラーと原因の一覧。

command not found

Bundlerがインストールされていない。

Your Ruby version is 2.5.0, but your Gemfile specified 2.3.5

RubyとGemfileのバージョンが違っている。

An error occurred while installing pg (0.20.0), and Bundler cannot continue.
Make sure that `gem install pg -v '0.20.0'` succeeds before bundling.

PostgreSQLがインストールされていない。

Run the app locally

ここでPostgreSQLが起動していないと

could not connect to server: No such file or directory

などのエラーで失敗する。

psqlでエラー発生時の対処 - のしメモ アプリ開発ブログ

$ cd /usr/local/Cellar/postgresql
$ curl -o fixBrewLionPostgresql.sh http://nextmarvel.net/blog/downloads/fixBrewLionPostgres.sh
$ chmod 777 fixBrewLionPostgresql.sh
$ ./fixBrewLionPostgresql.sh
$ pg_ctl -D /usr/local/var/postgres start

カレントディレクトリが移動してしまっているので、戻すのを忘れずに。

$ cd ~/ruby-getting-started

Provision add-ons

Please verify your account to install this add-on plan (please enter a credit card)

アカウントにクレジットカード情報を入力。Add-onが無料のものでも必要。

Use database

レコードが1件入っているていになっているが、テーブルは空なのでwidgetsにアクセスしたときにブラウザ側から自分で追加する。

$ heroku pg:psql

に入って出てこれなくなる。終了コマンドは¥q。helpを叩くと教えてくれる。

おわりに

無事完走できてよかった!

*1:これが噂の100万人を飲み込んだVim迷宮か…。Stack Overflow: 100万人の開発者を手助けするVim終了方法 | プログラミング | POSTD

*2:執筆時点のIntroductionにはRuby 2.3.4を前提と書いてあるが、gemfileには2.3.5が指定されている。トラップ…?

円筒形ガーメントバッグ Henty Wingmanを買ったよ

先日、友人の結婚式に出席するために前泊で移動する機会があったのですが、前日は私服で過ごしたかったこともあり、ガーメントバッグを購入しようと思い立ちました。
選定するうえで、私が絶対に譲れなかった条件は、革靴を収納できること
行き着いたのはHentyのWingmanでした。チャリ通勤で会社に着いてからスーツに着替えたい!みたいなニーズを叶えた円筒形ガーメントバッグです。
Henty Wingman Messenger 2 | MJSOFT (mjsoft.co.jp)

youtu.be

どれにしようかな

両肩で背負えるBackpackと斜め掛けのMessengerの二種類がありますが、私はMessengerを選びました。
理由は、

  1. 容量が小さそうなので、普段使っているリュックサックをメインにしたい
  2. キャリーバッグを持っているときは持ち手にくくりたい

この二点を鑑みるに、ストラップが二つあるBackpackだと取り回しが悪いと判断しました。

Wingmanより一回り大きいCopilotというシリーズもありますが、私はサブバッグとして使うので小さいWingmanにしました。それぞれのシリーズに、さらにサイズ違いのCPTとSTDがあり、CPTは女性用の小さいタイプなので注意が必要です*1

開封の儀

六角形のパッケージで届きます。

開けて中身を引き出すとこんな感じ。ハンガーが曲がって届いたというレビューが多数ありましたが、私の場合は全く問題ありませんでした。というか、どうしたらこれが曲がるのか分からないレベル。

使ってみよう

今回詰めてみた荷物はこちら。パジャマ代わりの薄手のスウェット一式と、二泊分の下着類です。革靴は…正確にわからないですが26~27cmくらいでしょう。

内側のジムバッグに詰めていきます。タオルや多少の洗面用具ならまだ入りそうです。

ハンガーはこのように外側の部分と連結できるようになっています。

また、ジムバッグも同じように固定できるので、ジムバッグ部分だけを持っても分解してしまうことはありません。
ぐるっと巻いて出来上がり。

レインカバーも付属しています。

良かったところ

もちろん、スーツを収納することに関しては全く問題なく、作りもしっかりしていて概ね満足です。
特に内側のジムバッグだけを分離して使えるのはとても便利です。専用のショルダーストラップが付属しています*2

あとPC用バッグが付属してますが、入れる気が無かったので使ってません*3

イマイチなところ

これは予想通りですが、メインバッグに使うには容量が心許ないです。靴と服を入れたら、他にはほぼ何も入りません。
また、ジムバッグが円筒形なので四角いものの収納が苦手です。スーツケースやリュックに収納することが前提の長方形のメッシュバッグなどは、先の写真のように丸めて入れることになります。丸められないものは…あきらめましょう。

Messengerに特有の問題だとは思いますが、やはりある程度の距離を歩くなど振動を伴う運動には向いていません。どんどんずり落ちてきます*4
これ一つだけで何とかしたい!という人にはCopilot Backpackがおすすめです。

*1:単に容量が小さいだけでなく、肩幅部分が狭いというレビューあり。

*2:ガーメントバッグとして使うときには、ショルダーストラップは取り外す必要があります。コンパクトなので、中にしまってもさほど嵩張りません。

*3:そんなとこ入れたら明らかに曲がるやろ…というレビューは多数。

*4:自転車だと大丈夫なんでしょうか?

「内向型人間のすごい力」を読んで人生を振り返る

スーザン・ケイン著「内向型人間のすごい力」という本を読みました。
面白いと思った部分を、自分の経験を交えて引用していこうと思います。

練習はひとりでするものじゃないの?

中学生の頃、ギターにのめり込んでいた私は、ギターを触ったこともないクラスメイトに言われました。
「今度、ギター教えてよ!」
そんなの、ギターと教本買って自分で練習するだけじゃないのか?案の定、彼とギターや音楽について語り合うことはありませんでした。

これまで会った発明家やエンジニアの大半は僕と似ているー内気で自分の世界で生きている。

もしきみが、発明家とアーティストの要素を持ったたぐい稀なエンジニアならば、僕はきみに実行するのが難しい助言をしようーひとりで働け。独力で作業してこそ、革新的な品物を生みだすことができる。委員会もチームも関係なく。

p116、スティーブ・ウォズニアックの自伝から引用

昨今では技術の規模が大きくなってしまい、独力で達成しうるイノベーションの機会は失われつつあるように思いますが、実際、独力による練習や学習には効果があるようです。

バイオリン専攻の学生を3つのグループに分けた。第一のグループは、将来世界的なソリストになれるほどの実力を持つ学生たち。第二のグループは、「すぐれている」という評価にとどまる学生たち。第三のグループは演奏者にはなれず、バイオリン教師をめざす学生たち。そして、全員に時間の使い方について同じ質問をした。
その結果、グループごとに驚くべき違いがあることが判明した。3つのグループが音楽関連の活動にかける時間は同じで、週に五〇時間以上だった。課題の練習にかける時間もほぼ同じだった。だが、上位の二つのグループは音楽関連の時間の大半を個人練習にあてていた。

p128、心理学者アンダース・エリクソンの実験

練習にかける総時間は同じ、というのが興味深いですね。

つぎつぎにさまざまな趣味や活動に興味を持つ外向型と違って、内向型はひとつのことに打ち込むことが多い。これは彼らにとって重要な長所である。なぜなら、自尊心は能力に由来し、その逆ではないからだ。ひとつのことに強い愛着を持って没頭することは、幸福と恩恵へと通じる確実な道だと立証されているのだ。才能や興味を育むことは、子供にとって大きな自信の源になりうる。

p420

小さい頃から、他人にはできない特技を持っていることが、自分が必要とされる条件だと思っていました。いまは、秀でたところが無ければ価値が無いとまでは思わなくなりました。しかし、そう思っていたときに身に着けた能力や、周囲を見渡して必要とされるであろう役割を見つけられる素養は、いまもとても役に立っています。

開放的なオフィスは誰のため?

中学生の頃、私はテレビとラジオを同時につけながら勉強をしていました。いまでは音楽を聞いていると読書の気が散るようになってしまい、当時はなぜそんな芸当ができたのか不思議なくらいです。

外向型の人と内向型の人に単語ゲームをするように指示する。ゲームは難しく、試行錯誤を重ねて、鍵となる原理を見つけなければならない。その最中に、ランダムに雑音が聞こえてくるヘッドホンをつける。ヘッドホンの音量は自分にとって「最適な」レベルに合わせるように言われる。その結果は、平均して、外向型の人は七二デシベル、内向型の人は五五デシベルだった。

p199

集中力の高まる環境ノイズの音量は人によって異なる、ということですね。私の職場は例によって大部屋のオフィスですが*1、今後さらなる大部屋化を計画しているようで…どうなることやら。

コミュニケーション能力ってなんなの?

私は小学校や中学校でしばしば学級委員の役割をあてられていました。学級委員というと、クラス会を取りまとめたり、体育祭や合唱コンクールなどの行事を先導するために、人前に立つことが多くあります。
一方、休み時間はひとりやふたりで過ごすことが多く、休みの日には一日中部屋にこもって絵を描いたりパソコンをいじったり楽器の練習をしたりしていました。このため、役割としてリーダーを演じることはできても、クラスの中心にいる人気者になることは、自分には向いていないと感じるようになりました。

外向型のふるまいがとくに上手な内向型は、「セルフモニタリング」と呼ばれる特質の得点が高いことがわかった。セルフモニタリングがうまい人は自分の言動や感情や思考を観察して、周囲の状況から必要性に応じて行動をコントロールできる。

彼らは郷に入れば郷に従うのだ。

p338

成長するにしたがい、自分の性格を受け容れながら、求められている役割を演じることができるようになっていきました。一方で、就職活動をはじめとして外交的な振る舞いが評価される状況を目の当たりにすると、自分の「コミュニケーション能力」の低さに失望することも多々ありました。

心から大切に思っている仕事を進めるために外交的にふるまっているのであって、この仕事が終われば本物の自分に戻ってゆっくりできる、そう自分に言い聞かせることもない。それどころか、心のうちで、自分ではない人間になることが成功への道だと言い聞かせていたのだ。これではセルフモニタリングではなく、自己否定だ。

p346

自己を見失っていた頃の自分に言い聞かせたいですね。就職活動では、あえて外交的に装わないことで、不必要に社交性を求められる職場からお祈りされる戦略を取りましたが、これは上手くいったと思います。

回復のための場所を見つけるのは、簡単とはかぎらない。土曜日の夜、あなたは暖炉のそばでゆっくり読書していたいのに、配偶者が大勢の仲間と食事に行きたいとしたら、どうすればいいのだろう?電話セールスの合間にはひとりで自室に閉じこもりたいのに、会社が職場をオープンオフィスに改装したら、どうすればいい?もしあなたが自由特性を実践しようとすれば、家族や友人や同僚の助けが必要だ。リトルはそれを「自由特性協定」を結ぶことと呼んでいる。

p352

一人暮らしをしている期間も長くなってきたので、身近な人との関係の保ち方はこれからの課題だと思っています。
また、大人なって共通のバックグラウンドを持たない人々との「世間話」を求めらる機会が増えてきました。

一般には、初対面の人と話をするとき、おたがいにリラックスするためにちょっとした無駄話をしてから、本題へと入っていくものだ。敏感な人々は、その逆を実践しているようだ。

p246

この特性を自覚しておくと、少し楽になれそうです。

これからの人生のために

私は「浮き沈みがなくて安定している」と評されることが多いですが、自分の中ではかなり大きな感情の波があると思っています。

セリアの問題は感情が欠けていることではない。コントロールを失わずに感情を表現することができないのだ。

まるで彼女は二つのギアを持っているかのようだー感情を溢れさせるギアと、超然とした冷静沈着さのギアと。

p369

感情を顕にしまいと思うがために無口になってしまいがちなので、うまくバランスを取っていきたいですね。

内向型の子供のためにあなたができる最良のことのひとつは、新しい体験に対応するのを助けてやることだ。

彼(彼女)は、人間との接触を恐れているのではなく、目新しさや過度の刺激によって不安を感じているのだ。

p400

私の両親はこの点、とても上手く育てくれたと思い感謝しています。当時は、放ったらかしで愛情が無いとふさぎ込むこともありましたが。私も子供をもつ機会があれば、同じように見守ってあげたいと思います。

過去の挫折体験をどのように語るかは、現状にどれほど満足しているかに大きく影響される。現在が幸福でない人は、過去の挫折を否定的に語る傾向が強く(たとえば「妻が去ってから、僕はすっかり変わってしまった」)、前向きに生きている人は過去の挫折を「一見すると不幸に見えて、じつはありがたいもの」として肯定的に語る傾向がある(たとえば、「離婚はなによりつらい体験だったけれど、再婚した妻との暮らしはもっと大きな幸福をもたらしてくれた」)。

p428

肯定的に語る人が幸福になるのか、幸福な人が肯定的に語るのか、因果がどちらにあるか定かではありません。私は「そのときどきの最善の選択の積み重ね」であると思っているので、過去は肯定的に捉えています。もし今後、過去を否定的に捉えることがあれば、いちど立ち止まって考え直してみたいと思います。

iOS11以降でPQI Air Card 2を使う方法(無料)

WiFi接続できる便利なSDカードアダプタPQI Air Card 2ですが、公式アプリの更新が止まっていてiOS11以降では起動しなくなります。

itunes.apple.com非公式の有料アプリもあるのですが、こちらの更新も止まっていて対応状況が不明です。*1
itunes.apple.com
AirPict for PQI Air Card

AirPict for PQI Air Card

  • itok
  • 写真/ビデオ
  • ¥240
数百円とはいえ、動くか分からないものに投げ銭するわけにもいかない…
というわけで調べていたところ、無料アプリで接続する方法を発見しました。

ftp/tenet が開いてる?
https://plus.google.com/+KenichiroMATOHARA/posts/5Ufnzs6qs1p

ということはFTPクライアントがあればいいわけですね。

Try Documents by Readdle. Despite the name, it is a very good file manager app with FTP and SFTP support. And it is free :)
Best iOS FTP client? ... | MacRumors Forums

itunes.apple.com

Documents by Readdle

Documents by Readdle

  • Readdle Inc.
  • 仕事効率化
  • 無料

手順
  • Documents by Readdleをインストール
  • サービス → アカウントを追加 → FTPサーバ と進む
  • ホストに「192.168.1.1」を入力、タイトルには好きな名前をつけて保存

  • デジカメ側のWiFiを起動、iOS側から接続する
  • Documents by Readdleのサービスに先ほど作ったアカウントをタップする


これでSDカード内に入れます。どのフォルダに写真が入っているかは、デジカメの種類によります。
写真は一旦ダウンロードフォルダに移動させましょう。iOS内の「写真」に直接入れようとするとなぜかアプリが落ちるようです。*2「写真」が表示されてない場合は
設定 → ファイルマネージャ → 写真を表示
をチェックしてみてください。

ついでに

PQI Air Card 2に接続中にキャリアの回線が使える設定もしておくと便利です。
goryugo.comhttp://goryugo.com/20140101/pqi_setting/

無印良品の洗濯表示タグが長すぎる問題

無印良品は、かつてバイトをしていたこともあって、とても愛着があって今もよく利用しています。
一時期から、世界中で展開する商品を一元化する流れからでしょうか、洗濯表示タグが異様に長くなってしまいました。
まぁタオルくらいなら許せる気がします。しかし先日買った「携帯用スリッパ」には、さすがにガッカリしました。
www.muji.net

公式画像でもチラ見えしてますが、実際には…

誰がこんなタグをぶら下げて履こうと思うのか…
いくら素敵な製品をデザインをしても、こんなもの付けられたら台無しですね。

こういうことがなぜ起こるかというと、製品設計をしている人が、最終的に顧客の手に渡る状態を知らない、ないし、手出しできないようになっているからだと思うんですね。
よくある例だと、雑誌のインタビューを受けた人が、いざ掲載された記事を読んでみたら、全く意図と違った脚色をされていた、とか。

自分の役割を果たせば仕事は終わり、ではなくて、その先の仕事がどうなっているか、欲を言えばさらに踏み込んでユーザーが実際はどう使っているのか、まで意識できるようにありたいものですね。

Excelセルにサジェスト(予測変換)機能をつける

仕事上、膨大な品目リストから一つの項目を選ばせることが多々あります。
通常は検索やフィルターを使うのですが、リストが別シートにある場合など、行き来する必要があり操作が煩雑になります。
こんなとき、Googleみたいに候補を表示してくれたらいいのに良いのに…なんて思う大抵のことは、誰かがやっている。

language-and-engineering.hatenablog.jp

suugleblog.blogspot.jp

先人は偉大ですね…!ありがとうございます。
この2つを使ってみて色々と気になるところがあったので、コードを整理しつつ両方を切り替えられるようにしてみました。VBEの操作方法や実際の挙動は元記事を参照してください。

標準モジュール

検索セルのあるシート

候補リストを別シートに退避すべきか?

”入力規則のFormula1に直接突っ込める文字数は255文字までの制限があるらしい。”
とのことですが、私の環境ではもっと突っ込めました。一つの項目がよほど長くない限りは、一つ目の方法で良さそうです。つまり、

Const USE_SUGGEST_LIST_SHEET = False

で、ほとんどの場合は十分だと思います。
候補リストを別シートに移した場合の不具合として、検索セルが複数あると、最新の候補がすべてのセルに反映されてしまいます。たとえば、一つ目の検索セルを「はてな」で確定したのに、二つ目の検索セルに「Ya」と入力すると、一つ目のセルにも「Yahoo」「Yaplog」などの候補が入力されてしまいます。
ただ、入力規則に直接入れる方法で保存すると、次に開いたときに同じシートに手動で設定した入力規則が壊れていることが多いようです…。誰か、対策方法が分かったら教えてくださいm(_ _)m
(2017/10/25追記)
どうやら入力規則は255文字以上のリストを表示することはできるのですが、保存ができないためにファイルが壊れてしまうようです。
対策として、255文字を超える場合には省略を示すOVERFLOW_DESCRIPTIONをリストに追加して、それ以上の項目を追加しないように修正しました。他にも、255文字を超える場合のみ候補リストを別シートに退避させる(つまりUSE_SUGGEST_LIST_SHEET = True)ような実装も有効だと思います。
(追記以上)

主な変更点

Application.EnableEvents

参照元のコードのようにApplication.EnableEventsを標準モジュール内に置くと、複数の検索セルがあって同時に削除やペーストをしたときに再帰的に呼び出されてしまい、途中でエラーを出してFalseのまま関数が終了してしまうことがあります。*1
また、シート側で検索結果(例えば入力が確定したかどうか)に応じてシート内の他のセルも編集したいとき、シート側のApplication.EnableEventsの間に処理を入れることで、シートに依存した処理をまとめて記述でき、モジュールの再利用性が高まります。

FindからForeach if Likeに

Findは処理時間が遅いという指摘がされているのと、なぜかMatchCaseが上手く行かなかったのでForeachで辞書項目を回して比較するようにしました。
excel-ubara.com
処理が早くなっただけでなく、内容もわかりやすく簡潔に記述できていると思います。
大文字・小文字を区別したい場合は、

If strKey = "" Or UCase(item.Value) Like "*" & UCase(strMatch) & "*" Then

からUCaseを取り除いてください。*2

(2017/10/25追記)
Like比較に使われるワイルドカード(?、*、#、[、])が含まれた語でも検索できるようにしました。なお、strMatchという別の変数を使ったのは、strKeyを完全一致の判定に使用しているためです。*3
(追記以上)

なお、辞書範囲から空白項目を除去するためにSpecialCellsを使っています。この関数は特定の種類のセルのみを抽出できる関数ですが、数式と文字列のどちらかを指定する必要があります。冒頭のDICTIONARY_CELL_TYPEで指定してください。該当セルがない場合、ランタイムエラーになります。ちょっとクセのある関数なので、不具合が生じる場合はMSDNを参照してみてください。
Range.SpecialCells メソッド (Excel)

確定時の処理と戻り値

二つ目の記事では候補が1つになった場合に確定としていましたが、辞書に「goo」と「Google」がある場合に確定できません。本記事のコードでは検索語と候補の文字列が完全一致した場合にのみ確定としています。
戻り値には完全一致した辞書項目のセルを返しています。完全一致した場合のみの処理は以下のように記述できます。

If Not( Suggest(DicSheetName, DicRangeAddress, target, target.Count = 1) Is Nothing ) Then
    '処理内容
End If

また、辞書シートの検索範囲以外から情報を得ようとする場合、たとえば、A列の検索範囲に「Google」などの項目が入っていて、B列に「https://google.com」などのURLが格納されている場合、

Dim foundCell As Range
Set foundCell = Suggest(DicSheetName, DicRangeAddress, target, target.Count = 1)
If Not( foundCell Is Nothing ) Then
    '処理内容、例えば
    'target.Offset(0,1) = foundCell.Offset(0,1)
End If

といった記述が可能です。*4

注意事項

辞書に同じ項目が複数存在するときは、最初の項目が返ってきます。
記事に焼き直したところはデバッグしてないので、もし間違いがあったら教えてください。

*1:この場合、復帰するにはイミディエイトウィンドウなどからApplication.EnableEvents = Trueに設定する必要があります。

*2:And→Orに修正しました(2017/10/25)

*3:現行の実装では"[]"を検索することはできません。また、Replaceは関数とRangeオブジェクトのメソッドとでは実装が異なるようで注意が必要でした。参照:【VBA入門】Replace関数とReplaceメソッドで文字列の置換 | 侍エンジニア塾ブログ | プログラミング入門者向け学習情報サイト

*4:Range.Offset プロパティ (Excel)