使用 Salesforce 特性与 Apex 集成
Salesforce特性与Apex集成完全指南:快速操作(QuickAction.Request/performQuickAction/创建操作vs自定义操作对象特定vs全局)、Apex Cursors大数据游标(无状态/固定结果集ID/5千万行限制/100次fetch事务/TransientCursorException可重试/PaginationCursor分页游标/CursorFetchResult封装/致Limits监控方法/每日OrgLimits)、审批处理(ProcessSubmitRequest提交/ProcessWorkitemRequest批准拒绝/Approval.process/lock/unlock)、自定义认证提供程序(Auth.AuthProviderPluginClass/OAuth2.0+OpenID+SAML)、OAuth2.0令牌交换处理器(Auth.TokenExchangeHandler/JWT+SAML断言)、DataWeave数据转换、External Services类型安全调用、Formula Evaluation动态公式、Platform Cache及更多平台特性。
本课程共有 8 个章节
同学们,我们来看这一页。不知道你们平时用Salesforce的时候,有没有想过一个问题:像Chatter里发消息、或者一个审批流程的提交和批准,这些界面上的操作,能不能直接用代码来控制呢?答案是,可以的。 因为Salesforce已经把很多用户界面的功能,都在Apex里开放出来了。也就是说,我们可以在代码里,直接去调用这些界面背后的能力。比如说,你可以写一小段Apex,就自动往Chatter里发布一条动态;或者用Apex里的“批准方法”,来提交一个审批请求,再让它自动通过,完全不用手动去点鼠标。 那这一章要讲什么呢?就是把所有这些可以经由Apex编程来访问的平台功能,一个一个拆解给你看。包括动作和指针、身份验证、DataWeave、外部服务、平台缓存,还有Salesforce知识等等,非常多。你把这一章学完,就能用程序去操控这些原本只在界面上才能用的功能了,代码的能力又会上一个台阶。 好,这页的意思清楚了,接下来我们就正式进入内容的学习。
同学们,咱们现在要讲的是Salesforce里的“快速操作”和它背后的Apex编程支持。别看这个Slide只有几行字,里头的门道还挺多。来,我先用大白话给大家串一遍。 快速操作是干什么的呢?简单说,就是让用户不用打开完整的记录编辑页面,就能快速完成一件事。比如在一个列表页上,点一下按钮,啪,直接创建一条新记录,这就是“创建操作”。或者你点一个按钮,弹出一个Lightning组件,跑一个自动化流程,甚至打开Visualforce页面或画布应用,这些都叫“自定义操作”。这些操作可以挂在某个对象的布局上,那就是“对象特定”的;也可以挂在全局发布者上,那就是“全局”的,哪儿都能用。不过注意一条规则:更新记录的操作必须绑定到具体的对象,不能是全局的,这个记一下。 好,那咱们作为开发者,怎么用Apex去处理这些操作呢?Slide上说了,Apex给了一组丰富的类。但这段文字里有几处拼写可能要纠正一下——可能是Slide生成时的小瑕疵,实际开发中你搜到的类名更规范。比如“用于元数据的QuickAction”,就是指`QuickAction`这个命名空间下的描述方法,像`QuickAction.DescribeQuickActions`,能让你拿到某个操作的定义、类型、标签这些元数据。接着,“用于提交请求的QuickDeliverase”,其实就是`QuickActionResult`,是用来把待执行的动作请求提交出去的,比如创建一个记录,调用这个类就能返回结果。还有“处理结果的QuickDeliverase”还是指`QuickActionResult`,因为同一个类既包含提交方法,返回的对象里也包含了处理结果的状态、错误信息、新记录ID等等。最后提到的各种“描述类”,是指像`QuickAction.DescribeQuickActionResult`、`QuickAction.DescribeLayoutResult`这样的类,它们能告诉你操作在界面上怎么展示、有哪些字段可用,这样你编程处理时,就知道该填什么参数了。你看,这些类把原本手动点按钮的事,变成了可以在代码里自动化进行的步骤。 可能你听到类名“QuickDeliverase”会觉得不对劲,那八成是转录错误,正确的应该是`QuickActionResult`。实际敲代码时,你会用到`QuickAction.QuickActionResult`。别担心,后面我们讲到具体示例时会看到。 现在就记住这几点:快速操作分创建和自定义;可以全局也可以绑定对象,唯独更新操作必须绑定对象;要用Apex控制它们,就去找QuickAction相关的类拿元数据,用QuickActionResult提交和处理结果,还有一系列Describe类帮你了解布局。这样你就能在触发器、批处理或者自定义API里实现自动创建记录或触发流程了。 好了,我们喝口水,然后看看下一个Slide怎么把这些类用起来。
同学们,咱们今天来聊聊 Apex 里一个非常实用但容易被忽略的工具——,指针,,英文叫 Cursor。 你可以把指针想象成一个在事务内部、帮你分批次读取大量数据的小助手。以前我们处理海量数据,可能要依赖 Batch Apex,但现在有了指针,很多时候你可以在一个事务里,用更灵活的方式完成类似的工作,而且它是无状态的。 那“无状态”是什么意思呢?就是说服务器不会帮你记住读到哪里了,你得自己在代码里跟踪这个“偏移位置”。你通过 `Database.getCursor` 方法,传入一条 SOQL 查询,就能创建出一个指针。然后,想取数据的时候,就调用 `fetch` 方法,告诉它“从第几行开始、取多少条记录”,它就把那一批结果返回给你。 需要注意,指针的结果集是它创建那一刻的快照,之后数据再怎么变,都不会影响你已经打开的这个指针。另外它也有容量和调用次数的上限:最多能处理五千万行记录,而且在一个事务里,调用 `fetch` 不能超过 100 次。 如果你需要更方便的翻页,还可以用 `fetchPage` 方法。它会返回一个叫 `CursorFetchResponse` 的对象,里面不止有获取到的记录列表,还包括被删除掉的行数、下一个读取索引,以及一个布尔值告诉你是不是已经全部读完了。这样循环处理大结果集时就更直观。 同时,指针的用量也是受限制监控的,你可以通过 `Limits` 类的方法,或者 `OrgLimits` 里的每日限额地图来跟踪使用情况。 实际项目中,把指针和 Queueable Apex 结合起来,就能做成一种很强大的批处理方案。比如用 Queueable 作业链起来,每次 `fetch` 一小批记录去处理,不但避开了 Batch Apex 每次只能处理 200 条的局限,整体执行也更快、更可控。可以说,它是 Batch Apex 的一种优雅替代。掌握了指针,你就多了一把高效处理大数据的利器。
同学们,我们来看这个叫 CredyChunkingDeliverable 的示例,它很好地展示了如何把 Cursor 和 Deliverable 这两种模式结合起来,处理大批量的数据。 首先,在它的构造函数里,会直接创建一个 Cursor。这个 Cursor 就像是我们手里的一根指针,它可以指向查询结果里的某一条记录,方便我们一段一段地往后取数据。 接下来,在 execute 方法中,每次都会从这个 Cursor 里获取 200 条记录。拿到这 200 条以后,就按批处理的方式把它们处理掉。处理完之后,程序会检查一下:指针后面是不是还有更多记录?如果还有,它就会自动安排一个新的 Deliverable 作业,让这个新作业继续去处理下一批 200 条。这样就实现了链式处理,直到所有数据都被处理完。 另外,示例里还有一个限制检查的部分,教我们怎么监控指针的使用状况。我们可以用到两个方法:一个是 Limits.getApexCursors,它能告诉我们当前上下文里已经用了多少个指针;另一个是 OrgLimits.getMap,通过它我们可以拿到各种每日限制。这里需要特别关注两个限制:DailyApexCursorScale 和 DailyApexCursorRowsScale。不管你用的是标准指针,还是翻页指针,这两个限制都是共享计数的,也就是说它们会合在一起计算你每天能用的指针数量和能取出的行数。掌握这些,就能避免因为超限而导致作业失败了。 这样讲,应该就清楚了吧。
大家好,今天我们来看一下在 Salesforce 里怎么用 Apex 代码自动处理审批流程。 简单来说,审批处理能让记录的审批过程完全由程序来控制,不用人手动点。你可以做两件主要的事:第一,把一条记录提交进某个审批流程;第二,对已经产生的工作项进行批准或拒绝。 先说提交。在 Apex 里我们要先创建一个 `Approval.ProcessSubmitRequest` 对象。通过这个对象,你可以指定要提交哪条记录,还能带上提交人、留言备注,甚至可以指定走哪个审批流程的定义。如果希望跳过流程里设置的“进入条件”检查,就直接调用 `setSkipEntryCriteria(true)`,这样无论条件满不满足都会提交。然后,调用 `Approval.process` 方法把这个请求送出去。这个方法会返回一个结果对象,我们通常叫 Process Result,里面包含了操作是否成功,以及审批实例的状态,比如状态是“待定”还是“已批准”。结果对象上还有一个 `getNewWorkitemIds` 方法,可以拿到这次提交产生的新工作项的 ID 列表。这些 ID 在下一步要用到。 好,接下来就是处理那些挂起的审批工作项,也就是执行批准或拒绝动作。这时候你需要创建一个 `Approval.ProcessWorkitemRequest` 对象。把刚才拿到的工作项 ID 设进去,然后通过 `setAction` 方法来指定动作,比如传字符串 `'Approve'` 就是批准,`'Reject'` 就是拒绝。设置好之后,同样调用 `Approval.process` 方法。这个方法也会返回 Process Result,里面就有这次操作是否成功,以及审批实例的最终状态,比如最终变为“已批准”或“已拒绝”。 有一点要特别注意,`Approval.process` 方法是受事务限制(TLR)影响的。也就是说在一个事务里你不能无限次地调用它,否则会碰到系统限制,比如 DML 操作次数上限或者审批处理次数上限。所以写批量代码时一定要考虑
好,同学们,今天咱们来看一个非常实用的技术点——怎么用Apex为PSO,也就是专业服务自动化应用,创建一个自定义的基于OAuth的身份验证提供程序插件。 听起来可能有点绕,其实说白了,就是你们公司可能用了一些第三方的服务来管理用户登录,比如Concur这种报销系统。Salesforce本身已经内置了对谷歌、Facebook这些常见身份提供商的支持,但如果你们的提供商不在那个列表里,我们就需要自己写一个插件,让Salesforce能跟它对接。 这个插件的核心是什么?就是要去扩展一个抽象类,叫做`Auth.AuthProviderPluginClass`。这个类已经给我们搭好了骨架,我们要做的就是去填充细节,实现它规定的三个方法。 这三个方法各司其职,掌控了整个OAuth认证流程的三个关键步骤。 第一个方法叫`initiate()`。它的作用是,当用户点击“登录”按钮时,我们需要构建一个URL,把用户引导到那个第三方的身份提供商页面,就像给他们指一条路,说:“你去那个网站,先验证自己的身份。”所以,`initiate`方法就是去构建并返回这个认证用的URL。 第二个方法叫`deliverCallback()`。用户在那个第三方网站登录成功之后,对方会把用户送回Salesforce,同时带回来一个授权码。这个时候,我们写的`deliverCallback`方法就会被触发。它要负责拿着这个授权码,再去向身份提供商换取真正的访问令牌和可选的刷新令牌。换好之后,把这些令牌包装在一个叫做`AuthProviderTokenResponse`的对象里,交给Salesforce系统。这样,Salesforce就知道:“哦,这个人确实已经通过验证了,这是他的通行证。” 第三个方法叫`getUserInfo()`。光有通行证还不行,我们还得知道这个人是谁,他的邮箱、姓名这些基本信息是什么。所以,`getUserInfo`方法会用拿到的访问令牌,去调用那个第三方提供商的API,把用户的详细信息取回来,然后按照Salesforce要求的格式,组织成一个`Auth.UserData`对象并返回。这样,Salesforce就能把这些信息映射到内部的用户记录上。 这里有个很有意思的例子——Concur。官方文档里有一个Concur身份提供程序的完整实现。因为在有些认证流程里,回来的信息可能是HTML格式的页面,而不是整洁的JSON数据。所以那个Concur示例就特别展示了怎么解析HTML,把需要的信息提取出来,非常接地气。 最后,作为开发者,我们当然要保证代码质量,写测试类是少不了的。由于这些方法都要和外部网络打交道,不可能每次都真的去连接外部服务做测试。所以我们就用`HttpCalloutMock`来模拟网络响应。通过实现这个Mock接口,我们可以伪造出身份提供商返回的各种数据,这样就可以在完全不联网的情况下,完整地测试我们的插件逻辑了。 这样一来,只要实现了这三个方法,再配上Mock测试,你就能为任何支持OAuth的外部服务打造一个专属的登录通道,让Salesforce的集成能力变得更加灵活和强大。好,今天的内容就到这里,大家下去可以试着看看文档里的Concur例子,动手感受一下。
今天我们来聊一聊 Salesforce 里一个特别实用的功能——,OAuth 2.0 代币交换,。 想象一下,你有一个很复杂的系统,里面有好几个不同的应用程序,它们都想安全地跟 Salesforce 通信。这时候,我们不能让每个应用都去存一份用户名密码,太不安全了。更好的方式是,它们各自拿一个自己身份提供商(IdP)签发的令牌,然后到 Salesforce 这边来换成 Salesforce 自己的访问令牌,这就叫“代币交换”。 在 Apex 里,我们可以通过扩展一个叫 `Auth.Oauth2TokenExec` 的类来实现这个交换逻辑。这个类有两个特别重要的方法,咱们一个一个来看。 --- ### 1. 验证传来的令牌:`validateIncomingToken()` 这个方法的作用就是:“你拿来的令牌,我得先验一验,看到底是真的还是假的。” 因为不同的系统发出来的令牌格式可能不一样,所以 Salesforce 很聪明地准备了几种验证方式: - ,如果是 JWT 格式的令牌,(一种用点分隔的字符串,很常见),它会用内置工具 `Auth.JWTUtil` 来校验签名和有效期。 - ,如果是不透明令牌,(看起来像一串乱码,没有规律),它就会调身份提供商的“内省端点”,通过 REST 请求去问:“这个令牌长这样,现在还合法吗?” - ,如果是 SAML 断言,,它会用 ML 解析(就是把那段 XML 格式的 SAML 数据解开)来做检查。 检查完以后呢,它会给我们返回一个 `TokenValidationReport` 对象。 这个报告里有啥?非常简单,就三样东西: - 一个,成功标志,(告诉我们令牌合法不合法) - 一些,自定义数据,(可以用来放我们自己的业务信息) - 还有,用户数据,(将来可能跟 Salesforce 里的用户关联起来) --- ### 2. 根据令牌找到对应的 Salesforce 用户:`getUserForTokenSubmit()` 令牌验完了是合法的,那接下来就有一个问题:“这个令牌到底是哪个用户的?” 这个方法就是干这个映射工作的。 它先去查询 Salesforce 里有没有一个现成的用户,对应令牌里标的那个“主题”(比如用户名或者邮箱)。 如果找到了,那就直接用它,省事。 但如果没找到,而我们的配置里有个参数叫 `cannerUser` 是 `true`,那它就自动帮你,建一个新用户,。它会构建一个 User 对象,准备插入到数据库里去。 这里还有个小细节:如果是那种,外部用户,(比如社区用户),光建一个 User 还不够,它还会同时帮你把关联的 ,Contact(联系人),、,Account(账户), 或者 ,PersonAccount(个人账户), 一起创建好,这样用户出来就是一个完整的生态,不会缺胳膊少腿。 --- ### 3. 最后一步:权限集的分配用 `@future` 来异步处理 用户建好了,接下来要给他分配权限集,这样他才能干该干的事。 但是呢,如果我们直接在同一个事务里做这件事,很可能会遇到 Salesforce 的一个限制——叫,混合 DML 错误,。 简单说就是,你在一个操作里同时又插用户(Setup 对象)又改别的数据(非 Setup 对象),系统会报错不让干。 所以老师这里教我们一个技巧:,用 `@future` 方法,。 就是把分配权限集这个操作放到一个异步的小任务里,跟主流程分开。这样主流程结账的时候,权限集那块儿还没开始跑,就不会触发混合限制,两全其美。 --- 好了,总结一下,今天我们学了在复杂的多应用系统里,怎么通过 OAuth 2.0 代币交换把外部身份的令牌换成 Salesforce 用户,并且安全地做好权限分配。两个方法:先验令牌,再找用户;最后别忘了用 `@future` 把权限集分配悄悄甩出去。是不是感觉也没那么难?以后遇到第三方集成,你也可以用这个模式,很稳当。 咱们下次课再见!
同学们,咱们今天来看这张幻灯片上列出的一些 Apex 里可以用的高级功能。这些功能能帮我们省掉很多繁琐的代码,还能让应用跑得更快、集成更方便。我把它们拆开,用大白话一个个给你讲讲。 先看第一个,,DataWeave 在 Apex 里启用数据转换脚本,。这就像一个翻译官,能把一种数据格式自动转成另一种。比如从外部系统拿来复杂的 JSON,想变成 Salesforce 里自定义的类型,以前你要写一堆解析代码,现在用 DataWeave 写个简单的脚本,Apex 调用一下就完成转换了,出错率还低。 然后是,外部服务,。这个功能会把注册好的外部 API 直接映射成强类型的 Apex 类。啥意思呢?你不需要再手动拼 HTTP 请求、解析 JSON 了,只要照着生成的类去点方法,像调用本地方法一样调用远程接口,比如查天气、查汇率,都是类型安全的,编译时就能发现字段拼写错误,比之前方便太多。 接着说,公式评估,,这里提到能避免用于重新计算的 TLR。不用记这个缩写,你只要知道:公式字段平时计算出来存在那儿,当依赖的数据变了,系统得重新算。以前有些场景会触发不必要的重新计算,拖慢性能。现在优化后,公式评估更聪明,省掉了那些重复计算,Apex 里访问公式字段时响应更快。 再来看,平台缓存,。它提供高性能的 NPS 缓存——你记成命名分区缓存就行,还有就是会话缓存。我们可以把经常查但不怎么变的数据,比如用户权限、系统配置,临时存到缓存里。Apex 存取缓存就像拿个钥匙开抽屉,比每次去数据库里翻快得多,尤其适合高并发场景,用户体验瞬间就上去了。 ,Salesforce Knowledge 以编程方式管理文章,。这里 PPT 写的 Knight,应该是 Knowledge,就是知识库。以前想在 Apex 里发布、归档文章得绕一大圈,现在可以直接用代码操作知识文章的生命周期,适合做自动化帮助中心或者内部知识协作的场景。 ,Salesforce File 可自定义下载,。就是说我们可以用 Apex 控制文件的下载行为,比如加上水印、检验权限、记录下载日志,甚至动态生成文件内容再让用户下载,不是只能直接给链接了,灵活度很高。 ,体验云,,也就是 Experience Cloud,让我们能打造品牌化的数字体验。Apex 里可以拿到当前社区、站点的上下文,写组件逻辑时根据品牌定制页面内容,把外部客户和合作伙伴的体验做到一体。 ,Chatter 审核触发自动内容策略执行,。企业在用 Chatter 协作时,怕有人发敏感词或者违规内容。现在我们可以写 Apex 触发器,当帖子发出时自动扫描、拦截或者打标记,把公司的内容管理政策用代码固化下来,不用人工盯着。 最后,幻灯片还列了一串“其他功能”,咱快速过一下,大家知道 Apex 能这么用就行: - ,电子邮件,:Apex 里可以发送和追踪邮件,能做邮件营销、通知。 - ,权限集组,:通过代码动态分配和检查权限集组,管理大规模用户更省力。 - ,元数据 API 访问,:允许 Apex 直接读写元数据,比如自定义字段、对象,做配置自动化。 - ,Salesforce Connect 外部对象,:把外部数据库的表像 Salesforce 本地对象一样操作,Apex 做查询时自动实时查外部系统,不用同步数据。 - ,报告 API,:通过 Apex 生成、读取报告结果,做数据分析和仪表盘集成。 - ,网站 URL 重写,:在 Apex 里定义规则,把网站上的旧 URL 重定向到新的,SEO 友好。 - ,支持类,:就是 Apex 自带的那些 Support 类,用来处理 URL 编码、加密解密、JSON 序列化等基础功能,时刻都会用上。 - ,领地管理触发器,:针对 Territory Management(用于销售区域)的自动处理逻辑,像分配客户给区域经理。 - ,Data 360 SOQL 集成,:让 SOQL 查询能跨过多个数据源做统一分析,Apex 可以调用这种查询拿到更全面的业务视图。 这些特性加在一起,你会发现 Apex 不仅能做简单的增删改查,还能跟外部系统、大数据、内容管理、社交协作深度结合。大家先有个印象,后面我们在具体场景里再细聊怎么用。好了,这页就讲到这里,休息一下,有问题的随时提。