Services/Chatwork/SendResultExtensions.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.Json.Serialization;

namespace ChatworkBulkSender.Services.Chatwork
{
    using System.Text.Json;
    using System.Text.RegularExpressions;

    // ChatWork API からのエラー JSON を受け取る DTO
    public class ChatworkErrorResponse
    {
        [JsonPropertyName("errors")]
        public string[] Errors { get; set; }
    }

    public static class SendResultExtensions
    {
        /// <summary>
        /// APIレスポンスのエラーのままだとわかりにくいため、ユーザー用のエラーメッセージを作成する。
        ///
        /// [詳細]
        /// SendResult.ErrorMessage の中身を解析して、
        /// 一般ユーザー向けのメッセージを SendResult.ErrorMessageForDisp にセットします。
        ///
        /// ※C#の拡張メソッドを使って作成されたメソッド。
        ///  コンパイラが「res.SetErrorMessageForDisp()」を「SendResultExtensions.SetErrorMessageForDisp(res);」と置き換えて処理してくれる。
        /// </summary>
        public static void SetErrorMessageForDisp(this SendResult result)
        {
            // 送信処理が成功している場合は何もしないで終了
            if (result.Success == Utils.Constants.SEND_RESULT.SUCCESS)
            {
                return;
            }

            var raw = result.SystemErrorMessage ?? string.Empty;
            // 1) ChatWork API レスポンス部を抜き出し
            var match = Regex.Match(raw, @"ResponseBody=(\{.*\})");
            if (match.Success)
            {
                var json = match.Groups[1].Value;
                try
                {
                    var resp = JsonSerializer.Deserialize<ChatworkErrorResponse>(json);
                    if (resp?.Errors?.Length > 0)
                    {
                        result.DisplayErrorMessage = MapChatworkError(resp.Errors[0]);
                        return;
                    }
                }
                catch
                {
                    // JSON パース失敗
                    result.DisplayErrorMessage = $"処理中に予期せぬエラーが発生しました。エラー詳細:{result.SystemErrorMessage}";
                }
            }

            // 2) ネットワークやその他例外メッセージ解析
            if (raw.StartsWith("[WebException]"))
            {
                result.DisplayErrorMessage = $"サーバーとの通信で問題が発生しました。ネットワーク接続を確認して、再度お試しください。エラー詳細:{result.SystemErrorMessage}";
            }
            else if (raw.Contains("File not found"))
            {
                result.DisplayErrorMessage = $"指定されたファイルが見つかりません。ファイルのパスをご確認ください。エラー詳細:{result.SystemErrorMessage}";
            }
            else
            {
                // その他エラー
                result.DisplayErrorMessage = $"処理中に予期せぬエラーが発生しました。エラー詳細:{result.SystemErrorMessage}";
            }
        }

        /// <summary>
        /// ChatWork API のエラーコード/メッセージを
        /// 一般ユーザー向け日本語メッセージにマッピングします。
        /// </summary>
        private static string MapChatworkError(string apiError)
        {
            // API トークン関連
            if (apiError.Contains("Invalid API token"))
            {
                return "APIトークンが無効です。設定を確認してください。";
            }

            // ルーム取得権限
            if (apiError.Contains("permission") && apiError.Contains("get this room"))
            {
                return "このチャットルームにアクセスする権限がありません。";
            }

            // メッセージ投稿権限
            if (apiError.Contains("permission") && apiError.Contains("post message"))
            {
                return "メッセージを投稿する権限がありません。";
            }

            // ファイルアップロード権限
            if (apiError.Contains("permission") && apiError.Contains("upload file"))
            {
                return "ファイルをアップロードする権限がありません。";
            }

            // ルーム未存在
            if (apiError.Contains("not found"))
            {
                return "指定されたチャットルームが見つかりません。";
            }

            // レートリミット(1ルームあたりのメッセージ投稿制限)
            if (apiError.Contains("Rate limit for message posting per room exceeded"))
            {
                return "連続してメッセージを投稿しすぎました。しばらく時間をおいてから再度お試しください。";
            }

            // ファイルサイズ超過
            if (apiError.Contains("File size") || apiError.Contains("too large"))
            {
                return "ファイルサイズが大きすぎます。5MB 以下のファイルを指定してください。";
            }

            // サポート外の形式
            if (apiError.Contains("UnsupportedMediaType") || apiError.Contains("Unsupported Media Type"))
            {
                return "サポートされていないファイル形式です。PDF ファイルなど対応形式をご確認ください。";
            }

            // 必須パラメーター欠如
            if (apiError.Contains("Missing") && apiError.Contains("file"))
            {
                return "アップロードするファイルが指定されていません。再度選択してください。";
            }

            // その他エラー
            return $"ChatworkAPIを使用して送信処理を試みたところ、予期せぬエラーが発生しました。: {apiError}";
        }
    }

}