-
Notifications
You must be signed in to change notification settings - Fork 0
/
2-3_reply_to_reply.ts
88 lines (75 loc) · 2.64 KB
/
2-3_reply_to_reply.ts
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
import {
type Event,
type Relay,
relayInit,
getPublicKey,
finishEvent,
nip19,
} from "nostr-tools";
import { currUnixtime } from "./utils.ts";
/* Bot用の秘密鍵をここに設定 */
const BOT_PRIVATE_KEY_HEX = ???;
const relayUrl = "wss://relay-jp.nostr.wirednet.jp";
/**
* テキスト投稿イベント(リプライ)を組み立てる
* @param content 投稿内容
* @param targetEvent リプライ対象のイベント
*/
const composeReplyPost = (content: string, targetEvent: Event): Event => {
/* Q-1: これまで学んだことを思い出しながら、
リプライを表現するイベントを組み立てよう */
???;
};
// リレーにイベントを送信
const publishToRelay = (relay: Relay, ev: Event) => {
const pub = relay.publish(ev);
pub.on("ok", () => {
console.log("succeess!");
});
pub.on("failed", () => {
console.log("failed to send event");
});
};
/* 暴走・無限リプライループ対策 */
// リプライクールタイム
const COOL_TIME_DUR_SEC = 60
// 公開鍵ごとに、最後にリプライを返した時刻(unixtime)を保持するMap
const lastReplyTimePerPubkey = new Map()
// 引数のイベントにリプライしても安全か?
// 対象の発行時刻が古すぎる場合・最後にリプライを返した時点からクールタイム分の時間が経過していない場合、安全でない
const isSafeToReply = ({ pubkey, created_at }: Event): boolean => {
const now = currUnixtime();
if (created_at < now - COOL_TIME_DUR_SEC) {
return false;
}
const lastReplyTime = lastReplyTimePerPubkey.get(pubkey);
if (lastReplyTime !== undefined && now - lastReplyTime < COOL_TIME_DUR_SEC) {
return false;
}
lastReplyTimePerPubkey.set(pubkey, now);
return true;
}
// メイン関数
const main = async () => {
const relay = relayInit(relayUrl);
relay.on("error", () => {
console.error("failed to connect");
});
await relay.connect();
console.log("connected to relay");
/* Q-2: 「このBotの公開鍵へのリプライ」を絞り込むフィルタを設定して、イベントを購読しよう */
// ヒント: nostr-toolsのgetPublicKey()関数を使って、秘密鍵(BOT_PRIVATE_KEY_HEX)から公開鍵を得ることができます
const sub = ???;
sub.on("event", (ev) => {
try {
// リプライしても安全なら、リプライイベントを組み立てて送信する
if (isSafeToReply(ev)) {
const replyPost = composeReplyPost("こんにちは!", ev);
publishToRelay(relay, replyPost);
}
} catch (err) {
console.error(err);
}
});
};
main().catch((e) => console.error(e));