【Markdown AI】15分で作る「絶対に怒られない謝罪文」ジェネレーター

# はじめに
この記事は [MarkdownAI Advent Calendar 2024](https://qiita.com/advent-calendar/2024/markdownai) の14日目の記事です。

「謝罪しなきゃ…でも、何を書けばいいかわからない！」

仕事でのちょっとしたミスや、友達への遅刻連絡など、謝罪メッセージを送る機会は意外と多いもの。
でも、適切な言葉遣いや表現を考え始めると、難しくて時間がかかってしまいますよね。

そこで今回はMarkdown AIを使って、「絶対に怒られない謝罪文ジェネレーター」を簡単に作る方法を紹介します！

# Markdown AIって何？
Markdown AIは、Markdown記法とAIを組み合わせて、誰でも簡単にWebサイトやコンテンツを作成できるツールです。
コードが書けなくても、AIがサーバー設定やデプロイ作業を自動で行ってくれるため、初心者や子供でも気軽に使えます！

# サイトの完成イメージ
ユーザーが簡単な入力を行うだけで、AIが誠意あふれる謝罪文を生成してくれるサイトを目指します。

**ユーザーの入力項目**
- 何を謝るのか？（例：納期遅延、誤送信、日程変更）
- 相手は誰？（例：上司、クライアント、友人）
- 謝罪の深刻度（軽いミス / 普通 / 深刻）
- メールのトーン（フォーマル / カジュアル）

# 開発手順
1. Markdown AIのセットアップ
1. AIモデルの作成
1. サイトコンテンツの作成
1. 動作確認・公開

ステップごとに解説していきます！

## ステップ1：Markdown AIのセットアップ
**1. [MarkdownAI公式サイト](https://mdown.ai/) にアクセスし、無料アカウントを作成します**

 ![スクリーンショット 2024-12-07 15.24.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998181/a2f2b65c-efec-3051-08ba-2934dc6d29fc.png)

**2. プラスボタンをクリックし、新しいプロジェクトを作成します**

![スクリーンショット 2024-12-09 11.43.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998181/7e5f2a29-31f6-3bd7-c094-ae1aaed92cda.png)


## ステップ2：AIモデルの作成
#### 1. create AI ボタンをクリック
![スクリーンショット 2024-12-09 11.42.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998181/8955ed23-45ff-ada0-b07a-ba424e01ca59.png)

#### 2. モデルを選択し、モデル名を入力
今回はgpt-4o-miniを選択しました。
![スクリーンショット 2024-12-07 15.58.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998181/b31e7be0-9b0a-abb3-b7ba-828667d848a6.png)

#### 3. プロンプトを入力
今回使用したプロンプトは以下の通りです。

```
### 指示  
以下の内容を基に、誠意のある謝罪メールを生成してください。  

### 入力内容  
- **ミスの内容**: {{ミスの内容}}  
- **相手の立場**: {{相手の立場}}  
- **謝罪の深刻度**: {{謝罪の深刻度}} 
- **トーン設定**: {{トーン設定}}

### 出力条件   
1. 丁寧な謝罪の導入文  
2. ミスの内容説明と反省の言葉  
3. 今後の対策や改善策  
4. 締めの言葉  

### 出力例  
お世話になっております。△△部の〇〇です。  

このたび、{{ミスの内容}}につきまして、ご迷惑をおかけしましたことを深くお詫び申し上げます。  
今後同様のことがないよう、確認体制を強化し、再発防止に努めてまいります。  

何卒ご容赦賜りますようお願い申し上げます。  
引き続きよろしくお願い申し上げます。  
```


#### 4. ナレッジを設定
AIへの入力形式を指定します。
今回はサイト上での入力内容を渡したいので、Markdownを選択します。
#### 5. 画面下部のCreateボタンをクリック

## ステップ3：サイトコンテンツの作成
#### 1. Markdown形式でコンテンツを記述
必要な要素をMarkdown形式で記載します。
```
## 謝罪内容入力フォーム

### 何を謝りますか？
**ミスの内容**  
{{ミスの内容}}  
`例: 提出期限を過ぎた、連絡が遅れた`

---

### 相手の立場は？
**相手の立場**  
{{相手の立場}}  
`例: 上司 / クライアント / 友人`

---

### 謝罪の深刻度は？
**謝罪の深刻度**  
{{謝罪の深刻度}}  
`例: 軽度 / 中度 / 重度`

---

### トーンを選んでください  
- フォーマル  
- カジュアル  

---

## **生成結果**

{{AIが生成した謝罪文}}  

```

#### 2. 入力フォームの追加
以下のサイトからMarkdownを入力フォームに変換します。
Markdownで書かれたコンテンツの全文をコピー・貼り付けし、変換してください。

https://mdown.ai/content/8da17007-cd8a-4038-bc63-6792835514f0

**例：変換後のコード**
```html
<form>
<div>
<label for="apology_content">何を謝りますか？</label>
<input type="text" id="apology_content" name="apology_content" placeholder="例: 提出期限を過ぎた、連絡が遅れた">
</div>
<div>
<label for="recipient_position">相手の立場は？</label>
<input type="text" id="recipient_position" name="recipient_position" placeholder="例: 上司 / クライアント / 友人">
</div>
<div>
<label for="apology_severity">謝罪の深刻度は？</label>
<input type="text" id="apology_severity" name="apology_severity" placeholder="例: 軽度 / 中度 / 重度">
</div>
<div>
<label>トーンを選んでください</label><br>
<input type="radio" id="tone_formal" name="tone" value="フォーマル">
<label for="tone_formal">フォーマル</label><br>
<input type="radio" id="tone_casual" name="tone" value="カジュアル">
<label for="tone_casual">カジュアル</label>
</div>
<div>
<button type="button" id="generate_button">謝罪文を生成</button>
</div>
<div id="result">
<label for="generated_apology">生成結果</label>
<textarea id="generated_apology" name="generated_apology" rows="3" cols="40" readonly></textarea>
</div>
</form>

<script>
(() => {
const button = document.getElementById('generate_button');
button.addEventListener('click', async event => {
button.disabled = true;

// AIによる謝罪文生成のロジックをここに追加
const apologyContent = document.getElementById('apology_content').value;
const recipientPosition = document.getElementById('recipient_position').value;
const apologySeverity = document.getElementById('apology_severity').value;
const tone = document.querySelector('input[name="tone"]:checked')?.value;

// ここでAIにリクエストを送信し、結果を取得する処理を実装
const generatedText = `謝罪文: ${apologyContent}に関して、${recipientPosition}に対して、${apologySeverity}の謝罪をします。トーンは${tone}です。`; // 仮の生成結果

document.getElementById('generated_apology').value = generatedText;
button.disabled = false;
});
})();
</script>
```

#### 3. 作成したAIモデルを追加
Insertボタンから、作成したAIモデルを挿入します。

![スクリーンショット 2024-12-09 11.42.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998181/4bbdaf10-456d-76d7-0c27-e9602f1a4e13.png)

![スクリーンショット 2024-12-09 11.47.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998181/e8bbb6df-08b3-143b-2f43-f72d465bc8be.png)


#### 4. ボタン動作の修正
AIモデルの追加操作で以下のようなコードが挿入されたと思います。
```html
<div style="display: inline-block;">
  <input type="text" id="text-1733706592" style="width: 200px;" value="Teach me about Markdown.">
  <button type="button" id="button-1733706592">Run AI</button>
</div>
<div id="answer-1733706592"></div>
  
<script>
(() => {
  const button = document.getElementById('button-1733706592');
  button.addEventListener('click', async event => {
    button.disabled = true;
  
    const serverAi = new ServerAI();
    const message = document.getElementById('text-1733706592').value;
    const answer = await serverAi.getAnswerText('your-api-token', '', message);
  
    document.getElementById('answer-1733706592').innerText = answer;
    button.disabled = false;
  });
})();
</script>
```
これをフォームの処理に合わせて少し書き換えます。

修正する内容は以下の3点です。
- Insertで追加された「Run AI」ボタンを削除する
- serverAIに送るメッセージをフォームの内容にする
- 受け取ったデータを表示する場所を変更する



```diff_html
<form>
<!-- 省略 -->
<div>
<button type="button" id="generate_button">謝罪文を生成</button>
</div>
<div id="result">
<label for="generated_apology">生成結果</label>
<textarea id="generated_apology" name="generated_apology" rows="3" cols="40" readonly></textarea>
</div>
</form>

<script>
(() => {
const button = document.getElementById('generate_button');
button.addEventListener('click', async event => {
button.disabled = true;

// AIによる謝罪文生成のロジックをここに追加
const apologyContent = document.getElementById('apology_content').value;
const recipientPosition = document.getElementById('recipient_position').value;
const apologySeverity = document.getElementById('apology_severity').value;
const tone = document.querySelector('input[name="tone"]:checked')?.value;

// ここでAIにリクエストを送信し、結果を取得する処理を実装
const generatedText = `謝罪文: ${apologyContent}に関して、${recipientPosition}に対して、${apologySeverity}の謝罪をします。トーンは${tone}です。`; // 仮の生成結果

- document.getElementById('generated_apology').value = generatedText;
- button.disabled = false;
- });
- })();
- </script>
- 
- 
- <div style="display: inline-block;">
-   <input type="text" id="text-1733706592" style="width: 200px;" value="Teach me about Markdown.">
-   <button type="button" id="button-1733706592">Run AI</button>
- </div>
- <div id="answer-1733706592"></div>
- 
- <script>
- (() => {
-   const button = document.getElementById('button-1733706592');
-   button.addEventListener('click', async event => {
-     button.disabled = true;
  
    const serverAi = new ServerAI();
-   const message = document.getElementById('text-1733706592').value;
+   const message = generatedText; //AIに送るデータをフォームの内容に変える
    const answer = await serverAi.getAnswerText('your-api-token', '', message);
  
-   document.getElementById('answer-1733706592').innerText = answer;
+   document.getElementById('generated_apology').value = answer; //出力を表示する場所を変える
    button.disabled = false;
  });
})();
</script>
```

#### 5. 見た目を整える
Viewボタンをクリックし、サイトのプレビューを確認します。

![スクリーンショット 2024-12-09 11.58.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998181/491d752f-1b41-dfce-894f-85ea318f5df8.png)

なんだか無骨で見づらいサイトですね。
コンテンツをMarkdownに書き直してみましょう。
**Markdown AIではform要素やdiv要素、label要素はなくても大丈夫**です。
ただし、inputやtextarea、buttonとそのidは消さないように注意してください。

```
# **絶対に怒られない謝罪文ジェネレーター**

### 入力フォーム

- **何を謝りますか？**
<input type="text" id="apology_content" name="apology_content" placeholder="例: 提出期限を過ぎた、連絡が遅れた">
  
- **相手の立場は？**
<input type="text" id="recipient_position" name="recipient_position" placeholder="例: 上司 / クライアント / 友人">
  
- **謝罪の深刻度は？**
<input type="text" id="apology_severity" name="apology_severity" placeholder="例: 軽度 / 中度 / 重度">
  
- **トーンを選んでください**
<div>
<input type="radio" id="tone_formal" name="tone" value="フォーマル">
<label for="tone_formal">フォーマル</label><br>
<input type="radio" id="tone_casual" name="tone" value="カジュアル">
<label for="tone_casual">カジュアル</label>
</div>

<button type="button" id="generate_button">謝罪文を生成</button>

### 生成結果
<textarea id="generated_apology" name="generated_apology" rows="3" cols="40" readonly></textarea>
```


## ステップ4：動作確認と公開
Viewボタンから再度プレビューを確認し、動作確認を行います。
フォームに適当な入力を行い、謝罪文を生成してみましょう。

![スクリーンショット 2024-12-09 11.20.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998181/eac7fca4-de8a-901d-668e-cce534fcbb72.png)

問題なく動作したのでこれを公開します。
Saveボタンをクリックし、URL、Publishと進むだけで公開されます。

![スクリーンショット 2024-12-09 11.22.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/998181/97ea297b-2df3-c28d-7058-c28cd7a9f96e.png)

ここで表示されているリンクがサイトのURLです。
アクセスして確認してみましょう。

https://mdown.ai/content/79e66563-3392-4b9f-8f58-f8347bc504c2

# まとめ
この記事では、Markdown AIを使ってAIを組み込んだサイトを作成・公開する手順を紹介しました。

Markdown AIを使ってみて感じたことは以下の通りです。

- **サイトに簡単にAIを組み込めるのがすごい**
コードが書けない初心者でも、簡単な設定とプロンプトの指定だけでAIモデルをサイトに組み込めるのは非常に画期的だと思いました。AIを使ったコンテンツ作成のハードルが一気に下がったと感じます。

- **サイトの公開が想像以上に簡単**
作成したコンテンツをプレビューし、そのまま数ステップで公開できる点は驚きでした。初心者が陥りがちな「作ってみたけれどもその先がよく分からずお蔵入り」という状況を避けられると感じました。

- **Markdownにない要素を追加するためにはHTMLを使う必要があるのは残念**
フォームやボタンなど、Markdown記法に元々ない要素を追加するためにはHTMLを記述する必要があり、少し手間に感じました。ただし、MarkdownとHTMLを混ぜて書くこともできたため、細かな調整ができる点は逆に便利でもありました。

「AIとかプログラミングなんてハードル高いよ…」と思っている人でも、Markdown AIなら気軽に挑戦できると思います。
今回は「謝罪文を作る」というアイディアをもとに制作しましたが、オリジナル小説を生成するサイトや、謎解きヒントを出すサイトなど、色々なアイデアに応用可能です。

Markdown AIで自分だけのAIサイトを作って、世界に公開してみてください！

# 参考

https://qiita.com/mdown_ai_jpn/items/d3e281565c876a0bd64f