summaryrefslogtreecommitdiff
path: root/src/api/bot/core.ts
blob: 002ac1b06e0beaec62bd3311f7d3fdcb403a15ba (plain)
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 * as EventEmitter from 'events';
import * as bcrypt from 'bcryptjs';

import User, { IUser } from '../models/user';

export default class BotCore extends EventEmitter {
	public user: IUser;

	private context: Context = null;

	constructor(user: IUser) {
		super();

		this.user = user;
	}

	public async q(query: string): Promise<string> {
		if (this.context != null) {
			return await this.context.q(query);
		}

		switch (query) {
			case 'ping':
				return 'PONG';
			case 'ログイン':
			case 'サインイン':
				this.context = new SigninContext(this);
				return await this.context.greet();
			default:
				return '?';
		}
	}

	public setUser(user: IUser) {
		this.user = user;
		this.emit('set-user', user);
	}
}

abstract class Context {
	protected core: BotCore;

	public abstract async greet(): Promise<string>;
	public abstract async q(query: string): Promise<string>;

	constructor(core: BotCore) {
		this.core = core;
	}
}

class SigninContext extends Context {
	private temporaryUser: IUser;

	public async greet(): Promise<string> {
		return 'まずユーザー名を教えてください:';
	}

	public async q(query: string): Promise<string> {
		if (this.temporaryUser == null) {
			// Fetch user
			const user: IUser = await User.findOne({
				username_lower: query.toLowerCase()
			}, {
				fields: {
					data: false,
					profile: false
				}
			});

			if (user === null) {
				return `${query}というユーザーは存在しませんでした... もう一度教えてください:`;
			} else {
				this.temporaryUser = user;
				return `パスワードを教えてください:`;
			}
		} else {
			// Compare password
			const same = bcrypt.compareSync(query, this.temporaryUser.password);

			if (same) {
				this.core.setUser(this.temporaryUser);
				return `${this.temporaryUser.name}さん、おかえりなさい!`;
			} else {
				return `パスワードが違います... もう一度教えてください:`;
			}
		}
	}
}