LoginSignup
2
1

More than 3 years have passed since last update.

Movable Type 7のData APIをJavaScriptのみで実装する

Last updated at Posted at 2020-09-10

本題について

Movable Type 7(以下MT)のData APIの実装を
jQueryで書いてるのはよく見かけるのですが、
JavaScriptのみはなかなか見つからなかったので、
以下4つのAPIをJavaScriptのみで実装してみましたので、
ここに紹介します。

  • login(ログイン)
  • logout(ログアウト)
  • Entries collection(記事一覧の取得)
  • Update single entry(記事の更新)※ここでは記事タイトル・記事本文の更新です。

参考

なお、ログイン成功時に取得したセッションデータは、sessionStorageに保存し、
認証に必要なAPI呼び出し時に、参照されるように実装しました。

環境

  • Movable Type Pro r.4607

ここではMTの本体は、localhost/mt7/ への配置とします。
エンドポイント以下になります。

http://localhost/mt7/mt-data-api.cgi/v4/・・・

Data API呼び出し方法

jQueryでは、以下の実装をよく見かけます。

$.ajax()

本題ではJavaScriptのみなので、window.fetchを使いました。

window.fetch(url, option)

url:Data APIのURL
option: ヘッダー情報、送信データ、送信形式を含めたJSON形式のデータ
参考 Fetch の使用

login(ログイン)

流れは以下。
- ユーザー名、パスワード(※)、クライアントIDを含めたリクエストボディを送信する
- ログインに成功したら、取得したsessionId等の各種情報をsessionStorageに保存する

※ここでパスワードとは、MTログイン時のパスワードではなく、「Webサービスパスワード」です。(MTのユーザー情報で確認できます)

const apiUrl = 'http://localhost/mt7/mt-data-api.cgi/v4/';
const clientId = 'authentication_signin_sample'; // 任意の文字列でOK
const currentSession = `mt_session_${clientId}`; // こちらも任意の文字列でOK
const currentToken = `mt_token_${clientId}`; // こちらも任意の文字列でOK

const login = ({ username, password } = { username: '', password: '' }) => {
  // リクエストボディ(ユーザー、パスワード、clientId)をセットする
  const body = new FormData();
  body.set('username', username);
  body.set('password', password);
  body.set('clientId', clientId);

  window.fetch(`${apiUrl}authentication`, {
    method: 'post',
    body,
    headers: { Accept: 'application/json' },
  })
    .then((data) => data.json())
    .then((data) => {
      if (data.error) {
        console.log(`NG!: ${data.error}`);
        return;
      }
      // ログインに成功したら、sessionStorageにSessionとTokenをセットする
      window.sessionStorage.setItem(currentSession, data.sessionId);
      window.sessionStorage.setItem(currentToken, JSON.stringify({
        accessToken: data.accessToken,
        expiresIn: data.expiresIn,
        gotTokenTime: Math.floor(new Date().getTime() / 1000),
      }));
      console.log('DONE!');
    })
    .catch((e) => { console.log(`NG!: ${e}`); });
};

ログイン成功時、取得したsessionId, accessTokenは以下になります。
(参考)

{
  "accessToken": "0t60z2zrz89WSfi8euUl21VZ3LOG4tc1pYWhzZLj",
  "sessionId": "ThRsb2XwYvFs93gvmbUeF3nu3JDIEIYP8polopI6",
  "expiresIn": 3600,
  "remember": false
}

logout(ログアウト)

ログイン成功時に取得したsessionIdをheader情報に加えdeleteします。
ログアウトに成功したら、sessionStorageを削除します。

const logout = () => {
  window.fetch(`${apiUrl}authentication`, {
    method: 'delete',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      'X-MT-Authorization': `MTAuth sessionId=${window.sessionStorage.getItem(currentSession)}`,
    },
  })
    .then((data) => {
      if (data.error) {
        console.log(`NG!: ${data.error}`);
        return;
      }
      window.sessionStorage.removeItem(currentSession);
      console.log('DONE!');
    })
    .catch((e) => { console.log(`NG!: ${e}`); });
};

Entries collection(記事一覧の取得)

記事一覧の取得は、認証を必要としないので、ヘッダー情報は不要です。

const getEntries = () => {
  window.fetch(`${apiUrl}sites/1/entries`) // 1はブログID
    .then((res) => res.json())
    .then((data) => {
      if (data.error) {
        console.log(`NG!: ${data.error}`);
        return;
      }
      // 取得したdataのitemsに全記事データを持ってます
      console.log(`DONE!: ${JSON.stringify(data.items)}`);
    })
    .catch((e) => { console.log(`NG!: ${e}`); });
};

Update single entry(記事の更新)

updateEntryの引数に、記事ID、記事タイトル、記事本文を渡します。
ログイン成功時に取得したaccessTokenをheader情報に加えます。

ちょっと謎の仕様なのですが、Data APIでは URLの末尾に__method=PUT パラメタを付けてPOSTすることで更新が可能のようです。
参考 MTDataAPIDebugger で Data API v2 を理解する

const updateEntry = (data) => {
  const { entryId, entryTitle, entryBody } = data;

  const body = new FormData();
  body.set('entry', JSON.stringify({
    title: entryTitle,
    body: entryBody,
  }));
  window.fetch(`${apiUrl}sites/1/entries/${entryId}?__method=PUT`, { // 1はブログID
    method: 'post',
    body,
    headers: { // MIMEタイプと、ログイン完了後に取得したaccessTokenをヘッダーに設定する
      Accept: 'application/json',
      'X-MT-Authorization': `MTAuth accessToken=${JSON.parse(window.sessionStorage.getItem(currentToken)).accessToken}`,
    },
  })
    .then((res) => res.json())
    .then((res) => {
      if (res.error) {
        console.log(`NG!: ${res.error}`);
        return;
      }
      console.log(`DONE!: ${JSON.stringify(res)}`);
    })
    .catch((e) => { console.log(`NG!: ${e}`); });
};

参考

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