8 分

Marketo Engage REST API を使用してマーケティング業務タスクを自動化する方法について解説します。この記事では、キャンペーンの作成の効率化、不要なデータ変更の取り消し、エンゲージメントインサイトの実用的なセールスアクションへの変換など、Marketo Engage 管理者の一般的なユースケースについて説明します。

応用数学と計算数学のバックラウンドを持つ私は、Marketo Engage の多くの実践者とは一線を画していると自負しています。マーケティング業務の仕事を始めたときに、自動化できる仕事が多いことに気がつきました。 自動化によって、仕事の効率を上げ、キャリアの成長を早めることができます。 API を活用して日々の業務を自動化することで、業務に埋もれることなく、より戦略的な課題に集中できます。

この記事では、Marketo Engage REST API の使用方法について説明し、私が気に入っている 3 つのユースケースを紹介して、その機能を示します。REST API を利用して Marketo Engage の効率性を高め、戦略的な問題により多くの時間を割けるようにする方法を説明します。

さあ、準備はいいですか?これらのビジネスシナリオで 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 インスタンスをクリーンでエラーのない状態に保つ方法について説明しています。
NOTE
この方法は、データのリバージョンの単純なケースにのみ対応できます。考慮すべき変更が多数ある場合は、戻す適切な値を選択するために、より高度なロジックが必要になります。
オフラインで使用するために、ビデオで示されているコードは、以下の「サンプルコード」節から入手できます。

ユースケース 3:インサイトをセールスアクションに変換する

セールス部門にとって、コンテキストは最も重要な要素です。特に、リードがマーケティングに適格なリード(MQL)になった理由を理解する場合、その重要性はさらに高まります。しかし、その適格性を判断するためのデータは、エンゲージメント指標の層の中に埋もれ、セールス担当者がその人物のストーリーを独自に組み立てるのに時間がかかってしまうことがよくあります。

そこで自動化が課題解決に役立ちます。Marketo Engage を AI と統合することで、エンゲージメントデータを明確でアクションにつながるインサイトに変換し、セールス部門が本当に重要なこと、つまり成約に注力できるよう支援します。

Marketo Engage REST API を使用すると、最近のエンゲージメントアクティビティを取り込み、生成 AI を通じて処理して簡潔な概要を生成し、その概要を Marketo Engage にプッシュして表示できます。つまり、リードが MQL になった方法を理解するために、セールス担当者が人物のアクティビティログを調べる必要がなくなりました。代わりに、リードのジャーニーに関するシンプルな、AI 生成の説明を入手できます。概要には、顧客が関心を示した製品やサービス、および顧客がブランドで実行した主要なアクションが含まれます。

セールスが Salesforce でこの情報に瞬時にアクセスできるようにすることで、自信を持って会話に取り組み、アウトリーチをパーソナライズし、最終的に、より多くの取引をより迅速に成約させることが可能です。

このユースケースは、リードが MQL に移行したときに REST API を使用することを目的としています。したがって、一度に 1 人のリードに対してのみ実行されます。この方法を大量のリードのバッチに適用する場合は、Bulk API が適しています。

次のビデオで、この設定が実際にどのように機能するのかを見てみましょう。
IMPORTANT
個人のデータを大規模言語モデル(LLM)に送信する前に、組織の適切なコンプライアンスリソースに問い合わせて、関連する法律や規制に準拠していることを確認します。
オフラインで使用するために、ビデオで示されているコードは、以下の「サンプルコード」節から入手できます。

重要ポイント

Marketo Engage REST API を使用してマーケティング業務タスクを合理化する方法については、以上です。

REST API を使用して次の 3 つの強力なユースケースについて説明しました。

  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