ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Flutter 플러터] 이메일 보내기 구현 (ex. 문의하기)
    Study/Flutter, Dart 2024. 12. 25. 16:07
    728x90
    반응형

    사용자 문의를 받을 때, 이메일, 실시간 채팅, 챗봇, 전화상담, FAQ 등이 있다.

     

    인력이 부족하고 실시간으로 대응하지 못한다면 챗봇이나 이메일이 적당한 방법일 것이다.

     

    기본적인 문의라면, 챗봇으로 자동화된 답변을 할 수 있지만, 복잡하고 비정형적인 문제라면 대처가 어려울 것이다.

     

    이메일 문의로 사용자의 문의를 받을 수 있는 기능을 구현해 볼 것이다.

     

    또한, 사용자가 앱 내에서 이탈 없이 문의사항이나 피드백을 보낼 수 있도록 하면, 사용자 경험을 향상 시킬 수 있을 것이다.

     

     

     

     

    필요사항

    Flutter에서 해당 기능을 구현하기 위해서는 몇 가지 패키지가 필요하다.

     

     

     

    1) 핸드폰 매일 앱으로 랜딩

     

    flutter_email_sender | Flutter package

    Allows send emails from flutter using native platform functionality.

    pub.dev

     

     

     

    2) 현재 디바이스의 정보 가져오기

     

    device_info_plus | Flutter package

    Flutter plugin providing detailed information about the device (make, model, etc.), and Android or iOS version the app is running on.

    pub.dev

     

     

     

    3) 어플리케이션의 정보 가져오기

     

    package_info_plus | Flutter package

    Flutter plugin for querying information about the application package, such as CFBundleVersion on iOS or versionCode on Android.

    pub.dev

     

     

     

    4) ios 기종에 대한 정보 가져오기

     

    ios_utsname_ext | Flutter package

    Extension method for translation ios utsname to full product name.

    pub.dev

    728x90

     

     

     

    추가적으로 android > app > src > main > AndroidManifest.xml 에 아래 코드를 넣어줘야 작동한다.

     

     

     

     

     

    구현

    1) 메일 앱이 작동한다면, 메일 앱으로 랜딩 후 정해진 포맷을 입력해 놓는 기능을 구현

    반응형

     

     

     

    2) 메일 앱이 존재하지 않거나 오류가 있어 작동되지 않는다면, 알림 팝업을 노출

     

     

     

     

    코드

    import 'dart:io';
    import 'package:device_info_plus/device_info_plus.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_email_sender/flutter_email_sender.dart';
    import 'package:ios_utsname_ext/extension.dart';
    import 'package:moneylog/themeData.dart';
    import 'package:package_info_plus/package_info_plus.dart';
    
    
    class MailContactWidget extends StatelessWidget {
      const MailContactWidget({super.key});
    
      @override
      Widget build(BuildContext context) {
        return InkWell(
          onTap: (){
            _sendEmail(context);
            },
          child: Container(
            width: double.infinity,
            height: 64,
            padding: const EdgeInsets.only(left: 24, right: 16),
            child: const Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text("문의하기", style: body2Bold,),
                Icon(Icons.keyboard_arrow_right_rounded,)
              ],
            ),
          ),
        );
      }
    }
    
    /// 메일 보내기
    void _sendEmail(BuildContext context) async {
    
      String body = await _getEmailBody();
    
      final Email email = Email(
          body: body,
          subject: "[머니로그 문의]",
          recipients: ["wj8529@gmail.com"],
          cc: [],
          bcc: [],
          attachmentPaths: [],
          isHTML: false
      );
    
      try {
        await FlutterEmailSender.send(email);
      } catch (error) {
        _showErrorAlert(context);
      }
    }
    
    /// 메일 앱 오류시 알림 팝업
    void _showErrorAlert(BuildContext context){
      showDialog(context: context, builder: (BuildContext context){
        return AlertDialog(
          title: const Text("메일 앱을 사용할 수 없습니다."),
          content: const Text("아래 이메일로 문의주시면 빠른 시일 내에 답변드릴게요!\n\nwj8529@gmail.com"),
          actions: <Widget>[
            TextButton(
              onPressed: (){
                Navigator.of(context).pop();
              },
              child: const Text("확인"),
            )
          ],
        );
      });
    }
    
    
    /// 앱 버전 불러오기
    Future<Map<String, dynamic>> _getAppInfo() async {
      PackageInfo info = await PackageInfo.fromPlatform();
      return {"머니로그 버전": info.version};
    }
    
    /// OS버전과 기기 불러오기
    Future<Map<String, dynamic>> _getDeviceInfo() async {
      DeviceInfoPlugin deviceInfoPlugin = DeviceInfoPlugin();
      Map<String, dynamic> deviceData = <String, dynamic>{};
    
      try {
        if (Platform.isAndroid) {
          deviceData = _readAndroidDeviceInfo(await deviceInfoPlugin.androidInfo);
        } else if (Platform.isIOS) {
          deviceData = _readIosDeviceInfo(await deviceInfoPlugin.iosInfo);
        }
      } catch(error) {
        deviceData = {
          "Error": "Failed to get platform version."
        };
      }
      return deviceData;
    }
    
    Map<String, dynamic> _readAndroidDeviceInfo(AndroidDeviceInfo info) {
      var release = info.version.release;
      var sdkInt = info.version.sdkInt;
      var manufacturer = info.manufacturer;
      var model = info.model;
    
      return {
        "OS 버전": "Android $release (SDK $sdkInt)",
        "기기": "$manufacturer $model"
      };
    }
    
    Map<String, dynamic> _readIosDeviceInfo(IosDeviceInfo info) {
      var systemName = info.systemName;
      var version = info.systemVersion;
      var machine = info.utsname.machine.iOSProductName;
    
      return {"OS 버전": "$systemName $version", "기기": machine};
    }
    
    
    /// 메일 글 작성
    Future<String> _getEmailBody() async {
      Map<String, dynamic> appInfo = await _getAppInfo();
      Map<String, dynamic> deviceInfo = await _getDeviceInfo();
    
      String body = '';
    
      body += "문의하기: \n\n";
      body += "======================\n";
      body += "아래 내용을 함께 보내주세요🤗\n";
    
      appInfo.forEach((key, value) {
        body += "$key: $value\n";
      });
    
      deviceInfo.forEach((key, value) {
        body += "$key: $value\n";
      });
    
      body += "==================\n";
    
      return body;
    }

     

     

     

    728x90
    반응형

    댓글

Designed by Tistory.