Facebook Graph APIを試してMapbox上で可視化

# 目的
- Facebook Graph API 位置情報があるデータを取得してみる
- 個人のFacebook写真アルバム内の写真情報を取得し
- Mapbox経由で位置情報がある写真をWeb可視化

# 1. About Facebook Graph API
## 1.1. 概要
参考
[https://developers.facebook.com/docs/graph-api/overview](https://developers.facebook.com/docs/graph-api/overview)
- Facebook上のアプリを開発する人が、ユーザーのFacebookにある情報をアクセスできるAPI
- ユーザーがそのAppliを利用したら「アプリがユーザー情報にアクセス可能」を承認しないと
- アクセスできるのFacebook情報種類が色々
- 今回写真関係の情報をチェックしてみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168196/f50625b5-fb50-f73a-a329-198385916494.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168196/0fe75d10-ba40-029b-bef1-83e2b335718b.png)



## 1.2. APIを触ってみる

以下のConsoleでAPIをTryできる
https://developers.facebook.com/tools/explorer/?method=GET&path=me&version=v14.0

`me` だけをRequestしたら個人アカウントのBasic情報がでてる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168196/4703213e-c008-e668-a1a5-8581e243f4bf.png)

左側に`albums/photos`をBrowseしたらデータが色々でてます。
これから位置情報があるを探してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168196/0a606d43-811e-4003-77c4-1e6b2116f677.png)

位置情報が出てないけど、`albums/photos/place` を検索したら追加されてます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168196/34a72af6-ebbb-ba4c-966d-dae1018d41bd.png)

画像URLを追加してEnoughだと思います
OKになればGETに書いてあるCURLをjavascript上で利用できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168196/1ebef4bf-e8d7-ed84-0bbf-6d3bf83cb631.png)

```javascript
curl = "https://graph.facebook.com/v14.0/me?fields=albums%7Bphotos.%7Bpicture%2Cplace%7D%7D&access_token="+token
```

# 2.Mapbox上で可視化
## 2.1. geojson作成とLayer設定
- 上記のResponseがAlbumごとで、JavascriptでScanしてMapboxで使えるGeojsonを作成
- コードイメージ：
```javascript
const curl = "https://graph.facebook.com/v14.0/me?fields=albums%7Bphotos.%7Bpicture%2Cplace%7D%7D&access_token="+token;

axios.get(url).then(function(result){
  const albums=result.data.albums.data;
  processAlbum(albums);
)};

function processAlbum(albums){
    for(var j=0; j < albums.length; j++){
      if(albums[j].photos){
      var photo = albums[j].photos.data;
          for(var i=0; i < photo.length; i++){
                  var thumb = photo[i].picture;
                  if(photo[i].place && photo[i].place.location){
                    var place_name = photo[i].place.name
                    var lon = photo[i].place.location.longitude;
                    var lat = photo[i].place.location.latitude;
                    addMapboxGeojson(thumb,place_name,lon,lat);
                }
            }
          }
       }
    }
}


```

- 最終的なGeojsonイメージがこちら
```json
fbjson =
[
{
        "type": "Feature",
        "properties": {
            "name": "Inis Mor, Aran Islands",
            "img": "https://scontent-nrt1-1.xx.fbcdn.net/v/t1.18169-9/393470_4579134715906_2075779361_n.jpg?stp=dst-jpg_p110x80&_nc_cat=108&ccb=1-7&_nc_sid=caaa8d&_nc_ohc=eHb63BUWeK8AX--KfO7&_nc_ht=scontent-nrt1-1.xx&edm=AC7C4-wEAAAA&oh=00_AT8TI9UX3xKNSJ6ztqNLi-ipfhozASuTE6z0YLBVlK91xA&oe=630C5776"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [
                -9.6643103442363,
                53.105765577622
            ]
        }
    },
    {
        "type": "Feature",
        "properties": {
            "name": "Inis Mor, Aran Islands",
            "img": "https://scontent-nrt1-1.xx.fbcdn.net/v/t1.18169-9/564276_4579135475925_1452845447_n.jpg?stp=dst-jpg_s130x130&_nc_cat=100&ccb=1-7&_nc_sid=caaa8d&_nc_ohc=ol4Vit2jxc8AX99ZUDn&_nc_ht=scontent-nrt1-1.xx&edm=AC7C4-wEAAAA&oh=00_AT-nMPADdHwceZ2GEoyu3c8qN0VuVQJJWp3zFZvykQxJ2g&oe=630D7F60"
        },
        "geometry": {
            "type": "Point",
            "coordinates": [
                -9.6643103442363,
                53.105765577622
            ]
        }
    },

...

]
```

- Mapbox layer とそのPopup設定イメージ 
- MapboxのBasic Codeから載せました
```javascript
map.addSource('places', {
    "type":"geojson",
    "data":fbjson
});

map.addLayer({
  "id": "places",
  "source": "fbplaces",
  "type": "circle",
  "paint": {
      "circle-radius": 3.5,
      "circle-color": "#ff00aa",
      "circle-opacity":0.6
  }
},
);

 map.on('mousemove', function (e) {
    var fe = map.queryRenderedFeatures(e.point, {layers: ['places']});
    if(fe.length){
         var clon = fe[0].geometry.coordinates[0];
         var clat = fe[0].geometry.coordinates[1];
         var place_name = fe[0].properties.name;
         var popupcontent = place_name+"<br><table><tr>";
         for(var j=0; j < fe.length; j++){
            if (j<3){
             var n = fe.length - j-1;
             var img_url = fe[n].properties.img;
             popupcontent += "<td>　<img src='"+img_url+"'/>　</td>";
           }
         }
             popup.setLngLat([clon,clat])
             .setHTML(popupcontent+"</tr></table>")
             .addTo(map);
    } else {
      popup.remove();
    }
  });
```

## 2.2. 結果 & 課題

PointにHoverするとPopupがでてます
![Capture d’écran 2022-08-04 à 13.03.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168196/c60ee3b9-80cb-0a69-13ce-4814714127d0.png)

- Graph API のtokenが1~2時間しか使えないので、毎回事前にAPIのTokenを作らないと
- Front End beginnerで手動でFacebook for developersページ上でTokenを取得＆コピーし、可視化画面にはりつ
- 個人情報のために例えば全体的なユーザーのPublic投稿を取得できない。Appliの承認したの各ユーザーしか取れない
- このページが完全にClient Sideで、Databaseとかに保存してない
- POIの位置が違う可能性があります。細かい地図を作りたければFacebook上でAnother locationを設定しよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168196/3ea122c2-b44a-7aa0-81a3-5a79aab3ed63.png)

# 最後に
使ってみたければ
https://github.com/bordoray/facebook-insight

**以上** :earth_africa: