如何在SAP云平台ABAP编程环境里把CDS-view暴露成OData服务

Jerry 2016年在学习SAP CDS view时,曾经写过一个CDS view的自学系列,其中有一篇提到了一个很方便的注解: @OData.publish: true 加上这个注解的CDS view,一旦激活后就会在ABAP Netweaver自动生成一个OData服务,在事务码/IWFND/MAINT_SERVICE里将其搜索出来并添加,就能够以OData服务的方式,消费这个view暴露出来的数据了。 当然@OData.publish这个注解为什么有这种神奇的魔力,在Jerry之前的博客里有详细介绍。 那么到了SAP云平台ABAP环境上,因为我们无法访问SAP GUI,所以要实现同样的效果,无法直接照搬上述步骤。幸运的是,在云上进行CDS view暴露的步骤依然简洁,整个过程5分钟就能搞定。 用ABAP Development Tools像登录On-Premises ABAP系统那样登录ABAP云环境,新建一个Service definition: 在Service的实现体里,使用关键字expose将ABAP环境里的标准view,I_Currency以Service的方式暴露出来。 这个Service需要以Service Binding的方式暴露成OData服务: 把第一步创建的Service分配给这个Service Binding: 注意下图右边的Service Details标签页里,此时是空的。点击Publish按钮: 发布成功后,我们看到了之前在Service实现里把I_Currency暴露成的名为Currency的实体: 对这个Currency Entity点右键,选择Open Fiori Elements App Preview,就能在预览模式下通过一个标准通用的Fiori Elements应用把当前系统上I_Currency里的数据显示出来: 点击这个Service URL超链接,也能直接打开对应OData服务的元数据(metadata)链接: 至此我们就可以用各种消费端来使用这个通过I_Currency暴露成的OData服务了,当然也可以开发一个SAP Fiori来消费,Jerry后续会介绍。 感谢阅读。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

October 14, 2019 · 1 min · jiezi

使用CDS-view开发SAP-Marketing-contact的facet追溯工具

这篇SAP社区博客里,我的一位同事介绍了SAP Marketing里contact facet数据模型的存储表:https://blogs.sap.com/2016/07... 主要是这两张表: CUAND_CE_IC_ROOT CUAND_CE_IC_FCET 现在我的需求是:对系统里Contact的Origin Data数据来源渠道个数从高到低的顺序进行排序: 解决方案:开发两个CDS view zcontact_origin@AbapCatalog.sqlViewName: 'SQL_VIEW_NAME'@AbapCatalog.compiler.compareFilter: true@AbapCatalog.preserveKey: true@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'Contact Origin tool'define view zcontact_origin as select from cuand_ce_ic_root as a inner join cuand_ce_ic_fcet as b on a.db_key = b.parent_key { key a.db_key, a.name_text, a.smtp_addr, b.db_key as children_key, b.id_origin} zcontact_count@AbapCatalog.sqlViewName: 'ZCONCOUNT'@AbapCatalog.compiler.compareFilter: true@AbapCatalog.preserveKey: true@AccessControl.authorizationCheck: #CHECK@EndUserText.label: 'count aggregation'define view ZCONTACT_COUNT as select from zcontact_origin { key zcontact_origin.db_key, zcontact_origin.smtp_addr, count(*) as facet_count} group by db_key, smtp_addr最后的效果: ...

July 14, 2019 · 1 min · jiezi

如何在阿里云上运行SAP-UI5应用

本来Jerry觉得这个知识点太简单了完全不值得写成微信公众号文章,但转念一想,可能网络上有一些刚刚初学UI5的朋友们可能会问到,所以还是写了。 今天一个成都同事问我这个问题,因为SAP WebIDE可以非常方便地将开发好的UI5应用一键部属到SAP的其他系统,比如On-Premises环境的SAP gateway系统;但对于SAP Cloud Platform之外的其他云平台,比如AWS或者阿里云,SAP官方文档讲得不多。 其实如果已经在WebIDE里完成了UI5应用的开发,要让它运行在其他IaaS云平台上比如AWS或者阿里云上,步骤也是比较简单的。 Jerry已经做好了一个简单的SAP UI5 Hello World应用,上传到了我的github上: https://github.com/i042416/we... 这个UI5应用的源代码,在该Github仓库的webapp文件夹下面: 这里面全是标准的UI5应用开发资源。 在这个项目的根目录即webapp文件夹的外层,多了两个文件:server.js和package.json, 分别是nodejs应用的入口文件和项目描述文件。 server.js的实现很简单,用nodejs的express module起一个server,把来自url "/ui5"的请求路由到文件夹webapp里,最后监听在环境变量PORT指定的端口号或者3000这个端口上。 最后登录阿里云,git clone把这个仓库克隆到阿里云上,npm install安装package.json文件里描述的依赖: 然后使用命令行node server.js启动服务器, 就可以通过<阿里云服务器的IP地址>:3000这个url访问这个UI5应用了。 如果想以守护进程的方式启动server, 也可以用pm2, 一个开源的nodejs进程管理工具。 用命令pm2 start server.js启动服务器即可, 这样即使阿里云服务器的SSH终端关闭,该UI5应用依然可以通过url <阿里云服务器的IP地址>:3000访问。 其实啰嗦了这么多,用一句话概括就是,在IaaS级别的云平台上启动Web服务器(nodejs express, Tomcat, Nginx等都行),运行在上面的UI5应用就能通过云平台被各种终端访问到了。 感谢阅读。 Jerry原创的关于SAP Fiori和UI5的更多文章 SAP Fiori应用的三种部署方式Jerry的Fiori原创文章合集SAP Fiori + Vue = ?Jerry的UI5框架代码自学教程Jerry的碎碎念:SAPUI5, Angular, React和Vue在Kubernetes上运行SAP UI5应用(上)在Kubernetes上运行SAP UI5应用(下)要获取更多Jerry的原创文章,请关注公众号"汪子熙":

July 14, 2019 · 1 min · jiezi

一步步用ABAP-Development-Tools连接SAP云平台上的ABAP编程环境

使用ABAP Development Tools的项目创建向导: New->ABAP Cloud Project: Service Instance Connection,选择SAP Cloud Platform CloudFoundry environment: 选择Region,输入用户名密码,前提是你得在这个region下有一个global Account。 下图是我在欧洲法兰克福(Frankfurt)这个Region的Global Account: 这个Global Account所属的space下面我创建了一个ABAP系统实例,ID为ME1: 这个ABAP运行实例具有16GB运行内存,64GB的HANA内存。 再回到ABAP Development Tools, 在项目创建向导里使用Cockpit里维护的上述属性: 点Next,在ABAP Development Tools里会看到一个嵌入的登录窗口: 点Finish: Finish点了之后,在ABAP Development Tools左侧的项目列表里就能看见创建好的ABAP Cloud项目了,接下来在这个项目里编写ABAP代码进行开发的方式,和我们用ADT连接On-Premises系统基本一致。大家可以看到下图创建好的高亮的ABAP Cloud项目(系统ID为ME1), 和其他On-Premises上的ABAP项目外观上没有区别。 这两种ABAP项目的差异在于,ABAP Cloud项目里能够使用的ABAP语言特性,只是传统ABAP语言的一个子集,比如传统ABAP语言里和Dynpro相关的关键字,即只能工作在SAPGUI中的那些关键字,因为在Cloud环境下不再适用了,所以在ABAP Development Tools的ABAP Cloud项目里禁止使用。 至于上图ABAP Cloud项目里的Released Objects如何使用,等Jerry有时间再继续写。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

July 3, 2019 · 1 min · jiezi

Marketing-Cloud-contact主数据的csv导入

使用这个mock数据生成器网站https://www.mockaroo.com/b679...,创建一个基于Marketing Cloud contact schema的csv文件。 如果偷懒的话,每个contact字段的值都可以选择随机生成。点Download Data下载到本地。 打开csv文件之后,还可以用文本编辑器对值进行微调。 进入Marketing Cloud,点Import进行导入: 在business administration这个catalog里的import monitor对导入过程进行监控: 导入成功: 导入的数据可以在Marketing Cloud里使用了: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 23, 2019 · 1 min · jiezi

Marketing-Cloud的contact-merge机制

Marketing Cloud的contact支持多种多样的数据源,如下图所示: SAP Hybris CommerceSAP ERPSAP Cloud for CustomerSAP Gigyaexternal social media 在系统的Origin data标签页里能看到一个merge后的contact的所有数据源: 看一些例子。初次从Hybris commerce里导入,Marketing Cloud系统里不存在ID为4711,mobile为12345的contact,所以自动创建一条主数据。 第二次从SAP Cloud for Customer里导入,因为待导入的contact和系统里已经存在的一条记录的mobile ID相同,故Marketing Cloud认为这是同一个人,因此做属性的merge: merge之后,来自Cloud for Customer的city和country字段被合并进了系统。 从这里出发进行Marketing Cloud里contact merge相关的配置customizing: 这里可以指定进行merge检测时基于的字段,这些字段既有SAP Marketing Cloud的标准字段,也允许用户自定义新的字段。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 23, 2019 · 1 min · jiezi

SAP-Cloud-Platform上Destination属性为odatagen的具体用途

今天工作发现,SAP Cloud Platform上创建Destination维护的WebIDEUsage属性很有讲究: 帮助文档:https://help.sap.com/viewer/8... 这个属性的枚举值: 看个例子。我维护的是odata_gen: 根据标准文档描述,拥有odata_abap属性的Destination指向的是一个gateway系统,将在SAP webIDE创建UI5应用的向导中的service catalog界面出现,如下图所示: 意思是终端用户可以通过Service Catalog界面,任意选择该Destination指向的gateway系统上激活的service。 odata_abap: 目标是个SAP gateway系统 而另一方面,如果把Destination的属性改成odata_gen: 此时该Destination不会出现在Service Catalog的下拉菜单里: 取而代之的是它会出现在service url里: 而我们必须手动维护某一个具体OData服务的地址:/sap/opu/odata/sap/CRM_OPPORTUNITY 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 23, 2019 · 1 min · jiezi

如何让某些用户对Marketing-Cloud的contact数据只能实施只读操作

打开maintain business role这个应用: 创建一个新的business role,然后添加下列这几个catalogs:SAP_CEC_BC_MKT_ADM_PC Marketing - Business AdministratorSAP_CEC_BC_MKT_DMB1_PC Marketing - Contacts and Profiles BaseSAP_CEC_BC_MKT_CFS1_PC Marketing - Contact ProfileSAP_CEC_BC_MKT_DST_PC Marketing - Data StewardshipSAP_CEC_BC_MKT_EXT_PC Extensibility and Adaptability - Marketing3 一个一个添加进去:SAP_CEC_BC_MKT_ADM_PC 此处把Write Access改成No Access,最后把这个business role分配给对应用户,该用户对于contact数据就只拥有读权限了。 要获取更多Jerry的原创文章,请关注公众号"汪子熙".

June 23, 2019 · 1 min · jiezi

基于SAML20的SAP云产品Identity-Authentication过程介绍

SAP官网的架构图https://cloudplatform.sap.com... 上图介绍了用户访问SAP云平台时经历的Authentication过程。本文使用的例子是用户访问SAP Marketing Cloud而非SAP云平台,但是原理一致。 步骤1:用户向Service provider发起服务请求。步骤2:Service provider把这个请求重定向到提供认证的租户上,在我这个例子是SAP ID service,即account.sap.com. 这里Marketing Cloud和SAP ID Service被配置为互相信任。 请求1响应头里的302重定向字段:https://let-me-in.hybris.com/...://hybris.com/sap/bc/ui5_ui5/ui2/ushell/shells/abap/FioriLaunchpad.html 被重定向到SAP云平台的account ID service(accounts.sap.com):https://accounts.sap.com/saml...:ydcHybris:spring:sp2&RelayState=https://hybris.com/sap/bc/ui5... 步骤3:IDP给用户发送一个html page,要求用户提供用户名和密码。 如果查看这个html的源代码,能发现除了用户名和密码两个输入字段外,还包含了一些隐含字段,如下图高亮所示,这些字段是IDP返回给用户时在服务器端生成的,用于步骤5的IDP服务器端认证处理: xsrfProtectionspIdspNameauthenticity_tokenidpSSOEndpoint步骤4:用户输入用户名和密码后,点击login按钮,这些信息通过HTML form发送到了SAP ID service的服务器端: sso请求的url:https://accounts.sap.com/saml... 第二个大写的SSO请求的url:https://let-me-in.demo.hybris... 步骤5:SAP ID service的服务器端完成验证,发送SAML assertions作为响应给用户。 这个SAML响应是XML格式的,结构如下: 步骤6也就是最后一步,拿到这个SAML assertion后,用户就能够访问service provider了。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 22, 2019 · 1 min · jiezi

SAP分析云及协同计划

大家好, 我是SAP成都研究院S/4HANA Sales 团队的软件工程师Derek。四年前我从SAP Consulting团队转到SAP Labs从事Sales Analytics相关应用的开发,在加入S/4HANA Sales 团队之前是BI咨询顾问,主要工作经历集中在BI(BW&BO), EIM, BPC, ECC, S/4 HAHA相关产品。 之前我所在团队同事Zhang Sean已经在他的文章 S/4HANA中的销售计划管理 里给大家分享过了S/4HANA的销售计划管理,今天我给大家带来的是S/4HANA分析云的协同计划。 前言 当今是数字经济的时代,数字经济就是决策经济。企业做出的决策越明智、越及时,企业的业务增长能力就越强。拖延是破坏者和被破坏者之间的区别,公司要么适应这个规则要么等待灭亡。 如果说数据是数字经济世界的燃料,那么分析就是引擎。研究表明,要使数据驱动的决策处于数字引领者的前沿,采用数据驱动思维的分析能力至关重要。 目前市场上的大多分析解决方案只能提供下图中的一部分功能。 商务智能(Business Intelligence)技术通常依赖于历史数据或已发生的事情,但与未来的计划和结果无关。这些分散的缺乏整合的方案很难帮助企业快速准确地做出决定并采取行动。而SAP分析云(SAP Analytics Cloud,以下简称SAC)能很好地解决这些问题。 作为基于SAP云平台构建的新一代SaaS,SAC可以在一个解决方案中为所有用户提供企业商务智能,预测,协同计划等功能。 什么是SAP分析云 SAC是商务智能和协同计划相结合的解决方案,通过预测分析和机器学习技术的强大功能为企业决策提供实时支持。无论是在客户前线还是在董事会,都能让企业实体洞察到新的见解并采取行动。SAC通过在一个产品中为用户提供所有分析功能来重新定义云分析(Cloud Analytics)。作为一个部署在SAP Cloud Platform上的SaaS解决方案,SAP负责完成硬件和软件的管理,以便客户可以专注于分析其业务。 SAP分析云主要功能 SAC让员工能够自由分析企业的业务,模拟并预测接下来会发生什么,设计协同计划并采取行动,实施决策以获得即时价值。业务成功需要完整的分析功能,如商务智能,计划和预测等来支持战略、运营和战术决策,而SAC则能够授权用户在需要实时分析业务的场景下进行情景洞察,以帮助其做出决策。 SAC解决方案为每个负责制定智能决策以提高其成果的用户提供分析。 什么是SAP分析云协同计划(SAC Planning) SAC的核心优势在于其计划功能,除了计划功能之外,SAC还包括大量分析和报告功能,以及易于专业人员和其他计划人员使用的集成预测功能。例如,用户可以在输入数据或更改值后自动预测。商业智能,协同计划,以及基于机器学习的预测分析是SAC的三大核心功能。很多朋友认为SAC只是SAP Business Objects Business Intelligence的云版本而已,其实不然——SAC除了商业智能外, 协同计划和预测分析才是其核心部分。本文将重点介绍SAC的财务计划和分析功能。在探讨SAC Planning前我们需要理解计划,预算,预测等术语: 计划:提供公司启动方向和财务目标的整体流程(如战略计划,长期计划,年度计划等)预算:提供计划的执行路径。计划提供了什么是可能,预算提供了基于被批准计划的预期(如销售/毛利预算,资本支出预算,人数预算,运营开支预算等)预测:使用实际业绩数据来预测业绩的剩余未知部分(如滚动预测)SAC Planning提供了如下主要功能:条件模拟,数据输入,复杂分配,分解及数据转播,协同计划及评论,基于驱动程序的计划,工作流,替代层次结构的支持,版本管理(乐观版本、悲观版本、私有版本),内置财务功能等。 1. SAC为计划人员提供了强大的功能 为了支持计划用户,SAC表中使用的表组件提供了数据的交互式可视化功能。在网格中,存在许多可用的Microsoft Excel快捷方式,凭借新的自定义行和列功能,计划人员可以使用常见的Microsoft Excel类公式轻松地将其他信息添加到网格中。自定义单元格还支持单元格图表,计划用户可以很快地创建出符合IBCS(International Bussiness Communication Standard, 国际商业标准图表)的差异报告。 2. 与SAP Analysis for Microsoft Office无缝集成 新版本的SAP Analysis for Microsoft Office可以直接消费SAC Planning模型, 计划用户可以通过其熟悉的Microsoft Excel环境连接到SAC进行工作。简化的Excel样式允许用户通过强大的排序/过滤功能轻松访问各种维度。图形化的拖拽结构管理,创建报表公式以聚合值或在摘要表中执行简单分析,报表公式可用于汇总来自多个来源的信息。 ...

June 1, 2019 · 1 min · jiezi

如何远程调试部署在CloudFoundry平台上的nodejs应用

网络上关于如何本地调试nodejs应用的教程已经很多了,工具有Chrome开发者工具,Visual Studio Code,和nodejs周边的一些小工具等等。 在实际情况中,我们可能遇到本地运行良好,但是部署到CloudFoundry生产环境后的情况,此时就需要直接调试在CloudFoundry处于运行状态的nodejs应用了。本文介绍详细步骤。 首先我们得有一个在CloudFoundry上正常工作的nodejs应用。为了演示起见,本文使用的应用为jerry-demo-server: 使用如下命令将cf ssh -N -T -L 9229:127.0.0.1:9229 jerry-demo-server 这个命令将CloudFoundry上远程应用的9229端口和本地9229端口上建立了一个SSH安全隧道。 接下来,我们在Chrome地址栏输入chrome://inspect, 即可看到运行在CloudFoundry上的应用已经可以本地调试了: 在Chrome开发者工具的源代码里设置断点: 然后在浏览器里再次输入应用的url,断点触发,就可以开始远程调试了: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 1, 2019 · 1 min · jiezi

使用SSH命令行远程登录运行在CloudFoundry上的应用

当我试图用如下命令行采用SSH远程登录到运行在CloudFoundry环境下的应用时, cf ssh -N -T -L 9229:127.0.0.1:9229 jerry-demo-server遇到这个错误消息: ssh: unable to authenticate, attempted methods [none password], no supported methods remain https://stackoverflow.com/que... https://pvtl.force.com/s/arti... 使用命令行查看我的这个应用的ssh-enabled标志位: cf ssh-enabled jerry-demo-server发现处于disabled状态: 于是用命令行将这个标志位打开: cf enable-ssh jerry-demo-server cf ssh-enabled jerry-demo-server cf enable-ssh jerry-demo-server 之后重启应用: 问题解决。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

June 1, 2019 · 1 min · jiezi

如何用Java代码在SAP-Marketing-Cloud里创建contact数据

我们可以使用SAP Marketing Cloud提供的Contact create OData API在第三方应用里创建Contact主数据. API地址:/sap/opu/odata/sap/CUAN_CONTACT_SRV/InteractionContacts 示例代码只有100多行: import java.io.IOException;import java.io.UnsupportedEncodingException;import java.net.URI;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.StatusLine;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpPost;import org.apache.http.entity.StringEntity;import org.apache.http.impl.client.HttpClientBuilder;import sun.misc.BASE64Encoder;public class SimpleContactCreator { private ConfigUtil mConfigUtil = new ConfigUtil(); HttpClient m_httpClient; private String getBasicAuth(){ final String text = mConfigUtil.getConfig("user") + ":" + mConfigUtil.getConfig("password"); BASE64Encoder encoder = new BASE64Encoder(); String credentials = "basic " + encoder.encode(text.getBytes()); return credentials; } private HttpClient getHttpClient() { if (this.m_httpClient == null) { this.m_httpClient = HttpClientBuilder.create().build(); } return this.m_httpClient; } private String getCSRFToken(){ String url = mConfigUtil.getConfig("tokenurl"); System.out.println("fetch CSRF token via url: " + url); final HttpGet get = new HttpGet(url); get.setHeader("Authorization", getBasicAuth()); get.setHeader("Cache-Control", "no-cache"); get.setHeader("content-type", "application/json"); get.setHeader("Accept", "application/json"); get.setHeader("x-csrf-token", "fetch"); HttpResponse response; String token = null; try { response = getHttpClient().execute(get); StatusLine statusLine = response.getStatusLine(); int code = statusLine.getStatusCode(); System.out.println("Status code: " + code); System.out.println("reason: " + statusLine.getReasonPhrase()); token = response.getFirstHeader("x-csrf-token").getValue(); System.out.println("token: " + token); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException | UnsupportedOperationException e) { e.printStackTrace(); } return token; } public void run(String body){ String token = getCSRFToken(); createContact(token, body); } private void createContact(String token, String body){ final HttpPost post = new HttpPost( URI.create(mConfigUtil.getConfig("contactcreateurl"))); post.setHeader("Authorization", getBasicAuth()); post.setHeader("Content-Type", "application/json"); post.setHeader("X-CSRF-Token", token); HttpEntity entity = null; try { entity = new StringEntity(body); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } post.setEntity(entity); HttpResponse response = null; try { response = getHttpClient().execute(post); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } System.out.println("Response statusCode for Batch => " + response.getStatusLine().getStatusCode()); } public static void main(String[] args) { SimpleContactCreator tool = new SimpleContactCreator(); String body = "{\"IsConsumer\":true," + "\"Filter\":{\"MarketingArea\":\"CXXGLOBAL\"}," + "\"__metadata\":{\"type\":\"CUAN_CONTACT_SRV.InteractionContact\"}," + "\"FirstName\":\"SAP Diablo\",\"LastName\":\"SAP Wang\",\"Country\":\"CN\"," + "\"EMailAddress\":\"seya@sap.com\",\"YY1_WECHATID_MPS\":\"i042416\"," + "\"YY1_FACEID_MPS\":\"d042416\"}"; tool.run(body); }} ...

May 25, 2019 · 2 min · jiezi

如何在调用Marketing-Cloud-contact创建API时增加对扩展字段的支持

需求:扩展字段“微信ID”是我创建出来的extension field,我想用Marketing Cloud提供的contact creation API,在创建contact时也能支持这个扩展字段。换言之,我希望在调用contact create API时,给Extension field维护值,contact创建成功后,Extension field会被调用API时传入的值填充。 首先在Chrome开发者工具里找到这个字段的技术名称technical name:YY1_WECHATID_MPS 在Contact创建页面上把扩展字段配置出来, 创建一个新的contact实例, 给这个扩展字段维护一个值,比如i042416, 通过chrome开发者工具的network标签页观察创建时的payload: 然后在nodejs代码里依法将扩展字段的名称和值维护进去即可: 完整源代码:https://github.com/i042416/we...要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 25, 2019 · 1 min · jiezi

如何使用Marketing-Cloud的扩展字段作为搜索条件进行搜索

需求:我在Marketing Cloud的contact模型上用custom field这个应用创建了一个Extension field,名称为微信ID。 现在客户的需求是使用这个字段作为过滤条件进行搜索。 首先在界面上执行一次搜索,在Chrome开发者工具network标签里将这次搜索中前端发给后台的HTTP请求明细记录下来: 然后在postman里照样维护一份: payload:--batch_bd03-9977-8095Content-Type: application/httpContent-Transfer-Encoding: binaryGET InteractionContacts?sap-client=100&$skip=0&$top=15&$filter=YY1_WECHATID_MPS%20eq%20%27i042410%27&$select=ImageURL%2cName%2cContactLevelName%2cCountryName%2cCity%2cEMailAddress%2cPhoneNumber%2cMobilePhoneNumber%2cCorporateAccountName%2cInteractionContactUUID%2cRelationship%2cType&$inlinecount=allpages HTTP/1.1sap-cancel-on-close: trueCache-Control: max-age=360sap-contextid-accept: headerAccept: application/jsonAccept-Language: enDataServiceVersion: 2.0MaxDataServiceVersion: 2.0x-csrf-token: fsZ87xxAy55LLhk56CCjCw== --batch_bd03-9977-8095-- 测试结果如下: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 25, 2019 · 1 min · jiezi

如何在Marketing-Cloud里创建extension-field扩展字段

首先在Marketing Cloud里找到创建扩展字段的tile入口,搜索关键字extension: 这会进入Fiori应用“Custom fields”,能看到系统里所有创建好的extension field。点击+加号按钮新建一个: 维护这个扩展字段的技术信息,比如标签,类型,长度等等。 创建好之后点击按钮Publish,确保字段处于publish状态。 接下来需要为特定的UI enable这个字段的显示。在标签页UIs and Reports里,在对应的UI记录后点击按钮"Enable Usage": 最后一步,在UI上这个扩展字段放出来。点击Adapt UI: 进入Contact UI,点击加号按钮: 选择刚才创建好的扩展字段: 保存并publish发布change,至此这个扩展字段创建成功。 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 25, 2019 · 1 min · jiezi

使用nodejs创建Marketing-Cloud的contact数据

源代码如下: var config = require("./mcConfig");var request = require('request');var url = config.tokenURL;console.log("user: " + config.user + " password: " + config.password); var getTokenOptions = { url: url, method: "GET", json:true, headers: { 'Authorization': 'Basic ' + new Buffer(config.user + ":" + config.password).toString('base64'), "content-type": "application/json", "x-csrf-token" :"fetch" }};function getToken() { return new Promise(function(resolve,reject){ var requestC = request.defaults({jar: true}); console.log("Step1: get csrf token via url: " + url ); requestC(getTokenOptions,function(error,response,body){ var csrfToken = response.headers['x-csrf-token']; if(!csrfToken){ reject({message:"token fetch error: " + error}); return; } console.log("Step1: csrf token got: " + csrfToken); resolve(csrfToken); }); });}function createContact(token){ return new Promise(function(resolve, reject){ var oPostData = {"CountryCode":"CN", "City":"Chengdu", "FirstName":"Jerry4", "LastName":"Wang2", "PostalCode":"610093", "RegionCode":"", "Street":"天府软件园", "HouseNumber":"天府软件园", "DateofBirth":null, "ContactPersonFacets":[ {"Id":"jerry1@sap.com", "IdOrigin":"EMAIL", "Obsolete":false, "Invalid":false}, {"Id":"", "IdOrigin":"PHONE", "Obsolete":false, "Invalid":false}, {"Id":"", "IdOrigin":"MOBILE", "Obsolete":false, "Invalid":false}, {"Id":"", "IdOrigin":"FAX", "Obsolete":false, "Invalid":false} ], "IsConsumer":true, "Filter":{ "MarketingAreaId":"CXXGLOBAL" } }; var requestC = request.defaults({jar: true}); var createOptions = { url: config.createContactURL, method: "POST", json:true, headers: { "content-type": "application/json", 'x-csrf-token': token }, body:oPostData }; requestC(createOptions,function(error,response,data){ if(error){ reject(error.message); }else { var oCreatedContact = data; console.log("created contact ID: " + oCreatedContact.d.ContactPersonId); resolve(data); } }); });}getToken().then(createContact).catch((error) =>{ console.log("error: " + error.message);});这里我把创建的contact的名称字段硬编码成Jerry4: ...

May 25, 2019 · 1 min · jiezi

使用postman修改SAP-Marketing-Cloud-contact主数据

Marketing Cloud里的contact主数据,创建成功后也不是所有字段都能够被修改。在Personal data区域的字段是可以被修改的。 比如我在“客户属性”字段里维护了一些值: 然后点保存: 其中第二个batch操作是通过一个roundtrip读取contact模型下多个子节点的数据,和我们这个修改的场景没有关联。 使用postman进行修改: body字段维护以下内容:--batch_1f7d-bd35-caedContent-Type: multipart/mixed; boundary=changeset_8f9e-9a44-9f9e --changeset_8f9e-9a44-9f9eContent-Type: application/httpContent-Transfer-Encoding: binary MERGE Consumers('02000A21209F1EE99CDF1A1FC9AA8065')?sap-client=100 HTTP/1.1Cache-Control: max-age=360sap-contextid-accept: headerAccept: application/jsonAccept-Language: enDataServiceVersion: 2.0MaxDataServiceVersion: 2.0x-csrf-token: fQ2Pwfmf0K_LVYoKV9QYUw==Content-Type: application/jsonContent-Length: 215 {"__metadata":{"uri":"https://jerry.hybris.com/sap/opu/odata/sap/CUAN_CONTACT_SRV/Consumers('02000A21209F1EE99CDF1A1FC9AA8065')","type":"CUAN_CONTACT_SRV.Consumer"},"YY1_CustomerType_ENH":"Jerry测试2"}--changeset_8f9e-9a44-9f9e-- --batch_1f7d-bd35-caed-- 我想修改的字段的新的值为:Jerry测试2 执行postman后,发现值已经更新了,修改成功 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 25, 2019 · 1 min · jiezi

如何使用Chrome开发者工具找到Marketing-Cloud某个contact的guid

我们使用nodejs对contact进行修改时,需要指定待修改contact实例的guid。 这个guid属于technical属性,在Marketing Cloud UI上默认情况下不可见。如何找到这个属性值呢? 其实就在浏览器地址栏的url里: 当然在Chrome开发者工具的network标签页里也能找到这个guid: 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

May 25, 2019 · 1 min · jiezi