Edited at

【chrome extension】ダウンロードが"完了したとき"にアクションを行う方法


この記事は?

chrome.downloads.onCreated.addListener()を使うと「ダウンロードシーケンスを開始した時」になってしまいますね。

ダウンロード先を決めるウィンドウが開いている時すでにリスナーは発火しているわけです。

そうではなく「ダウンロードし終わった時」にアクションを起こしたい場合はどうすればいいのかを解説します。


コード紹介

まずは結論から、ということでコードをそのまま紹介します。

let myDownloadItem = undefined

chrome.downloads.onCreated.addListener((downloadItem) => {
// 後で使用する。必要なければonCreated()の部分は不要
myDownloadItem = downloadItem
})

chrome.downloads.onChanged.addListener((downloadDelta) => {
let nowState = downloadDelta.state
if (nowState && nowState.current == 'complete') {

// myDownloadItemを使用して必要な処理を行う

myDownloadItem = undefined // 必要ないかもしれない
}
});


解説

onChanged.addListener()でコールバック関数に渡されるのはDownloadItemではなくDownloadDeltaです。

downloadDeltaとは簡単に言うと「DownloadItemのプロパティの内、適当なものが変化したもの」です。

学校の物理の授業で何らかの値xが時間経過などで変化したものをx'と書いたのと同じノリです。

原文を載せておきます。


An object representing the downloads.DownloadItem object that changed, and the status of all the properties that changed in it.

https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/API/downloads/onChanged#addListener_syntax


さて、DownloadDeltaですが、console.log()で確認したところ、以下のような感じでした。

{

"endTime": {
"current": "2019-10-26T04:36:57.568Z"
},
"id": 82,
"state": {
"current": "complete",
"previous": "in_progress"
}
}

ここで注目するべきはstateです。

このstateDownloadItemのプロパティのstateです。

その型はdownloads.Stateとなっており、その値は以下の3つです。


  • in_progress

  • interrupted

  • complete

実装者はこれら3つの値を判別しif文でも使用して適切に処理を分けることが可能になるわけですね。

これで解説は以上です。


宣伝

今回紹介したテクニックを用いて初めてのChrome extensionを作成しました。

ReDownload: https://chrome.google.com/webstore/detail/redownload/ofjdipkapbcippofdocjaefbgekmkoai?utm_source=chrome-ntp-icon


参考資料

stack overflow: How to make Chrome Downloads API wait until a download has ended?