Marketo Engage REST API を使用してマーケティング業務タスクを自動化する方法について解説します。この記事では、キャンペーンの作成の効率化、不要なデータ変更の取り消し、エンゲージメントインサイトの実用的なセールスアクションへの変換など、Marketo Engage 管理者の一般的なユースケースについて説明します。
応用数学と計算数学のバックラウンドを持つ私は、Marketo Engage の多くの実践者とは一線を画していると自負しています。マーケティング業務の仕事を始めたときに、自動化できる仕事が多いことに気がつきました。 自動化によって、仕事の効率を上げ、キャリアの成長を早めることができます。 API を活用して日々の業務を自動化することで、業務に埋もれることなく、より戦略的な課題に集中できます。
この記事では、Marketo Engage REST API の使用方法について説明し、私が気に入っている 3 つのユースケースを紹介して、その機能を示します。REST API を利用して Marketo Engage の効率性を高め、戦略的な問題により多くの時間を割けるようにする方法を説明します。
- ユースケース 1 - キャンペーン作成を合理化する: Marketo Engage キャンペーンの作成に費やす時間はどれくらいですか?このプロセスは、少なくとも 1 日 2 時間を要するでしょう。また、キャリアレベルによっては、この時間はさらに長くなる可能性が高いです。しかし、このタスクの最悪の部分は、コピーから貼り付けまで、キャンペーンの作成作業の 90%が手動の作業だということです。したがって、このタスクは自動化に最適な候補です。
- ユースケース 2 - 不要なデータ変更を元に戻す: ダーティデータの処理は、マーケティング運用チームにとって悪夢のような作業です。多数の無効な値を含むリストを受け取り、それを事前にクリーンアップせずに読み込んでしまいます。おそらく、忙しすぎて気づかなかったのでしょう。Marketo Engage データベースで結果を確認すると、心臓が飛び出そうになります。心配しないでください。REST API などの効率的な方法を使用して、不正なリストのインポートを素早く修正する方法を紹介します。
- ユースケース 3 - インサイトをセールスアクションに変換する: セールス担当者から次のように尋ねられることはどれくらいあるでしょうか。「なぜこのリードが MQL なのですか?この人はどのようなトピックに興味を持っているのでしょう?」これらの質問に答えるには、アクティビティログを詳しく調べて、人物が MQL として認定された理由を特定する必要があります。以下のデモセクションでは、REST API を使用してこのデータ変換プロセスを自動化する方法を説明します。
さあ、準備はいいですか?これらのビジネスシナリオで REST API をどのように活用しているのか、詳しく説明していきます。
ユースケース 1:キャンペーン作成を合理化する
Marketo Engage は、プロセスの合理化に役立つテンプレートとトークンを使用した、マーケティング業務をスケーリングするための強力なツールです。しかし、現実に目を向けてみましょう。手作業がまだ多く含まれています。マーケティング業務に従事している人は、プログラムの複製、トークンの更新、スマートキャンペーンのアクティブ化にかなりの時間を費やしていることでしょう。
1 週間に管理するキャンペーンの数が少なければ、対処できる場合があります。しかし、数十、あるいは数百ものキャンペーンを扱う場合、すべてを手動で行うことは現実的ではありません。ミスが発生し、キャンペーン間の一貫性を確保することが、真の課題になります。そこで Marketo Engage REST API が役立ちます。繰り返しタスクを自動化することで、時間を節約し、エラーを減らし、すべてのマーケティング活動全体で一貫性を維持できます。
REST API を使用すると、プログラム全体を素早く複製しながら、すべてを構造化して統一できます。最も経験豊富な Marketo Engage の実務担当者でもミスを犯します。自動化によりリスクを最小限に抑え、データの整合性を維持できます。
このプロセスでは、引き続きマーケティングニーズに合わせてキャンペーンをカスタマイズできます。REST API を使用すると、キャンペーン構造の一貫性を維持しながら、トークンなどの主要な要素を変更できます。
以下のデモビデオで、提供されたサンプルコードの使用方法と、組織のニーズに合わせて調整する方法について説明しています。
オフラインで使用するために、ビデオで示されているコードは、以下の「サンプルコード」節から入手できます。
ユースケース 2:不要なデータ変更を元に戻す
次のような状況を想像してみてください。既に仕事に追われているところに、マーケターから Marketo Engage にリードリストをアップロードしてほしいと緊急の依頼が入りました。急いで作業を終えたところ、SDR からデータがすべて間違っているとの連絡が入りました。役職名が間違っており、古いリードが上書きされ、すべてが混乱しています。
これは、マーケティング業務の専門家にとって悪夢のような状況です。これらのエラーを手作業で修正するには、数時間、場合によっては数日かかることもあります。しかし、ご心配なく。Marketo Engage の REST API には、データのためのタイムマシンのようなソリューションがあり、不要な変更を簡単に追跡して元に戻すことができます。
REST API を使用すると、最近のデータ値の変更のログを取り込み、誤った更新を識別し、元の情報をわずか数回の手順で復元できます。手作業でデータの混乱を整理する代わりに、ロールバックプロセスを自動化して、データベースの正確性と信頼性を確保できます。
次のビデオでは、REST API を使用して、不正なデータの読み込みを元に戻し、Marketo Engage インスタンスをクリーンでエラーのない状態に保つ方法について説明しています。
オフラインで使用するために、ビデオで示されているコードは、以下の「サンプルコード」節から入手できます。
ユースケース 3:インサイトをセールスアクションに変換する
セールス部門にとって、コンテキストは最も重要な要素です。特に、リードがマーケティングに適格なリード(MQL)になった理由を理解する場合、その重要性はさらに高まります。しかし、その適格性を判断するためのデータは、エンゲージメント指標の層の中に埋もれ、セールス担当者がその人物のストーリーを独自に組み立てるのに時間がかかってしまうことがよくあります。
そこで自動化が課題解決に役立ちます。Marketo Engage を AI と統合することで、エンゲージメントデータを明確でアクションにつながるインサイトに変換し、セールス部門が本当に重要なこと、つまり成約に注力できるよう支援します。
Marketo Engage REST API を使用すると、最近のエンゲージメントアクティビティを取り込み、生成 AI を通じて処理して簡潔な概要を生成し、その概要を Marketo Engage にプッシュして表示できます。つまり、リードが MQL になった方法を理解するために、セールス担当者が人物のアクティビティログを調べる必要がなくなりました。代わりに、リードのジャーニーに関するシンプルな、AI 生成の説明を入手できます。概要には、顧客が関心を示した製品やサービス、および顧客がブランドで実行した主要なアクションが含まれます。
セールスが Salesforce でこの情報に瞬時にアクセスできるようにすることで、自信を持って会話に取り組み、アウトリーチをパーソナライズし、最終的に、より多くの取引をより迅速に成約させることが可能です。
このユースケースは、リードが MQL に移行したときに REST API を使用することを目的としています。したがって、一度に 1 人のリードに対してのみ実行されます。この方法を大量のリードのバッチに適用する場合は、Bulk API が適しています。
次のビデオで、この設定が実際にどのように機能するのかを見てみましょう。
オフラインで使用するために、ビデオで示されているコードは、以下の「サンプルコード」節から入手できます。
重要ポイント
Marketo Engage REST API を使用してマーケティング業務タスクを合理化する方法については、以上です。
REST API を使用して次の 3 つの強力なユースケースについて説明しました。
- キャンペーンの複製を自動化して手作業を削減し、一貫性を確保する。
- 不要なデータ変更を追跡して元に戻すことで、クリーンアップ作業の時間を短縮する。
- セールス部門に MQL に関するインサイトを即座に提供し、より効果的なフォローアップ会話を可能にする。
これらの自動化技術は、単に時間を節約するだけではありません。正確性を確保し、データの整合性を維持し、マーケティング部門とセールス部門がよりスマートに業務を行うことを可能にします。
REST API を使用すると、多くの可能性が見えてきて圧倒されるかもしれません。そこで、いくつかのヒントを紹介します。
- 小さなことから始める: まず簡単なことから試してみましょう。最初の API 呼び出しを作成し、結果を取得します。この最初の呼び出しで、自分ができることのイメージが膨らんでくるはずです。最初のプログラムを作成する自分を想像してみてください。
- プログラミングを学び、怖がらないこと: コーディングは見た目より簡単です。多くの場合、奇妙な英語を記述するようなものです。私は Python が好みです。オンラインで優れた Python のコースを探して受講し、学ぶことができます。
- コミュニティとつながる: Marketo Engage 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']
templateID=5200
folderName="Active Webinars"
programName="WB-2025-02-20-Test"
eventName="Webinar Test"
eventDate="2025-02-20"
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"]
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']
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)
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)
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
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
不要なデータの変更を元に戻す
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']
sinceDate="2025-04-22T00:00:00-00:00"
field='Job Title'
fieldRest='Title'
listID=299
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
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'])
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
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']
df=pd.merge(df,df1,left_index=True, right_index=True)
df=df.drop(columns=['attributes'])
df=df.drop_duplicates(subset='leadId', keep="first")
df
df.to_excel("dataToCorrect.xlsx")
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'])
インサイトをセールスアクションに変換する
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']
leadid="1007244"
ndays=60
gptAPIKey="Bearer␣
↪sk-proj-ne6OZggjgQhQU6XcG0ocHNPNzBvOOULTkk8a-75Y75rHKS-vyztxPYq0OLaFsnhtGivx9bVUNoT3BlbkFJH
fieldName="MktoPersonNotes"
today = datetime.today()
sinceDate = today - timedelta(days=ndays)
sinceDate = sinceDate.strftime("%Y-%m-%dT00:00:00")
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
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
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
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