プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

LINE ボット開発のための開発者アカウントの取得について

仕事の関係で LINE のボット開発をやることになりそうです。

で、調査がてら LINE の開発者登録をしようとしたら、少し戸惑ったので、気になったところをいろいろとメモっておきます。 なお、この内容は記事を書いた時点(2019/9/11)の情報なので、先々変わることがあると思いますがご了承ください。

開発者登録に必要なアカウント

下記の記事などや、

LINE の Messaging API の説明を見ると、書いてありますが、LINEの開発には、

  • LINE アカウント(開発者アカウントとして登録する)
  • LINE 公式アカウント(以前の LINE@アカウント)

の2つが必要になります。

さて、ここで、個人でボットを開発するのではなく、仕事としてボットを開発する場合を考えると、 開発者アカウントは LINE アカウントに紐づいているので、私の個人の LINE アカウントは使いたくありません (会社とかの組織の場合はどうしてるんですかね?)。

ボットで使う予定の機能は Messaging API なので、そのページを見ても、

f:id:junichim:20190911114618p:plain

とあり、LINEアカウントがなければ取得してくださいとあります。

PC版LINEアカウント

で、上記のリンクをたどり ダウンロードページ を見ると、PC版のLINEアプリがあります。 調べてみると、PC版のLINEアプリは、電話番号があれば、アカウントを登録できるようです。

ヘルプセンター | LINE (『PCで新規登録するには?』で検索)

昔からPC版のLINEアカウントってありましたっけ?てっきり、スマホがないとLINEアカウントって作れないと思い込んでいました。

ということで、個人の LINE アカウント(こっちはスマホとその電話番号に紐づいてる)とは別に、仕事用の電話番号を使ってLINEアカウントを作成し、 このLINEアカウントを開発者アカウントとして登録すれば、問題なさそうです。

やってみます。

PC版LINEのインストール

まず、ダウンロードページからPC版LINEのソフトをインストールします(Windows10 Pro, 1903 で作業してます)。 インストール後、起動すると画面下部に、『新規登録』のボタンがあるので、

f:id:junichim:20190911115627p:plain

ここをクリックします。次に、電話番号の入力を求める画面が表示されます。

f:id:junichim:20190911115721p:plain

前述したように、仕事用の電話番号を入力します。

電話番号を入力して、次に進むと、SMSで認証番号を送ったので、その番号を入力するように求められます。
今回は試していませんが、SMSが使えない場合は通話による認証もできるようです。

認証が問題なくできれば、いくつかの設定項目(友達への追加を許可するか否か、メールアドレスの登録をするか否か)を入力すると、アカウントが作成されます。

アカウント作成時にメールアドレスを登録していなければ、LINE の開発者アカウントとして登録する際に、メールアドレスによるログインが必要になるので、このPC版LINEアカウントにメールアドレスを登録しておきます。

PC版LINEを起動して、電話番号でログインして、設定画面を開きます。

f:id:junichim:20190911122016p:plain

メールのところをクリックして追加します(上記画面は追加後なのでリンクは表示されていません)。 入力したメールアドレスに対して、認証情報を含むメールが届くので、メール記載の認証情報を入力すれば、登録完了です。

開発者アカウントの登録

ここまでくれば開発者アカウントの登録はあと少しです。

LINE Developer のログインページを開いて、『LINEアカウントでログイン』を選択します。

f:id:junichim:20190911122932p:plain

メールアドレスとパスワードが求められるので、先ほど作成したPC版LINEアカウントのメールアドレスとパスワード(最初に電話番号でアカウントを作成したときのパスワードと同じです)を入力します。

問題がなければ、

f:id:junichim:20190911123151p:plain

こんな感じの開発者情報の入力画面が表示されます。なお、画面中央の『森ソフト』という名前は、PC版LINEアカウントの名前です。 開発者名とメールアドレスを入力すれば完了です。

これで、晴れてLINEの開発者アカウントとして登録することができました。 あとは、いろいろと試していきたいと思います。

(参考)PC版LINEの制限

PC版LINEはいろいろと制限があるようです。気づいた点だけでも書いておきます。詳しくは下記のヘルプページを参照してください。

ヘルプセンター | LINE

  • 『電話番号による友達への追加を許可する設定』これは新規登録時のみ設定可能で後から変更はできない
    (『友だち追加を拒否するには?』で検索)
  • メールアドレスの変更はできない
    (『登録メールアドレスをPC(パソコン)版で変更できますか?』で検索)

モバイルプロジェクター買いました

以前からモバイルプロジェクターには興味があったんですが、最近は伊勢IT交流会の開催場所も、プロジェクター付きのところが安定して借りられていたので、少し遠ざかっていました。

ですが、先日、伊勢IT交流会の納涼会を開催することになった際に、LT希望者を募ったら、宴会にも関わらず希望する方がいらっしゃいました(ありがたいことですよね)。

なので、これは頑張って準備せねば、と思い、モバイルプロジェクターを購入して、なんとかLTができるようにしましたので、その時の話を簡単にメモっときます。

機種選定

さて、モバイルプロジェクターの機種って、どんなのがあるんでしょうか? 全然知らなかったのですが、下記サイトなどを見ると、 DLP という形式のものが、小型軽量で実際問題として持ち運びができそうです。

sakidori.co

参加人数をおおよそ確定して、LTやる方向で決定してから会場選定まで、日にちが全然なかったので、大急ぎでプロジェクターの手配も行いました。

こういう時はお急ぎ便も使えるAmazon で調べます。
色々見てると、サンワサプライのモバイルプロジェクターの型落ち品が1万円台でお安く出ていました。

サンワサプライ MHL内蔵モバイルプロジェクター PRJ-5N

サンワサプライ MHL内蔵モバイルプロジェクター PRJ-5N

この機種だと、解像度が 854x480 まで対応していて、お値段も安いのでいい感じです。接続は HDMI のみ。細かいスペック等は製品のページ見てください。

www.sanwa.co.jp

この機種の後継機種だと、台形補正とかもついているようですが、お値段的にずいぶんとお高くなるので、こちらにしました。 ちなみに、同じぐらいの価格帯でサンワダイレクトの 400-PRJ023 もあったのですがこちらは解像度が 640x360 だったのでやめました。

一応、参加者のPCがVGAのみの場合に備えて、 VGA -> HDMI の変換ケーブルも用意しておきました。

実際に使ってみる

さて、実際に使ってみました。 普段の懇親会は居酒屋さんパターンが多いのですが、今回は遠方から来てる方もいらっしゃったので、割烹大喜さんでお部屋を取っていただきました。

プロジェクターを使いたい旨をお伝えしておいたら、壁は継ぎ目はあるものの薄めの平面の壁の部屋をご用意していただきました。

f:id:junichim:20190826161153j:plain

これなら十分投影できそうです。

さて、実際のLTまでに、事前に試す余裕がなかったので、ぶっつけ本番になりました。こんな感じでテーブルにセットして、

f:id:junichim:20190826161321j:plain

実際に投影してみると

f:id:junichim:20190826161228j:plain

いい感じですね。壁まである程度距離を取るとそれなりに大きなサイズでも十分見ることができます。

とはいえ、LT前はこの写真みたいに、照明がある状態でも十分明るいと思っていたのですが、さすがに文字を写すときつくなったので、照明を落として対応しました。 少し暗くなれば十二分に使えました。
スペック上は、100 ANSIルーメンってあり、これが体感としてどのぐらいの明るさかピンと来てなかったのが、これでよくわかりました。簡易用途なら十分ですね。

残念ながら、実際のLT中の写真は、スマホのバッテリーがなくなったため、取り損ないました。すいません。

まとめ

モバイルプロジェクターといっても、持ち運びが嫌になるようなイメージがあったのですが、これだったら十分に持ち運びして使えそうです。 もっとも、電源の延長ケーブルとか VGA->HDMI の変換ケーブルとかのほうがかさばるぐらいでした。

ちなみに納涼会はこんな感じでした。

f:id:junichim:20190826162457j:plain

さて、次はどこで活用しようかな。

修正UTF-7 のエンコード/デコード処理について

はじめに

メインのメールとして、さくらインターネットのレンタルサーバーのメールを使っています。

今までは POP でローカルにメールを取ってきて処理していたのですが、最近、さすがに不便になってきたので、 IMAP で処理しようと思い立ちました。 幸い、さくらのメールは、 Webメール としてもアクセスできるので、問題なさそうです。

と思ったのですが、試し始めると大きな問題が。
というのも、さくらインターネットの Webメールでは、メールのフォルダへの振り分けができないのです。 いろんなメールが来るので、それをいちいち手作業で振り分けているのも、さすがにつらいものがあります。

いろいろと調べてみると、さくらインターネットの場合、 IMAP サーバ として Courier IMAP を使っており、 MDA (Mail Delivery Agent) として maildrop というがメールの受信と振り分けをやってくれているようです(maildropに関するさくら側の情報はないので、推測です)。 で、その設定ファイル .mailfilter を書いてやれば、一応振り分けはできるとのことです(こちらのさくらインターネットのヘルプでmailfilterについて触れてます)。

それなら、簡単だと思いつつ、Webメールのインターフェースから適当にフォルダを作って、

f:id:junichim:20190817104104p:plain

SSHでログインしてフォルダ名を確認すると、

[myuser@xxxxxxx ~/MailBox/account/maildir]$ ls -laF
total 84
drwx------  17 myuser  users  1024 Aug 17 10:37 ./
drwx------   5 myuser  users   512 Aug 16 15:57 .&MEIwRDBGMEgwSg-/
drwx------   6 myuser  users   512 Jul 11 16:04 .&Yy8wilIGMFEwxjC5MMg-/
drwx------   6 myuser  users   512 Jul 11 16:07 .&Yy8wilIGMFEwxjC5MMg-.&Txp5Pv8S-/
drwx------   6 myuser  users   512 Aug 10 18:23 .&Yy8wilIGMFEwxjC5MMg-.company1/
drwx------   5 myuser  users   512 Aug 10 19:33 ../
drwx------   6 myuser  users   512 Jul 11 15:37 .Archive/
drwx------   6 myuser  users   512 Jul 11 15:41 .Draft/
drwx------   6 myuser  users   512 Jul 11 15:37 .Junk E-mail/
drwx------   6 myuser  users   512 Aug  1 22:49 .Sent/
drwx------   6 myuser  users   512 Jul 11 15:41 .Trash/
drwx------   6 myuser  users   512 Jul 13 00:02 .spam/

のように、一瞬文字化けか?と思うようなわけわからん記号のフォルダが存在しています。

調べてみると、これは、日本語などのマルチバイト文字をエンコードしたフォルダ名とのこと。 このエンコード方法が IMAP で決められていて、それが『修正UTF-7』という方法になるんだそうです。

まだまだ知らないことだらけですね。

.mailfilter を書くにあたり、どれがどのフォルダに該当するのかわからないのは、はなはだ不便です。 が、ちょっとネットを見てみても、入力文字列を 修正UTF-7 にエンコードしてくれるサービスが見つかりません。
多くの方、困ってないのかな?

ということで、仕方ないので、今年のお盆休みの課題として、 修正UTF-7 にエンコード/デコードしてくれるツールを作りましたので、メモ残しておきます。

修正UTF-7

まずは、 修正UTF-7 の規格について調べます。

ゆっくり読むと、それほど難しくはないようです。

まとめると、

  • & は &- にエンコードする
  • & 以外のASCII印字可能文字はそのままとする
  • それ以外の文字は、UTF-16BE(ビッグエンディアン)でエンコード後、修正Base64でエンコードして、前に & 後ろに - を付加する

修正Base64は、

  • Base64で変換する
  • / (スラッシュ)を , (カンマ)で置き換える
  • 4文字に満たない場合も = (等号)でパディングしない

とのことです。

では、実装してみましょう

実装

今回は WSL 上の node.js (v10.16.0) で作業しました。

変換処理のメイン部分は下記の記事を参考にしました。

JavaScript で Modified UTF-7 にエンコード&デコード - Qiita

ただ、自分で、Base64 や UTF-16BE へのエンコーディングは避ける方針とし、

  • UTF-16BEへのエンコーディングは、 iconv-lite
  • base64 へのエンコーディングは、 Buffer

を使いました。

エンコード処理

エンコード処理の主な部分について触れておきます。

function encode(str) {
        var encoded = str
            .replace(/&/g, "&-")
            .replace(/[\u0000-\u0019\u007f-\uffff]+/g, modifiedBase64Encode);

        //console.log(encoded)
        return encoded;
}

最初に & を &- に変換しています。この変換を行っても、いわゆるASCII印字可能文字が増えるだけなので、修正Base64でのエンコード対象外になり、後段の処理に影響は及ぼしません。
次に、正規表現でASCII印字可能文字範囲以外が連続して出てくる箇所を見つけて、修正base64でエンコードするという処理になります。ASCII 印字可能文字の範囲が 0x20 ~ 0x7e までなので、そこを外した範囲指定になります。

ちなみにこれって、node.js(JavaScript)の文字列の内部のエンコーディングが、UTF-16だから成立しているのだと思います。 たとえば、

mor@DESKTOP-H6IEJF9:/tmp/mutf7$ node
> "あ".charCodeAt(0).toString(16)
'3042'

とすれば、『あ』に対応する UTF-16のコード U+3042 が表示されるのがわかります。

修正base64の処理はこんな感じになります。

function modifiedBase64Encode(str) {
        const buf = iconv.encode(str, "utf16-be");
        //console.log(str);
        //console.log(buf);
        return "&"+ buf.toString("base64").replace(/\//g, ",").replace(/=/g, "") + "-";
}

正規表現で変換対象として文字列を、UTF-16BEでエンコード後、さらにbase64で変換し、修正base64に合うように、文字を置換しておきます。

一連の処理の結果、正しい変換結果になっているかどうかは、さくらインターネットのWebメールで実際にフォルダ名を設定して確認しておきます。

デコード処理は基本的にこれと逆の処理をすればよいことになるので、省略しておきます。興味があれば、ソースをご覧ください。

ツールとして整理

基本の変換処理は実装できたので、ツールとして仕立てます。
ツールとして仕立てようとすると、引数をうまく処理する必要があります。 そのあたりの引数処理を行うために commander というライブラリを使いました。

いやー、便利なもんですね。

できたもの

最終的には、こんな感じになりました。

#!/usr/bin/env node
/**
 * 修正UTF-7 エンコード・デコード関数
 *
 * https://qiita.com/tkooler_lufar/items/66b01f1a88c9e018f76e
 * https://smdn.jp/programming/netfx/tips/modified_utf7/
 */

'use strict';

const iconv = require('iconv-lite');
const program = require('commander');

// コマンドライン引数処理
program.version('0.0.1')
       .usage('文字列')
       .description("与えられた文字列について、修正UTF7によるエンコード/デコードを行います")
       .option("-d, --decode","修正UTF7文字列をデコードします");

program.parse(process.argv);
//console.log("optons: " + program.opts());

var args = program.args
if (!args || args.length == 0) {
    console.log("no target string");
    process.exit(1);
    return;
}
//console.log("args: " + program.args);

if (program.decode) {
        var decoded = decode(args[0]);
        console.log(decoded);
        return;
}
var encoded = encode(args[0])
console.log(encoded)
return;

/////////////////////////////////////
// 以下、関数

function encode(str) {
        var encoded = str
            .replace(/&/g, "&-")
            .replace(/[\u0000-\u0019\u007f-\uffff]+/g, modifiedBase64Encode);

        //console.log(encoded)
        return encoded;
}
function decode(str) {
        var decoded = str
            .replace(/&([A-Za-z0-9\+\,]+)-/g, modifiedBase64Decode)
            .replace(/&-/g, "&");

        //console.log(decoded)
        return decoded;
}

function modifiedBase64Encode(str) {
        const buf = iconv.encode(str, "utf16-be");
        //console.log(str);
        //console.log(buf);
        return "&"+ buf.toString("base64").replace(/\//g, ",").replace(/=/g, "") + "-";
}
function modifiedBase64Decode(str, substr) {
        const buf = Buffer.from(substr.replace(/,/g, "/"), "base64")
        //console.log(str);
        //console.log(substr);
        //console.log(buf);
        const decoded = iconv.decode(buf, "utf16-be");
        //console.log(decoded);
        return decoded;
}

動作確認

動かしてみます。

オプションを指定しないときは、エンコードします。

mor@DESKTOP-H6IEJF9:/tmp/mutf7$ node index.js あいうえお
&MEIwRDBGMEgwSg-
mor@DESKTOP-H6IEJF9:/tmp/mutf7$ node index.js 日本語
&ZeVnLIqe-

サロゲートペアの文字(下記の例だと、𩸽(ほっけ)、𠮷)が入っていても大丈夫です。

mor@DESKTOP-H6IEJF9:/tmp/mutf7$ node index.js 𩸽定食𠮷野家
&2GfePVuamN,YQt+3kc5btg-

デコードもできます。

mor@DESKTOP-H6IEJF9:/tmp/mutf7$ node index.js -d "&MEIwRDBGMEgwSg-"
あいうえお

一応、 Github にもあげておきます。

github.com

余談

以下余談です。

その1:紆余曲折

すんなりと上記の実装が書けたわけではなく、いろいろと紆余曲折がありました。

最初、 node.js (javascript) の場合、base64に変換するのが、 Buffer を使えばできるとのことだったので、

var buf = Buffer.from("対象文字列")
var res = buf.toString("base64");

としてました。 変換結果を確認すると、違ってます。

何だろう?と思い調べてみると、 Buffer#from は文字コードを指定しないと、UTF-8でエンコードするそうです。文字列の内部表現がUTF-16なので、てっきりUTF-16だと思い込んでしまいました。

じゃあ、UTF-16BEを指定すればいいやと思いきや、Bufferは UTF-16BE には対応していないそうです(UTF-16LEはあるんですけどね)。

はじめてのNode.js:Node.js内でバイナリデータを扱うための「Buffer」クラス | OSDN Magazine

困ったなと思ってあれこれ見てたとき、ふと、ツールを作る前に iconv で修正UTF-7に変換すればいいやん、と考えていたことを思い出しました。 ただ、iconv の場合、下記に示すように、修正UTF-7には対応してなかったんですが、UTF-16はいけます。

mor@DESKTOP-H6IEJF9:/tmp/mutf7$ iconv --list | grep -i utf
ISO-10646/UTF-8/
ISO-10646/UTF8/
UTF-7//
UTF-8//
UTF-16//
UTF-16BE//
UTF-16LE//
UTF-32//
UTF-32BE//
UTF-32LE//
UTF7//
UTF8//
UTF16//
UTF16BE//
UTF16LE//
UTF32//
UTF32BE//
UTF32LE//
mor@DESKTOP-H6IEJF9:/tmp/mutf7$

ということで、 node.js から iconv を使うためのライブラリを探してみると

mor@DESKTOP-H6IEJF9:/tmp/mutf7$ npm search iconv
NAME                      | DESCRIPTION          | AUTHOR          | DATE       | VERSION  | KEYWORDS
iconv                     | Text recoding in…    | =bnoordhuis     | 2019-03-31 | 2.3.4    |
iconv-lite                | Convert character…   | =ashtuchkin     | 2019-06-26 | 0.5.0    | iconv convert charset icu
codepage                  | pure-JS library to…  | =sheetjs        | 2018-07-08 | 1.14.0   | codepage iconv convert strings
・・・

いろいろとありました。
この中の、 iconv-lite がよさそうだったので、今回はこれを使うことにしました。

その2:さくらのWebメールとサロゲートペア

さくらインターネットのwebメールでは、サロゲートペアにあたる文字が含まれるフォルダは正しく処理されませんでした。

例えば、『𩸽定食』というフォルダを作成すると

f:id:junichim:20190817113734p:plain

フォルダは作られるんだけど、画面上は文字化けしています。

f:id:junichim:20190817113949p:plain

ちなみに、直接該当アカウントのmaildir を見ると

[myuser@xxxxxxx ~/MailBox/account/maildir]$ ls -laF
total 88
drwx------  18 myuser  users  512 Aug 17 11:37 ./
drwx------   5 myuser  users  512 Aug 17 11:37 .&2GfePVuamN8-/
drwx------   5 myuser  users  512 Aug 16 15:57 .&MEIwRDBGMEgwSg-/
drwx------   6 myuser  users  512 Jul 11 16:04 .&Yy8wilIGMFEwxjC5MMg-/
drwx------   6 myuser  users  512 Jul 11 16:07 .&Yy8wilIGMFEwxjC5MMg-.&Txp5Pv8S-/
drwx------   6 myuser  users  512 Aug 10 18:23 .&Yy8wilIGMFEwxjC5MMg-.company1/
drwx------   5 myuser  users  512 Aug 10 19:33 ../

のように、正しく作られています(.&2GfePVuamN8- が𩸽定食のフォルダに該当しています)。

また、中身を見ようとしても、『読み込み中』が表示されて、そこで処理が止まってしまいます。このフォルダ名の変更、削除もできません。

いくつかのサロゲートペアの文字で試しても同様の結果になりましたが、サロゲートペアの文字一般についても同じ問題が起きるのかまでは調査していません。
もしくは、サロゲートペアの問題なのか、それとも別の問題があるのかまで特定したわけでもありません。

ですが、もし、Webメールのフォルダを操作していて不思議な挙動があれば、サロゲートペアを疑ってみるのもいいかもしれません。

ちなみに、この状態でフォルダを削除するには、SSHでログインして、 ~/Mailbox/メールアドレス名/maildir 以下にある、該当フォルダを直接削除すれば可能です。 ただ、フォルダ名は修正UTF7でエンコードされているので、間違って他のフォルダを消さないように注意してください。

(参考) JavaScript における文字コードと「文字数」の数え方 | blog.jxck.io