LINEBotに送った画像をGoogleDriveに保存して共有URLを返すまで
はじめに
GoogleDriveAPIを触っていたので、LINEBotに送信した画像を代わりにアップロードし、共有URLを返して欲しくなったので実装してみました。
どうなりたいか
LINEBotに送った画像をGooleDriveにアップロードし、共有URLを返してくれるDEMO #lineapi pic.twitter.com/eHoLXtrQvb
— ようかん / Yosuke Inoue @LAE (@inoue2002) January 23, 2021
単純に画像URLが欲しい時に使う感じです。(パソコンだとなんとでもなるけど、スマホ単体の時には結構助かる)
仕組み
①画像を受け取るLINEBotを実装する
LINEBotでユーザーから画像メッセージを受け取ると以下のようなJSONが送られてきます。
{
"type": "message",
"replyToken": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"source": { "userId": "123456789abcdefghijk", "type": "user" },
"timestamp": 1611364562326,
"mode": "active",
"message": {
"type": "image",
"id": "13429433729723",
"contentProvider": {
"type": "line"
}
}
}
LINE Messaging APIでは直接画像データが送られてくる訳ではないので注意が必要です。
JSONの中のmessage
プロパティの中にあるid
を使ってコンテンツ取得のAPIを叩くことでデータを取得することができます。
※画像の他にも動画や音声ファイルなども同じようにid
が送られてきます。
詳しくは公式のリファレンスのこちらをご覧ください。
②メッセージIDから画像データを取得する
LINE Messaging APIにはユーザーが送ってきたデータをコンテンツ取得のAPIを利用して扱うことができます。詳しくは公式リファレンスはのこちらをご覧ください。
nodejsだと以下のように利用できます(公式リファレンス引用)
const line = require('@line/bot-sdk');
const client = new line.Client({
channelAccessToken: '<channel access token>'
});
client.getMessageContent('<messageId>')
.then((stream) => {
stream.on('data', (chunk) => {
...
});
stream.on('error', (err) => {
// error handling
});
});
③サービスアカウントを作成する
まず、サービスアカウントというものを作成しなければいけません。
LambdaからgoogleDriveAPIを操作するこちらの記事の通りにサービスアカウントを作成し、連携することで、google APIを利用することができるようになります。
④サービスアカウントにGoogle Driveのファイルを共有する
画像をアップロードする権限を付与しなければいけません。
サービスアカウントを作成したときにダウンロードするJSONの中にあった、client_email
のメールアドレスをコピーし、画像をアップロードしたいDriveのファイルをそのメールアドレスに共有します。
▼GoogleDriveでフォルダ共有の方法
⑤フォルダIDを取得する
先ほどサービスアカウントに共有したフォルダを開き、そのフォルダのIDを取得します。
https://drive.google.com/drive/u/1/folders/xxxxxxxxxxxxxxxxxxxxxxxx
フォルダを開いた状態の時のurlを確認し、/folders以降のxxxxxxxxxxxxxxxxxxxxxxxx
をコピーします。
⑥Google APIでGoogle Driveにアップロードする
画像をアップロードする部分は以下のように書くことができます。
const drive = google.drive({ version: "v3", auth: jwtClient });
//アップロードする画像のデータを取得
const imageStream = await client.getMessageContent(event.message.id);
var fileMetadata = {
//nameはDriveに保存する時のファイル名になります
name: `photo.jpg`,
parents: ["<先ほど取得したフォルダID>"],
};
var media = {
mimeType: "image/jpeg",
body: imageStream,
};
await drive.files.create(
{
resource: fileMetadata,
media: media,
fields: "id",
},
function (err, file) {
if (err) {
// Handle error
console.error(err);
} else {
//file.data.idをアップロードされたファイルID
resolve(file.data.id);
}
}
);
⑦返ってきたファイルIDを元に画像URLを作る
https://drive.google.com/uc
にパラメータとして先ほど取得したファイルIDをつけることで画像URLが完成します。
ex)
https://drive.google.com/uc?id=1T4QABnxnU_gNt6ORxNvnKU9EiiFxn795
⑧応答するメッセージを作成(リファレンス引用)
応答メッセージの記述も公式リファレンスを参考にしながら書くことができます。こちら
const line = require('@line/bot-sdk');
const client = new line.Client({
channelAccessToken: '<channel access token>'
});
const message = {
type: 'text',
text: '保存に成功したよ!https://drive.google.com/uc?id=1T4QABnxnU_gNt6ORxNvnKU9EiiFxn795'
};
client.replyMessage('<replyToken>', message)
.then(() => {
...
})
.catch((err) => {
// error handling
});
最後に
はじめてGoogle Drive APIを触ったついでに作ってみたのですが、やっぱり何かと画像URLを作成してくれるのは楽ですよね。PCがあればそれほど必要ないかもしれないですが、何かと役に立ちますよ。是非皆さんも挑戦してみてください。お疲れ様でした。
▼ちなみにGoogleDriveの反映スピード半端ないです。
LINEBot▶️googleDrive 画像のアップロードに成功した#lineapi pic.twitter.com/PC59b6CmfG
— ようかん / Yosuke Inoue @LAE (@inoue2002) January 20, 2021
Author And Source
この問題について(LINEBotに送った画像をGoogleDriveに保存して共有URLを返すまで), 我々は、より多くの情報をここで見つけました https://qiita.com/inoue2002/items/5732568fe640e1e7bb79著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .