PHP（Laravel）からMicrosoft Translator APIを使って自動翻訳

# 前提
Laravelでcron実行、名言をメール送信
https://qiita.com/ky-jp16/items/15651257923430f2b6bd
上記の記事で、Laravelの名言出力機能を使って、cronで毎日一度、名言をメール送信する機能を作った。
今回、これにMicrosoft TranslatorのAPIを呼び出して、英語を自動翻訳したものもメールで送信するようにしたいと思う。


# 環境
- Laravel 10.4.1
- さくらVPSサーバー CentOS7
- PHP 8.2.4

# 作業
cronの設定などは前述の記事に既に記載してあるので、機能追加した翻訳部分のみを記述する。

## 参考
今回はこの記事を参考に進めていく。
[Microsoft Translator v3をPHPから使用する方法](https://keruuweb.com/how-to-use-microsoft-translator-v3-from-php/)

まず、Microsoft Azureにアクセスし、アカウントの登録、Translatorのリソースの作成をして、APIで使用するキーを取得する。
リソースは一定程度の使用までの無料版があるので、それを設定して作成する。
→Free F0 (Up to 2M characters translated per month)
　1か月に200万文字まで無料　とのプランがあるのでそれを選ぶ。


## コマンドラインからの動作確認をする
これがサンプル通りだと、エラーが出てなかなかうまくいかなかった。
成功したのがこちらのやり方。
`--insecure`パラメータを付け、
Regionパラメータ
`-H "Ocp-Apim-Subscription-Region:JapanEast"`
も付ける（日本在住の場合）。
これでやっとうまくいった。
※your key には Azureから取得した、キー1 もしくは キー2 の値を入力する（以下同様）。
```bash:bash
curl --insecure -X POST "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&from=en&to=ja" -H "Ocp-Apim-Subscription-Key:<your key>" -H "Ocp-Apim-Subscription-Region:JapanEast" -H "Content-Type: application/json; charset=UTF-8" -d "[{'Text':'If you do not have a consistent goal in life, you can not live it in a consistent way.'}]"
```

`--insecure`パラメータを付けない場合、
`curl: (35) schannel: next InitializeSecurityContext failed: Unknown error (0x80092012) - 失効の関数は証明書の失効を確認
できませんでした。`
とのエラーになり、
regionを、`JapanEast`ではなく`Japan East`にすると、
`{"error":{"code":401000,"message":"The request is not authorized because credentials are missing or invalid."}}`
とのエラーになり、気づくのに時間がかかった（MicrosoftAzureの管理画面では、`Japan East`との記載になっているため）。

これで正しく実行できると、下記のように、コマンドラインに自動翻訳の結果が表示される。
```bash:bash
curl --insecure -X POST "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&from=en&to=ja" -H "Ocp-Apim-Subscription-Key:<your key>" -H "Ocp-Apim-Subscription-Region:JapanEast" -H "Content-Type: application/json; charset=UTF-8" -d "[{'Text':'If you do not have a consistent goal in life, you can not live it in a consistent way.'}]"

[{"translations":[{"text":"あなたが人生で一貫した目標を持っていないならば、あなたは一貫した方法でそれを生きることができません。","to":"ja"}]}]
```


## コマンドの実行ファイルに、翻訳機能を加える。
\Laravelapp\app\Console\Commands\SendInspiring.php
が、Laravelでのコマンドの実行ファイルとなるので、これを編集して、翻訳機能を加えていく。
SendInspiring.phpの中に関数translateを追加し、それを呼び出すようにした。
PHPでの呼び出し部分は、
https://keruuweb.com/how-to-use-microsoft-translator-v3-from-php/
を参考にさせて頂いた。

呼び出す関数部分。your keyは自分で取得したキーを入れる。
```php:SendInspiring.php
private function translate($text): void
{
    // cURLの初期化
    $ch = curl_init();

    // キーとリージョンの指定
    $key = "<your key>";
    $region = "JapanEast";
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    "Ocp-Apim-Subscription-Key: " . $key,
    "Ocp-Apim-Subscription-Region: " . $region,
    "Content-Type: application/json; charset=UTF-8"
    ));

    // URLと翻訳言語の指定
    $from = 'en';
    $to = 'ja';
    $url = "https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&from=".$from."&to=".$to;
    curl_setopt($ch, CURLOPT_URL, $url);

    // 翻訳テキストの指定
    // json_encodeには角カッコ2つのデータを渡してJSON配列を作る点に注意
    // $text = "Hello, what is your name?";
    $json = json_encode([['Text' => $text]]);
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // 送信と応答
    $result = curl_exec($ch);

    // レスポンスをデコード
    $decode = json_decode($result);

    // エラーチェック
    if (isset($decode->error)) {
        throw new Exception("翻訳に失敗しました。code:". $decode->error->code . " message:" . $decode->error->message);
    }

    // 翻訳結果表示
    echo $decode[0]->translations[0]->text;
    return;
}
```

この関数を、呼び出し元を下記のように変更して、英文に続けて、翻訳した日本語文を呼び出すようにした。
```diff_php:SendInspiring.php
// 偉人の名言を出力する
// strip_tags: 文字列から HTML および PHP タグを取り除く（php関数）
- echo strip_tags(Inspiring::quote()). "\n";
+ $moto_tags = strip_tags(Inspiring::quote());
+ echo $moto_tags;
+ echo $this->translate($moto_tags);
return;
```

ここで、手動で　php artisan SendInspiring　でコマンドを呼び出したところ、正しく、英文と和訳文が表示されることが確認できた。
```bash:bash
>php artisan SendInspiring

  “ I have not failed. I've just found 10,000 ways that won't work. ”
  — Thomas Edison

私は失敗していません。私はちょうどうまくいかない10,000の方法を見つけました。"
  — トーマス・エジソン
```


その後、実際にcron実行することで、メールに翻訳文が自動追加されるようになった。
```email:email
subject：2023/05/01 - today's Inspiring
to:		****@gmail.com
from:	Laravel APP <****@gmail.com>
本文：
  “ It is never too late to be what you might have been. ”
  — George Eliot

「あなたがそうであったかもしれないものになるのに遅すぎることは決してありません。」
  — ジョージ・エリオット
```

# 参考

[PHPでMicrosoft Translate APIの翻訳機能を使ってみる](https://arubeh.com/archives/783)
[Microsoft Translator v3をPHPから使用する方法 – KeruuWeb](https://keruuweb.com/how-to-use-microsoft-translator-v3-from-php/)