はじめに
皆さんはVRChatというゲームを知っていますか?VRの中で色んな人とおしゃべりをするゲーム(SNS?)です。
このゲーム、コミュニティ主導のプロジェクト(公式ではない)として、APIが存在します。
本記事ではこのAPI利用について、Pythonを用いた実装方法を共有します。
なにができるの?
例えば以下に挙げるような内容をゲームの中からではなく、APIから実行可能となります
- フレンドのステータス確認
- リクエストインバイトの承認
- ワールド情報の取得
皆さんがよく利用している、OyasumiVRやVRCXもVRChat APIが組み込まれ、利用されています。
実際に使ってみよう
APIのドキュメントはこちらに詳しく記載されています。
もちろんAPIをそのままPostman等で利用することも可能ですが、言語によってはライブラリが提供されています。今回はPythonのライブラリを用いて実装していきます。
ライブラリの導入
いつものやつ
pip install vrchatapi
ユーザーログイン
APIの情報を取得するには予めログインしておく必要があります。
以下のコードで認証済みのインスタンスを作成することができます。
(username
がメールアドレスであることを想定しています。)
ここで使用するusername
とpassword
は、画像で示すような普段HPにログインする情報を用いると上手くいくと思います。
import vrchatapi
from vrchatapi.api import authentication_api
from vrchatapi.exceptions import UnauthorizedException
from vrchatapi.models.two_factor_auth_code import TwoFactorAuthCode
from vrchatapi.models.two_factor_email_code import TwoFactorEmailCode
configuration = vrchatapi.Configuration(
username = username, # e-mail
password = password,
)
api_client = vrchatapi.ApiClient(configuration)
api_client.user_agent = f"Mozilla/5.0 {username}"
auth_api = authentication_api.AuthenticationApi(api_client)
try:
current_user = auth_api.get_current_user()
# 初回は2FAが有効になっているため、2FAのコードを入力する
except UnauthorizedException as e:
if e.status == 200:
auth_api.verify2_fa_email_code(two_factor_email_code=TwoFactorEmailCode(input("Email 2FA Code: ")))
elif "2 Factor Authentication" in e.reason:
auth_api.verify2_fa(two_factor_auth_code=TwoFactorAuthCode(input("2FA Code: ")))
else:
print("Exception when calling API: %s\n", e)
except vrchatapi.ApiException as e:
print("Exception when calling API: %s\n", e)
利用してみよう
正常にログインできると、先ほどのapi_client
を用いて実際にAPIを利用することができます。
60秒毎に1回以上のクエリ実行を行わないようにしましょう
ユーザー情報取得
from vrchatapi.api import users_api
user_id = "usr_xxxxxxxx"
users_api = users_api.UsersApi(api_client)
user = users_api.get_user(user_id=user_id)
print(user)
以下にレスポンス例の一部を示しました。
bio
やnote
、status_description
はHPからでもよく見る内容ですね。
current_avatar_image_url
からはアバターの写真を確認することができます。
このユーザーは緑ステータスでプラべに籠ってアバター改変していることが分かりますね!
{
"bio": "人が多い場所では基本無言です",
"current_avatar_image_url": "https://api.vrchat.cloud/api/1/file/file_xxxxxxxx/2/file",
"display_name": "hiyori",
"id": "usr_xxxxxxxx",
"is_friend": true,
"location": "private",
"note": "ポピ横で出会った",
"state": "online",
"status": "active",
"status_description": "アバター改変中",
"world_id": "private"
}
レスポンス全体
{
"allow_avatar_copying": true,
"badges": [],
"bio": "人が多い場所では基本無言です",
"bio_links": ["https://x.com/xxxxxxx"],
"current_avatar_image_url": "https://api.vrchat.cloud/api/1/file/file_xxxxxxxx/2/file",
"current_avatar_tags": [],
"current_avatar_thumbnail_image_url": "https://api.vrchat.cloud/api/1/image/file_xxxxxxxx/2/256",
"date_joined": "2024-01-01",
"developer_type": "none",
"display_name": "hiyori",
"friend_key": "xxxxxxxx",
"friend_request_status": "completed",
"id": "usr_xxxxxxxx",
"instance_id": "private",
"is_friend": true,
"last_activity": "2024-12-09T13:00:00.000Z",
"last_login": "2024-12-09T09:00:00.000Z",
"last_mobile": null,
"last_platform": "standalonewindows",
"location": "private",
"note": "ポピ横で出会った",
"platform": "standalonewindows",
"profile_pic_override": "",
"profile_pic_override_thumbnail": "",
"pronouns": "",
"state": "online",
"status": "active",
"status_description": "アバター改変中",
"tags": [
"language_jpn",
"system_world_access",
"system_avatar_access",
"system_trust_basic",
"system_trust_known",
"system_feedback_access",
"system_trust_trusted",
"system_trust_veteran",
"language_eng"
],
"traveling_to_instance": "private",
"traveling_to_location": "private",
"traveling_to_world": "private",
"user_icon": "",
"username": null,
"world_id": "private"
}
ワールド情報取得
from vrchatapi.api import worlds_api
world_id = "wrld_beddab1e-fee1-cafe-f00d-ca7c0dd1eca7"
worlds_api = worlds_api.WorldsApi(api_client)
world = worlds_api.get_world(world_id=world_id)
print(world)
以下にレスポンス例の一部を示しました。
今回はpublicに公開されているSuRoomの情報を取得してみました。
image_url
からはSuRoomのサムネイルが、instances
からは現在のSuRoomのインスタンス情報を確認できますね!
{
"author_id": "usr_0d262187-c8f4-43f1-b78f-d1618fc9a1c3",
"author_name": "citrusxr",
"capacity": 32,
"description": "Experience true VR home world. Multilingual supported. created by : CITRUS Studio members:[\"Shatoo\", \"ureishi\", \"Rastvas\", \"Izzy_da\"]",
"favorites": 94748,
"featured": false,
"heat": 7,
"id": "wrld_beddab1e-fee1-cafe-f00d-ca7c0dd1eca7",
"image_url": "https://api.vrchat.cloud/api/1/file/file_0043cc43-931c-4c4e-87a0-2e0e4622d320/3/file",
"instances": [
["36000~region(jp)", 20],
["61000~region(jp)", 1],
["92000~region(jp)", 2],
["71000~region(jp)", 5],
["13000~region(jp)", 6],
["11000~region(jp)", 7]
],
"name": "SuRroom",
"organization": "vrchat",
"release_status": "public",
"thumbnail_image_url": "https://api.vrchat.cloud/api/1/image/file_0043cc43-931c-4c4e-87a0-2e0e4622d320/3/256",
}
実際のSuRoomのHPから得られる情報とほぼ一致しているかと思います
(少しずれているのは取得時間の問題)
レスポンス全体
{
"author_id": "usr_0d262187-c8f4-43f1-b78f-d1618fc9a1c3",
"author_name": "citrusxr",
"capacity": 32,
"created_at": "2022-12-19T13:01:34.364000+00:00",
"description": "Experience true VR home world. Multilingual supported. created by : CITRUS Studio members:[\"Shatoo\", \"ureishi\", \"Rastvas\", \"Izzy_da\"]",
"favorites": 94748,
"featured": false,
"heat": 7,
"id": "wrld_beddab1e-fee1-cafe-f00d-ca7c0dd1eca7",
"image_url": "https://api.vrchat.cloud/api/1/file/file_0043cc43-931c-4c4e-87a0-2e0e4622d320/3/file",
"instances": [
["36004~region(jp)", 2],
["61520~region(jp)", 14],
["92575~region(jp)", 2],
["71747~region(jp)", 1],
["13460~region(jp)", 1],
["11783~region(jp)", 1]
],
"labs_publication_date": "2023-03-17T13:40:55.999Z",
"name": "SuRroom",
"namespace": null,
"occupants": 557,
"organization": "vrchat",
"popularity": 9,
"preview_youtube_id": null,
"private_occupants": 511,
"public_occupants": 46,
"publication_date": "2023-03-17T13:40:56.019Z",
"recommended_capacity": 16,
"release_status": "public",
"tags": [
"author_tag_home",
"author_tag_relax",
"author_tag_party",
"author_tag_sleep",
"admin_onboarding_japan",
"system_approved"
],
"thumbnail_image_url": "https://api.vrchat.cloud/api/1/image/file_0043cc43-931c-4c4e-87a0-2e0e4622d320/3/256",
"udon_products": [],
"unity_packages": [
{
"asset_url": "https://api.vrchat.cloud/api/1/file/file_0f4d90d3-0e01-4286-84ae-275f64567c83/55/file",
"asset_version": 4,
"created_at": "2023-09-10T05:01:25.520000+00:00",
"id": "unp_490f9905-5e31-4d2a-8aac-534b8f49ddc2",
"platform": "standalonewindows",
"unity_version": "2019.4.31f1"
},
{
"asset_url": "https://api.vrchat.cloud/api/1/file/file_ede24b0c-e349-4c94-a603-eea05b83d93a/232/file",
"asset_version": 1,
"created_at": "2023-12-28T04:11:11.209000+00:00",
"id": "unp_e15a3397-a1da-4f1e-8d9c-8dc1fc025e04",
"platform": "standalonewindows",
"unity_version": "2019.4.31f1"
},
{
"asset_url": "https://api.ierzchat.cloud/api/1/file/file_ede24b0c-e349-4c94-a603-eea05b83d93a/287/file",
"asset_version": 4,
"created_at": "2024-05-01T04:17:44.310000+00:00",
"id": "unp_6b7c3881-ef91-4fcf-b4f1-40f99c7494f6",
"platform": "standalonewindows",
"unity_version": "2022.3.6f1"
},
{
"asset_url": "https://api.vrchat.cloud/api/1/file/file_ede24b0c-e349-4c94-a603-eea05b83d93a/399/file",
"asset_version": 4,
"created_at": "2024-11-24T14:41:57.095000+00:00",
"id": "unp_68276bd4-63b7-4867-aa1d-a685208c1950",
"platform": "standalonewindows",
"unity_version": "2022.3.22f1",
"world_signature": "AORwBdPa0kezOjcnONA+bqJo3t8tYTYjpvwW6nOl8bAHGBq8zw=="
}
],
"updated_at": "2024-11-24T14:41:57.320000+00:00",
"version": 171,
"visits": 5870877
}
ちなみに
以上で使用しているuser_id
やworld_id
の情報は、APIのレスポンス情報の他にブラウザからも取得できます(デベロッパーモードのNetworkタブ)。
まとめ
VRChatには非公式ですがAPIが存在し、ライブラリを通じて簡単に利用できます。
リクイン承認の自動化や、フレンドのステータス変更に伴う通知機能など多くのサービスに応用できるので、ぜひ試してみてはいかがでしょうか?