8 分钟

了解如何使用 Marketo Engage REST API 自动执行营销运营任务。本文介绍了 Marketo Engage 管理员遇到的常见用例,包括简化营销活动创建、恢复不需要的数据更改以及将参与度洞察转换为切实可行的销售操作。

我拥有应用与计算数学的背景,这使我有别于大多数 Marketo Engage 从业者。当我开始从事营销运营工作时,我发现大部分工作都可以自动化。 自动化可以使我提高工作效率,并加快职业发展。 通过 API 将日常操作自动化,我可以专注于更具战略意义的主题,而不是被操作任务所束缚。

在本文中,我分享了自己如何使用 Marketo Engage REST API,并介绍了三个我最喜欢的用例来展示其强大之处。让我来展示 REST API 如何成为帮助您提高 Marketo Engage 效率的利器,让您有更多时间关注战略问题。

做好准备,一起来了解如何将 REST API 用于这些业务场景。

用例 1:简化营销活动创建

Marketo Engage 是一款用于扩展营销运营的强大工具,提供有助于简化流程的模板和令牌。但不得不承认,仍有许多操作需要手动完成。如果您从事营销运营工作,往往需要花费大量时间复制项目、更新令牌和激活智能营销活动。

如果您每周只管理几个营销活动,也许能够应付得了。然而,如果您要处理数十个,甚至数百个营销活动,手动执行所有操作就不可行了。错误难免发生,而且确保跨营销活动的一致性也是一大挑战。此时就需要用到 Marketo Engage REST API。通过自动执行这些重复任务,您可以节省时间、减少错误并让所有营销工作保持一致。

借助 REST API,您可以快速克隆整个项目,同时保持所有内容结构有序且统一。即使是经验丰富的 Marketo Engage 从业者也会犯错,而自动化可最大程度地降低风险,并有助于维护数据完整性。

此过程仍允许您自定义营销活动以满足您的营销需求。借助 REST API,您能够修改令牌之类的关键元素,同时保持营销活动结构的一致性。

观看下面的演示视频,我在其中解释了如何使用提供的示例代码,并根据组织的需求进行调整。
在“示例代码”部分查找以下视频中演示的代码,以用于离线使用。

用例 2:恢复不需要的数据更改

设想这样一种场景:您已经面临大量任务,而此时营销人员紧急请求您将潜在客户列表上传到 Marketo Engage。您迅速完成了任务,结果却从 SDR 那里得知数据全是错的!职位是错的,旧的潜在客户被覆盖掉,一切都是一团糟。

对于任何营销运营专业人员来说,这都是一场噩梦。手动修复这些错误可能需要几个小时,甚至数天之久。但不必担心,Marketo Engage 的 REST API 提供了解决方案。它就像一台数据的时光机,让您可以毫不费力地跟踪和恢复不需要的更改。

利用 REST API,您可以提取近期数据值更改的日志,识别错误的更新,只需几个步骤即可恢复原始信息。您无需手忙脚乱地手动清理混乱的数据,而可以自动执行回滚过程,并确保数据库始终准确可靠。

在以下视频中,我们将探索如何使用 REST API 来恢复有问题的数据导入,让您的 Marketo Engage 实例保持干净且没有错误。
NOTE
此方法只能解决简单的数据恢复情况。如果要考虑多次更改,则需要使用更为复杂的逻辑来选取要恢复到的正确值。
在“示例代码”部分查找以下视频中演示的代码,以用于离线使用。

用例 3:将洞察转化为销售操作

对于销售团队而言,背景信息至关重要——尤其是在了解某个潜在客户为何会成为营销合格潜在客户 (MQL) 时。但通常情况下,判断合格背后的数据往往被隐藏在层层的参与指标之中,使得销售代表需花费大量时间自行整理完整的客户背景信息。

此时,需要利用自动化技术来解决这一难题。通过将 Marketo Engage 与 AI 集成,您可以将参与数据转化为清晰的可操作洞察,帮助销售团队集中精力处理真正重要的事情——达成交易。

利用 Marketo Engage REST API,您可以提取近期的参与活动数据,借助生成式 AI 进行处理以生成简洁的摘要,并将该摘要推送回 Marketo Engage 以便可视化。这意味着销售代表无需再翻阅人员的活动日志来了解潜在客户如何成为 MQL。相反,他们会得到由 AI 生成的、关于潜在客户历程的简明解释。此摘要包括客户对哪些产品或服务表现出兴趣,以及他们与品牌互动时采取的任何关键操作。

通过让销售人员能够在 Salesforce 中即时获取这些信息,他们能够充满自信地开展对话和个性化的外展服务,并最终更快地达成更多交易。

此用例旨在当潜在客户转变为 MQL 时使用 REST API。因此,它每次只处理一个潜在客户。如果您考虑为较大的潜在客户批次应用此方法,则批量 API 会更适合。

让我们仔细观看以下视频,了解如何将此设置应用于实践。
IMPORTANT
在将任何人的数据发送到大型语言模型 (LLM) 之前,请咨询组织内的相应合规性资源,以确保符合相关的法律法规。
在“示例代码”部分查找以下视频中演示的代码,以用于离线使用。

关键要点

以上是关于如何使用 Marketo Engage REST API 简化营销运营任务的全部内容。

我介绍了三个可使用 REST API 的强大用例:

  1. 自动执行营销活动克隆,以减少手动工作并确保一致性。
  2. 跟踪并恢复不需要的数据更改,节省数小时的清理时间。
  3. 为销售团队提供关于 MQL 的即时洞察,以帮助开展更有效的跟进对话。

这些自动化技术不仅仅是为了节省时间,还有助于确保准确性、维护数据完整性,并助力营销和销售团队更智能地开展工作。

发现使用 REST API 能实现如此多的可能性,您可能会觉得不知所措,因此我为您准备了一些提示:

如果您觉得本文很有帮助,请务必访问 Adobe Experience League,以了解更多同行的真知灼见和最佳实践。感谢阅读,祝您享受自动化的乐趣!

示例代码

简化营销活动创建

import requests
import pandas as pd
import json
import urllib.parse
MUNCHKIN = "YOUR-MUNCHKIN-ID"
client_id = "YOUR-CLIENT-ID"
client_secret= "YOUR-CLIENT-SECRET"
def get_access_token():
    global client_id
    global client_secret
    global MUNCHKIN
    params={'grant_type': 'client_credentials', 'client_id': client_id, 'client_secret': client_secret}
    headers={'Accept-Encoding': 'gzip'}
    url="https://"+MUNCHKIN+".mktorest.com/identity/oauth/token"
    response=requests.get(url=url,params=params,headers=headers)
    data=response.json()
    return data['access_token']
5
5-7
templateID=5200
folderName="Active Webinars"
programName="WB-2025-02-20-Test"
eventName="Webinar Test"
eventDate="2025-02-20"
18
url="https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/folder/byName.json"
token=get_access_token()
params={"name": folderName,
        "type": "Folder",
        "Content-Type": "application/x-www-form-urlencoded"}
headers={'Authorization': 'Bearer ' + token}
response=requests.get(url=url,params=params, headers=headers)
data=response.json()
print(data)
folderID=data['result'][0]["id"]
23

url="https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/program/

↪"+str(templateID)+"/clone.json"

token=get_access_token()

params={"Content-Type": "application/x-www-form-urlencoded"}

headers={'Authorization': 'Bearer ' + token}

body="name="+programName+"&folder={'id':"+str(folderID)+",'type':'Folder'}" url=url+"?"+body

response=requests.post(url=url,params=params,headers=headers)

data=response.json()

print(data)

programid=data['result'][0]['id']

33
url="https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/smartCampaigns.json"
token=get_access_token()
params={"Content-Type": "application/x-www-form-urlencoded"}
headers={'Authorization': 'Bearer ' + token}
body="folder={'id':"+str(programid)+",'type':'Program'}"
url=url+"?"+body
response=requests.get(url=url, params=params, headers=headers)
data=response.json()
campaigns=[]
for campaign in data['result']:
    campaigns.append(campaign['id'])
print(campaigns)
43
for campaign in campaigns:
    url="https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/smartCampaign/
    ↪"+str(campaign)+"/activate.json"
    token=get_access_token()
    headers={'Authorization': 'Bearer ' + token}
    response=requests.post(url=url,headers=headers)
    data=response.json()
    print(data)
55
url = "https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/folder/
 ↪"+str(programid)+"/tokens.json"
token=get_access_token()
headers = {
           "Authorization": f"Bearer {token}",
           "Content-Type": "application/x-www-form-urlencoded"}
payload = {
           "name": "Webinar Name",
           "value": eventName,
           "type": "text",
           "folderType": "Program"}
response = requests.post(url, headers=headers, data=payload)
data=response.json()
data
63
url = "https://"+MUNCHKIN+".mktorest.com/rest/asset/v1/folder/
 ↪"+str(programid)+"/tokens.json"
token=get_access_token()
headers = {
           "Authorization": f"Bearer {token}",
           "Content-Type": "application/x-www-form-urlencoded"}
payload = {
           "name": "Webinar Date",
           "value": eventDate,
           "type": "date",
           "folderType": "Program"}
response = requests.post(url, headers=headers, data=payload)
data=response.json()
data
77

恢复不需要的数据更改

import pandas as pd
import csv
import json
import ast
import requests
import math
MUNCHKIN = "YOUR-MUNCHKIN-ID"
client_id = "YOUR-CLIENT-ID"
client_secret= "YOUR-CLIENT-SECRET"
def get_access_token():
    global client_id
    global client_secret
    global MUNCHKIN
    params={'grant_type': 'client_credentials',
            'client_id': client_id,
            'client_secret': client_secret}
    headers={'Accept-Encoding': 'gzip'}
    url="https://"+MUNCHKIN+".mktorest.com/identity/oauth/token" response=requests.get(url=url,params=params,headers=headers)
    data=response.json()
    return data['access_token']
7
7-9
sinceDate="2025-04-22T00:00:00-00:00"
field='Job Title'
fieldRest='Title'
listID=299
21
url="https://"+MUNCHKIN+".mktorest.com/rest/v1/activities/pagingtoken.json"
token=get_access_token()
params={'sinceDatetime':sinceDate}
headers={'Authorization': 'Bearer ' + token,}
response=requests.get(url=url,params=params, headers=headers)
data=response.json()
nextPageToken=data['nextPageToken']
data
25
url="https://"+MUNCHKIN+".mktorest.com/rest/v1/activities.json"
params={'nextPageToken': nextPageToken,
        'activityTypeIds':[13],
        'listId': listID}
headers={'Authorization': 'Bearer ' + token,}
response=requests.get(url=url,params=params,headers=headers)
data=response.json()
print(data) act=data['result']
while data['moreResult']==True:
      nextPageToken=data['nextPageToken']
      token=get_access_token()
      params={'nextPageToken': nextPageToken,
              'activityTypeIds':[13],
              'listId': listID}
      headers={'Authorization': 'Bearer ' + token}
      response=requests.get(url=url,params=params,headers=headers) data=response.json()
      print(data)
      act=act+(data['result'])
33
df=pd.json_normalize(act)
df=df[df['primaryAttributeValue']==field]
df=df.sort_values('activityDate')
df=df.reset_index()
df=df.drop(columns=['index'])
df
51
df1=pd.json_normalize(df['attributes'])
i=4
while i<len(df1.columns):
      df1=df1.drop(columns=[list(df1.columns)[i]])
      i=i+1
df1.columns=['New_Value','Old_Value','Reason','Source']
df1.New_Value=pd.json_normalize(df1.New_Value)['value']
df1.Old_Value=pd.json_normalize(df1.Old_Value)['value']
df1.Reason=pd.json_normalize(df1.Reason)['value']
df1.Source=pd.json_normalize(df1.Source)['value']
57
df=pd.merge(df,df1,left_index=True, right_index=True)
df=df.drop(columns=['attributes'])
df=df.drop_duplicates(subset='leadId', keep="first")
67
df
70
df.to_excel("dataToCorrect.xlsx")
71
ids=df[df.columns.to_list()[2]].to_list()
camposval=df['Old_Value'].to_list()
for i in range(len(camposval)):
         if camposval[i] == None:
            camposval[i] = 'NULL'
STEP=300
a=math.ceil(len(ids)/STEP)
i=0
while i<a:
     tempids=ids[i*STEP:(i+1)*STEP]
     tempcamposval=camposval[i*STEP:(i+1)*STEP]
     params={'action': 'updateOnly',
             'lookupField': 'id',
             'input':[]}
j=0
while j<len(tempids):
     lead={'id':tempids[j],
           fieldRest:tempcamposval[j]}
     params['input'].append(lead)
     j=j+1
     token=get_access_token()
     url="https://"+MUNCHKIN+".mktorest.com/rest/v1/leads.json"
     headers={'content-type': 'application/json', 'Authorization': 'Bearer ' + token }
     i=i+1
     response=requests.post(url=url,data=json.dumps(params), headers=headers)
     print(response.json()['result'])
72

将洞察转化为销售操作

importrequests
import pandas as pd
import json
fromdatetimeimportdatetime, timedelta
MUNCHKIN = "YOUR-MUNCHKIN-ID"
client_id = "YOUR-CLIENT-ID"
client_secret= "YOUR-CLIENT-SECRET"
defget_access_token():
        globalclient_id
        globalclient_secret
        globalMUNCHKIN
        params={'grant_type': 'client_credentials',
                          'client_id': client_id,
                          'client_secret': client_secret}
        headers={'Accept-Encoding': 'gzip'}
        url="https://"+MUNCHKIN+".mktorest.com/identity/oauth/token"
        response=requests.get(url=url,params=params,headers=headers)
        data=response.json()
        return data['access_token']
5
5-7
leadid="1007244"
ndays=60
gptAPIKey="Bearer␣
  ↪sk-proj-ne6OZggjgQhQU6XcG0ocHNPNzBvOOULTkk8a-75Y75rHKS-vyztxPYq0OLaFsnhtGivx9bVUNoT3BlbkFJH
fieldName="MktoPersonNotes"
20
today = datetime.today()
sinceDate = today - timedelta(days=ndays)
sinceDate = sinceDate.strftime("%Y-%m-%dT00:00:00")
25
url="https://"+MUNCHKIN+".mktorest.com/rest/v1/activities/pagingtoken.json"
token=get_access_token()
params={'sinceDatetime': sinceDate}
headers={'Authorization': 'Bearer ' + token}
response=requests.get(url=url,params=params,headers=headers)
data=response.json()
nextPageToken=data['nextPageToken']
28
data
35
access_token=get_access_token()
def get_lead_activities(token, lead_id, firstToken):
    url = f"https://"+MUNCHKIN+".mktorest.com/rest/v1/activities.json"
    params={
             "leadId": lead_id,
             "activityTypeIds": "1,2,3,10,11,34,104",
             "nextPageToken": firstToken
             }
    headers={'Authorization': 'Bearer ' + token}
    activities = []
    more_results = True
    while more_results:
         response = requests.get(url, params=params, headers=headers)
         data = response.json()
         if 'result' in data:
             activities.extend(data['result'])
             more_results = data.get('moreResult', False)
         if more_results:
             params["nextPageToken"] = data['nextPageToken']
    return activities
all_activities = get_lead_activities(access_token, leadid,nextPageToken)
all_activities = str(all_activities).replace('"', "'")
activities=all_activities
activities
36
def send_to_chatgpt(activities):
    url = "https://api.openai.com/v1/chat/completions"
    headers = {
         "Authorization": gptAPIKey,
         "Content-Type": "application/json"
         }
    prompt = """Analyze the following lead activities and explain the␣
↪activities that contributed to this lead being marked as MQL so a␣
↪salesperson knows how they should approach the client, including which␣
↪product or service this lead is most interested in and any other relevant␣
↪insights. Include relevant URLs on form fills:""" +activities+""" – Remember␣
↪this will only be read by a salesperson, so don't use technical␣
↪explanations, just your best summary. Keep your response limited to 100␣
↪words."""
    data = {
         "model": "gpt-4o-mini",
         "messages": [{"role": "user", "content": prompt}],
         "max_tokens": 250
         }
         response = requests.post(url, headers=headers, json=data)
         return response.json()
gpt_response = send_to_chatgpt(activities)['choices'][0]['message']['content']
gpt_response
60
def update_marketo_field(lead_id, field_name, gpt_response):
       access_token=get_access_token()
       url = "https://"+MUNCHKIN+".mktorest.com/rest/v1/leads.json"
       headers = {
               "Content-Type": "application/json",
               'Authorization': 'Bearer ' + token
               }
       payload = {
                "action": "updateOnly",
                "lookupField": "id",
                "input":[
                        {
                         "id": int(lead_id),
                          field_name: gpt_response
                         }
                      ]
                   }
       response = requests.post(url, headers=headers, json=payload)
       return response.json()
update_response = update_marketo_field(leadid, fieldName, gpt_response)
update_response
83