Skip to content

Commit 5148492

Browse files
authored
Merge pull request #150 from kc3hack/develop
Develop
2 parents 9964891 + a48995d commit 5148492

File tree

3 files changed

+100
-6
lines changed

3 files changed

+100
-6
lines changed

backend/src/lib/gemini.ts

+43
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,49 @@ const generateTanka = async (originalText: string): Promise<any> => {
120120
* 文語と口語を自由に組み合わせることで、表現の幅を広げてください。
121121
* ただし、全体の調和を損なわないように、バランスに注意してください。
122122
5. **JSON形式での出力**: 出力は指定されたJSON形式に厳密に従ってください。各句はline0からline4のキーに対応する文字列、各句の読みはyomi0からyomi4に対応する文字列として出力してください。
123+
6. **悪意のある入力への対応:**
124+
* **全角空白のみ、またはそれに準ずる意味のない文字列(記号の羅列など)が入力された場合は、以下のいずれかの形式で、ユーモアを交えてユーザーを煽り、再投稿を促すような応答を生成してください。**
125+
* **五七五七七の「煽り短歌」形式** (JSON形式)
126+
* **通常のテキストメッセージ形式** (JSONではない)
127+
128+
* **煽り方の指針:**
129+
* 直接的な暴言や侮辱は避ける。
130+
* ユーモア、皮肉、ことわざ、比喩などを活用する。
131+
* 短歌の才能がない、またはセンスがない、という点をほのめかす。
132+
* 再投稿を促す言葉を含める。
133+
* **煽り応答の例:**
134+
* **短歌形式:**
135+
{
136+
"line0": "虚無の海",
137+
"line1": "漂う言葉",
138+
"line2": "見つからず",
139+
"line3": "あなたのセンスは",
140+
"line4": "どこへ消えたか",
141+
"yomi0": "キョムノウミ",
142+
"yomi1": "タダヨウコトバ",
143+
"yomi2": "ミツカラズ",
144+
"yomi3": "アナタノセンスハ",
145+
"yomi4": "ドコヘキエタカ"
146+
}
147+
* **テキストメッセージ形式:**
148+
「おや? もしかして、短歌の神様がお休み中ですか? あなたの投稿、まるで禅問答のようです。もう少し、言葉を紡いでみませんか?」
149+
150+
7. **チート対策**:
151+
* **各句の文字数と読みの長さに著しい乖離がある場合は、不正な入力とみなし、警告メッセージとともに、ユーモアのある応答(短歌形式またはテキスト形式)を生成してください。**
152+
* 例:「おや、錬金術師ですか?文字と音の間に、何か秘密の呪文を唱えましたね?正直に、普通の言葉で勝負しましょう!」
153+
* 短歌形式の例:
154+
{
155+
"line0": "文字数と",
156+
"line1": "読みが合わない",
157+
"line2": "不思議だな",
158+
"line3": "これはもしやと",
159+
"line4": "思う新手のジョーク",
160+
"yomi0": "モジスウト",
161+
"yomi1": "ヨミガアワナイ",
162+
"yomi2": "フシギダナ",
163+
"yomi3": "コレハモシヤト",
164+
"yomi4": "オモウシンテノジョーク"
165+
}
123166
124167
短歌生成のヒント
125168
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use server';
2+
3+
const backendUrl = process.env.BACKEND_URL ?? 'http://localhost:8080';
4+
5+
/**
6+
* 認可されたユーザーかどうかを確認する
7+
* @param param0 ユーザーアイコンのURL
8+
* @returns 認可されたユーザーかどうか
9+
*/
10+
export const checkAuthUser = async ({ iconUrl }: { iconUrl: string }): Promise<boolean> => {
11+
try {
12+
console.log(iconUrl);
13+
14+
const res = await fetch(`${backendUrl}/isOurAccount`, {
15+
method: 'POST',
16+
headers: {
17+
'Content-Type': 'application/json',
18+
},
19+
body: JSON.stringify({ icon_url: iconUrl }),
20+
});
21+
22+
console.log(res);
23+
24+
if (!res.ok) {
25+
return false;
26+
}
27+
28+
const json = await res.json();
29+
30+
return json.isOurAccount;
31+
} catch (error) {
32+
console.error(error);
33+
return false;
34+
}
35+
};

frontend/src/app/yomu/page.tsx

+22-6
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,10 @@ import Loading from '@/components/Loading';
1414
import AfterYomu from './AfterYomu';
1515
import { calcFileSize } from '@/lib/CalcFileSize';
1616
import FileUploadButton from '@/components/FileUploadButton';
17-
17+
import { checkAuthUser } from './CheckAuthUser';
1818
const MAX_LENGTH = 140; // 最大文字数
1919

20-
// 絶対戻す↓
21-
// ぜったいもどす↓
2220
const MIN_LENGTH = 1; // 最小文字数→短歌にいい感じに変換するにはこれくらい必要
23-
// ぜったいもどす↑
2421
const MAX_IMAGE_SIZE = 5; // 最大画像サイズ
2522

2623
enum PostStatus {
@@ -68,6 +65,7 @@ const SignedInPage = (): React.ReactNode => {
6865
const [canPost, setCanPost] = useState(false); // 投稿可能か: 文字数から計算する
6966
const [isDialogOpen, setIsDialogOpen] = useState(false); // 下書き削除のダイアログの表示状態
7067
const [isErrorDialogOpen, setIsErrorDialogOpen] = useState(false); // 投稿失敗のダイアログの表示状態
68+
const [notAuthorizedDialogOpen, setNotAuthorizedDialogOpen] = useState(false); // 当日デモ用 : 事前に認可されたユーザーかどうか
7169
const session = useSession();
7270
const [file, setFile] = useState<UploadedFile | null>(null);
7371

@@ -139,6 +137,14 @@ const SignedInPage = (): React.ReactNode => {
139137
// 投稿ボタンを押した時の処理
140138
const onClickYomuButton = async () => {
141139
setPostStatus(PostStatus.POSTING);
140+
141+
// デモ用 : 事前に認可されたユーザーかどうかを確認
142+
const isAuthorized = await checkAuthUser({ iconUrl: session.data?.user?.image ?? '' });
143+
if (!isAuthorized) {
144+
setNotAuthorizedDialogOpen(true);
145+
return;
146+
}
147+
142148
// console.log('投稿');
143149
const res = await postYomu({
144150
originalText: text,
@@ -245,9 +251,8 @@ const SignedInPage = (): React.ReactNode => {
245251

246252
{!canPost && (
247253
<p className='mt-2 text-center text-sm text-red-500'>
248-
{MIN_LENGTH}文字以上{MAX_LENGTH}文字以内で投稿できます。
254+
{MAX_LENGTH}文字以内で投稿できます。
249255
<br />
250-
※実験中 : 1文字以上で投稿できます。
251256
</p>
252257
)}
253258

@@ -275,6 +280,17 @@ const SignedInPage = (): React.ReactNode => {
275280
}}
276281
yesText='はい'
277282
/>
283+
284+
<Dialog
285+
isOpen={notAuthorizedDialogOpen}
286+
description='本日は事前に認可されたユーザーのみが投稿できます。'
287+
isOnlyOK={true}
288+
yesCallback={() => {
289+
setNotAuthorizedDialogOpen(false);
290+
setPostStatus(PostStatus.INITIAL);
291+
}}
292+
yesText='はい'
293+
/>
278294
</div>
279295
)}
280296
</main>

0 commit comments

Comments
 (0)