✌️
This commit is contained in:
		
							parent
							
								
									6a5c6280ff
								
							
						
					
					
						commit
						fffea98462
					
				
					 5 changed files with 66 additions and 16 deletions
				
			
		| 
						 | 
					@ -4,11 +4,11 @@ import * as bcrypt from 'bcryptjs';
 | 
				
			||||||
import User, { IUser } from '../models/user';
 | 
					import User, { IUser } from '../models/user';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class BotCore extends EventEmitter {
 | 
					export default class BotCore extends EventEmitter {
 | 
				
			||||||
	public user: IUser;
 | 
						public user: IUser = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private context: Context = null;
 | 
						private context: Context = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	constructor(user: IUser) {
 | 
						constructor(user?: IUser) {
 | 
				
			||||||
		super();
 | 
							super();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.user = user;
 | 
							this.user = user;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,34 +1,77 @@
 | 
				
			||||||
import * as EventEmitter from 'events';
 | 
					import * as EventEmitter from 'events';
 | 
				
			||||||
import * as express from 'express';
 | 
					import * as express from 'express';
 | 
				
			||||||
 | 
					import * as request from 'request';
 | 
				
			||||||
import * as crypto from 'crypto';
 | 
					import * as crypto from 'crypto';
 | 
				
			||||||
//import User from '../../models/user';
 | 
					//import User from '../../models/user';
 | 
				
			||||||
import config from '../../../conf';
 | 
					import config from '../../../conf';
 | 
				
			||||||
/*import BotCore from '../core';
 | 
					import BotCore from '../core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const sessions: {
 | 
					const sessions: Array<{
 | 
				
			||||||
	userId: string;
 | 
						sourceId: string;
 | 
				
			||||||
	session: BotCore;
 | 
						session: BotCore;
 | 
				
			||||||
}[] = [];
 | 
					}> = [];
 | 
				
			||||||
*/
 | 
					
 | 
				
			||||||
module.exports = async (app: express.Application) => {
 | 
					module.exports = async (app: express.Application) => {
 | 
				
			||||||
	if (config.line_bot == null) return;
 | 
						if (config.line_bot == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const handler = new EventEmitter();
 | 
						const handler = new EventEmitter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	app.post('/hooks/line', (req, res, next) => {
 | 
						handler.on('message', async (ev) => {
 | 
				
			||||||
		// req.headers['X-Line-Signature'] は常に string ですが、型定義の都合上
 | 
							// テキスト以外(スタンプなど)は無視
 | 
				
			||||||
		// string | string[] になっているので string を明示しています
 | 
							if (ev.message.type !== 'text') return;
 | 
				
			||||||
		const sig1 = req.headers['X-Line-Signature'] as string;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const hash = crypto.createHmac('sha256', config.line_bot.channel_secret)
 | 
							const sourceId = ev.source.userId;
 | 
				
			||||||
			.update(JSON.stringify(req.body));
 | 
							let session = sessions.find(s => {
 | 
				
			||||||
 | 
								return s.sourceId === sourceId;
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!session) {
 | 
				
			||||||
 | 
								session = {
 | 
				
			||||||
 | 
									sourceId: sourceId,
 | 
				
			||||||
 | 
									session: new BotCore()
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sessions.push(session);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const res = await session.session.q(ev.message.text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							request({
 | 
				
			||||||
 | 
								url: 'https://api.line.me/v2/bot/message/reply',
 | 
				
			||||||
 | 
								headers: {
 | 
				
			||||||
 | 
									'Authorization': `Bearer ${config.line_bot.channel_access_token}`
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								json: {
 | 
				
			||||||
 | 
									replyToken: ev.replyToken,
 | 
				
			||||||
 | 
									messages: [{
 | 
				
			||||||
 | 
										type: 'text',
 | 
				
			||||||
 | 
										text: res
 | 
				
			||||||
 | 
									}]
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}, (err, res, body) => {
 | 
				
			||||||
 | 
								if (err) {
 | 
				
			||||||
 | 
									console.error(err);
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						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((req as any).rawBody);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const sig2 = hash.digest('base64');
 | 
							const sig2 = hash.digest('base64');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// シグネチャ比較
 | 
							// シグネチャ比較
 | 
				
			||||||
		if (sig1 === sig2) {
 | 
							if (sig1 === sig2) {
 | 
				
			||||||
			console.log(req.body);
 | 
								req.body.events.forEach(ev => {
 | 
				
			||||||
			handler.emit(req.body.type);
 | 
									handler.emit(ev.type, ev);
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			res.sendStatus(200);
 | 
								res.sendStatus(200);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			res.sendStatus(400);
 | 
								res.sendStatus(400);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,12 @@ app.disable('x-powered-by');
 | 
				
			||||||
app.set('etag', false);
 | 
					app.set('etag', false);
 | 
				
			||||||
app.use(bodyParser.urlencoded({ extended: true }));
 | 
					app.use(bodyParser.urlencoded({ extended: true }));
 | 
				
			||||||
app.use(bodyParser.json({
 | 
					app.use(bodyParser.json({
 | 
				
			||||||
	type: ['application/json', 'text/plain']
 | 
						type: ['application/json', 'text/plain'],
 | 
				
			||||||
 | 
						verify: (req, res, buf, encoding) => {
 | 
				
			||||||
 | 
							if (buf && buf.length) {
 | 
				
			||||||
 | 
								(req as any).rawBody = buf.toString(encoding || 'utf8');
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}));
 | 
					}));
 | 
				
			||||||
app.use(cors({
 | 
					app.use(cors({
 | 
				
			||||||
	origin: true
 | 
						origin: true
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,6 +70,7 @@ type Source = {
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	line_bot?: {
 | 
						line_bot?: {
 | 
				
			||||||
		channel_secret: string;
 | 
							channel_secret: string;
 | 
				
			||||||
 | 
							channel_access_token: string;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	analysis?: {
 | 
						analysis?: {
 | 
				
			||||||
		mecab_command?: string;
 | 
							mecab_command?: string;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@
 | 
				
			||||||
		"ordered-imports": [false],
 | 
							"ordered-imports": [false],
 | 
				
			||||||
		"arrow-parens": false,
 | 
							"arrow-parens": false,
 | 
				
			||||||
		"object-literal-shorthand": false,
 | 
							"object-literal-shorthand": false,
 | 
				
			||||||
 | 
							"object-literal-key-quotes": false,
 | 
				
			||||||
		"triple-equals": [false],
 | 
							"triple-equals": [false],
 | 
				
			||||||
		"no-shadowed-variable": false,
 | 
							"no-shadowed-variable": false,
 | 
				
			||||||
		"no-string-literal": false,
 | 
							"no-string-literal": false,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue