-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfollowtool.html
115 lines (94 loc) · 4.76 KB
/
followtool.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
---
title: フォローツール
layout: post
---
<p>このツールを使うと、うかどん以外の人を簡単にフォローできます。</p>
<p>Mastodonだけでなく、Misskeyも対応しています(misskey.ioも当然大丈夫)</p>
<p>フォローボタンを押したら、うかどんのページに飛びますので、そこでもう一度フォローを押してください。</p>
<p>Blueskyの参加者と今のままやりとりするヒント:
<br><a href="#" class="profile-check-link" data-username="bsky.brid.gy" data-server="bsky.brid.gy">Bridgy Fedを相互フォロー</a>してください。そのあとで、
<br>・https://bsky.app/profile/ap.brid.gy これ
<br>・ap.brid.gyで終わるユーザー個別リンク
<br>の2つをBlueskyユーザーさんに教えてフォローしてもらってください。
</p>
<p>
<input type="text" id="usernameInput" placeholder="ユーザー名 (@なし)" style="margin: 10px 0; padding: 5px;">
<input type="text" id="serverInput" placeholder="サーバ名 (例: mastodon.social)" style="margin: 10px 0; padding: 5px; width: 250px;">
<button id="checkButton" style="margin: 10px 0; padding: 5px 10px;">確認</button>
</p>
<p>
<button id="followButton" style="margin: 10px 0; padding: 10px 20px; border-radius: 5px; font-size: 1.2em; font-weight: bold; display: none;">フォロー</button>
</p>
<div id="profile" style="margin-top: 20px; border: 1px solid gray; padding: 10px; display: none;"></div>
<script>
// グローバル変数
let profileUrl = '';
let profileDiv = null;
let followButton = null;
// プロフィールチェック関数
async function checkProfile(username, server) {
const account = `${username}@${server}`;
try {
// WebFinger リクエスト
const webfingerUrl = `https://${server}/.well-known/webfinger?resource=acct:${account}`;
const webfingerResponse = await fetch(webfingerUrl);
if (!webfingerResponse.ok) throw new Error('WebFinger情報の取得に失敗しました。');
const webfingerData = await webfingerResponse.json();
// プロフィールURLの取得
const profileLink = webfingerData.links.find(link => link.rel === 'self' && link.type === 'application/activity+json');
if (!profileLink) throw new Error('プロフィールURLが見つかりません。');
profileUrl = profileLink.href;
// プロフィール情報の取得
const profileResponse = await fetch(profileUrl, {
headers: { 'Accept': 'application/activity+json' }
});
if (!profileResponse.ok) throw new Error('プロフィールの取得に失敗しました。');
const profileData = await profileResponse.json();
// プロフィール情報の表示
profileDiv.innerHTML = `
<h2>${profileData.name || username}</h2>
<p>${account}</p>
<img src="${profileData.icon?.url || '/api/placeholder/100/100'}" alt="Avatar" style="width: 100px; height: 100px;">
<p>${profileData.summary || 'No bio available'}</p>
`;
profileDiv.style.display = 'block';
followButton.style.display = 'block';
} catch (error) {
alert('エラーが発生しました: ' + error.message);
}
}
// DOMが読み込まれた後に実行
document.addEventListener('DOMContentLoaded', () => {
const checkButton = document.getElementById('checkButton');
followButton = document.getElementById('followButton');
const usernameInput = document.getElementById('usernameInput');
const serverInput = document.getElementById('serverInput');
profileDiv = document.getElementById('profile');
checkButton.addEventListener('click', () => {
const username = usernameInput.value.trim();
const server = serverInput.value.trim();
if (!username || !server) {
alert('ユーザー名とサーバ名を入力してください。');
return;
}
checkProfile(username, server);
});
followButton.addEventListener('click', () => {
const followUrl = `https://ukadon.shillest.net/authorize_interaction?uri=${encodeURIComponent(profileUrl)}`;
window.open(followUrl, '_blank');
});
// プロフィールチェックリンクのイベントリスナーを追加
document.querySelectorAll('.profile-check-link').forEach(link => {
link.addEventListener('click', (e) => {
e.preventDefault();
const username = e.target.dataset.username;
const server = e.target.dataset.server;
if (!username || !server) {
alert('ユーザー名とサーバ名が指定されていません。');
return;
}
checkProfile(username, server);
});
});
});
</script>