はじめに
前回の続きです。deno-linebotで画像なんかのファイルをポストした場合の扱い方がよくわからなかったので調べてみました。
Event.message.content()
ReadmeのEvent.message.content()に Get image, video, and audio data sent by users as a Buffer object. This is a shorthand for: LineBot.getMessageContent(event.message.messageId)
とさらっと説明されています。
let content = await event.message.content();
console.log(content.toString('base64'));
どういうことかと思ってソースコードを覗いてみるとこのへんとかこのへんがそれっぽい感じです。たしかにLineBot.getMessageContent()
っぽくmessageId
をキーにアップされたコンテンツをfetch()してますね。取得できたbufferをhex string化して返しています。
検証してみる
とりあえず前回のソースコードのメッセージ受信部を以下のように変更して実行します
bot.on('message', async (event: any) => {
try {
console.info(`Received message from LINE Client`)
console.info(`Type: ${event.type} ID: ${event.message.id}, Content: `)
let content = await event.message.content();
console.log(content.toString('base64'));
} catch (e) {
console.error(e)
}
})
deno run -A ./src/index.ts
適当な画像を投稿すると以下のようにそれっぽい文字列が出力されました
Received message fom LINE Client
Type: message ID: 458220234579902546, Content:
ffd8ffe000104a46494600010100000100010000ffe202284943435f50524f46494c450001010000021800000000043000006d6e74725247422058595a20000000000000000000000000616...
ちゃんと動いている感じなので、オウム返しを作り込んでみます。
やってみる
アップされた画像をサーバー上に保存してオウム返しするようにしてみます。まずファイルを保存するディレクトリを作成します
mkdir -p data
全ソースコードはこちら
import { opine, json, serveStatic } from "https://deno.land/x/opine@2.3.3/mod.ts";
import type { HTTPSOptions } from "https://deno.land/x/opine@2.3.3/mod.ts"
import { linebot } from "https://deno.land/x/linebot@v1.1.0/mod.ts"
import { hexToBuffer } from "https://deno.land/x/hextools/mod.ts";
const opineHttpsOptions: HTTPSOptions = {
port: 3000,
certFile: "cert/cert.pem",
keyFile: "cert/key.pem",
}
const options = {
channelId: "YOUR_CHANNEL_ID",
channelSecret: "YOUR_CHANNEL_SECRET",
channelAccessToken: "YOUR_CHANNEL_ACCESS_TOKEN",
verify: true
}
const bot = linebot(options)
const app = opine()
const linebotParser = bot.parser(json)
app.use(serveStatic("data"))
app.post("/messaging/event", linebotParser)
bot.on('message', async (event: any) => {
try {
console.info(`Received message from LINE Client`)
console.info(`Type: ${event.type} ID: ${event.message.id}`)
const content = await event.message.content()
const buffer = hexToBuffer(content)
const fileName = `${Date.now()}.jpg`
await Deno.writeFile(`./data/${fileName}`, buffer)
const baseUrl = `https://line-bot.bathtimefish.com:3000`
const contentUrl = `${baseUrl}/${fileName}`
await event.reply({
type: "image",
originalContentUrl: contentUrl,
previewImageUrl: contentUrl
})
} catch (e) {
console.error(e)
}
})
app.listen(opineHttpsOptions)
event.message.content()
で取得したhex stringをhextoolsを使ってArray Bufferに変換しています。
opineのserveStaticでdata
ディレクトリを外部に公開しています
実行します
deno run -A ./src/index.ts
画像をアップするとdata
ディレクトリに保存された画像のパスが生成され、リプライされます。はい猫ちゃんかわいいですねかわいい。
おわりに
同じ方法で動画や音声も扱えます。event.reply()
のメッセージオブジェクトに関してはEvent.reply(message)に解説されているので参考にしてください