6
2

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.

[LINE Bot 開発入門] LINE Bot Serverを作ってみる その3

Posted at

はじめに

LINE Bot Serverを作ってみる その2のつづきです。
前回開設の途中で終わったdispatchMessageEventの部分からです。

サンプルの全ソースコードはこちらです
https://github.com/bathtimefish/line-bot-server-example

Message Eventを判別する

event.ts
export const dispatchMessageEvent = async (event: line.MessageEvent): Promise<(Promise<line.MessageAPIResponseBase> | undefined)[]> => {
  let result = undefined;
  const replyToken: string = event.replyToken; // message event has a reply token
  let textEventMessage: line.TextEventMessage;
  let imageEventMessage: line.ImageEventMessage;
  let imageUrl: string;
  switch (event.message.type) {
  case 'text':
    /* Text Event Message用の処理 */
    break;
  case 'image':
    /* Image Event Message用の処理 */
    break;
  }

LINE Platformから送信されるメッセージタイプは複数あります。イベントはmessage.typeを持っているので上記の処理ではswitch文で評価しメッセージタイプを識別しています。このコードはサンプルのためTextEventMessageImageEventMessageのみを判別しています。その他のイベントを処理するにはこのswitch文を拡張することで対応できます

イベントメッセージタイプは現時点で他にFileEventMessageAudioEventMessageVideoEventMessageStickerEventMessageLocationEventMessageがありそれぞれにTypeScriptの型定義が提供されています

また、イベントはreplyTokenを持ちます。replyTokenは返信用のメッセージトークンで受信したメッセージイベントに対してメッセージを返信するために使用します

テキストメッセージを返信する

event.ts
  switch (event.message.type) {
  case 'text':
    textEventMessage = {
      type: 'text',
      id: event.message.id,
      text: event.message.text,
    };
    result = client.replyMessage(
      replyToken,
      textEventMessage,
    );
    break;

TextEventMessageを受信した場合の処理を記述しています。このサンプルでは受信したメッセージのテキストをそのまま返信するようにしています。いわゆるオウム返しです。返信には上記のようにTextEventMessageを作成しreplyTokenと合わせてreplyMessageで返信します。

画像メッセージを処理する

event.ts
  case 'image':
    imageEventMessage = {
      type: 'image',
      contentProvider: event.message.contentProvider,
      id: event.message.id,
    }
    imageUrl = await downloadImageContent(imageEventMessage);
    textEventMessage = {
      type: 'text',
      id: event.message.id,
      text: imageUrl,
    };
    result = client.replyMessage(
      replyToken,
      textEventMessage,
    );
    break;

ImageEventMessageの場合、送信されるメッセージデータに画像データそのものが載ってくるわけではありません。イベントメッセージのidに対応する画像データをダウンロードする処理を記述する必要があります。LINE Messaging API SDKにはデータをダウンロードするためのmethodが用意されています。処理を順に見ていきましょう

上記ではまず、受信したイベントを元にImageEventMessageを作成し、downloadImageContentに渡しています

event.ts
const downloadImageContent = async (imageEventMessage: line.ImageEventMessage): Promise<string> => {
  const exp = 'jpg';
  const downloadPath= path.join(__dirname, '../public', 'downloaded', `${imageEventMessage.id}.${exp}`);
  const messageId = await downloadContent(imageEventMessage.id, downloadPath);
  const imageUrl = `${config.baseUrl}/downloaded/${messageId}.${exp}`;
  return imageUrl;
};

ここではサーバー上に画像データを保存するパスを用意したあとdownloadContentにidを渡して用意したパスに画像データをダウンロードして保存します。正常に保存されたら画像にアクセスできるURLを作成して返しています

event.ts
const downloadContent = async (messageId: string, downloadPath: string): Promise<string> => {
  const stream = await client.getMessageContent(messageId);
  return new Promise((resolve, reject) => {
    const writable = fs.createWriteStream(downloadPath);
    stream.pipe(writable);
    stream.on('end', () => { resolve(messageId); });
    stream.on('error', () => { reject(); });
  });
};

downloadContentでLINE Platformから画像データをダウンロードして保存しています。getMessageContentがそれです。getMessageContentはPromise<internal.Readable>を返します。このReadble Streamをfs.createWriteStreamを使って指定のパスにファイルとして保存しています

event.ts
    imageUrl = await downloadImageContent(imageEventMessage);
    textEventMessage = {
      type: 'text',
      id: event.message.id,
      text: imageUrl,
    };
    result = client.replyMessage(
      replyToken,
      textEventMessage,
    );
    break;

dispatchMessageEventに戻って読むとdownloadImageContentが返す画像のURLをTextEventMessageとして返信しています。LINEアプリで画像をアップすると画像のURLが返ってくる仕組みになります。

image_event_message.png

以上がdispatchMessageEventでやっていることです

おわりに

今回はサンプルBotサーバーの心臓部である部分のコードを解説しました。その他のコードはWebサーバーの基本機能部分ですので説明を割愛します

これで「[LINE Bot 開発入門] LINE Bot Serverを作ってみる」の連載は終わりです。この記事でLINE Bot サーバーのコードレベルでの基本的な仕組みを理解いただければ幸いです。おつかれさまでした!

6
2
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
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?