diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2017-10-07 03:36:46 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2017-10-07 03:36:46 +0900 |
| commit | 6a5c6280ffd3ffe820beb23294f1c2c1f5deb9cf (patch) | |
| tree | eb9006394a36bfa80bd255e9d86a524060c37828 /src/api/bot | |
| parent | Merge pull request #817 from syuilo/greenkeeper/@types/mongodb-2.2.13 (diff) | |
| download | sharkey-6a5c6280ffd3ffe820beb23294f1c2c1f5deb9cf.tar.gz sharkey-6a5c6280ffd3ffe820beb23294f1c2c1f5deb9cf.tar.bz2 sharkey-6a5c6280ffd3ffe820beb23294f1c2c1f5deb9cf.zip | |
:v:
Diffstat (limited to 'src/api/bot')
| -rw-r--r-- | src/api/bot/core.ts | 88 | ||||
| -rw-r--r-- | src/api/bot/interfaces/line.ts | 37 |
2 files changed, 125 insertions, 0 deletions
diff --git a/src/api/bot/core.ts b/src/api/bot/core.ts new file mode 100644 index 0000000000..002ac1b06e --- /dev/null +++ b/src/api/bot/core.ts @@ -0,0 +1,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 `パスワードが違います... もう一度教えてください:`; + } + } + } +} diff --git a/src/api/bot/interfaces/line.ts b/src/api/bot/interfaces/line.ts new file mode 100644 index 0000000000..4bee844c12 --- /dev/null +++ b/src/api/bot/interfaces/line.ts @@ -0,0 +1,37 @@ +import * as EventEmitter from 'events'; +import * as express from 'express'; +import * as crypto from 'crypto'; +//import User from '../../models/user'; +import config from '../../../conf'; +/*import BotCore from '../core'; + +const sessions: { + userId: string; + session: BotCore; +}[] = []; +*/ +module.exports = async (app: express.Application) => { + if (config.line_bot == null) return; + + const handler = new EventEmitter(); + + app.post('/hooks/line', (req, res, next) => { + // req.headers['X-Line-Signature'] は常に string ですが、型定義の都合上 + // string | string[] になっているので string を明示しています + const sig1 = req.headers['X-Line-Signature'] as string; + + const hash = crypto.createHmac('sha256', config.line_bot.channel_secret) + .update(JSON.stringify(req.body)); + + const sig2 = hash.digest('base64'); + + // シグネチャ比較 + if (sig1 === sig2) { + console.log(req.body); + handler.emit(req.body.type); + res.sendStatus(200); + } else { + res.sendStatus(400); + } + }); +}; |