Flutter Templates
如何使用 Flutter 和 Back4App 构建 AI 邮件自动回复应用程序
40 分
介绍 在本教程中,您将使用 flutter 构建一个基于ai的电子邮件响应应用程序,前端使用 back4app ,后端使用。该应用将与gmail或outlook等电子邮件服务集成,使用ai模型(如openai的gpt 3)分析来信,并生成个性化的回复。到本教程结束时,您将拥有一个功能齐全的应用,可以管理电子邮件,生成自动回复,并允许用户个性化他们的电子邮件互动。 该应用利用back4app的parse server的强大功能来处理用户身份验证、数据存储和云功能,提供可扩展的后端解决方案,而无需管理服务器基础设施。集成ai能力和电子邮件服务将增强您的flutter开发技能,并为构建先进的数据驱动应用程序提供基础。 先决条件 要完成本教程,您需要: 一个 back4app 账户 。在 back4app https //www back4app com/ 注册一个免费账户。 在您的本地计算机上安装 flutter sdk 。请按照官方 flutter 安装指南 https //flutter dev/docs/get started/install 进行操作。 对 dart 和 flutter 开发有基本了解。如果您是flutter新手,请考虑在继续之前查看 flutter 文档 https //flutter dev/docs 。 熟悉 rest apis 和 异步编程 在dart中。 与 ai服务提供商 (例如,openai)有一个账户。注册一个api密钥以访问ai模型。 一个 电子邮件账户 (gmail或outlook)用于集成测试。 步骤 1 — 设置您的 back4app 后端 在此步骤中,您将创建一个新的back4app应用,设置数据类,并配置后端以与您的flutter应用一起工作。 1 1 在 back4app 上创建一个新应用 登录到您的 back4app 控制面板 https //dashboard back4app com/ 点击 "创建新应用" 输入一个 应用名称 (例如,"ai 邮件响应器")并选择您的 应用图标 如果提示,请选择您的服务器位置。 点击 "创建" 1 2 获取应用密钥 在您的应用控制面板中,导航到 应用设置 > 安全与密钥 记下 应用 id 和 客户端密钥 。您将需要这些用于您的 flutter 应用配置。 1 3 定义您的数据模型类 我们将在 back4app 中创建以下类: 用户 (默认) 邮箱账户 邮件模板 响应历史 1 3 1 创建 emailaccount 类 前往 数据库 > 浏览器 点击 "创建一个类" 选择 "自定义" 并命名为 emailaccount 点击 "创建类" 添加以下列到 emailaccount 用户 (pointer< user>) 指向 用户 对象。 电子邮件地址 (字符串) 账户类型 (字符串) 例如,gmail,outlook。 认证令牌 (字符串) 将存储加密令牌。 1 3 2 创建 emailtemplate 类 重复步骤以创建一个名为 emailtemplate 的新类。 添加以下列到 emailtemplate 用户 (pointer< user>) 模板名称 (字符串) 模板内容 (字符串) 模板类型 (字符串) 例如,正式,随意,跟进。 1 3 3 创建 responsehistory 类 创建一个名为 responsehistory 的新类。 添加以下列到 responsehistory 用户 (pointer< user>) 原始邮件摘要 (string) 生成的响应 (string) 用户编辑的响应 (string) 节省的时间 (number) 1 4 设置类级别权限 确保只有经过身份验证的用户可以访问他们的数据: 在每个类中,转到 安全性 部分。 设置 类级别权限 (clp) 以仅允许经过身份验证的用户进行读/写访问。 步骤 2 — 初始化您的 flutter 项目 在此步骤中,您将设置您的 flutter 项目并配置它以连接到 back4app。 2 1 创建一个新的 flutter 项目 打开您的终端并运行: flutter create ai email responder 导航到项目目录 cd ai email responder 2 2 添加所需依赖 打开 pubspec yaml 并添加以下依赖 dependencies flutter sdk flutter parse server sdk flutter ^4 0 1 flutter email sender ^5 0 2 http ^0 13 4 provider ^6 0 2 fl chart ^0 45 1 运行 flutter pub get 来安装包 2 3 在您的应用中初始化 parse 创建一个新文件 lib/config/back4app config dart // lib/config/back4app config dart const string keyapplicationid = 'your application id'; const string keyclientkey = 'your client key'; const string keyparseserverurl = 'https //parseapi back4app com'; 将 'your application id' 和 'your client key' 替换为来自 back4app 的密钥。 在 lib/main dart , 初始化 parse // lib/main dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'config/back4app config dart'; import 'app dart'; void main() async { widgetsflutterbinding ensureinitialized(); await parse() initialize( keyapplicationid, keyparseserverurl, clientkey keyclientkey, autosendsessionid true, debug true, ); runapp(myapp()); } 创建 lib/app dart // lib/app dart import 'package\ flutter/material dart'; import 'screens/home screen dart'; class myapp extends statelesswidget { @override widget build(buildcontext context) { return materialapp( title 'ai email responder', theme themedata( primaryswatch colors blue, ), home homescreen(), ); } } 步骤 3 — 实现用户认证 您现在将使用 parse server 实现用户注册和登录。 3 1 创建认证屏幕 创建 lib/screens/login screen dart 和 lib/screens/signup screen dart 为了简洁,我们将重点关注登录功能。 // lib/screens/login screen dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'home screen dart'; class loginscreen extends statefulwidget { @override loginscreenstate createstate() => loginscreenstate(); } class loginscreenstate extends state\<loginscreen> { final texteditingcontroller usernamecontroller = texteditingcontroller(); final texteditingcontroller passwordcontroller = texteditingcontroller(); future\<void> douserlogin() async { final username = usernamecontroller text trim(); final password = passwordcontroller text trim(); final user = parseuser(username, password, null); final response = await user login(); if (response success) { navigator pushreplacement( context, materialpageroute(builder (context) => homescreen()), ); } else { showerror(response error! message); } } void showerror(string message) { scaffoldmessenger of(context) showsnackbar(snackbar(content text('error $message'))); } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('login'), ), body padding( padding const edgeinsets all(16), child column( children \[ textfield( controller usernamecontroller, decoration inputdecoration(labeltext 'username', icon icon(icons person)), ), textfield( controller passwordcontroller, decoration inputdecoration(labeltext 'password', icon icon(icons lock)), obscuretext true, ), sizedbox(height 20), elevatedbutton( onpressed douserlogin, child text('login'), ), ], ), ), ); } } 3 2 更新主页导航 修改 lib/app dart 以在用户未认证时将其引导至登录屏幕。 // lib/app dart import 'package\ flutter/material dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; import 'screens/home screen dart'; import 'screens/login screen dart'; class myapp extends statelesswidget { future\<bool> hasuserloggedin() async { final currentuser = await parseuser currentuser() as parseuser?; return currentuser != null; } @override widget build(buildcontext context) { return futurebuilder\<bool>( future hasuserloggedin(), builder (context, snapshot) { if (snapshot hasdata && snapshot data == true) { return materialapp( title 'ai email responder', theme themedata(primaryswatch colors blue), home homescreen(), ); } else { return materialapp( title 'ai email responder', theme themedata(primaryswatch colors blue), home loginscreen(), ); } }, ); } } 步骤 4 — 集成电子邮件服务 在此步骤中,您将使用 flutter email sender 包设置电子邮件集成。 4 1 配置电子邮件发送者 为您的 android 和 ios 配置添加必要的权限。 对于 android , 更新 android/app/src/main/androidmanifest xml \<uses permission android\ name="android permission internet"/> 对于 ios , 确保您的 info plist 包含 \<key>nsapptransportsecurity\</key> \<dict> \<key>nsallowsarbitraryloads\</key> \<true/> \</dict> 4 2 实现电子邮件发送功能 创建 lib/services/email service dart // lib/services/email service dart import 'package\ flutter email sender/flutter email sender dart'; class emailservice { future\<void> sendemail(string subject, string body, list\<string> recipients) async { final email email = email( body body, subject subject, recipients recipients, ishtml false, ); await flutteremailsender send(email); } } 4 3 实现电子邮件获取(占位符) 从 gmail 等提供商获取电子邮件需要 oauth 和 api 集成,这可能很复杂。对于本教程,我们将模拟电子邮件获取。 创建 lib/models/email dart // lib/models/email dart class email { final string sender; final string subject; final string body; final datetime date; email({ required this sender, required this subject, required this body, required this date, }); } 创建 lib/services/email service dart (使用虚拟数据更新): // lib/services/email service dart import ' /models/email dart'; class emailservice { future\<list\<email>> fetchemails() async { // simulate network delay await future delayed(duration(seconds 2)); return \[ email( sender 'john doe\@example com', subject 'meeting reminder', body 'don\\'t forget about our meeting tomorrow at 10 am ', date datetime now() subtract(duration(hours 1)), ), // add more dummy emails ]; } // existing sendemail method } 步骤 5 — 集成 ai 服务以生成响应 您现在将设置 ai 集成以生成电子邮件响应。 5 1 设置 http 请求到 ai api 安装 http 包(已添加)。 创建 lib/services/ai service dart // lib/services/ai service dart import 'dart\ convert'; import 'package\ http/http dart' as http; class aiservice { final string apikey = 'your openai api key'; final string apiurl = 'https //api openai com/v1/engines/davinci/completions'; future\<string> generateresponse(string emailcontent) async { final response = await http post( uri parse(apiurl), headers { 'authorization' 'bearer $apikey', 'content type' 'application/json', }, body jsonencode({ 'prompt' 'reply to the following email \n$emailcontent', 'max tokens' 150, }), ); if (response statuscode == 200) { final data = jsondecode(response body); return data\['choices']\[0]\['text'] trim(); } else { throw exception('failed to generate response'); } } } 注意: 将 'your openai api key' 替换为您的实际 api 密钥。 5 2 实现响应编辑器小部件 创建 lib/widgets/response editor dart // lib/widgets/response editor dart import 'package\ flutter/material dart'; class responseeditor extends statelesswidget { final string initialresponse; final texteditingcontroller controller; responseeditor({required this initialresponse}) controller = texteditingcontroller(text initialresponse); @override widget build(buildcontext context) { return textfield( controller controller, maxlines null, decoration inputdecoration( hinttext 'edit your response here ', border outlineinputborder(), ), ); } } 5 3 显示ai生成的响应 在 lib/screens/email detail screen dart , 集成ai服务。 // lib/screens/email detail screen dart import 'package\ flutter/material dart'; import ' /models/email dart'; import ' /services/ai service dart'; import ' /widgets/response editor dart'; import ' /services/email service dart'; class emaildetailscreen extends statefulwidget { final email email; emaildetailscreen({required this email}); @override emaildetailscreenstate createstate() => emaildetailscreenstate(); } class emaildetailscreenstate extends state\<emaildetailscreen> { final aiservice aiservice = aiservice(); final emailservice emailservice = emailservice(); string? airesponse; bool isloading = false; future\<void> generateresponse() async { setstate(() { isloading = true; }); try { final response = await aiservice generateresponse(widget email body); setstate(() { airesponse = response; }); } catch (e) { scaffoldmessenger of(context) showsnackbar(snackbar(content text('ai error $e'))); } finally { setstate(() { isloading = false; }); } } void sendresponse(string responsetext) { emailservice sendemail( 're ${widget email subject}', responsetext, \[widget email sender], ); scaffoldmessenger of(context) showsnackbar(snackbar(content text('email sent'))); } @override void initstate() { super initstate(); generateresponse(); } @override widget build(buildcontext context) { final responseeditor = airesponse != null ? responseeditor(initialresponse airesponse!) null; return scaffold( appbar appbar( title text('email from ${widget email sender}'), ), body padding( padding const edgeinsets all(16), child isloading ? center(child circularprogressindicator()) column( children \[ text(widget email body), sizedbox(height 20), responseeditor != null ? expanded(child responseeditor) container(), elevatedbutton( onpressed () { if (responseeditor != null) { sendresponse(responseeditor controller text); } }, child text('send response'), ), ], ), ), ); } } 步骤6 — 管理邮件模板 您现在将使用back4app实现邮件模板管理。 6 1 定义 emailtemplate 模型 创建 lib/models/email template dart // lib/models/email template dart import 'package\ parse server sdk flutter/parse server sdk dart'; class emailtemplate extends parseobject implements parsecloneable { emailtemplate() super('emailtemplate'); emailtemplate clone() this(); @override emailtemplate clone(map\<string, dynamic> map) => emailtemplate clone() fromjson(map); string? get templatename => get\<string>('templatename'); set templatename(string? value) => set\<string>('templatename', value); string? get templatecontent => get\<string>('templatecontent'); set templatecontent(string? value) => set\<string>('templatecontent', value); string? get templatetype => get\<string>('templatetype'); set templatetype(string? value) => set\<string>('templatetype', value); } 6 2 实现模板服务 创建 lib/services/template service dart // lib/services/template service dart import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/email template dart'; class templateservice { future\<list\<emailtemplate>> fetchtemplates() async { final query = querybuilder\<emailtemplate>(emailtemplate()); final response = await query find(); if (response success && response results != null) { return response results as list\<emailtemplate>; } else { return \[]; } } future\<void> addtemplate(emailtemplate template) async { await template save(); } } 6 3 创建模板管理界面 创建 lib/screens/template management screen dart // lib/screens/template management screen dart import 'package\ flutter/material dart'; import ' /models/email template dart'; import ' /services/template service dart'; class templatemanagementscreen extends statefulwidget { @override templatemanagementscreenstate createstate() => templatemanagementscreenstate(); } class templatemanagementscreenstate extends state\<templatemanagementscreen> { final templateservice templateservice = templateservice(); list\<emailtemplate> templates = \[]; bool isloading = true; future\<void> loadtemplates() async { final fetchedtemplates = await templateservice fetchtemplates(); setstate(() { templates = fetchedtemplates; isloading = false; }); } @override void initstate() { super initstate(); loadtemplates(); } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('email templates'), ), body isloading ? center(child circularprogressindicator()) listview\ builder( itemcount templates length, itembuilder (context, index) { final template = templates\[index]; return listtile( title text(template templatename ?? 'unnamed'), subtitle text(template templatetype ?? 'no type'), ); }, ), floatingactionbutton floatingactionbutton( onpressed () { // implement template creation }, child icon(icons add), )); } } 第7步 — 实现响应历史跟踪 您现在将保存ai生成的响应和用户编辑到back4app以进行分析。 7 1 定义responsehistory模型 创建 lib/models/response history dart // lib/models/response history dart import 'package\ parse server sdk flutter/parse server sdk dart'; class responsehistory extends parseobject implements parsecloneable { responsehistory() super('responsehistory'); responsehistory clone() this(); @override responsehistory clone(map\<string, dynamic> map) => responsehistory clone() fromjson(map); string? get originalemailsummary => get\<string>('originalemailsummary'); set originalemailsummary(string? value) => set\<string>('originalemailsummary', value); string? get generatedresponse => get\<string>('generatedresponse'); set generatedresponse(string? value) => set\<string>('generatedresponse', value); string? get usereditedresponse => get\<string>('usereditedresponse'); set usereditedresponse(string? value) => set\<string>('usereditedresponse', value); int? get timesaved => get\<int>('timesaved'); set timesaved(int? value) => set\<int>('timesaved', value); } 7 2 发送电子邮件后保存响应历史 更新 lib/screens/email detail screen dart 在 sendresponse 方法中 import ' /models/response history dart'; // void sendresponse(string responsetext) async { await emailservice sendemail( 're ${widget email subject}', responsetext, \[widget email sender], ); // save response history final responsehistory = responsehistory() set('originalemailsummary', widget email body) set('generatedresponse', airesponse) set('usereditedresponse', responsetext) set('timesaved', calculatetimesaved()); await responsehistory save(); scaffoldmessenger of(context) showsnackbar(snackbar(content text('email sent'))); navigator pop(context); } int calculatetimesaved() { // placeholder implementation return 5; // assume 5 minutes saved } 步骤 8 — 使用图表添加分析 您现在将使用 fl chart 实现一个基本的分析仪表板。 8 1 实现分析服务 创建 lib/services/analytics service dart // lib/services/analytics service dart import 'package\ parse server sdk flutter/parse server sdk dart'; import ' /models/response history dart'; class analyticsservice { future\<list\<responsehistory>> fetchresponsehistories() async { final query = querybuilder\<responsehistory>(responsehistory()); final response = await query find(); if (response success && response results != null) { return response results as list\<responsehistory>; } else { return \[]; } } future\<int> calculatetotaltimesaved() async { final histories = await fetchresponsehistories(); return histories fold(0, (sum, item) => sum + (item timesaved ?? 0)); } } 8 2 创建分析仪表板 创建 lib/screens/analytics screen dart // lib/screens/analytics screen dart import 'package\ flutter/material dart'; import 'package\ fl chart/fl chart dart'; import ' /services/analytics service dart'; class analyticsscreen extends statefulwidget { @override analyticsscreenstate createstate() => analyticsscreenstate(); } class analyticsscreenstate extends state\<analyticsscreen> { final analyticsservice analyticsservice = analyticsservice(); int totaltimesaved = 0; future\<void> loadanalytics() async { final timesaved = await analyticsservice calculatetotaltimesaved(); setstate(() { totaltimesaved = timesaved; }); } @override void initstate() { super initstate(); loadanalytics(); } @override widget build(buildcontext context) { return scaffold( appbar appbar( title text('analytics'), ), body center( child text('total time saved $totaltimesaved minutes'), )); } } 步骤 9 — 实现离线支持 您现在将使用 parse 的本地数据存储为您的应用添加离线功能。 9 1 启用本地数据存储 在 lib/main dart , 启用本地数据存储 await parse() initialize( keyapplicationid, keyparseserverurl, clientkey keyclientkey, autosendsessionid true, debug true, corestore await corestoresembastimp getinstance(), ); 9 2 修改数据模型以进行固定 在你的模型中(例如, responsehistory ),添加固定和取消固定对象的方法: future\<void> pin() async { await this pin(); } future\<void> unpin() async { await this unpin(); } 9 3 实现离线管理器 创建 lib/utils/offline manager dart // lib/utils/offline manager dart import ' /models/email dart'; import 'package\ parse server sdk flutter/parse server sdk dart'; class offlinemanager { future\<void> cacheemails(list\<email> emails) async { for (var email in emails) { final parseobject = parseobject('email') set('sender', email sender) set('subject', email subject) set('body', email body) set('date', email date); await parseobject pin(); } } future\<list\<email>> getcachedemails() async { final query = querybuilder\<parseobject>(parseobject('email')); final response = await query frompin() find(); if (response success && response results != null) { return response results! map((e) { return email( sender e get\<string>('sender') ?? '', subject e get\<string>('subject') ?? '', body e get\<string>('body') ?? '', date e get\<datetime>('date') ?? datetime now(), ); }) tolist(); } else { return \[]; } } } 9 4 在没有连接时使用离线数据 在您的电子邮件获取逻辑中,检查连接性并在离线时使用缓存数据。 结论 在本教程中,您使用 flutter 和 back4app 构建了一个 ai 电子邮件响应应用程序。您: 设置了一个具有必要数据模型和安全配置的 back4app 后端。 初始化了一个 flutter 项目并将其连接到 back4app。 实现了与 parse server 的用户身份验证。 集成了电子邮件发送并模拟了电子邮件获取。 集成了 ai 服务以生成电子邮件响应。 管理电子邮件模板并将其存储在 back4app 中。 跟踪响应历史以进行分析。 使用 fl chart 添加基本分析功能。 使用 parse 的本地数据存储实现离线支持。 此应用程序为构建更高级的功能提供了基础,例如与oauth的真实电子邮件集成、先进的ai能力和改进的ui/ux设计。 下一步 电子邮件集成 使用gmail或outlook api通过oauth认证实现真实的电子邮件提取。 增强的ai功能 微调ai提示以获得更好的响应,并根据用户数据实现个性化。 ui/ux改进 改善应用程序的界面以提供更好的用户体验。 测试和部署 编写单元和集成测试,并准备将应用程序部署到应用商店。 安全增强 加密敏感数据并实施强大的错误处理和输入验证。 有关如何将back4app与flutter一起使用的更多信息,请参阅 back4app flutter指南 https //www back4app com/docs/flutter/parse sdk/ 。