Salesforce-单击按钮调用外部API并根据响应更新自定义字段

Salesforce-单击按钮调用外部API并根据响应更新自定义字段,salesforce,salesforce-lightning,Salesforce,Salesforce Lightning,因此,我首先要说,我是一名拥有丰富经验的C#.Net/Javascript开发人员,但我对Salesforce没有任何经验。今天以前从没见过。因此,另一个团队要求我向联系人对象添加一个自定义按钮,单击该按钮将调用外部API并用响应更新联系人中的自定义字段。它被宣传为“只要编写一些Javascript,在点击按钮时调用API,它就被嵌入到页面中,15分钟的工作……” 在一个看起来相当过时的文档之后,我进入了对象管理器,选择了联系人对象,进入了按钮、链接和操作页面。在此之前,我假设这是使用执行Jav

因此,我首先要说,我是一名拥有丰富经验的C#.Net/Javascript开发人员,但我对Salesforce没有任何经验。今天以前从没见过。因此,另一个团队要求我向联系人对象添加一个自定义按钮,单击该按钮将调用外部API并用响应更新联系人中的自定义字段。它被宣传为“只要编写一些Javascript,在点击按钮时调用API,它就被嵌入到页面中,15分钟的工作……”

在一个看起来相当过时的文档之后,我进入了对象管理器,选择了联系人对象,进入了按钮、链接和操作页面。在此之前,我假设这是使用执行Javascript行为完成的,在Lightning版本中,我建议不要使用该行为。所以在谷歌搜索了很多之后,我读到了关于APEX类、Visualforce组件、Lightning组件、Salesforce REST API等的内容,而不是15分钟的工作

本质上,需求是在这个联系人页面中嵌入一个按钮(或操作,或..?),这样当销售人员单击它时,它会收集联系人的一些详细信息,并使用它们形成对外部服务的API调用。数据将用于形成响应,然后必须读取(作为JSON,然后进行解析)并写入联系人的自定义字段

开发解决方案的最佳方法是什么?在Apex调试环境中,我将调用API和解析JSON响应的代码放在一起,我假设我需要将其封装在Apex类中,并使用一个调用此代码并返回响应的方法。我不确定的是,如何从按钮调用它,并更新联系人中的字段。 我需要从Apex类方法中完成所有这些吗?传递对触点的引用,或者是否有其他组件需要位于两者之间并执行此操作。 我假设我需要使用Salesforce API来更新联系人,对吗


感谢您的指点。

我会写信告诉您我的方法

记录页面/页面布局上的按钮->照明组件或流->收集数据的Apex类->Apex类请求和响应API(不要忘记将端点添加到远程站点设置)->解析响应和更新联系人(您可以在Apex中使用查询和DML操作)

照明组件这将是非常简单的只是有一个apex类作为控制器的例子

<aura:component implements="force:appHostable,lightning:isUrlAddressable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" controller="contactController" access="global" >

<aura:handler name="init" value="{!this}" action="{!c.fetchContact}"/>
</aura:component>
助手

({
fetchAccHelper : function(component, event, helper) {
    var action = component.get("c.fetchContacts");
    action.setParams({
    });
    action.setCallback(this, function(response){
        var state = response.getState();
        if (state === "SUCCESS") {
        }
    });
    $A.enqueueAction(action);
}
})

假设is apex函数是fetchContacts,而class contactController则是ohman。这可能是一个15分钟的工作,但肯定是“当你知道怎么做时很容易”,或者举一些例子;)

  • 你的用户界面是什么,经典还是闪电?他们有计划很快迁移到Lightning吗?如果你发现“执行JavaScript”黑客已经过时,我想这是闪电
  • 你在乎按钮/动作在哪里吗?右上角的所有其他按钮都可以吗?还是您希望它几乎可以拖放到页面中的任何区域
  • API调用是否需要用户名、密码或证书?它将确定您是只需要在防火墙上白名单端点(设置->远程站点设置),还是需要更高级的东西(设置->命名凭据)
  • 您是否有SFDX命令行(CLI)、VSCode/并决定安装一些工具?Lightning Web组件是最先进、最光滑的组件,但您无法直接在浏览器中创建它们(至少目前还不能),您需要工具。Visualforce还可以,但对于这个用例来说并没有什么特别之处,Aura组件编写起来有点笨重——但您可以在开发人员控制台中完成这两项工作,而无需额外的工具
  • 解析JSON响应——这取决于它有多复杂,您可以手工制作解析器,但生命太短了。这是一个很好的apex代码生成器,与解析WSDL时得到的代码类似:
  • 我们将尝试使用光环组件的方式。这很难看,LWC是未来,但嘿,它会让你开始


    转到设置->远程站点设置,并使用
    https://en.wikipedia.org/

    创建新的Apex类:

    public与共享类Stack63364119{
    静态最终字符串端点https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&srsearch=';
    @可听的
    公共静态字符串doCallout(Id contactId){
    如果(contactId==null){
    抛出新的MyException('缺少记录id');
    }
    列出联系人=[从联系人中选择MailingCountry,其中Id=:contactId];
    if(contacts.isEmpty()| | String.isBlank(contacts[0].MailingCountry)){
    抛出新的MyException('找不到联系人');
    }
    触点c=触点[0];
    HttpRequest req=新的HttpRequest();
    请求setEndpoint(endpoint+c.MailingCountry);
    请求setMethod('GET');
    HTTPResponse res=new Http().send(req);
    调试(res.getStatus());
    调试(res.getBody());
    //无需特殊解析,只需将其放入描述字段即可
    //无错误处理
    如果(res.getStatusCode()==200){
    c、 Description=res.getBody().缩写(32000);
    更新c;
    }
    return res.getBody();
    }
    公共类MyException扩展了异常{}
    }
    
    在开发者控制台中创建新的“Lighning组件”(它将是Aura,而不是LWC)。您可以勾选“闪电快速行动”的最后一个复选框。名称可以与类相同,但不必相同

    对于组件(~html部分),请粘贴此

    <!-- Loosely based on https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/controllers_server_actions_call.htm -->
    <aura:component controller="Stack63364119" implements="force:hasRecordId,force:lightningQuickAction" >
        <!-- in the name of all that is holy do not name the JS function same as the Apex class function, it'll give you very cryptic errors to debug -->
        <aura:handler name="init" value="{!this}" action="{!c.runCallout}"/> 
    </aura:component>
    
    ({
        runCallout : function(cmp) {
            let action = cmp.get('c.doCallout');
            action.setParams({contactId : cmp.get('v.recordId')});
            action.setCallback(this, function(response){
                let state = response.getState();
                if (state === "SUCCESS") {
                    alert('Saved OK: ' + response.getReturnValue());
                    $A.get("e.force:closeQuickAction").fire(); // if you want to self-close
                } else if (state === "ERROR") {
                    var errors = response.getError();
                    if (errors) {
                        if (errors[0] && errors[0].message) {
                            console.log("Error message: " + errors[0].message);
                        }
                    } else {
                        console.log("Unknown error");
                    }
                }
            });
            $A.enqueueAction(action);
        }
    })
    
    最后转到对象管理器->联系人->按钮链接和操作。创建新的快速操作。 并将其添加到页面布局中

    这应该让你开始。也许您会决定将其拆分一点,Apex将只进行调出,将结果返回到UI,如果用户满意,则可以使用以下方法之一更新联系人:。分离关注点无稽之谈(但会
    ({
        runCallout : function(cmp) {
            let action = cmp.get('c.doCallout');
            action.setParams({contactId : cmp.get('v.recordId')});
            action.setCallback(this, function(response){
                let state = response.getState();
                if (state === "SUCCESS") {
                    alert('Saved OK: ' + response.getReturnValue());
                    $A.get("e.force:closeQuickAction").fire(); // if you want to self-close
                } else if (state === "ERROR") {
                    var errors = response.getError();
                    if (errors) {
                        if (errors[0] && errors[0].message) {
                            console.log("Error message: " + errors[0].message);
                        }
                    } else {
                        console.log("Unknown error");
                    }
                }
            });
            $A.enqueueAction(action);
        }
    })