3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

日本語プログラミング言語「なでしこ」Advent Calendar 2021

Day 3

なでしこさんでLINE Botを作りたい! ~なでしこの最新バージョンを答えてくれるLINE Bot~

Last updated at Posted at 2021-12-02

 結構放置して間が空いちゃいましたケド、前回作ったおうむ返しのボットを改良して、なでしこの最新バージョンを教えてくれるようにする話し。
 あと、プラグインには、プッシュメッセージや、友達全員に一斉にプッシュ(ブロードキャストメッセージ)送信できる機能を追加。
 アドベントカレンダーの記事ではありますが、例によって出来たの出来ないのと騒ぎます;

おさらい

 前の記事はアドベントカレンダー外なので、一応念のためリンクを貼っておきます。
 なでしこで、日本語でラインボットを作るべく色々頑張る話です。

①『LINE Botを作りたい! ~アカウントの作成とボットの設定から、おうむ返しボットを動かすまで~
 LINE Developersのアカウントを取得し、各種設定を行い、とりあえずLINEボット作成(node.js)をお試しするまで。

②『なでしこさんのプログラムをherokuで動かしたい!
 Herokuのアカウント取得して、なでしこのプログラムをherokuにデプロイして動かすまで。

③『なでしこさんでLINE Botを作りたい! ~おうむ返し+αのボットが日本語で作れたよ~
 プラグインを作って、なでしこからLINEmessagingAPIを使い、日本語でおうむ返しのLINEボットを作ってHerokuで動かすまで。

定型返信部分の改良

 本題の前に。
 前回はとりあえず、おうむ返し以外のキーワードに対する応答をもし~違えばもし~と、ひたすらもしの条件分岐で並べたのですが、キーワードと返信テキストをcsvファイルにして「返信メッセージリスト」を作成し、それを反復することにしました。
 こんなの。

reply_list.csv
なでしこ,誰でも簡単プログラマー{改行}https://nadesi.com/
なでしこさん,呼んだ?
{ユーザー名},{ユーザー名}さんって、すてきな名前だね☆

 忘れかけていましたが、cnako3なのでファイルの入出力が出来るんです。やったね!
 あっ、plugin_csv取り込むの忘れず。
 csv(カンマ区切り)、tsv(タブ区切り)のデータを扱うためのプラグインです。

なでしこさん マニュアル > plugin_csv

 基本プラグインなのでインストールは要りません。プログラム冒頭で取り込んでおけばOK。

!『plugin_csv』を取り込む。
返信メッセージリスト=「reply_list.csv」を開いて、それをCSV取得。

 返信メッセージリストを反復して、送られてきた語句がキーワード部分と合致したら、返信テキスト部分をLINE返信するだけだけど、{ユーザー名}{改行}だけ、なでしこの変数みたいに書いたら変換できるようにしといた。

//(一部)
返信メッセージリストを反復
  語句=対象[0]の『{ユーザー名}』をユーザー名に置換。
  もし、受信メッセージ=語句ならば、
    返信テキスト=対象[1]の『{ユーザー名}』をユーザー名に置換。
    返信テキスト=対象[1]の『{改行}』を改行に置換。
    イベントリスト[No]=返信テキストのLINEテキストメッセージを返信先へLINE返信。戻る。
  ここまで。
ここまで。

 これで、応答出来る語句を増やすのがカンタンになりました~♪

なでしこの最新バージョンを答えてくれるようにする

 そして本題。
 おうむ返しと定型の応答だけじゃアレなんで、「バージョン」と送ったら、v1とv3の最新バージョンを教えてくれる機能を追加したい。
 コレで実用的なボットになるね!(?)

v3の最新バージョンを取得する

 v3の最新バージョンを知る方法は、ここにあります。
 https://n3s.nadesi.com/nako_version.jsonをAJAXで取得すればいいんですね。簡単なJSONさんですよ♪

{
"version": "3.2.30",
"major": 3,
"minor": 2,
"patch": 30
}

 このversionのとこを返せば良さそう。

v1の最新バージョンを取得する

 v1は・・・? 何か手だてがあるかのう・・・と捜索したところ、RSSはありました。
 https://download.nadesi.com/v1/History.xml
 忘れかけてましたが、cnako3なのでxmlでも大丈夫。やったね☆
 htmlパースするやつ入れなきゃダメかも?

拡張プラグインのインストール。

 RSSのxmlを解析するために、nadesiko3-htmlparserを使います。

なでしこさん マニュアル > nadesiko3-htmlparser

 nadesiko3-htmlparserは、拡張プラグインです。
 拡張プラグインを使うためには別途インストールしなきゃなりません。

Node版プラグインを使う方法

インストール

cd desktop/nako3
npm install nadesiko3-htmlparser

取り込む

!『nadesiko3-htmlparser』を取り込む。

HTMLパース

 <item><title>にバージョンが入っているようなので、一番最初の<item>から<title>の内容を取得すれば良さそうなんですが、CDATAセクションから価を取る術が分からぬ~。
 ・・・こんなの。

<title><![CDATA[1.582]]></title>

 もっと賢い手立てがありそうな気もしますけど、とりあえず正規表現マッチでこんな感じ?

# v1のバージョンを取得
v1バージョンURLへGET送信した時には
  対象をHTMLパース。
  ITEM=「item」のDOM要素取得。
  ITEMをDOM配列変換。
  タイトルはITEM[0]から「title」をDOM子要素検索。
  タイトルのHTML取得して、「/\[CDATA\[(.*?)\]\]/」で正規表現マッチ。
  v1=抽出文字列[0]
ここまで。

 うーん、1.582ですって。なでしこのトップページに記載されているバージョンWindows版 v1.583 (2021/07/11)と違いますね・・・
 でも、RSS的にはそうなってるんだからしょうがない!(のか?)
 nakopadの「なでしこについて」で見られるバージョンはバージョン:1.583、「更新履歴を見る」では2021/07/10 version 1.582
 なんかマイナーチェンジがRSSに反映されてないっぽい?ケド、ま、次バージョンアップしたら直るでしょう(え)

LINEボットで答える

●バージョン取得
  # v1のバージョンを取得
  v1バージョンURLへGET送信した時には
    対象をHTMLパース。
    ITEM=「item」のDOM要素取得。
    ITEMをDOM配列変換。
    タイトルはITEM[0]から「title」をDOM子要素検索。
    タイトルのHTML取得して、「/\[CDATA\[(.*?)\]\]/」で正規表現マッチ。
    v1=抽出文字列[0]
    バージョン情報[0]=「なでしこ1の最新バージョンは、{v1}だよ☆」のLINEテキストメッセージ。
    # v3のバージョンを取得
    v3バージョンURLへGET送信した時には
      v3=対象をJSONデコード。
      バージョン情報[1]=「なでしこ3の最新バージョンは、{v3["version"]}だよ☆」のLINEテキストメッセージ。
      # 二つ同時に返信
      イベントリスト[No]=バージョン情報を返信先へLINE返信。
    ここまで。
  ここまで。
ここまで。

 メッセージは配列で渡すことで同時に五つまで送信できるようで、そのお試しも兼ねて、二つをそれぞれ別のメッセージオブジェクトとして作成し、同時に送信しています。
linebot2.jpg
 できた!

プラグイン側の機能追加

メッセージオブジェクト

 スタンプ、画像、動画、音声、位置情報、二択の確認メッセージが作れるようにしました。

てすと

 スタンプが送られてきたらスタンプを、画像が送られてきたら画像を、位置情報が送られてきたら位置情報を返信するようにしてみたよ☆(動画と音声は試してない;)
 また、「おやつ」と送ったら、「チョコ」か「ポテチ」の二択を出します。
linebot10.jpg
linebot11.jpg
 できた!!

メッセージ

 プッシュ、マルチキャスト、ブロードキャストメッセージが送れるようにしました。
 プッシュはユーザーIDを指定して一人の人に、マルチキャストはユーザーIDの配列で複数の人に、ブロードキャストは友達になってる人全員にメッセージを送信するやつ。
 ブロードキャストは、リファレンスを見てもShellしかサンプルコードがなくって、ええ~(;Д;)ってなりますが実装はあるようです。
 client.broadcast(message)でいけました☆
 (同様にナローキャストもあるようなんですが、お試しできないからよく分からない。まあ、友達ワタシしかいませんから、実際のところマルチキャストもブロードキャストも本当にみんなに送られんのか試せませんがw)

プラグイン置き場

https://github.com/snowdrops89/nako3_plugin_linebot

 とりあえず、今ワタシがやりたそうなコトと言ったらこんなものかな。

コード

linebot.nako3
!『Plugin_linebot.js』を取り込む。
!『nadesiko3-htmlparser』を取り込む。
!『plugin_csv』を取り込む。

#---宣言----------
イベントリスト=空配列。C=0。No=0。
イベント種別=空。返信先=空。ユーザーID=空。ユーザー名=空。受信メッセージ=空。
返信メッセージリスト=「reply_list.csv」を開いて、それをCSV取得。
返信テキスト=空。

#---情報取得----------
定数 v1バージョンURL=『https://download.nadesi.com/v1/History.xml』
定数 v3バージョンURL=『https://n3s.nadesi.com/nako_version.json』
バージョン情報=空配列。

#---サーバー----------
LINEボット起動した時には
  「{PORT番号}でサーバ起動しました」と表示。
  LINEイベント受信時には
    イベント処理。
  ここまで。
ここまで。

●イベント処理
  C=0。
  LINEイベントを反復
   No=対象キー。
   イベント種別=LINEイベント[No]["type"]
   もし、イベント種別=「unfollow」ならば、続ける。
   返信先=LINEイベント[No]["replyToken"]
   ユーザーID=LINEイベント[No]["source"]["userId"]。
   ユーザーIDのプロフィール取得した時には
    ユーザー名=対象["displayName"]。
    イベント種別で条件分岐
     「follow」ならば、フォロー。。。
     「message」ならば、メッセージ。。。
    ここまで。
    C=C+1。
    もし、C=(イベントリストの配列要素数)ならば、イベントリストをLINEメッセージ送信。
   ここまで。
  ここまで。
ここまで。

●フォロー
  返信テキスト=「{ユーザー名}さん、はじめまして!{改行}お友達になってくれてありがとう☆」
  イベントリスト[No]=返信テキストのLINEテキストメッセージを返信先へLINE返信。
ここまで。

●メッセージ
  メッセージ種別=LINEイベント[No]["message"]["type"]
  メッセージ種別で条件分岐
   「text」ならば、
     受信メッセージ=LINEイベント[No]["message"]["text"]
     受信メッセージで条件分岐。
      「バージョン」ならば、バージョン取得。。。
      「おやつ」ならば、イベントリスト[No]=「チョコ」と「ポテチ」で「どっち?」のLINE二択メッセージを返信先へLINE返信。。。
      「ぷっしゅ」ならば、ユーザーIDに「プッシュです」のLINEテキストメッセージをLINEプッシュ。。。
      「全員」ならば、「一斉プッシュです!」のLINEテキストメッセージをLINE一斉プッシュ。。。
      違えば、
       返信メッセージリストを反復
         語句=対象[0]の『{ユーザー名}』をユーザー名に置換。
         もし、受信メッセージ=語句ならば、
           返信テキスト=対象[1]の『{ユーザー名}』をユーザー名に置換。
           返信テキスト=返信テキストの『{改行}』を改行に置換。
           イベントリスト[No]=返信テキストのLINEテキストメッセージを返信先へLINE返信。戻る。
         ここまで。
       ここまで。
       返信テキスト=受信メッセージ&「?」
       イベントリスト[No]=返信テキストのLINEテキストメッセージを返信先へLINE返信。
      ここまで。
     ここまで。
   ここまで。
   「sticker」ならば、
     返信スタンプ=空配列。
     返信スタンプ[0]=「わーいスタンプだ~」のLINEテキストメッセージ。
     返信スタンプ[1]=「8515」から「16581243」のLINEスタンプメッセージ。
     イベントリスト[No]=返信スタンプを返信先へLINE返信。
   ここまで。
   「image」ならば、
     返信画像=空配列。
     画像URL=「https://n3s.nadesi.com/image.php?f=8.jpg」
     返信画像[0]=「画像だ!」のLINEテキストメッセージ
     返信画像[1]=画像URLと画像URLのLINE画像メッセージ。
     イベントリスト[No]=返信画像を返信先へLINE返信。
   ここまで。
   「location」ならば、
     イベントリスト[No]=「たいとる」と「じゅうしょ」で[35.687574,139.72922]のLINE位置情報メッセージを返信先へLINE返信。
   ここまで。
  ここまで。
ここまで。

●バージョン取得
  # v1のバージョンを取得
  v1バージョンURLへGET送信した時には
    対象をHTMLパース。
    ITEM=「item」のDOM要素取得。
    ITEMをDOM配列変換。
    タイトルはITEM[0]から「title」をDOM子要素検索。
    タイトルのHTML取得して、「/\[CDATA\[(.*?)\]\]/」で正規表現マッチ。
    v1=抽出文字列[0]
    バージョン情報[0]=「なでしこ1の最新バージョンは、{v1}だよ☆」のLINEテキストメッセージ。
    # v3のバージョンを取得
    v3バージョンURLへGET送信した時には
      v3=対象をJSONデコード。
      バージョン情報[1]=「なでしこ3の最新バージョンは、{v3["version"]}だよ☆」のLINEテキストメッセージ。
      # 二つ同時に返信
      イベントリスト[No]=バージョン情報を返信先へLINE返信。
    ここまで。
  ここまで。
ここまで。

 なでしこ貯蔵庫にも上げてみました。
 cnako3のプログラムなので動かせませんが、Qiitaの記事ではなでしこのコードにシンタックスハイライトが付かなくて見辛いので・・・

https://n3s.nadesi.com/id.php?845

動作確認

 もしよろしければ試してみてください。

友達登録

215ybrvp.png

キーワード

キーワード 応答
なでしこ 誰でも簡単プログラマー
なでしこさん よんだ?
(自分のLINEの表示名) ○○さんってすてきな名前だね
(スタンプ) (スタンプ)
(画像) (画像)
(位置情報) (位置情報)
おやつ 「チョコ」「ポテチ」の二択
バージョン なでしこ1のバージョン/なでしこ3のバージョン

 それ以外はおうむ返しです。

続くかもしれないし続かないかもしれない

 これで、なでしこの最新バージョンを答えてくれる機能が付いて、ボットに実用性が付加されました。やったね☆
 でも・・・
 バージョンを教えてくれるって、LINEボットに本っ当にやって欲しいのってこうじゃないよね。
 バージョンアップしたらプッシュして教えてほしい。
 毎日定時にバージョンをチェックしに行って、アップしてたらお知らせしてくれる的な?

 実は・・・自分のパソコン上でやってみた分には出来たんですけれどね・・・
 Herokuさんでは出来ませんでした。
 どうやらHerokuさんは、プログラムでファイルのデータを書き換えても、定期的にgitで管理されてる元の状態に戻ってしまうラシイ。(ので、一度バージョンアップしたら、毎日お知らせが上がってしまう状態になってしまう)
 これを解決するには、データファイルをどっか別のトコ(S3とか)に置くか、Heroku Postgresなるアドオンを使って、csvとかじゃなくデータベースにするってことになるらしい。むむむ・・・
(なでしこさん側にも、PostgreSQLを使うためのプラグインがあった気がするけどそもそもえすきゅーえるを知らないからね。むむむむむ( ゚ε゚;)
 ううっ、そのうちがんばる;;;;;

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?