💬

MarkdownをLineのFlex messageに変換するパッケージを作った (markdown-flex-message)

2024/01/30に公開

markdown-flex-message icon

概要

MarkdownをLineのFlex messageに変換できる新しいnpmパッケージ markdown-flex-message をリリースしました🎉

https://github.com/Arahabica/markdown-flex-message

ChatGPTなどからのMarkdown形式のテキストもサクッとFlex Messageに変換できます。

経緯

「先生AI」というLINEのAIチャットボットを作っているのですが、ChatGPTなどから返ってくる返答がMarkdown形式でしたので、そのまま返答すると可読性に難がありました。

これを解決するために、MarkdownをLINEのFlexメッセージに変換する機能を開発し、良い感じにできたので、npmパッケージとして公開しました。

使用例

実際の使用例はこちらです。画像をご覧ください。

markdown-flex-message Sample

「先生AI」はこちらから実際に利用可能です。
https://sensei-bot.me

使い方

まずは、markdown-flex-messageをインストールします。

$ npm install markdown-flex-message --save

そして、下記のように、convertToFlexMessage メソッドにMarkdownを流しこんであげれば、Flex Messageに変換してくれます。

import { convertToFlexMessage } from 'markdown-flex-message'
import * as line from '@line/bot-sdk'

const markdownText = `
# Fruits
* apple
* banana
* cherry
`.trim()

convertToFlexMessage(markdownText)
  .then(({ flexMessage }) => {
    const client = new line.messagingApi.MessagingApiClient({
      channelAccessToken: '{{YOUR_CHANNEL_ACCESS_TOKEN}}'
    })
    return client.pushMessage({
      to: '{{YOUR_USER_ID}}',
      messages: [flexMessage]
    })
  })
  .then(() => {
    console.log('sent.')
  })

上記のコードの場合、下記のようなメッセージになります。

Flex 1

さらに詳細な使い方はGitHubのREADMEに記載しています。

https://github.com/Arahabica/markdown-flex-message

どうやって作ったか

  1. Markdownをパース

marked パッケージを使用してMarkdownをパースし、トークンリストを取得しました。

通常は、いきなりHTMLに変換されてしまうのですが、lexerという関数を使えば、MarkdownからHTMLにする途中のトークンリストをJSON形式で取得できるので、それを使っています。

https://github.com/markedjs/marked

  1. MarkdownをFlex messageに変換

トークンリスト(パースされたJSON)を地道にFlex messageの形式に変換していきました。

  1. 画像の表示

画像をダウンロードし、image-size パッケージを使用して画像のアスペクト比を取得し、Flexメッセージでの表示を可能にしました。

  • Flex Messageで画像を表示する際にアスペクト比が必要

https://github.com/image-size/image-size

  1. コードの表示

prismjs を使用してコードのシンタックスハイライトを実装しました。

こちらはzennにも使われているものです。tokenizeという関数を使えば、JSON形式でトークンリストを返してくれるので、トークンタイプ(変数、キーワードなど)ごとに色を指定してあげて、表示しました。

https://github.com/PrismJS/prism

気を付けること

晴れてMarkdownをFlex Messageに変換することができたんですが、一点罠がありました。

Flex Message cannot copy

Flexメッセージはテキストをコピーすることができないのです。

これについては仕様でどうしようもないので、元のマークダウンを表示させる専用のページを用意してそのページへのリンクを下部に設置しました。これが地味に面倒でした。。。

https://developers.line.biz/ja/news/2024/02/05/messaging-api-updated/

使ってね

markdown-flex-message はAIチャットボット以外にも多様な用途で活用できると思います。是非試してみてください!

https://github.com/Arahabica/markdown-flex-message

ボイスアップラボ

Discussion