mirror of
https://github.com/syuilo/ai.git
synced 2024-11-09 15:38:00 +00:00
Compare commits
2 commits
ecb983089c
...
31abe7146e
Author | SHA1 | Date | |
---|---|---|---|
31abe7146e | |||
fb271619cc |
44
src/ai.ts
44
src/ai.ts
|
@ -53,7 +53,6 @@ export default class 藍 {
|
|||
private meta: loki.Collection<Meta>;
|
||||
|
||||
private contexts: loki.Collection<{
|
||||
isDm: boolean;
|
||||
noteId?: string;
|
||||
userId?: string;
|
||||
module: string;
|
||||
|
@ -146,7 +145,7 @@ export default class 藍 {
|
|||
if (data.text && data.text.startsWith('@' + this.account.username)) {
|
||||
// Misskeyのバグで投稿が非公開扱いになる
|
||||
if (data.text == null) data = await this.api('notes/show', { noteId: data.id });
|
||||
this.onReceiveMessage(new Message(this, data, false));
|
||||
this.onReceiveMessage(new Message(this, data));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -156,7 +155,7 @@ export default class 藍 {
|
|||
if (data.text && data.text.startsWith('@' + this.account.username)) return;
|
||||
// Misskeyのバグで投稿が非公開扱いになる
|
||||
if (data.text == null) data = await this.api('notes/show', { noteId: data.id });
|
||||
this.onReceiveMessage(new Message(this, data, false));
|
||||
this.onReceiveMessage(new Message(this, data));
|
||||
});
|
||||
|
||||
// Renoteされたとき
|
||||
|
@ -174,7 +173,7 @@ export default class 藍 {
|
|||
// メッセージ
|
||||
mainStream.on('messagingMessage', data => {
|
||||
if (data.userId == this.account.id) return; // 自分は弾く
|
||||
this.onReceiveMessage(new Message(this, data, true));
|
||||
this.onReceiveMessage(new Message(this, data));
|
||||
});
|
||||
|
||||
// 通知
|
||||
|
@ -218,14 +217,10 @@ export default class 藍 {
|
|||
return;
|
||||
}
|
||||
|
||||
const isNoContext = !msg.isDm && msg.replyId == null;
|
||||
const isNoContext = msg.replyId == null;
|
||||
|
||||
// Look up the context
|
||||
const context = isNoContext ? null : this.contexts.findOne(msg.isDm ? {
|
||||
isDm: true,
|
||||
userId: msg.userId
|
||||
} : {
|
||||
isDm: false,
|
||||
const context = isNoContext ? null : this.contexts.findOne({
|
||||
noteId: msg.replyId
|
||||
});
|
||||
|
||||
|
@ -270,19 +265,12 @@ export default class 藍 {
|
|||
await delay(1000);
|
||||
}
|
||||
|
||||
if (msg.isDm) {
|
||||
// 既読にする
|
||||
this.api('messaging/messages/read', {
|
||||
messageId: msg.id,
|
||||
// リアクションする
|
||||
if (reaction) {
|
||||
this.api('notes/reactions/create', {
|
||||
noteId: msg.id,
|
||||
reaction: reaction
|
||||
});
|
||||
} else {
|
||||
// リアクションする
|
||||
if (reaction) {
|
||||
this.api('notes/reactions/create', {
|
||||
noteId: msg.id,
|
||||
reaction: reaction
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,20 +393,12 @@ export default class 藍 {
|
|||
* コンテキストを生成し、ユーザーからの返信を待ち受けます
|
||||
* @param module 待ち受けるモジュール名
|
||||
* @param key コンテキストを識別するためのキー
|
||||
* @param isDm トークメッセージ上のコンテキストかどうか
|
||||
* @param id トークメッセージ上のコンテキストならばトーク相手のID、そうでないなら待ち受ける投稿のID
|
||||
* @param data コンテキストに保存するオプションのデータ
|
||||
*/
|
||||
@autobind
|
||||
public subscribeReply(module: Module, key: string | null, isDm: boolean, id: string, data?: any) {
|
||||
this.contexts.insertOne(isDm ? {
|
||||
isDm: true,
|
||||
userId: id,
|
||||
module: module.name,
|
||||
key: key,
|
||||
data: data
|
||||
} : {
|
||||
isDm: false,
|
||||
public subscribeReply(module: Module, key: string | null, id: string, data?: any) {
|
||||
this.contexts.insertOne({
|
||||
noteId: id,
|
||||
module: module.name,
|
||||
key: key,
|
||||
|
|
|
@ -11,31 +11,30 @@ import config from '@/config';
|
|||
|
||||
export default class Message {
|
||||
private ai: 藍;
|
||||
private messageOrNote: any;
|
||||
public isDm: boolean;
|
||||
private note: any;
|
||||
|
||||
public get id(): string {
|
||||
return this.messageOrNote.id;
|
||||
return this.note.id;
|
||||
}
|
||||
|
||||
public get user(): User {
|
||||
return this.messageOrNote.user;
|
||||
return this.note.user;
|
||||
}
|
||||
|
||||
public get userId(): string {
|
||||
return this.messageOrNote.userId;
|
||||
return this.note.userId;
|
||||
}
|
||||
|
||||
public get text(): string {
|
||||
return this.messageOrNote.text;
|
||||
return this.note.text;
|
||||
}
|
||||
|
||||
public get quoteId(): string | null {
|
||||
return this.messageOrNote.renoteId;
|
||||
return this.note.renoteId;
|
||||
}
|
||||
|
||||
public get visibility(): string {
|
||||
return this.messageOrNote.visibility;
|
||||
return this.note.visibility;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -50,15 +49,14 @@ export default class Message {
|
|||
}
|
||||
|
||||
public get replyId(): string {
|
||||
return this.messageOrNote.replyId;
|
||||
return this.note.replyId;
|
||||
}
|
||||
|
||||
public friend: Friend;
|
||||
|
||||
constructor(ai: 藍, messageOrNote: any, isDm: boolean) {
|
||||
constructor(ai: 藍, note: any) {
|
||||
this.ai = ai;
|
||||
this.messageOrNote = messageOrNote;
|
||||
this.isDm = isDm;
|
||||
this.note = note;
|
||||
|
||||
this.friend = new Friend(ai, { user: this.user });
|
||||
|
||||
|
@ -85,20 +83,13 @@ export default class Message {
|
|||
await delay(2000);
|
||||
}
|
||||
|
||||
if (this.isDm) {
|
||||
return await this.ai.sendMessage(this.messageOrNote.userId, {
|
||||
text: text,
|
||||
fileId: opts?.file?.id
|
||||
});
|
||||
} else {
|
||||
return await this.ai.post({
|
||||
replyId: this.messageOrNote.id,
|
||||
text: text,
|
||||
fileIds: opts?.file ? [opts?.file.id] : undefined,
|
||||
cw: opts?.cw,
|
||||
renoteId: opts?.renote
|
||||
});
|
||||
}
|
||||
return await this.ai.post({
|
||||
replyId: this.note.id,
|
||||
text: text,
|
||||
fileIds: opts?.file ? [opts?.file.id] : undefined,
|
||||
cw: opts?.cw,
|
||||
renoteId: opts?.renote
|
||||
});
|
||||
}
|
||||
|
||||
@autobind
|
||||
|
|
|
@ -32,13 +32,12 @@ export default abstract class Module {
|
|||
/**
|
||||
* コンテキストを生成し、ユーザーからの返信を待ち受けます
|
||||
* @param key コンテキストを識別するためのキー
|
||||
* @param isDm トークメッセージ上のコンテキストかどうか
|
||||
* @param id トークメッセージ上のコンテキストならばトーク相手のID、そうでないなら待ち受ける投稿のID
|
||||
* @param data コンテキストに保存するオプションのデータ
|
||||
*/
|
||||
@autobind
|
||||
protected subscribeReply(key: string | null, isDm: boolean, id: string, data?: any) {
|
||||
this.ai.subscribeReply(this, key, isDm, id, data);
|
||||
protected subscribeReply(key: string | null, id: string, data?: any) {
|
||||
this.ai.subscribeReply(this, key, id, data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,12 +35,6 @@ export default class extends Module {
|
|||
if (!msg.text) return false;
|
||||
if (!msg.includes(['引継', '引き継ぎ', '引越', '引っ越し'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isDm) {
|
||||
msg.reply(serifs.core.transferNeedDm);
|
||||
return true;
|
||||
}
|
||||
|
||||
const code = msg.friend.generateTransferCode();
|
||||
|
||||
msg.reply(serifs.core.transferCode(code));
|
||||
|
@ -72,9 +66,6 @@ export default class extends Module {
|
|||
if (!msg.text.includes('って呼んで')) return false;
|
||||
if (msg.text.startsWith('って呼んで')) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
const name = msg.text.match(/^(.+?)って呼んで/)![1];
|
||||
|
||||
if (name.length > 10) {
|
||||
|
@ -94,7 +85,7 @@ export default class extends Module {
|
|||
msg.reply(serifs.core.setNameOk(name));
|
||||
} else {
|
||||
msg.reply(serifs.core.san).then(reply => {
|
||||
this.subscribeReply(msg.userId, msg.isDm, msg.isDm ? msg.userId : reply.id, {
|
||||
this.subscribeReply(msg.userId, reply.id, {
|
||||
name: name
|
||||
});
|
||||
});
|
||||
|
@ -152,7 +143,7 @@ export default class extends Module {
|
|||
done();
|
||||
} else {
|
||||
msg.reply(serifs.core.yesOrNo).then(reply => {
|
||||
this.subscribeReply(msg.userId, msg.isDm, reply.id, data);
|
||||
this.subscribeReply(msg.userId, reply.id, data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,16 +37,6 @@ export default class extends Module {
|
|||
isEnded: false
|
||||
});
|
||||
|
||||
if (!msg.isDm) {
|
||||
if (exist != null) {
|
||||
msg.reply(serifs.guessingGame.alreadyStarted);
|
||||
} else {
|
||||
msg.reply(serifs.guessingGame.plzDm);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const secret = Math.floor(Math.random() * 100);
|
||||
|
||||
this.guesses.insertOne({
|
||||
|
@ -59,7 +49,7 @@ export default class extends Module {
|
|||
});
|
||||
|
||||
msg.reply(serifs.guessingGame.started).then(reply => {
|
||||
this.subscribeReply(msg.userId, msg.isDm, msg.isDm ? msg.userId : reply.id);
|
||||
this.subscribeReply(msg.userId, reply.id);
|
||||
});
|
||||
|
||||
return true;
|
||||
|
@ -93,7 +83,7 @@ export default class extends Module {
|
|||
|
||||
if (guess == null) {
|
||||
msg.reply(serifs.guessingGame.nan).then(reply => {
|
||||
this.subscribeReply(msg.userId, msg.isDm, reply.id);
|
||||
this.subscribeReply(msg.userId, reply.id);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -131,7 +121,7 @@ export default class extends Module {
|
|||
|
||||
msg.reply(text).then(reply => {
|
||||
if (!end) {
|
||||
this.subscribeReply(msg.userId, msg.isDm, reply.id);
|
||||
this.subscribeReply(msg.userId, reply.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ export default class extends Module {
|
|||
postId: post.id
|
||||
});
|
||||
|
||||
this.subscribeReply(null, false, post.id);
|
||||
this.subscribeReply(null, post.id);
|
||||
|
||||
this.log('New kazutori game started');
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ export default class extends Module {
|
|||
private reminds: loki.Collection<{
|
||||
userId: string;
|
||||
id: string;
|
||||
isDm: boolean;
|
||||
thing: string | null;
|
||||
quoteId: string | null;
|
||||
times: number; // 催促した回数(使うのか?)
|
||||
|
@ -70,7 +69,6 @@ export default class extends Module {
|
|||
const remind = this.reminds.insertOne({
|
||||
id: msg.id,
|
||||
userId: msg.userId,
|
||||
isDm: msg.isDm,
|
||||
thing: thing === '' ? null : thing,
|
||||
quoteId: msg.quoteId,
|
||||
times: 0,
|
||||
|
@ -78,13 +76,13 @@ export default class extends Module {
|
|||
});
|
||||
|
||||
// メンションをsubscribe
|
||||
this.subscribeReply(remind!.id, msg.isDm, msg.isDm ? msg.userId : msg.id, {
|
||||
this.subscribeReply(remind!.id, msg.id, {
|
||||
id: remind!.id
|
||||
});
|
||||
|
||||
if (msg.quoteId) {
|
||||
// 引用元をsubscribe
|
||||
this.subscribeReply(remind!.id, false, msg.quoteId, {
|
||||
this.subscribeReply(remind!.id, msg.quoteId, {
|
||||
id: remind!.id
|
||||
});
|
||||
}
|
||||
|
@ -126,7 +124,6 @@ export default class extends Module {
|
|||
msg.reply(serifs.reminder.doneFromInvalidUser);
|
||||
return;
|
||||
} else {
|
||||
if (msg.isDm) this.unsubscribeReply(key);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -145,28 +142,22 @@ export default class extends Module {
|
|||
if (friend == null) return; // 処理の流れ上、実際にnullになることは無さそうだけど一応
|
||||
|
||||
let reply;
|
||||
if (remind.isDm) {
|
||||
this.ai.sendMessage(friend.userId, {
|
||||
text: serifs.reminder.notifyWithThing(remind.thing, friend.name)
|
||||
try {
|
||||
reply = await this.ai.post({
|
||||
renoteId: remind.thing == null && remind.quoteId ? remind.quoteId : remind.id,
|
||||
text: acct(friend.doc.user) + ' ' + serifs.reminder.notify(friend.name)
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
reply = await this.ai.post({
|
||||
renoteId: remind.thing == null && remind.quoteId ? remind.quoteId : remind.id,
|
||||
text: acct(friend.doc.user) + ' ' + serifs.reminder.notify(friend.name)
|
||||
});
|
||||
} catch (err) {
|
||||
// renote対象が消されていたらリマインダー解除
|
||||
if (err.statusCode === 400) {
|
||||
this.unsubscribeReply(remind.thing == null && remind.quoteId ? remind.quoteId : remind.id);
|
||||
this.reminds.remove(remind);
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
// renote対象が消されていたらリマインダー解除
|
||||
if (err.statusCode === 400) {
|
||||
this.unsubscribeReply(remind.thing == null && remind.quoteId ? remind.quoteId : remind.id);
|
||||
this.reminds.remove(remind);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.subscribeReply(remind.id, remind.isDm, remind.isDm ? remind.userId : reply.id, {
|
||||
this.subscribeReply(remind.id, reply.id, {
|
||||
id: remind.id
|
||||
});
|
||||
|
||||
|
|
|
@ -146,9 +146,6 @@ export default class extends Module {
|
|||
private nadenade(msg: Message): boolean {
|
||||
if (!msg.includes(['なでなで'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
//#region 1日に1回だけ親愛度を上げる(嫌われてない場合のみ)
|
||||
if (msg.friend.love >= 0) {
|
||||
const today = getDate();
|
||||
|
@ -181,9 +178,6 @@ export default class extends Module {
|
|||
private kawaii(msg: Message): boolean {
|
||||
if (!msg.includes(['かわいい', '可愛い'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
msg.reply(getSerif(
|
||||
msg.friend.love >= 5 ? serifs.core.kawaii.love :
|
||||
msg.friend.love <= -3 ? serifs.core.kawaii.hate :
|
||||
|
@ -196,9 +190,6 @@ export default class extends Module {
|
|||
private suki(msg: Message): boolean {
|
||||
if (!msg.or(['好き', 'すき'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
msg.reply(
|
||||
msg.friend.love >= 5 ? (msg.friend.name ? serifs.core.suki.love(msg.friend.name) : serifs.core.suki.normal) :
|
||||
msg.friend.love <= -3 ? serifs.core.suki.hate :
|
||||
|
@ -211,9 +202,6 @@ export default class extends Module {
|
|||
private hug(msg: Message): boolean {
|
||||
if (!msg.or(['ぎゅ', 'むぎゅ', /^はぐ(し(て|よ|よう)?)?$/])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
//#region 前のハグから1分経ってない場合は返信しない
|
||||
// これは、「ハグ」と言って「ぎゅー」と返信したとき、相手が
|
||||
// それに対してさらに「ぎゅー」と返信するケースがあったため。
|
||||
|
@ -245,9 +233,6 @@ export default class extends Module {
|
|||
private humu(msg: Message): boolean {
|
||||
if (!msg.includes(['踏んで'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
msg.reply(
|
||||
msg.friend.love >= 5 ? serifs.core.humu.love :
|
||||
msg.friend.love <= -3 ? serifs.core.humu.hate :
|
||||
|
@ -260,9 +245,6 @@ export default class extends Module {
|
|||
private batou(msg: Message): boolean {
|
||||
if (!msg.includes(['罵倒して', '罵って'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
msg.reply(
|
||||
msg.friend.love >= 5 ? serifs.core.batou.love :
|
||||
msg.friend.love <= -5 ? serifs.core.batou.hate :
|
||||
|
@ -275,9 +257,6 @@ export default class extends Module {
|
|||
private itai(msg: Message): boolean {
|
||||
if (!msg.or(['痛い', 'いたい']) && !msg.extractedText.endsWith('痛い')) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
msg.reply(serifs.core.itai(msg.friend.name));
|
||||
|
||||
return true;
|
||||
|
@ -287,9 +266,6 @@ export default class extends Module {
|
|||
private ote(msg: Message): boolean {
|
||||
if (!msg.or(['お手'])) return false;
|
||||
|
||||
// メッセージのみ
|
||||
if (!msg.isDm) return true;
|
||||
|
||||
msg.reply(
|
||||
msg.friend.love >= 10 ? serifs.core.ote.love2 :
|
||||
msg.friend.love >= 5 ? serifs.core.ote.love1 :
|
||||
|
|
|
@ -47,7 +47,6 @@ export default class extends Module {
|
|||
|
||||
// タイマーセット
|
||||
this.setTimeoutWithPersistence(time, {
|
||||
isDm: msg.isDm,
|
||||
msgId: msg.id,
|
||||
userId: msg.friend.userId,
|
||||
time: str
|
||||
|
@ -61,15 +60,9 @@ export default class extends Module {
|
|||
const friend = this.ai.lookupFriend(data.userId);
|
||||
if (friend == null) return; // 処理の流れ上、実際にnullになることは無さそうだけど一応
|
||||
const text = serifs.timer.notify(data.time, friend.name);
|
||||
if (data.isDm) {
|
||||
this.ai.sendMessage(friend.userId, {
|
||||
text: text
|
||||
});
|
||||
} else {
|
||||
this.ai.post({
|
||||
replyId: data.msgId,
|
||||
text: text
|
||||
});
|
||||
}
|
||||
this.ai.post({
|
||||
replyId: data.msgId,
|
||||
text: text
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue