DelphiでSlackの投稿ボットを作る(日本語問題)

どうも太田アベル(@LandscapeSketch)です。

今日はDelphiでSlackに自動投稿するボットのベースを作ります。情報が少なかったので備忘録を兼ねて。

まずSlackでアプリの登録し、トークンを得ます。(方法は他サイトに譲るw)

フォームに

  • TRESTClient
  • TRESTRequest
  • TRESTResponse
  • TMemo
  • ボタン2つ

を設置。

2019-02-15_16h29_00.jpg

エンドポイントを登録

TRESTClientにエンドポイントを登録します。

プロパティのBaseURLに「https://slack.com/api」を入力。

Paramsに新しい新規Itemを作り、nameに”token”Valueに先ほど得たアプリのトークン文字列を入れます。KindはpkGETorPOSTのままでOK。共通で使うキーなどはTRESTClientに保持させると便利。

2019-02-15_16h32_59.jpg

Responseの用意

TRESTRequestの問い合わせに対して、値の取得などはTRESTResponseが行います。

TRESTRequestのResponseプロパティに、RESTResponse1を選択。

2019-02-15_16h35_55.jpg

これだけでOK!

Requestの返値はResponseが自動で保持します。

リクエストしてみる

まずはテスト。slackは「auth.test」クエリで正常テストを行えます。

RESTRequestのプロパティに書いていってもいいですが、コードから書けば柔軟になります。

Button1のイベントハンドラに

 RESTRequest1.Resource := 'auth.test';
 RESTRequest1.Execute;
 Memo1.Lines.Text := RESTResponse1.Content;

たったこれだけで取得から受信までできます!

さっそくコンパイルしてぽちっとな。

なんだかボカシだらけになってしまいましたが、JSONが返ってきていて、先頭の”ok”にtrueが入っていれば、通信は正常です!

2019-02-15_16h41_12.jpg

メッセージを送る!

通信が正常なので、メッセージを送ってみます。

メッセージに最低限必要なのが

  • チャネル名
  • メッセージ本文
  • “as_user”にfalse

が必要です。as_userはユーザーとして投稿するフラグ(で認識あってる?)なので、これが立っていると単なるボットとしての投稿ができません。falseが返ってきます。(slackはまだ勉強中なので認識がおかしい場合はコメントください。)

パラメータはParams.AddItemで書いていきます。

Button2のイベントハンドラに下記コードを投入。

 

procedure TForm1.Button2Click(Sender: TObject);
begin

with RESTRequest1 do
begin
Resource := 'chat.postMessage';
Params.Clear;

with Params.AddItem do
begin
name := 'channel';
Value := TNetEncoding.URL.Encode('#売上速報', [], []);
Options := [TRESTRequestParameterOption.poDoNotEncode];
end;

with Params.AddItem do
begin
name := 'text';
Value := TNetEncoding.URL.Encode('これは速報です!' + #13#10 + '改行テスト!', [], []);
Options := [TRESTRequestParameterOption.poDoNotEncode];
end;

with Params.AddItem do
begin
name := 'icon_emoji';
Value := ':robot_face:';
end;

with Params.AddItem do
begin
name := 'as_user';
Value := 'false';
end;

RESTRequest1.Execute;
Memo1.Lines.Text := RESTResponse1.Content;

end;
end;

さてここで1点ハマりポイント。

ParamのValueに日本語文字列をそのままいれても文字化けします。UTF8Encodeしてもダメ、UrlEncodeでもダメです。

確実に表示できたのは

Value := TNetEncoding.URL.Encode(‘これは速報です!’ + #13#10 + ‘改行テスト!’, [], []);
Options := [TRESTRequestParameterOption.poDoNotEncode];

この書き方。

TNetEncoding.URL.Encodeは後ろの2つの引数を入れると挙動が変わります。「+」とか記号のエンコードがだいぶ違う。ここに明示的に空のオプションを渡せば、素直になります。

詳しくはこちらのページ>Delphi の URLEncode は罠が多い

文字列を明示的に変換し、さらにオプションにpoDoNotEncodeに設定し、勝手に内部処理させないようにします。

そしてぽちっとな!

2019-02-15_16h53_49.jpg

グッドですね!

[matome]

とりあえずこれで最低限のメッセージは送れます。この記事にあるように、売上連絡ぐらいなら20分もあればできるのではないでしょうか。

ハマりどころは日本語処理なので、ここさえ迷わなければカンタンです!エンコード迷宮に入ると1時間以上かかるけどね・・・

[/matome]

 

コメント