Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: Email notify API [SaaS API] #717

Closed
kevinten10 opened this issue Jul 12, 2022 · 11 comments · Fixed by #729 or #780
Closed

proposal: Email notify API [SaaS API] #717

kevinten10 opened this issue Jul 12, 2022 · 11 comments · Fixed by #729 or #780

Comments

@kevinten10
Copy link
Member

kevinten10 commented Jul 12, 2022

Hi, This is Email notify API proposal.

What would you like to be added:

saas api: Email notify api

Why is this needed:

#712

Support situation:

SMS Docs
Dapr SMTP https://docs.dapr.io/zh-hans/reference/components-reference/supported-bindings/smtp/
Aliyun Email https://help.aliyun.com/document_detail/29444.htm?spm=a2c4g.11186623.0.0.5cdb68dbdqeRpy
AWS SES https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html
Tencent Email https://cloud.tencent.com/document/product/1288/51034
Webpower Email

API spec:

// Saas API
// Send the message to Email.
rpc SendEmail(SendEmailRequest) returns (SendEmailResponse) {}

------

// SendEmailRequest is the message send to email.
message SendEmailRequest {
  // The invoke Id.
  string id = 1;

  // The saas service name, like 'aliyun.email'/'aws.ses'/'...'
  string saas_name = 2;

  // The unique identifier for the Email application.
  string application_id = 3;

  // The Email sender address.
  string email_from_address = 4;

  // The Email destination addresses.
  repeated string email_to_addresses = 5;

  // The Email subject.
  string subject = 6;

  // The Email content body.
  bytes data = 7;

  // The metadata which will be sent to Email components.
  map<string, string> metadata = 8;
}

message SendEmailResponse {
  // The saas requestId.
  string request_id = 1;

  // The data response from Email service.
  bytes data = 2;

  // The metadata returned from Email service.
  map<string, string> metadata = 3;
}

字段设计考虑:

1. Email原生API非常复杂,难取交集

aliyun/aws/tencent/...,在原生API设计上都有很多自己独特的请求参数,这取决于云Email自身的一些设计。

例如:

  • 邮件模板ID:有的Email具有模板,有的不需要模板即可发送。
  • application_id:有的只需要一个id,有的需要3个id(webpower等)

2. Email具有弱移植性

一个公司,如果Email的目的是做通知(数量较少,对内),而不是大规模的对客营销/通知(这种场景应该自行部署一个服务,而不是使用runtime提供的saas能力),那么大概率也只会使用一种Email服务(申请、维护、成本、管理、地域等各方面)。

所以本身Email代码就不需要很强的可移植性,那么对于一些特有的字段,可以接受放在metadata中。

3. Runtime API取核心字段,其他字段放metadata

尽可能取多种Email都有的一些概念,将这些字段放在API中,其他字段放metadata。

对于一次Email发送,有几个字段是必需的:

  1. application_id:Email属于比较重量级的资源,同时可能具备一定的社会影响,所以资源监管比较严格。往往需要提前审核Email模板等,会赋予一个application_id,作为该模板的标识。
  2. email_from_address:发件人地址
  3. email_to_addresses:邮件接收地址列表
  4. subject:邮件主题
  5. data:email的content body,可能是一段html

以及,设计两个基础字段:

  1. id:用于进行一定的标识,从而可以实现基于id获取配置的功能。往往Email的配置相对静态,可以通过id获取Email的相关配置,减少在metadata中的字段
  2. saas_name:多Email场景时使用,保留这样的可拓展性。当用到该场景时,由于不同Email的发送参数有巨大差异,如果在代码中传递metadata等字段,则可能无法移植,这时候就需要上述的 id 功能。
@kevinten10
Copy link
Member Author

以实际使用来说,当把application_id传入configurationSetName时,这几个参数就足以在AWS SES上进行email发送了

@kevinten10
Copy link
Member Author

其他关于参数的讨论见:#715

@seeflood seeflood mentioned this issue Jul 13, 2022
@seeflood
Copy link
Member

seeflood commented Jul 19, 2022

  • 关于“移植性”
    我理解是有这种需求的,比如一套监控系统,部署到阿里云的时候,想发warning邮件得调阿里云的 email 服务,部署到aws的时候得调 aws 的邮件服务……

@seeflood
Copy link
Member

  • 关于“抄送”
    加一个 cc 字段如何,代表抄送
  repeated string cc = 8;

@wenxuwan
Copy link
Member

附件需字段要吗?我看腾讯云和aws里面有附件字段。
image

如果需要的话,到时候得注意一下附件的大小问题,超过4M的话,默认的grpc unary rpc调用会有问题。

@seeflood
Copy link
Member

seeflood commented Jul 19, 2022

  • 能否介绍下哪些字段是必填,哪些是选填?

  • 关于 metadata
    能否先不添加 metadata ,感觉这个是万恶之源 😢

  • 关于 idapplication_id 和 邮件模板ID
    能否介绍下这三个字段的区别,是不是说 application_id 就是 邮件模板ID?

  • 关于模板参数
    使用模板的场合,能否添加一个模板参数字段,用于模板渲染?

  map<string, string> template_params = 8;

例如腾讯 email服务的传参就有这种字段:
https://cloud.tencent.com/document/api/1288/51053#Template

如果担心 api里字段太多、让用户困惑,那可以拆成多个方法,比如:

sendEmailByTemplateID(request) response

sendEmailByXXX(request) response

@kevinten10
Copy link
Member Author

关于“移植性”
我理解是有这种需求的,比如一套监控系统,部署到阿里云的时候,想发warning邮件得调阿里云的 email 服务,部署到aws的时候得调 aws 的邮件服务……

是的,我应该写错了,这种场景应该是存在的。

@kevinten10
Copy link
Member Author

附件需字段要吗?我看腾讯云和aws里面有附件字段。

我不太清楚,你们会有这样的场景么。我目前接触到的和了解到的,这套api主要是做notify用的,如果有复杂内容,一般是给个url链接,然后可以跳转到对应云产品的页面进行查看。

是会有一些发送数据分析/数据报表的email,但这些一般都是有个单独的服务/平台,去计算出来。
像一个专家系统,可能这类系统会自己去对接某个云的email服务,并深度使用它的sdk/api。
这种一般应该是个独立的服务,应该也不存在跨语言的问题。

@kevinten10
Copy link
Member Author

关于 metadata
能否先不添加 metadata ,感觉这个是万恶之源 😢

我觉得也是....之前似乎讨论过,我们可以设计一个 "全集" 的notify api。

关于 id 和 application_id 和 邮件模板ID
能否介绍下这三个字段的区别,是不是说 application_id 就是 邮件模板ID?

是这样想的:

id可以理解为一个场景的id,一个应用比如可能有3种email场景,那接入方只传入id=1/2/3即可,其他参数可以自动获取。

因为email的特征是,像以下这些参数,基本不太会变动,所以没必要让接入方每次都传入一大堆参数才能发出去email。

传个id就可以了,再从configuration等地方,获取对应的配置即可。(这样还可以实现热更新的逻辑)

{
    “id”: {
        "application_id": "value1",
        "email_from_address": "value2",
        "subject": "value3"
    }
}

application_id:有的云email服务上,就是templateID,但在aws上可能是 configurationSetName,基本也可以理解为,一套模板的配置id。

这里或许可以改成 templateId ? 使用 application_id 这个词语的原因主要是语义更加抽象。

关于模板参数
使用模板的场合,能否添加一个模板参数字段,用于模板渲染?

我感觉可以啊,我对这种场景不太了解。
我们目前不太用这种模板字段填充的方式,一般都是直接拼成一段html/text,然后直接发出去。没有让云email服务帮我们填充字段。

@kevinten10
Copy link
Member Author

如果担心 api里字段太多、让用户困惑,那可以拆成多个方法,比如:

就是saas api,还是往 "全集" 的方向走是么。

毕竟这些api,都是弱移植性的,用户用起来也不太会改了。

那这样,拆成几个语义更加清晰的方法,似乎比追求通用性,差异字段放在metadata中更好,更易用。

我也认同这个思路,那看起来:

  • 需要把这套api拆成几个常用的场景的子api。
  • 去除metadata,把参数放到子api的参数定义中。
  • 标明,每个子api,所支持的云email服务。

@seeflood
Copy link
Member

seeflood commented Jul 20, 2022

  • 早期设计目标:
    阿里云,AWS,可能还有GCP

action:

  • 看下 id 和 application id 能否合成一个
  • 是否有必要拆分成:
    sendEmailByTemplate
    sendEmailByRawData

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants