見出し画像

Scratch apiの使い方まとめ

かなり雑な記事なのでこれを参考にするのはお勧めしない。もっとわかりやすい記事を作っているからそっちを書き終わったらこの記事は消す。

タイトルの通り。Scratch apiは公式ドキュメントなどは存在していないので結構使い方で苦戦する人が多いと思う。大体のapiを使えるようになるようにまとめようとしてみる。Api一覧はここにまとめてある。

前提

この記事ではJavascriptを使って説明する。変数やら関数やらの最低限の知識はあったほうがいいかもしれない。主はPythonわからないので。

GETメソッドを使うapiの使い方

GETメソッドを使う大体のものはブラウザにリンクを貼るだけで使える。apiを使ってみたいだけならこれでいいだろう。まあ、この記事ではコードを書く上での使い方を説明する記事だから、ブラウザのコンソール上とNode上で使う方法も説明する。

Scratchサイト内で開いたコンソール上でapiを使うことができる。一応サイト外で開いたコンソール上でも使えないことはないが、危険すぎる手段を使うのでやめたほうがいい。ここでも説明しない。

ブラウザのコンソール上でのコード例

xX_Freezer_Xxの基本情報を取得し、JSON化してコンソールに出力している。GETメソッドを使うapiなら大体はこれでいけるはず。
ドメインがscratch.mit.eduのapiなら最初の"https://scratch.mit.edu"を省いても動く。

const data = await(await fetch("https://api.scratch.mit.edu/users/xX_Freezer_Xx/",{headers:{"X-Requested-With":"XMLHttpRequest"}})).json();
console.log(data);

Node.js上でのコード例

Node.js v18.0以上を使っているならベータ版のfetch apiを使うことができる。なので上のコード例をasync修飾子を追加した関数の中で実行するだけでできる。

const a = async()=>{
   const data = await(await fetch("https://api.scratch.mit.edu/users/xX_Freezer_Xx/",{headers:{"X-Requested-With":"XMLHttpRequest"}})).json();
   console.log(data);
}
a();

関数の戻り値に入れたいなら

const getdata = async()=>{
   const data = await(await fetch("https://api.scratch.mit.edu/users/xX_Freezer_Xx/",{headers:{"X-Requested-With":"XMLHttpRequest"}})).json();
   return data;
}
const func = async()=>{
   const data = await getdata();
   console.log(data);
}
func();

ただ、Node v18はまだ対応していないサーバーもかなりあるのでfetchが使えないこともかなりある。ということでv18未満でも使えるhttpsとpromiseを使った取得方法を説明する。

promiseがどういうものなのかは自分で調べてくれ。

const https = require("https");
const getdata = ()=>{
   return new Promise((resolve)=>{
       https.get(`https://api.scratch.mit.edu/users/xX_Freezer_Xx/`,(resp)=>{
           let chunks = [];
           resp.on('data', (chunk) => {
           
               chunks.push(chunk);
             }).on("end",()=>{
               const data = Buffer.concat(chunks);
               const reg = JSON.parse(Buffer.from(data,"utf-8").toString())
               
               resolve(reg);
             })
       });
   })
 }
const func = ()=>{
   getdata().then((res)=>{console.log(res)});
}
func();

Nodejs上では、GETメソッドを使うものの中でsessionを取得するものだけ特殊。どうやって取得するのかがよくわからない。。

POST/PUTメソッドを使うものの使い方

POSTメソッドを使うものはブラウザにリンクを貼るだけでは使えない。Nodejsかブラウザのコンソール上でのみ動かせる。

ブラウザのコンソールでのコード例

bodyに何も入れる必要がないものならこれでいける。このコードはスタジオに作品を追加する。

const addtostudio =  async()=>{
   const token = (await(await fetch("/session",{headers:{"x-requested-with": "XMLHttpRequest"}})).json()).user.token;
   const add =  await fetch(`https://api.scratch.mit.edu/studios/31595385/project/685515407`,{headers:{"x-token":token,"x-requested-with": "XMLHttpRequest"},method:"POST"});
   console.log(add.status);
}
addtostudio();

bodyに何かを入れる必要があるならこう。bodyに文字列化させたJSON形式のデータを入れている。(JSON以外の何か別のものを入れるならもちろんその別の形式のものを入れる必要があるが、大体のものはJSONなのでここではJSONで説明させてもらう。)例のapiをまとめている記事で説明しているbodyをそのまま書き込めばいい。このコードではPUTメソッドを使っているが、POSTを使うならPUTの部分をPOSTに書き換えればいい。DELETEとかでも同じ。

これは説明欄を書き換えるコード。

const change =  async(body)=>{
   const token = (await(await fetch("/session",{headers:{"x-requested-with": "XMLHttpRequest"}})).json()).user.token;
   const add =  await fetch(`https://api.scratch.mit.edu/projects/714568806`,{headers:{"x-token":token,"content-type": "application/json"},method:"PUT",body:JSON.stringify(body)});
   console.log(add.status);
}
change({instructions:"hello"});

Node.js上でのコード例

ここはまだまだ書きかけ。修正も必要。主でもしっかりは理解していないからね。


Node.js上でのPOSTメソッドを使うのはかなり面倒。ほぼすべてのものはNode.js上でログインして取得できるパスワードのようなもの(scratchsessionidとscratchcsrftoken)が必要になる。さらに、ログインすると他のデバイスからログアウトされるScratchのだるすぎる仕様も相まって超絶めんどくさい。


ログイン方法

v18以上でのfetchを使ったコード例

const login = async (username, password) => {
 const res = await fetch("https://scratch.mit.edu/login/", {
     headers: {
         "x-csrftoken": "a",
         "x-requested-with": "XMLHttpRequest",
         "Cookie": "scratchcsrftoken=a;scratchlanguage=en;",
         "referer": "https://scratch.mit.edu"
     },
     body: JSON.stringify({ username, password, useMessages: true }),
     method: "POST"
 })
 if(res.status === 200) {
   const session = res.headers.get("set-cookie").match(/\"(.*)\"/g)[0];
   return session;
 }
}

const func = async()=>{
    const sessionid = await login("username","password");
    //この変数 sessionid にscratchsessionidが格納される。
}


v18未満でのhttpsとpromiseを使ったコード例

const https = require("https");
const login = (name,pass)=>{
 return new Promise((resolve) =>{
   const reqoptions = {
       hostname: 'scratch.mit.edu',
       path: '/login/',
       headers: {
         "x-csrftoken": "a",
         "x-requested-with": "XMLHttpRequest",
         "Cookie": "scratchcsrftoken=a;scratchlanguage=en;",
         "referer": "https://scratch.mit.edu"
       },
       method: "POST"
     }
     const data = JSON.stringify({ username:name, password:pass, useMessages: true })
     const req = https.request(reqoptions, res => {
 
         res.on('data', () => {
           console.log(res.statusMessage);
           for(c of res.rawHeaders){
             if(c.includes("scratchsessionsid")){
               resolve(c.match(/\"(.*)\"/g)[0]);
               break;
             }
           }
             resolve(res.rawHeaders[15].includes(""));
         });
     })
       
     req.on('error', error => {
       console.error(error);
     })
       
     req.write(data);
     req.end();
 
 })
 
}

login("username","password").then((res)=>{const sessionid = res;/*この変数にscratchsessionidが格納される。*/})

これに関してはどうしてこうなるのか考えずにそのまま使った方がいい。そんなこと考えても正直意味がないので。

sessionidを取得した後でNode上でApiを使う方法

上で説明したログインをする関数が使える状態が前提になる。

v18以上


間違いとか結構あると思うからあったら教えて。

関連記事


この記事が気に入ったらサポートをしてみませんか?