3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

UnityからSlackのメール転送機能にメールを送る

Last updated at Posted at 2022-09-27

Unityでメールを送りたい

色々ときっかけはあるのですが、省略してやりたいことを言います。
Slackをいろいろとプログラムで弄りたいときに、大抵は皆さんBOTを準備されると思うのですが、BOTを入れる権限がないSlackチャンネルでもいちおうできることがあります。それが、Slackのメール転送機能です。
Slackのチャンネル全体の設定から 環境設定 >> メッセージ&メディア >> Slack へのメールの転送 と進むと、件の機能にたどり着くことができます。

どんな重要メールも、固有のユニークメールアドレスに転送することで Slack にアップロードすることができます。メールは Slackbot がお届けし、非公開のままにしておくことも、またはチームと共有することもできます。

と、短く説明書きがあり、設定をすることで「固有のユニークメールアドレス」を発行することができます。
要するに、こいつにメール送るとSlackでも通知来るよって機能なのですが、こいつにUnityからメール送ってSlackに転送させたかった。
それがやりたいことの概要になります。
...なぜUnityかとか、聞かないでください。
プログラマーたるもの、自分のフィールドで戦いたいこともあるんじゃないですかね...笑

既存のUnityメール送信実装案の検討

UniMail

まあ、有名なやつで、UniMailってやつがあります。

UniMailの内部の処理は以外と簡単で、

UniMail.cs
Application.OpenURL(string.Format("mailto:{0}?subject={1}&body={2}", mailTo, Uri.EscapeDataString(subject), Uri.EscapeDataString(body)));

この一文に尽きるって感じかなぁ。エディタでやるとなると特に。
自分の読解力がなくて見落としているかもですが。
結論を言うと、これ、自分の環境ではURLが開くだけでメール送信はできませんでした。

Gmailで送信(コガネブログ様)

こちらの記事も調べている中で出てきました。

これは普通にいけそう。
でも当時の自分は、何をトチ狂っていたのか、勉強したてのUnityWebRequestを使いたいと思ってまして、これを却下してしまいました。
そこにこだわったせいで、慣れない別言語で苦しむことになるのですが...。

GASを使うのだ

GAS(GoogleAppsScript)には便利なAPIがあることを、少し前から自分は知っていました。

GmailApp.sendEmail('メールアドレス', '件名', '本文');

そうだ、これを使えばUnityでもメール送信できるじゃん!とか思って、そこから苦難の道が始まるんすよね...orz

  • いちおうスプレッドシートにログを残して、とか考えたせいで、スプレッドシートからGASにたどり着くまでに苦労するし...
    (以前使っていたときはメニューバーのツールからいけたんですけど、いつのまにか拡張機能に移動していた)
  • Chromeでログインしているアカウントとは違うGoogleアカウントのスプレでやろうとしたから、そもそもGAS開けられないし...
    (GASはChromeでログインしているアカウントと同じアカウントじゃないとGASにたどり着けないらしい)
  • GASは変更があったら毎度毎度「新しいデプロイ」にしなきゃいけないことに詰まるし...

という、環境面で散々でした。
もちろん言語面でも苦労はあったんだけど、なんとか切り抜けました...。

実際の実装

GAS(GoogleAppsScript)側の実装

code.gs
function doPost(e)
{
  //  パラメータでJsonを受け取り、パース
  const jsonString = e.postData.getDataAsString(); //文字列で取得
  const date = JSON.parse(jsonString); //Object形式に変換
  const toMail = date.toMail; //メアド
  const subject = date.subject; //件名
  const body = date.body; //本文
  const timerecord = Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy/MM/dd HH:mm:ss"); //時刻
  const writeDate = [[timerecord, date.toMail, date.subject, date.body]];
  
  //スプレッドシートにログを残す
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  const maxRow = sheet.getMaxRows();
  const lastRow = sheet.getRange(maxRow, 1).getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  sheet.getRange(lastRow+1, 1, 1, 4).setValues(writeDate);

  //メール送信
  GmailApp.sendEmail(toMail, date.subject, date.body);

  let output = ContentService.createTextOutput();
  output.setMimeType(ContentService.MimeType.JSON);
  output.setContent(JSON.stringify({ message: "success" }));
  return output;
}

Unity側の実装

実際はUniTask使っていたんですけど、こちらではコルーチン版貼りますね。
いちおう挙動は確認済です。

SlackMail.cs
using System;
using System.Collections;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;

public class SlackMail : MonoBehaviour
{
    // 必要なデータ
    [SerializeField] private MailData mailData = null;
    
    // GASの公開リンク
    [SerializeField] private string URI = "";
    
    private static readonly (string name, string value) header = ("Content-Type", "application/json");
    
    [System.Serializable]
    public sealed class MailData
    {
        public string toMail; //メールアドレス
        public string subject; //件名
        public string body; //本文
    }

    [System.Serializable]
    public sealed class ResponseData
    {
        public string message;
    }
    
    private void Start()
    {
        StartCoroutine(Post(mailData));
    }

    private IEnumerator Post(MailData postMailData)
    {
        if (mailData == null)
        {
            yield break;
        }
        
        var json = JsonUtility.ToJson(postMailData);
        var bodyRaw = Encoding.UTF8.GetBytes(json);

        var request = new UnityWebRequest(URI, UnityWebRequest.kHttpVerbPOST)
        {
            uploadHandler = new UploadHandlerRaw(bodyRaw),
            downloadHandler = new DownloadHandlerBuffer()
        };

        request.SetRequestHeader(header.name, header.value);

        yield return request.SendWebRequest();

        // 非同期処理の結果を参照する
        if (request.result != UnityWebRequest.Result.Success)
        {
            // 通信失敗時
            Debug.LogException(new Exception(request.error));
            yield break;
        }
        
        var result = request.downloadHandler.text;
        Debug.Log(result);
        var response = JsonUtility.FromJson<ResponseData>(result);
        Debug.Log(response.message);
    }
}

あとは、必要事項をUnityエディタから登録してもらって...

あとがき

なんだかんだ言って、GASがわかってきた気がするので、これ使って色々しようかなと。
UnityのNetcodeと連携とか、純粋にGASのみで開発もありっすね。
まあ、疲れましたが...

参考文献

これは書籍だけど、貼っておくか...参考になったので...

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?