2025-04-28 00:16:55 -07:00

140 lines
3.7 KiB
JavaScript

import 'dotenv/config';
import vrchat from "vrchat";
import globalAxios from "axios";
import { CookieJar } from "tough-cookie";
import FileCookieStore from 'tough-cookie-file-store';
globalAxios.defaults.jar = new CookieJar(new FileCookieStore("./cookies.json"));
import {Bot, RichText} from "@skyware/bot";
var bot = new Bot({
emitEvents: false
});
await bot.login({
identifier: process.env.BSKY_DID,
password: process.env.BSKY_PW
});
var conversation = await bot.getConversationForMembers([process.env.BSKY_ADMIN_DID]);
//await conversation.sendMessage({text: "bot start"});
var vrc_conf = new vrchat.Configuration({
username: process.env.VRC_USR,
password: process.env.VRC_PW,
baseOptions: {headers: {"User-Agent": "fishcat"}}
});
var vrc_auth_api = new vrchat.AuthenticationApi(vrc_conf);
//var vrc_users_api = new vrchat.UsersApi(vrc_conf);
var vrc_friends_api = new vrchat.FriendsApi(vrc_conf);
//var vrc_worlds_api = new vrchat.WorldsApi(vrc_conf);
var vrc_user;
async function get_current_user_or_login() {
var res = await vrc_auth_api.getCurrentUser();
console.debug(res);
vrc_user = res.data;
if (vrc_user.requiresTwoFactorAuth) {
if (vrc_user.requiresTwoFactorAuth[0] == "emailOtp") {
await prompt2fa();
await get_current_user_or_login();
} else {
throw new Error("unsupported 2fa");
}
}
}
async function prompt2fa() {
console.log("prompt 2fa");
await conversation.sendMessage({text: "2fa required"});
do {
await new Promise(r => setTimeout(r, 5000));
var {messages} = await conversation.getMessages();
var lastmsg = messages[0];
if (lastmsg.senderDid != process.env.BSKY_ADMIN_DID) continue;
var code = lastmsg.text.match(/\d{6}/)?.[0];
if (!code) {
await conversation.sendMessage({text: "invalid"});
continue;
}
var res = await vrc_auth_api.verify2FAEmailCode({code});
console.debug(res);
await conversation.sendMessage({text: "ok"});
} while (!code)
}
//await get_current_user_or_login();
var last_online;
async function check_friends() {
await get_current_user_or_login();
var online = await vrc_friends_api.getFriends(0, 50, false).then(res => res.data);
online = online.filter(user => user.location && user.location != "offline");
if (vrc_user.state == "online") online.unshift(vrc_user);
console.debug("online", online);
if (last_online) {
var went_online = [];
var went_offline = [];
for (let user of online) {
let last_user = last_online.find(u => u.id == user.id);
if (!last_user) {
// user went online
went_online.push(user);
}
}
for (let last_user of last_online) {
let now_user = online.find(u => u.id == last_user.id);
if (!now_user) {
// user went offline
went_offline.push(last_user);
}
}
}
if (!last_online || went_online?.length || went_offline?.length) {
let priv = online.filter(user => user.location == "private");
let notpriv = online.filter(user => user.location != "private");
let text = new RichText();
if (notpriv.length) {
text.addText("Online: ")
for (let u of notpriv) {
text.addLink(u.displayName, `https://vrchat.com/home/user/${u.id}`);
text.addText(", ");
}
}
if (priv.length) {
text.addText("\n\nPrivate: ");
for (let u of priv) {
text.addLink(u.displayName, `https://vrchat.com/home/user/${u.id}`);
text.addText(", ");
}
}
let post = await bot.post({text});
console.log("posted", post.uri);
}
last_online = online;
}
while (true) {
try {
await check_friends();
} catch (error) {
console.error(error.stack);
}
await new Promise(r => setTimeout(r, 1000*60*5));
}