Skip to content

Commit

Permalink
slow-quiz: Finish implementation of ChatGPT answers
Browse files Browse the repository at this point in the history
  • Loading branch information
hakatashi committed Sep 5, 2023
1 parent 14f531c commit 0b818e0
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 28 deletions.
95 changes: 71 additions & 24 deletions slow-quiz/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import {ChatCompletionRequestMessage, Configuration, OpenAIApi} from 'openai';
import {increment} from '../achievements';
import logger from '../lib/logger';
import type {SlackInterface} from '../lib/slack';
import {getMemberIcon, getMemberName} from '../lib/slackUtils';
import State from '../lib/state';
import {Loader} from '../lib/utils';
import {getUserIcon, getUserMention, getUserName} from './util';
import answerQuestionDialog from './views/answerQuestionDialog';
import footer from './views/footer';
import gameDetailsDialog from './views/gameDetailsDialog';
Expand Down Expand Up @@ -238,6 +238,7 @@ class SlowQuiz {
id: payload?.view?.private_metadata,
viewId: payload?.view?.id,
comment: state?.slowquiz_post_comment_input_comment?.value,
type: 'user',
user: payload?.user?.id,
})
));
Expand All @@ -252,6 +253,7 @@ class SlowQuiz {
id: payload?.view?.private_metadata,
viewId: payload?.view?.id,
comment: state?.slowquiz_post_comment_input_comment?.value,
type: 'user',
user: payload?.user?.id,
})
));
Expand Down Expand Up @@ -452,11 +454,17 @@ class SlowQuiz {
answer = answerMatches.groups.answer;
}

const rubyMatches = answer.match(/[((](?<ruby>.+?)[))]/);
const rubyMatches = answer?.match(/[((](?<ruby>.+?)[))]/);
if (rubyMatches?.groups?.ruby) {
answer = rubyMatches.groups.ruby;
}

answer = answer?.replaceAll(/[^ぁ-ゟァ-ヿa-z0-9]/ig, '');

if (answer === '') {
answer = null;
}

return {
answer,
result,
Expand Down Expand Up @@ -507,11 +515,39 @@ class SlowQuiz {
});
}

getUserMention({user, type}: {user: string, type: 'user' | 'bot'}) {
if (type === 'user') {
return `<@${user}>`;
async createBotAnswers() {
for (const game of this.state.games) {
const botId = 'chatgpt-3.5-turbo:ver1';
const userId = `bot:${botId}`;

if (game.status !== 'inprogress') {
continue;
}

if (game.correctAnswers.some((answer) => answer.user === userId)) {
continue;
}

const {answer, result} = await this.getChatGptAnswer(game);
if (answer !== null) {
this.answerQuestion({
type: 'bot',
game,
ruby: answer,
user: botId,
});
}

if (result !== null) {
await this.postComment({
id: game.id,
viewId: '',
comment: result,
type: 'bot',
user: botId,
});
}
}
return `*${user}*`;
}

answerQuestion({
Expand All @@ -526,7 +562,7 @@ class SlowQuiz {
user: string,
}) {
const userId = type === 'user' ? user : `bot:${user}`;
const userMention = this.getUserMention({user, type});
const userMention = getUserMention(userId);

game.answeredUsers.push(userId);

Expand All @@ -541,7 +577,7 @@ class SlowQuiz {
game.wrongAnswers = [];
}
game.wrongAnswers.push({
user,
user: userId,
progress: game.progress,
days: game.days,
date: Date.now(),
Expand All @@ -556,7 +592,7 @@ class SlowQuiz {
}

game.correctAnswers.push({
user,
user: userId,
progress: game.progress,
days: game.days,
date: Date.now(),
Expand Down Expand Up @@ -617,45 +653,54 @@ class SlowQuiz {
this.updateLatestStatusMessages();
}

postComment({
async postComment({
id,
viewId,
comment,
type,
user,
}: {
id: string,
viewId: string,
comment: string,
type: 'user' | 'bot',
user: string,
}) {
const game = this.state.games.find((g) => g.id === id);
const userId = type === 'user' ? user : `bot:${user}`;

if (!game) {
this.postEphemeral('Error: 問題が見つかりません', user);
return null;
if (type === 'user') {
this.postEphemeral('Error: 問題が見つかりません', user);
}
return;
}

if (game.status === 'finished') {
this.postEphemeral('Error: この問題の解答受付は終了しています', user);
return null;
if (type === 'user') {
this.postEphemeral('Error: この問題の解答受付は終了しています', user);
}
return;
}

if (!Array.isArray(game.comments)) {
game.comments = [];
}

game.comments.push({
user,
user: userId,
progress: game.progress,
days: game.days,
date: Date.now(),
answer: comment,
});

return this.slack.views.update({
view_id: viewId,
view: postCommentDialog(game, user),
});
if (type === 'user') {
await this.slack.views.update({
view_id: viewId,
view: postCommentDialog(game, user),
});
}
}

deleteQuiz({viewId, id, user}: {viewId: string, id: string, user: string}) {
Expand Down Expand Up @@ -758,6 +803,8 @@ class SlowQuiz {
channel: message.channel,
}));
}

await this.createBotAnswers();
}

chooseNewGame() {
Expand Down Expand Up @@ -861,8 +908,8 @@ class SlowQuiz {
},
{
type: 'image',
image_url: await getMemberIcon(answer.user),
alt_text: await getMemberName(answer.user),
image_url: await getUserIcon(answer.user),
alt_text: await getUserName(answer.user),
},
],
}))),
Expand Down Expand Up @@ -933,16 +980,16 @@ class SlowQuiz {
{
type: 'mrkdwn',
text: oneLine`
${await getMemberName(game.author)} さんの問題 /
${await getUserName(game.author)} さんの問題 /
${getGenreText(game.genre)}】 /
本日${game.answeredUsers.length}人解答 /
${game.correctAnswers.length}人正解済み
`,
},
...await Promise.all(game.correctAnswers.map(async (correctAnswer) => ({
type: 'image',
image_url: await getMemberIcon(correctAnswer.user),
alt_text: await getMemberName(correctAnswer.user),
image_url: await getUserIcon(correctAnswer.user),
alt_text: await getUserName(correctAnswer.user),
} as ImageElement))),
],
});
Expand Down
26 changes: 26 additions & 0 deletions slow-quiz/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {getEmoji, getMemberIcon, getMemberName} from '../lib/slackUtils';

export const getUserMention = (userId: string) => {
if (userId.startsWith('bot:')) {
const botId = userId.replace(/^bot:/, '');
return `*${botId}*`;
}
return `<@${userId}>`;
};

export const getUserIcon = (userId: string) => {
if (userId.startsWith('bot:')) {
return getEmoji('chatgpt', process.env.TEAM_ID);
}
return getMemberIcon(userId);
};

export const getUserName = (userId: string) => {
if (userId.startsWith('bot:')) {
const botId = userId.replace(/^bot:/, '');
return botId;
}
return getMemberName(userId);
};


9 changes: 5 additions & 4 deletions slow-quiz/views/gameDetailsDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ import {View} from '@slack/web-api';
import type {KnownBlock} from '@slack/web-api';
import {sortBy} from 'lodash';
import type {Game, Submission} from '../index';
import {getUserMention} from '../util';

type UserSubmission = Submission & { type: 'wrong_answer' | 'correct_answer' | 'comment' }

const formatSubmission = ({days, type, user, answer}: UserSubmission) => {
if (type === 'wrong_answer') {
return `${days}日目: <@${user}> *解答「${answer}」* → 不正解`;
return `${days}日目: ${getUserMention(user)} *解答「${answer}」* → 不正解`;
}
if (type === 'correct_answer') {
return `${days}日目: <@${user}> *解答「${answer}」* → 正解`;
return `${days}日目: ${getUserMention(user)} *解答「${answer}」* → 正解`;
}
return `${days}日目: <@${user}> ${answer}`;
return `${days}日目: ${getUserMention(user)} ${answer}`;
};

const getSubmissionsBlocks = (submissions: UserSubmission[]) => {
Expand Down Expand Up @@ -73,7 +74,7 @@ export default (game: Game) => {
type: 'section',
text: {
type: 'mrkdwn',
text: `<@${game.author}>`,
text: getUserMention(game.author),
},
},
{
Expand Down

0 comments on commit 0b818e0

Please sign in to comment.