From 3f0f307104300e148b02f05fd51ac833f9b75b01 Mon Sep 17 00:00:00 2001 From: syuilo Date: Sat, 11 Nov 2017 00:27:02 +0900 Subject: [PATCH] =?UTF-8?q?[LINE]=20=E9=80=9A=E7=9F=A5=E3=81=AE=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/bot/core.ts | 24 +++++++++++++++- src/api/models/notification.ts | 39 ++++++++++++++++++++++++++ src/common/get-notification-summary.ts | 28 ++++++++++++++++++ src/common/get-reaction-emoji.ts | 14 +++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 src/common/get-notification-summary.ts create mode 100644 src/common/get-reaction-emoji.ts diff --git a/src/api/bot/core.ts b/src/api/bot/core.ts index 832439088..ff3f68180 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'; @@ -84,6 +85,7 @@ export default class BotCore extends EventEmitter { 'logout, signout: サインアウトします\n' + 'post: 投稿します\n' + 'tl: タイムラインを見ます\n' + + 'no: 通知を見ます\n' + '@<ユーザー名>: ユーザーを表示します'; case 'me': @@ -115,6 +117,11 @@ export default class BotCore extends EventEmitter { case 'タイムライン': return await this.tlCommand(); + case 'no': + case 'notifications': + case '通知': + return await this.notificationsCommand(); + case 'guessing-game': case '数当てゲーム': this.setContext(new GuessingGameContext(this)); @@ -155,6 +162,7 @@ export default class BotCore extends EventEmitter { this.emit('updated'); } + // TODO: if (this.user == null) return 'まずサインインしてください。'; を @signinRequired みたいなデコレータでいい感じにする public async tlCommand(): Promise { if (this.user == null) return 'まずサインインしてください。'; @@ -163,7 +171,21 @@ export default class BotCore extends EventEmitter { }, this.user); const text = tl - .map(post => getPostSummary(post)) + .map(post => post.user.name + ': ' + getPostSummary(post)) + .join('\n-----\n'); + + return text; + } + + public async notificationsCommand(): Promise { + if (this.user == null) return 'まずサインインしてください。'; + + const notifications = await require('../endpoints/i/notifications')({ + limit: 5 + }, this.user); + + const text = notifications + .map(notification => getNotificationSummary(notification)) .join('\n-----\n'); return text; diff --git a/src/api/models/notification.ts b/src/api/models/notification.ts index 1065e8baa..ecd1c25e1 100644 --- a/src/api/models/notification.ts +++ b/src/api/models/notification.ts @@ -1,8 +1,47 @@ import * as mongo from 'mongodb'; import db from '../../db/mongodb'; +import { IUser } from './user'; export default db.get('notifications') as any; // fuck type definition export interface INotification { _id: mongo.ObjectID; + created_at: Date; + + /** + * 通知の受信者 + */ + notifiee?: IUser; + + /** + * 通知の受信者 + */ + notifiee_id: mongo.ObjectID; + + /** + * イニシエータ(initiator)。通知を行う原因となったユーザー + */ + notifier?: IUser; + + /** + * イニシエータ(initiator)。通知を行う原因となったユーザー + */ + notifier_id: mongo.ObjectID; + + /** + * 通知の種類。 + * follow - フォローされた + * mention - 投稿で自分が言及された + * reply - (自分または自分がWatchしている)投稿が返信された + * repost - (自分または自分がWatchしている)投稿がRepostされた + * quote - (自分または自分がWatchしている)投稿が引用Repostされた + * reaction - (自分または自分がWatchしている)投稿にリアクションされた + * poll_vote - (自分または自分がWatchしている)投稿の投票に投票された + */ + type: 'follow' | 'mention' | 'reply' | 'repost' | 'quote' | 'reaction' | 'poll_vote'; + + /** + * 通知が読まれたかどうか + */ + is_read: Boolean; } diff --git a/src/common/get-notification-summary.ts b/src/common/get-notification-summary.ts new file mode 100644 index 000000000..bf8610599 --- /dev/null +++ b/src/common/get-notification-summary.ts @@ -0,0 +1,28 @@ +import { INotification } from '../api/models/notification'; +import getPostSummary from './get-post-summary'; +import getReactionEmoji from './get-reaction-emoji'; + +/** + * 通知を表す文字列を取得します。 + * @param notification 通知 + */ +export default function(notification: INotification & any): string { + switch (notification.type) { + case 'follow': + return `${notification.notifier.name}にフォローされました`; + case 'mention': + return `言及されました: ${notification.notifier.name}「${getPostSummary(notification.post)}」`; + case 'reply': + return `返信されました: ${notification.notifier.name}「${getPostSummary(notification.post)}」`; + case 'repost': + return `Repostされました: ${notification.notifier.name}「${getPostSummary(notification.post)}」`; + case 'quote': + return `引用されました: ${notification.notifier.name}「${getPostSummary(notification.post)}」`; + case 'reaction': + return `リアクションされました: ${notification.notifier.name} <${getReactionEmoji(notification.reaction)}>「${getPostSummary(notification.post)}」`; + case 'poll_vote': + return `投票されました: ${notification.notifier.name}「${getPostSummary(notification.post)}」`; + default: + return `<不明な通知タイプ: ${notification.type}>`; + } +} diff --git a/src/common/get-reaction-emoji.ts b/src/common/get-reaction-emoji.ts new file mode 100644 index 000000000..c66120537 --- /dev/null +++ b/src/common/get-reaction-emoji.ts @@ -0,0 +1,14 @@ +export default function(reaction: string): string { + switch (reaction) { + case 'like': return '👍'; + case 'love': return '❤️'; + case 'laugh': return '😆'; + case 'hmm': return '🤔'; + case 'surprise': return '😮'; + case 'congrats': return '🎉'; + case 'angry': return '💢'; + case 'confused': return '😥'; + case 'pudding': return '🍮'; + default: return ''; + } +}