2
0

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 1 year has passed since last update.

deno-linebotで画像ファイルを扱ってみる

Posted at

はじめに

前回の続きです。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) とさらっと説明されています。

sample.ts
let content = await event.message.content();
console.log(content.toString('base64'));

どういうことかと思ってソースコードを覗いてみるとこのへんとかこのへんがそれっぽい感じです。たしかにLineBot.getMessageContent()っぽくmessageIdをキーにアップされたコンテンツをfetch()してますね。取得できたbufferをhex string化して返しています。

検証してみる

とりあえず前回のソースコードのメッセージ受信部を以下のように変更して実行します

src/index.ts
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

全ソースコードはこちら

src/index.ts
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のserveStaticdataディレクトリを外部に公開しています

実行します

deno run -A ./src/index.ts

画像をアップするとdataディレクトリに保存された画像のパスが生成され、リプライされます。はい猫ちゃんかわいいですねかわいい。

Screenshot.png

おわりに

同じ方法で動画や音声も扱えます。event.reply()のメッセージオブジェクトに関してはEvent.reply(message)に解説されているので参考にしてください

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?