こんにちは。先週は投稿をさぼってしまいました。
今回はALIS APIを使っていこうと思います。
Twitter APIから得て保存したデータを元に、今度はALIS APIを叩いてALISのユーザIDを保存したいと思います。
"use strict";
const { readFileSync } = require("fs");
const fetch = require("node-fetch");
const { DynamoDB } = require("aws-sdk");
const dynamodb = new DynamoDB({ region: "ap-northeast-1" });
const dynClient = new DynamoDB.DocumentClient({
endpoint: "http://localhost:8000",
service: dynamodb,
});
function getUsers() {
const users_obj = JSON.parse(readFileSync("json/ugokMembers.json", "utf-8"));
let users = [];
users_obj.forEach((user) => {
users.push({
id: user.user_id,
name: user.name,
});
});
return users;
}
今回書いたコードが上記です。
Users関数内でDBに保存しているユーザ情報を取得しています。
本当はユーザ名をDBから直接取っていたのですが、アクセス数を減らすために一度JSON形式に保存したものを読み込む形にしています。
ugokMembers.jsonには、それぞれのメンバーのuser_id, name, twitter_id, alis_idを書いています。
そこからそれぞれのuser_id, nameのみを取り出してusersリストに格納しています。
async function getAlisUser(user) {
const request = await fetch(
encodeURI(`https://alis.to/api/search/users?query=${user.name}`)
);
const body = await request.json();
if (body.length === 0) {
console.log(`${user.name}のデータがありません`);
} else {
const params = {
TableName: "Member",
Key: {
userId: user.id,
},
UpdateExpression: "SET #a.#i = :newId",
ExpressionAttributeNames: {
"#a": "alis",
"#i": "id",
},
ExpressionAttributeValues: {
":newId": body[0].user_id,
},
};
try {
dynClient.update(params).promise();
console.log(`success!${user.id},${user.name}`);
} catch (error) {
console.log(error);
}
}
}
次にgetAlisUser変数です。(なぜかハイライトがききませんでした😢)
この関数内でALIS APIを使用しています。
fetchを使ってリクエストを送りました。Twitterの名前を使ってユーザ検索をするため、URIに日本語や記号(例:やよい🌛UGOK)を含んでしまいます。そのため、そのままではリクエストを送ることができません。なので、encodeURI関数を使って、リクエストを送ることができる形にエンコードしています。
次に、今はまだALISのユーザー名をTwitterと同じにしていない人がいることがあります。そう言う場合にデータがなくてDBに保存できない!ということが起こりうるので、例外処理を挟んでいます。
ALISのユーザ情報が見つかった人のみ、次の処理に進むことができます。
DBにはALISのIDを保存したいので、Twitter名から検索して得たユーザ情報からidを抽出し、保存しています。
async function main() {
const users = getUsers();
Promise.all(
users.map(async (user) => {
getAlisUser(user);
})
).catch((error) => {
console.error(error);
});
}
main();
最後に全部を呼び出すmainの関数を用意して、、
これでUGOKのリストからTwitterのユーザを保存、そのユーザ名を元にALISのユーザを保存することができました!
ところどころにあるasync/await, Promiseについて、かなり苦戦したことを覚えています・・・;;なんとか実装できてよかったです。
次は記事のいいねの数を取得するAPIを使ったことについてまとめたいなと思います。
参考記事
promiseを繰り返したい!という時に見た記事が多すぎたので、一番参考になった記事を置いておきます。
--------------------------
以下:async/await, Promiseについての自分用メモ
async/awaitを使わずにこのコードを実行してしまうと、APIのレスポンスを待たずに次の処理にいってしまいます。そうなってしまうと、保存したいデータの中身を知らないまま、DBの更新処理にうつってしまいます。データをもっていないので当然エラーになりますよね。そうなることを防ぐために非同期処理を同期処理にするasync/await, Promiseを使います。
awaitをつけると、つけた処理が完了するまで待ってくれます。awaitはasync関数内でしか使うことができないので、functionの前にasyncをつけておきます。
async/awaitは最初は暗号のようでうまくできずに苦しみましたが、Promiseを勉強してから学ぶと少し理解しやすかったです。