# LIFFアプリを開発する
LIFFアプリは、HTMLやJavaScriptで構成されるウェブアプリです。ここでは、LIFFアプリを開発する手順とLIFFアプリ特有の処理について説明します。
# LIFFアプリのタイトルを設定する
LIFFアプリのタイトルは、LIFFアプリのタイトルバーに表示されます。
LIFFアプリのHTMLソースの<title>
要素に、LIFFアプリのタイトルを指定します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>タイトル</title>
# LIFFアプリにLIFF SDKを組み込む
LIFFアプリには、以下の2種類の方法でLIFF SDKを組み込めます。
# CDNパスを指定する
LIFF SDKで提供する機能を利用するには、LIFFアプリのHTMLソースの<script>
要素のsrc
属性に、LIFF SDKのCDNパスを指定します。
LIFFでは、以下の2種類のCDNパスを用意しています。目的に合ったCDNパスを指定してください。
CDNパス | 説明 |
---|---|
CDNエッジパス | メジャーバージョンのみを含むCDNパスです。常に最新の機能を使用する場合は、このCDNパスを使用します。メジャーバージョンがアップデートされたときのみURLを更新する必要があります。 例:https://static.line-scdn.net/liff/edge/2/sdk.js |
CDN固定パス | パッチバージョンまで含むCDNパスです。特定のバージョンの機能を使用する場合は、このCDNパスを使用します。LIFFアプリを更新しない限り、指定したパッチバージョンを使い続けることができます。LIFFの新機能や、セキュリティ改善、バグ修正を反映したいときのみURLを更新してください。自動的に更新されないため、LIFF SDKのアップデートの影響を受けません。 例:https://static.line-scdn.net/liff/edge/versions/2.22.3/sdk.js |
CDN固定パスを使用している開発者は、LIFFアプリを更新するタイミングを決める必要があります。アップデートの内容を正しく理解し、自分のLIFFアプリに適しているか判断するために、『LIFFドキュメント』の「リリースノート」をこまめに確認してください。
CDN固定パスを指定する例:
<script charset="utf-8" src="https://static.line-scdn.net/liff/edge/versions/2.22.3/sdk.js"></script>
LIFF SDKはUTF-8で書かれているため、HTMLソースをUTF-8以外の文字コードで作成する場合は、charset="utf-8"
をあわせて指定してください。
# npmパッケージを利用する
LIFFでは、npmパッケージも公開しています。npmを利用して、LIFF SDKをインストールすることもできます。
適切なSDKバージョンを使用することは開発者の責任です。SDKバージョンを最新の状態に保つために、LIFFリリースノートを定期的に確認し、ローカルのSDKを頻繁に更新してください。LIFFのバージョニングポリシーの詳細は『LIFF SDK(sdk.js)のアップデートポリシー』を参照してください。
webpack v5から、Node.jsのポリフィルが削除されました。 (opens new window)その影響により、webpack v5を使ったプロジェクトでLIFF v2.16.0以前のnpm版を使用すると、ビルド時にエラーが発生します。詳しくは、2021年10月26日のニュース、「LIFF v2.16.1をリリースしました」を参照してください。
LIFF SDKをnpmでインストールし、アプリに組み込むための手順は、以下のとおりです。
以下のコマンドをターミナルで実行し、npmでLIFF SDKをインストールしてください。
$ npm install --save @line/liff
あるいは、以下のコマンドをターミナルで実行し、YarnでLIFF SDKをインストールすることもできます。
$ yarn add @line/liff
SDKをアプリに組み込む
JavaScriptまたはTypeScriptファイルに以下のコードを組み込んでください。
import liff from '@line/liff'; liff.init({ liffId: '1234567890-AbcdEfgh', // Use own liffId });
TypeScriptの型の定義は
@line/liff
パッケージに含まれています。window.liff を宣言および編集しないでください下位互換性を維持するため、グローバルLIFFインスタンスの
window.liff
を宣言および編集しないでください。LINEが正常に動作しなくなる可能性があります。
関連ページ:https://www.npmjs.com/package/@line/liff (opens new window)
プラガブルSDKを使うと、LIFF SDKのファイルサイズを削減できます。詳しくは、「プラガブルSDK」を参照してください。
# LIFF APIを呼び出す
LIFF SDKを組み込むと、以下の操作を実行できます。
- LIFFアプリを初期化する
- LIFFアプリが動作している環境を取得する
- ログイン処理を行う
- URLを開く
- 二次元コードリーダーを表示する
- LIFFアプリが起動された画面を取得する
- ユーザーのプロフィールを取得する
- ユーザーとLINE公式アカウントの友だち関係を取得する
- 現在のページのパーマネントリンクを取得する
- 現在のトーク画面にメッセージを送信する
- ユーザーの友だちにメッセージを送信する(シェアターゲットピッカー)
- LIFFアプリを閉じる
# LIFFアプリを初期化する
liff.init()
メソッドを実行すると、LIFFアプリが初期化され、LIFFアプリからLIFF SDKのほかのメソッドを実行できるようになります。
LIFF URLへのアクセス時やLIFF間遷移時などに、URLに liff.*
のようなクエリパラメータが付与されることがあります。
例:
liff.state
(LIFF URLに指定した追加情報を示す)liff.referrer
(LIFF間遷移前のURLを示す。詳しくは、「LIFF間遷移前のURLを取得する」を参照してください)
上記は、LIFFアプリを正常に動作させるために、SDK側から付与されるクエリパラメータです。
LIFFアプリのURLに独自の処理を行う場合は、LIFFアプリの起動やLIFF間遷移などLIFFアプリの正常な動作を保証するため、liff.init
がresolveされるまでliff.*
のクエリパラメータを変更しないように設計してください。
以下のプロパティおよびメソッドは、liff.init()
メソッドを実行する前でも利用できます。
LIFFアプリを初期化する前にLIFFアプリを動作させている環境を取得したり、LIFFアプリ初期化に失敗した際にLIFFアプリを閉じたりできます。
- liff.ready
- liff.getOS()
- liff.getLanguage()
- liff.getVersion()
- liff.getLineVersion()
- liff.isInClient()
- liff.closeWindow()
- liff.use()
- liff.i18n.setLang()
liff.closeWindow()
メソッドは、LIFF SDKバージョンが2.4.0以上の場合のみ、liff.init()
によるLIFFアプリの初期化が終了する前でも実行できます。
liff.init()
メソッドのconfig
オブジェクトのwithLoginOnExternalBrowser
プロパティにtrue
を指定することで、外部ブラウザでのLIFFアプリ初期化時に、liff.login()
メソッドを自動で実行できます。
liff.init({
liffId: '1234567890-AbcdEfgh', // Use own liffId
withLoginOnExternalBrowser: true, // Enable automatic login process
}).then(() => {
// Start to use liff's api
});
liffId
に指定するLIFFアプリIDは、LIFFアプリをチャネルに追加すると取得できます。詳しくは、「LIFFアプリをチャネルに追加する」を参照してください。
liff.init({
liffId: '1234567890-AbcdEfgh', // Use own liffId
})
.then(() => {
// start to use LIFF's api
})
.catch((err) => {
console.log(err);
});
なお、liff.ready
で、LIFFアプリ起動後、liff.init()
の実行が初めて終了したときにresolveするPromise
オブジェクトを取得できます。
詳しくは、『LIFF v2 APIリファレンス』の「liff.init()」および「liff.ready」を参照してください。
liff.init()
メソッドは、1次リダイレクト先URLに付与されるliff.state
やaccess_token=xxx
などの情報を元に初期化処理を行います。エンドポイントURLにクエリパラメータやパスが含まれている場合、正しくLIFFアプリを初期化するために、1次リダイレクト先URLと2次リダイレクト先URLで、1回ずつliff.init()
メソッドを実行してください。リダイレクトについて詳しくは、「LIFF URLにアクセスしてからLIFFアプリが開くまでの動作について」を参照してください。liff.init()
メソッドが返すPromise
オブジェクトがresolveする前に、サーバーやフロントエンド側の処理などでURLを変更しないようにしてください。URLを変更すると、INIT_FAILED
が返され、LIFFアプリを開けません。たとえば、liff.init()
実行後にlocation.replace()
などでリダイレクトする場合は、Promise
オブジェクトがresolveされてから画面遷移するように設計してください。liff.init({ liffId: '1234567890-AbcdEfgh', // Use own liffId }).then(() => { // Redirect to another page after the returned Promise object has been resolved window.location.replace('https://liff.line.me/1234567890-AbcdEfgh/path'); });
liff.state
が含まれる1次リダイレクト先URLは、liff.init()
実行時に2次リダイレクト先URLへリダイレクトされます。liff.init()
実行前の1次リダイレクト先URLにはユーザーのアクセストークンなどの機密情報が含まれるため、Google Analyticsなど外部のロギングツールにURLの情報を送らないように注意してください。
なお、LIFF v2.11.0以降のバージョンでは、liff.init()
がresolveされたタイミングでURLから機密情報が除外されます。そのため、以下のようにthen()
メソッド内でページビューを送信することで、機密情報の漏洩を防ぐことができます。ロギングツールを利用する場合は、LIFFアプリをv2.11.0以降にバージョンアップすることをお勧めします。LIFF v2.11.0の更新内容について詳しくは、『LIFFドキュメント』の「リリースノート」を参照してください。liff.init({ liffId: '1234567890-AbcdEfgh', // Use own liffId }).then(() => { ga('send', 'pageview'); });
# 外部ブラウザでLINEログインを利用する場合
外部ブラウザでLINEログインを利用する場合は、以下のとおりliff.init()
メソッドを2回実行します。
LIFF SDKロード後に、
liff.init()
メソッドを実行します。liff.login()
メソッドを実行し、認証ページおよび認可画面の処理が終了すると、LIFFアプリ(redirectUri
)にリダイレクトされます。そこで、改めてliff.init()
メソッドを実行します。liff.init()
メソッドの処理中にエラーが発生した場合、またはログイン時にユーザーが認可をキャンセルした場合は、errorCallback
が実行されます。
LIFFブラウザ内でLINEログインによる認可リクエストを行った際の動作は保証されません。また、LIFFアプリを外部ブラウザやLINE内ブラウザで開く場合には、必ずliff.login()
メソッドでログイン処理を行い、LINEログインによる認可リクエストは行わないでください。
# LIFFアプリが動作している環境を取得する
liff.isInClient()
メソッドやliff.getOS()
メソッドなどを実行して、LIFFアプリが動作している環境を取得します。
// print the environment in which the LIFF app is running
console.log(liff.getLanguage());
console.log(liff.getVersion());
console.log(liff.isInClient());
console.log(liff.isLoggedIn());
console.log(liff.getOS());
console.log(liff.getLineVersion());
詳しくは、『LIFF APIリファレンス』の各メソッドを参照してください。
- liff.getLanguage()
- liff.getVersion()
- liff.isInClient()
- liff.isLoggedIn()
- liff.getOS()
- liff.getLineVersion()
# ログイン処理を行う
外部ブラウザおよびLINE内ブラウザの場合、liff.login()
メソッドを実行して、ログイン処理を行います。
LIFFブラウザの場合、liff.init()
実行時に自動でログイン処理が実行されるため、liff.login()
は利用できません。
liff.init()
メソッドのwithLoginOnExternalBrowser
プロパティをtrue
に指定した場合、外部ブラウザでもLIFFアプリ初期化時にliff.login()
メソッドを自動で実行することができます。詳しくは、『LIFF APIリファレンス』の「liff.init()」を参照してください。
// login call, only when external browser or LINE's in-app browser is used
if (!liff.isLoggedIn()) {
liff.login();
}
また、liff.logout()
メソッドを実行して、ログアウトすることもできます。
// logout call only when external browse or LINE's in-app browser is used
if (liff.isLoggedIn()) {
liff.logout();
window.location.reload();
}
詳しくは、『LIFF v2 APIリファレンス』の「liff.login()」および「liff.logout()」を参照してください。
# URLを開く
liff.openWindow()
メソッドを実行して、指定したURLをLINE内ブラウザまたは外部ブラウザで開きます。
以下のコードはhttps://line.me
を外部ブラウザで開きます。
// openWindow call
liff.openWindow({
url: 'https://line.me',
external: true,
});
詳しくは、『LIFF v2 APIリファレンス』の「liff.openWindow()」を参照してください。
# 二次元コードリーダーを表示する
liff.scanCodeV2()
メソッドを実行して、二次元コードリーダーを起動し、ユーザーが読み取った文字列を取得します。
// scanCodeV2 call
liff.scanCodeV2()
.then((result) => {
// e.g. result = { value: 'Hello LIFF app!' }
})
.catch((err) => {
console.log(err);
});
詳しくは、『LIFF APIリファレンス』の「liff.scanCodeV2()」を参照してください。
従来のliff.scanCode()
メソッドは非推奨になります。二次元コードリーダーを実装する場合は、liff.scanCodeV2()
メソッドを使用することをお勧めします。
liff.scanCodeV2()
メソッドは以下の環境で動作します。
- iOS:iOS14.3以降かつLINEバージョン11.7.0以降
- Android:LINEバージョン11.7.0以降
- 外部ブラウザ:WebRTC API (opens new window) をサポートするウェブブラウザ
OS | バージョン | LINEアプリのバージョン | 外部ブラウザ | |
---|---|---|---|---|
10.17.0〜11.6.x | 11.7.0以降 | |||
iOS | 11〜14.2 | ❌ | ❌ | ✅ ※1 |
14.3以降 | ❌ | ✅ ※2 | ✅ ※1 | |
Android | すべてのバージョン | ❌ | ✅ ※2 | ✅ ※1 |
PC | すべてのバージョン | ❌ | ❌ | ✅ ※1 |
※1 WebRTC API (opens new window)をサポートするウェブブラウザのみ利用できます。
※2 LIFFブラウザの画面サイズがFull
の場合のみ利用できます。詳しくは、『LIFFドキュメント』の「LIFFブラウザの画面サイズ」を参照してください。
LIFFアプリをチャネルに追加するときに、[Scan QR]をオンにしてください。[Scan QR]の設定は、LIFFアプリ追加後もLINE DevelopersコンソールのLIFFタブで変更できます。
# LIFFアプリが起動された画面を取得する
liff.getContext()
メソッドを実行して、LIFFアプリが起動された画面(1対1のトーク、グループトーク、複数人トーク、または外部ブラウザ)に関する情報を取得します。
const context = liff.getContext();
console.log(context);
// {"type": "utou", "userId": "U70e153189a29f1188b045366285346bc", "viewType": "full", "accessTokenHash": "ArIXhlwQMAZyW7SDHm7L2g", "availability": {"shareTargetPicker": {"permission": true, "minVer": "10.3.0"}, "multipleLiffTransition": {"permission": true, "minVer": "10.18.0"}}}
詳しくは、『LIFF v2 APIリファレンス』の「liff.getContext()」を参照してください。
# ユーザーのプロフィールを取得する
LIFFアプリでIDトークンを取得して、ユーザーのプロフィールを取得する方法は2つあります。 目的に合わせて正しく使い分けてください。
LIFFアプリをチャネルに追加するときに、openid
スコープを選択してください。スコープを選択しなかった場合やユーザーが認可しなかった場合は、IDトークンを取得できません。スコープの選択は、LIFFアプリ追加後もLINE DevelopersコンソールのLIFFタブで変更できます。
LIFFアプリをチャネルに追加するときに、email
スコープを選択し、ユーザーが認可すると、メールアドレスも取得できます。スコープの選択は、LIFFアプリ追加後もLINE DevelopersコンソールのLIFFタブで変更できます。
# サーバーに送信するために取得する
LIFFアプリからサーバーにユーザー情報を送信する場合は、以下の方法で取得したアクセストークンまたはIDトークンを送信します。 サーバーでユーザー情報を使用する方法について詳しくは、「LIFFアプリおよびサーバーでユーザー情報を使用する」を参照してください。
liff.getAccessToken()
メソッドを実行して、現在のユーザーのアクセストークンを取得します。なお、ユーザーがLIFFアプリを閉じると、有効期限が切れていなくてもアクセストークンは無効化されます。// get access token if (!liff.isLoggedIn() && !liff.isInClient()) { window.alert('To get an access token, you need to be logged in. Tap the "login" button below and try again.'); } else { const accessToken = liff.getAccessToken(); console.log(accessToken); }
詳しくは、『LIFF v2 APIリファレンス』の「liff.getAccessToken()」を参照してください。
liff.getIDToken()
メソッドを実行して、「現在のユーザーの生のIDトークン」を取得します。liff.init(() => { const idToken = liff.getIDToken(); console.log(idToken); // print raw idToken object });
詳しくは、『LIFF v2 APIリファレンス』の「liff.getIDToken()」を参照してください。
# LIFFアプリで使用するために取得する
liff.getDecodedIDToken()
メソッドを実行して、現在のユーザーのプロフィール情報およびメールアドレスを取得します。
LIFFアプリでユーザーの表示名などを利用する場合に、このAPIを利用してください。
liff.getDecodedIDToken()
で取得したユーザー情報をサーバーに送信しないでください。
代わりに、liff.getIDToken()
で取得したIDトークンを送信します。
liff.init(() => {
const idToken = liff.getDecodedIDToken();
console.log(idToken); // print decoded idToken object
});
詳しくは、『LIFF v2 APIリファレンス』の「liff.getDecodedIDToken()」を参照してください。
# ユーザーとLINE公式アカウントの友だち関係を取得する
ユーザーと、LIFFアプリが追加されているLINEログインのチャネルにリンクされているLINE公式アカウントの友だち関係を取得します。
LINEログインのチャネルにLINE公式アカウントをリンクする方法については、『LINEログインドキュメント』の「LINEログインしたときにLINE公式アカウントを友だち追加する(友だち追加オプション)」を参照してください。
liff.getFriendship().then((data) => {
if (data.friendFlag) {
// something you want to do
}
});
詳しくは、『LIFF v2 APIリファレンス』の「liff.getFriendship()」を参照してください。
LIFFアプリをチャネルに追加するときに、profile
スコープを選択してください。スコープを選択しなかった場合やユーザーが認可しなかった場合は、友だち関係を取得できません。スコープの選択は、LIFFアプリ追加後もLINE DevelopersコンソールのLIFFタブで変更できます。
# LIFFアプリの任意のページのパーマネントリンクを取得する
liff.permanentLink.createUrlBy()
メソッドを実行して、LIFFアプリの任意のページのパーマネントリンクを取得できます。
// For example, if the endpoint URL of the LIFF app is https://example.com/path1?q1=v1 and its LIFF ID is 1234567890-AbcdEfgh
liff.permanentLink
.createUrlBy('https://example.com/path1?q1=v1')
.then((permanentLink) => {
// https://liff.line.me/1234567890-AbcdEfgh
console.log(permanentLink);
});
liff.permanentLink
.createUrlBy('https://example.com/path1/path2?q1=v1&q2=v2')
.then((permanentLink) => {
// https://liff.line.me/1234567890-AbcdEfgh/path2?q=2=v2
console.log(permanentLink);
});
詳しくは、『LIFF v2 APIリファレンス』の「liff.permanentLink.createUrlBy()」を参照してください。
# 現在のトーク画面にメッセージを送信する
liff.sendMessages()
メソッドを実行して、ユーザーの代わりに、LIFFアプリが開かれているトーク画面にメッセージを送信します。この機能は1対1のトークルームから起動したLIFFアプリでのみ利用できます。1回のリクエストでメッセージオブジェクトを最大5つまで送信できます。
以下のコードは、LIFFアプリが表示されているトーク画面に、ユーザーのメッセージとして「Hello, World!」を送信します。
// sendMessages call
if (!liff.isInClient()) {
window.alert('This button is unavailable as LIFF is currently being opened in an external browser.');
} else {
liff.sendMessages([
{
type: 'text',
text: 'Hello, World!',
},
])
.then(() => {
window.alert('Message sent');
})
.catch((error) => {
window.alert('Error sending message: ' + error);
});
}
詳しくは、『LIFF v2 APIリファレンス』の「liff.sendMessages()」を参照してください。
# ユーザーの友だちにメッセージを送信する(シェアターゲットピッカー)
liff.shareTargetPicker()
メソッドを実行して、ターゲットピッカー(グループまたは友だちを選択する画面)を表示し、ターゲットピッカーで選択した相手に、開発者が作成したメッセージを送信します。このメッセージは、ユーザーが送信したかのように、グループまたは友だちに表示されます。
以下のコードは、ターゲットピッカーを表示し、選択したグループまたは友だちに、ユーザーのメッセージとして「Hello, World!」を送信します。
あらかじめ、liff.isApiAvailable()
メソッドを実行すると、LIFFアプリを起動した環境でターゲットピッカーが使用可能であることを確認できます。
if (liff.isApiAvailable('shareTargetPicker')) {
liff.shareTargetPicker([
{
type: 'text',
text: 'Hello, World!',
},
]);
}
詳しくは、『LIFF v2 APIリファレンス』の「liff.isApiAvailable()」および「liff.shareTargetPicker()」を参照してください。
- ターゲットピッカーを表示するには、LINE Developersコンソールでシェアターゲットピッカーをオンにしてください。詳しくは、「シェアターゲットピッカーを利用するには」を参照してください。
- 外部ブラウザで利用する場合は、
liff.login()
を呼び出して、ログイン処理を行ってから、liff.shareTargetPicker()
を呼び出します。
# LIFFアプリを閉じる
liff.closeWindow()
メソッドを実行して、開いているLIFFアプリを閉じます。
// closeWindow call
if (!liff.isInClient()) {
window.alert('This button is unavailable as LIFF is currently being opened in an external browser.');
} else {
liff.closeWindow();
}
詳しくは、『LIFF v2 APIリファレンス』の「liff.closeWindow()」を参照してください。
liff.closeWindow()
の外部ブラウザでの動作は、保証対象外です。
# OGPタグを設定する
LIFFアプリの各ページにOGPタグを設定すると、たとえばLINEのトークルームでLIFFアプリのURL(https://liff.line.me/{liffId}
)をシェアしたときに、任意のタイトルや説明文、サムネイル画像を表示できます。
LIFFで対応しているOGPタグは以下のとおりです。 OGPタグについて詳しくは、「The Open Graph protocol (opens new window)」を参照してください。
<html lang="ja" prefix="og: http://ogp.me/ns#">
<meta property="og:title" content="タイトル">
<meta property="og:type" content="`website`、`blog`、または`article`">
<meta property="og:description" content="ページの簡単な説明">
<meta property="og:url" content="ページのURL">
<meta property="og:site_name" content="サイト全体を表す名前">
<meta property="og:image" content="サムネイル画像のURL">
LIFFアプリのURLを、line://app/{liffId}
(非推奨)の形式でシェアしたときは、OGPタグは無視されます。
# LIFFアプリではない外部のサイトに遷移した場合(LINEバージョン12.13.0以降のみ)
LINEのバージョン12.13.0以降のLIFFブラウザでは、LIFFアプリからLIFFアプリでない外部サイトを開いた場合、「外部サイトに遷移した」ということを示すポップアップが表示されます。
ポップアップは、同じウィンドウで外部サイトを開いた場合にのみ表示されます。別のウィンドウで外部サイトを開いた場合は、ポップアップは表示されません。
LIFFアプリで、エンドポイントURL(例:https://example.com/path
)より上の階層(例:https://example.com/
)へ遷移した際の動作は保証されません。
# 次のステップ
LIFFアプリを開発したら、任意のサーバーにデプロイしてください。デプロイ後は、以下の操作を行います。