summaryrefslogtreecommitdiff
path: root/src/api/bot
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/bot')
-rw-r--r--src/api/bot/core.ts143
-rw-r--r--src/api/bot/interfaces/line.ts2
2 files changed, 126 insertions, 19 deletions
diff --git a/src/api/bot/core.ts b/src/api/bot/core.ts
index 53fb18119e..ddae6405f5 100644
--- a/src/api/bot/core.ts
+++ b/src/api/bot/core.ts
@@ -5,6 +5,7 @@ import User, { IUser, init as initUser } from '../models/user';
import getPostSummary from '../../common/get-post-summary';
import getUserSummary from '../../common/get-user-summary';
+import getNotificationSummary from '../../common/get-notification-summary';
import Othello, { ai as othelloAi } from '../../common/othello';
@@ -62,7 +63,7 @@ export default class BotCore extends EventEmitter {
return bot;
}
- public async q(query: string): Promise<string | void> {
+ public async q(query: string): Promise<string> {
if (this.context != null) {
return await this.context.q(query);
}
@@ -84,7 +85,10 @@ export default class BotCore extends EventEmitter {
'logout, signout: サインアウトします\n' +
'post: 投稿します\n' +
'tl: タイムラインを見ます\n' +
- '@<ユーザー名>: ユーザーを表示します';
+ 'no: 通知を見ます\n' +
+ '@<ユーザー名>: ユーザーを表示します\n' +
+ '\n' +
+ 'タイムラインや通知を見た後、「次」というとさらに遡ることができます。';
case 'me':
return this.user ? `${this.user.name}としてサインインしています。\n\n${getUserSummary(this.user)}` : 'サインインしていません';
@@ -113,7 +117,16 @@ export default class BotCore extends EventEmitter {
case 'tl':
case 'タイムライン':
- return await this.tlCommand();
+ if (this.user == null) return 'まずサインインしてください。';
+ this.setContext(new TlContext(this));
+ return await this.context.greet();
+
+ case 'no':
+ case 'notifications':
+ case '通知':
+ if (this.user == null) return 'まずサインインしてください。';
+ this.setContext(new NotificationsContext(this));
+ return await this.context.greet();
case 'guessing-game':
case '数当てゲーム':
@@ -155,21 +168,7 @@ export default class BotCore extends EventEmitter {
this.emit('updated');
}
- public async tlCommand(): Promise<string | void> {
- if (this.user == null) return 'まずサインインしてください。';
-
- const tl = await require('../endpoints/posts/timeline')({
- limit: 5
- }, this.user);
-
- const text = tl
- .map(post => getPostSummary(post))
- .join('\n-----\n');
-
- return text;
- }
-
- public async showUserCommand(q: string): Promise<string | void> {
+ public async showUserCommand(q: string): Promise<string> {
try {
const user = await require('../endpoints/users/show')({
username: q.substr(1)
@@ -200,6 +199,8 @@ abstract class Context extends EventEmitter {
if (data.type == 'guessing-game') return GuessingGameContext.import(bot, data.content);
if (data.type == 'othello') return OthelloContext.import(bot, data.content);
if (data.type == 'post') return PostContext.import(bot, data.content);
+ if (data.type == 'tl') return TlContext.import(bot, data.content);
+ if (data.type == 'notifications') return NotificationsContext.import(bot, data.content);
if (data.type == 'signin') return SigninContext.import(bot, data.content);
return null;
}
@@ -232,7 +233,7 @@ class SigninContext extends Context {
}
} else {
// Compare password
- const same = bcrypt.compareSync(query, this.temporaryUser.password);
+ const same = await bcrypt.compare(query, this.temporaryUser.password);
if (same) {
this.bot.signin(this.temporaryUser);
@@ -285,6 +286,110 @@ class PostContext extends Context {
}
}
+class TlContext extends Context {
+ private next: string = null;
+
+ public async greet(): Promise<string> {
+ return await this.getTl();
+ }
+
+ public async q(query: string): Promise<string> {
+ if (query == '次') {
+ return await this.getTl();
+ } else {
+ this.bot.clearContext();
+ return await this.bot.q(query);
+ }
+ }
+
+ private async getTl() {
+ const tl = await require('../endpoints/posts/timeline')({
+ limit: 5,
+ max_id: this.next ? this.next : undefined
+ }, this.bot.user);
+
+ if (tl.length > 0) {
+ this.next = tl[tl.length - 1].id;
+ this.emit('updated');
+
+ const text = tl
+ .map(post => `${post.user.name}\n「${getPostSummary(post)}」`)
+ .join('\n-----\n');
+
+ return text;
+ } else {
+ return 'タイムラインに表示するものがありません...';
+ }
+ }
+
+ public export() {
+ return {
+ type: 'tl',
+ content: {
+ next: this.next,
+ }
+ };
+ }
+
+ public static import(bot: BotCore, data: any) {
+ const context = new TlContext(bot);
+ context.next = data.next;
+ return context;
+ }
+}
+
+class NotificationsContext extends Context {
+ private next: string = null;
+
+ public async greet(): Promise<string> {
+ return await this.getNotifications();
+ }
+
+ public async q(query: string): Promise<string> {
+ if (query == '次') {
+ return await this.getNotifications();
+ } else {
+ this.bot.clearContext();
+ return await this.bot.q(query);
+ }
+ }
+
+ private async getNotifications() {
+ const notifications = await require('../endpoints/i/notifications')({
+ limit: 5,
+ max_id: this.next ? this.next : undefined
+ }, this.bot.user);
+
+ if (notifications.length > 0) {
+ this.next = notifications[notifications.length - 1].id;
+ this.emit('updated');
+
+ const text = notifications
+ .map(notification => getNotificationSummary(notification))
+ .join('\n-----\n');
+
+ return text;
+ } else {
+ return '通知はありません';
+ }
+ }
+
+ public export() {
+ return {
+ type: 'notifications',
+ content: {
+ next: this.next,
+ }
+ };
+ }
+
+ public static import(bot: BotCore, data: any) {
+ const context = new NotificationsContext(bot);
+ context.next = data.next;
+ return context;
+ }
+}
+
class GuessingGameContext extends Context {
private secret: number;
private history: number[] = [];
diff --git a/src/api/bot/interfaces/line.ts b/src/api/bot/interfaces/line.ts
index 0caa71ed2b..43c25f8032 100644
--- a/src/api/bot/interfaces/line.ts
+++ b/src/api/bot/interfaces/line.ts
@@ -135,6 +135,8 @@ class LineBot extends BotCore {
actions: actions
}
}]);
+
+ return null;
}
public async showUserTimelinePostback(userId: string) {