【Python × Twilio x 恋愛】彼女の電話にモールス信号で「好き」と伝えるシステムを作った話

こんにちは。tampopo256です。
普段は教育系のWebサービスを作ったりしています。

:::note warn
実践すると彼女と喧嘩の原因になる恐れがあります...
:::


## はじめに：伝えたいけど、直接はちょっと…

ある日ふと思ったんです。

> 「どうすれば、エンジニアっぽく、ちょっとロマンチックに愛を伝えられるか？」

LINEや手紙でもなく、もっと**ニッチで意味不明で、でも伝わったら最高に嬉しい方法**。

そう、**モールス信号で電話をかけよう**と。

## 概要：彼女の電話番号にビープ音で「DAISUKI」と伝える

仕組みはこうです。

1. **彼女には「今日の19時、電話出てね」とだけ伝える**
2. その時間に、僕のサーバーから自動で電話をかける
3. 通話では何も喋らず、「ピッ、ピピー、ピッピッ…」という**謎のビープ音**
4. それが実は**モールス信号で「DAISUKI」だった**

後からLINEで「もしかして…あれモールス信号…？」って来たときの、あの気持ち。
最高です。

## システム構成

* Python で完結
* Twilio で電話発信
* Flask でモールス音声を配信
* pydub で音声を生成（モールス）
* gTTS 不使用（今回は文字読み上げではなく周波数生成）

## 1. モールス信号音声を生成（`morse_generator.py`）

```python
from pydub.generators import Sine
from pydub import AudioSegment

MORSE_CODE_DICT = {
    'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..',
    'E': '.',  'F': '..-.', 'G': '--.',  'H': '....',
    'I': '..', 'J': '.---', 'K': '-.-',  'L': '.-..',
    'M': '--', 'N': '-.',   'O': '---',  'P': '.--.',
    'Q': '--.-','R': '.-.', 'S': '...',  'T': '-',
    'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-',
    'Y': '-.--','Z': '--..', ' ': ' '
}

UNIT = 150  # ms

def generate_morse_audio(message: str, output_path: str):
    dot = Sine(700).to_audio_segment(duration=UNIT)
    dash = Sine(700).to_audio_segment(duration=UNIT * 3)
    silence_unit = AudioSegment.silent(duration=UNIT)
    letter_space = AudioSegment.silent(duration=UNIT * 3)
    word_space = AudioSegment.silent(duration=UNIT * 7)
    result = AudioSegment.silent(duration=0)

    for char in message.upper():
        if char == ' ':
            result += word_space
            continue
        morse = MORSE_CODE_DICT.get(char)
        if morse:
            for symbol in morse:
                if symbol == '.':
                    result += dot
                elif symbol == '-':
                    result += dash
                result += silence_unit
            result += letter_space

    result.export(output_path, format="mp3")
```

> 実行例：

```python
generate_morse_audio("DAISUKI", "static/morse.mp3")
```

---

## 2. モールス音声をTwilio通話で配信（`app.py`）

```python
from flask import Flask, Response
from twilio.twiml.voice_response import VoiceResponse

app = Flask(__name__)

@app.route("/call_morse", methods=["GET", "POST"])
def call_morse():
    response = VoiceResponse()
    response.play("https://yourdomain.com/static/morse.mp3")
    return Response(str(response), mimetype='application/xml')
```

> Twilioは `HTTPS` で外部アクセスできる必要があります。開発時は `ngrok` 等が便利です。
筆者はgoogle storageに仮置きしました...

---

## 3. Twilioで電話をかけるスクリプト（`call_sender.py`）

```python
from twilio.rest import Client
import os

account_sid = os.getenv("TWILIO_SID")
auth_token = os.getenv("TWILIO_AUTH_TOKEN")
client = Client(account_sid, auth_token)

call = client.calls.create(
    to="+81XXXXXXXXXX",  # 彼女の番号
    from_="+1YYYYYYYYYY",  # Twilio取得番号
    url="https://yourdomain.com/call_morse"
)

print(f"Call SID: {call.sid}")
```

---

## 4. 起動の流れ

```bash
# 1. モールス音声を生成
python morse_generator.py

# 2. Flaskサーバー起動
python app.py

# 3. 電話をかける
python call_sender.py
```

---

## 補足：サプライズを成立させるTips

* 📅 事前に「19時に電話出てね」とだけ伝える
* 📞 彼女が出た瞬間、何も言わずに**ビープ音だけ**を流す
* 💡 ヒントは一切出さず、後日「解読」されるのを待つ
* 💌 追撃で「何か意味、あったかも…」と思わせるのもアリ


## おわりに：暗号と愛は、鍵を共有する者にだけ通じる

このプロジェクトを通じて改めて思いました。

> 暗号も愛も、「鍵」を持っている相手にしか意味がない。
> そしてその鍵を**預ける行為こそが、信頼なのかもしれない。**

もしあなたが伝えたい想いがあるなら、
ちょっと遠回りだけど、こんな“回りくどい表現”もいいかもしれません。


## 次は…

* QRコード読み取りでメッセージを変える機能
* 時限式メッセージ解除
* LINE通話連携 or 留守電モールス録音

興味ある方は、ハートやコメントいただけると嬉しいです！