본문으로 건너뛰기

Unity 메시지 푸시 연동 문서

최근 업데이트 2026. 10. 07.

1. FCM 푸시​

1.1 "푸시 ID" 전송​

  • AE Login을 호출하거나 계정을 전환한 후 FCM의 Token을 업로드합니다.
//AE SDK 초기화
TDAnalytics.Init("APPID", "SERVER");
//계정 ID 설정
TDAnalytics.Login("ACCOUNT_ID");
//FCM token을 AE 시스템에 전송
Firebase.Messaging.FirebaseMessaging.GetTokenAsync().ContinueWith(task => {
var result = task.Result;
//메인 스레드로 전환하여 전송해야 합니다. UnityMainThreadDispatcher는 부록을 참고하십시오
UnityMainThreadDispatcher.Instance.Enqueue(() =>
{
//FCM token을 AE 시스템에 전송
TDAnalytics.UserSet(new Dictionary<string, object>() {
{ "fcm_token", task.Result }
});
});
});
  • FCM Token이 변경되면 유저 속성을 업데이트합니다:
private void Start()
{
// FCM Token 업데이트 델리게이트 이벤트 등록
Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
}

public void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token)
{
//FCM token을 AE 시스템에 전송
TDAnalytics.UserSet(new Dictionary<string, object>() {
{ "fcm_token", token.Token }
});
}

1.2 푸시 클릭 이벤트 수집​

유저가 알림을 클릭할 때 푸시 클릭 이벤트를 업로드합니다. FCM의 OnMessageReceived 콜백에서 푸시 파라미터를 가져올 수 있습니다.

private void Start()
{
// FCM 메시지 델리게이트 이벤트 등록
Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
}

public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)
{
// 푸시 이벤트 전송(TETrackMessageReceived는 부록 참고)
if (e.Message.Data.ContainsKey("te_extras"))
{
this.TETrackMessageReceived(e.Message.Data);
}
}

1.3 푸시 메시지 처리​

다음 두 가지 방식 중 하나를 선택할 것을 권장합니다.

  • 일반 파라미터: TEHandlePushAction 메서드를 호출합니다.
  • 패스스루 파라미터: TEHandlePassThroughAction 메서드를 호출합니다.
private void Start()
{
// FCM 메시지 델리게이트 이벤트 등록
Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
}

public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)
{
//일반 파라미터를 처리하는 경우 다음 메서드를 호출(TEHandlePushAction은 부록 참고)
this.TEHandlePushAction(e.Message.Data);
//패스스루 파라미터를 처리하는 경우 다음 메서드를 호출
this.TEHandlePassThroughAction(e.Message.Data);
}

2. JPush 푸시​

팁

JPush 공식 사이트에서는 아직 Unity 플러그인을 제공하지 않으므로 JPush에서 관리하는 오픈 소스 플러그인 JPush Unity Plugin을 참고할 수 있습니다. 아래 내용은 모두 JPush Unity Plugin을 기반으로 구현했습니다.

2.1 "푸시 ID" 전송​

  • AE Login을 호출하거나 계정을 전환한 후 JPush의 Registration ID를 업로드합니다.
//AE SDK 초기화
TDAnalytics.Init("APPID", "SERVER");
//계정 ID 설정
TDAnalytics.Login("ACCOUNT_ID");
//JPush Registration ID를 AE 시스템에 전송
string jiguangId = JPushBinding.GetRegistrationId();
TDAnalytics.UserSet(new Dictionary<string, object>() {
{ "jiguang_id", jiguangId }
});
  • JPush의 OnGetRegistrationId 인터페이스에서 JPush의 Registration ID를 업로드합니다.
void OnGetRegistrationId(string result)
{
//JPush Registration ID를 AE 시스템에 전송
TDAnalytics.UserSet(new Dictionary<string, object>() {
{ "jiguang_id", result }
});
}

2.2 푸시 클릭 이벤트 수집​

void OnOpenNotification(string jsonStr)
{
IDictionary<string, object> json = ThinkingData.Analytics.Utils.TDMiniJson.Deserialize(jsonStr);
if (json.ContainsKey("te_extras"))
{
object v = json["te_extras"];
this.TETrackMessageReceived((IDictionary<string, string>)v);
}
}

2.3 푸시 메시지 처리​

다음 두 가지 방식 중 하나를 선택할 것을 권장합니다.

  • 일반 파라미터: TEHandlePushAction 메서드를 호출합니다.
  • 패스스루 파라미터: TEHandlePassThroughAction 메서드를 호출합니다.
void OnOpenNotification(string jsonStr)
{
Debug.Log("recv---openNotification---" + jsonStr);
IDictionary<string, object> json = ThinkingData.Analytics.Utils.TDMiniJson.Deserialize(jsonStr);
if (json.ContainsKey("extras"))
{
object v = json["extras"];
//일반 파라미터를 처리하는 경우 다음 메서드를 호출
this.TEHandlePushAction((IDictionary<string, string>)v);
//패스스루 파라미터를 처리하는 경우 다음 메서드를 호출
this.TEHandlePassThroughAction((IDictionary<string, string>)v);
}
}

부록​

클라이언트가 수신하는 푸시 파라미터 예시​

다음은 클라이언트가 수신하는 확장 필드 파라미터만 보여 줍니다

{
"te_extras": {
//푸시 클릭 시 이동 방식
"ops_loading_type": "OPEN_APP",
//패스스루 파라미터
"passthrough_params": {
"param1": "abc",
"param2": 101,
"param3": [{
"subText1": "xyz",
"subText2": 2
}]
},
//AE 운영 채널 회신 속성
"#ops_receipt_properties": {
"ops_task_id": "0082",
"ops_project_id": 1,
"ops_task_instance_id": "0082_20230331",
"ops_push_language": "default",
"ops_task_exec_detail_id": "55"
}
}
}

TETrackMessageReceived​

private void TETrackMessageReceived(IDictionary<string, string> data)
{
//FCM message 이벤트를 AE 시스템에 전송
Dictionary<string, object> te_extras = ThinkingData.Analytics.Utils.TDMiniJson.Deserialize(data["te_extras"]);
Dictionary<string, object> properties = new Dictionary<string, object>();
if (te_extras.ContainsKey("#ops_receipt_properties"))
{
properties.Add("#ops_receipt_properties", te_extras["#ops_receipt_properties"]);
}
TDAnalytics.Track("te_ops_push_click", properties);
TDAnalytics.Flush();
}

TEHandlePushAction​

private void TEHandlePushAction(IDictionary<string, string> data)
{
Dictionary<string, object> te_extras = ThinkingData.Analytics.Utils.TDMiniJson.Deserialize(data["te_extras"]);
string type = te_extras["ops_loading_type"].ToString();
if ("OPEN_APP".Equals(type))
{
// App 열기 메시지 처리, --> App을 실행하십시오
}
else if ("OPEN_URL".Equals(type))
{
string url = te_extras["ops_url"].ToString();
if (!string.IsNullOrEmpty(url))
{
// URL 열기 메시지 처리, --> URL을 처리하십시오
}
}
else if ("CUSTOMIZED".Equals(type))
{
string custom = te_extras["ops_customized"].ToString();
if (!string.IsNullOrEmpty(custom))
{
// 커스텀 메시지 처리, --> 커스텀 메시지를 처리하십시오
}
}
}

TEHandlePassThroughAction​

private void TEHandlePassThroughAction(IDictionary<string, string> data)
{
Dictionary<string, object> te_extras = ThinkingData.Analytics.Utils.TDMiniJson.Deserialize(data["te_extras"]);
string passThroughParams = te_extras["passthrough_params"].ToString();
//passThroughParams는 패스스루 파라미터이며, 이어서 구체적인 비즈니스 로직을 구현합니다
}

UnityMainThreadDispatcher​

public class UnityMainThreadDispatcher : MonoBehaviour
{
private static readonly Queue<Action> _executionQueue = new Queue<Action>();

public static UnityMainThreadDispatcher Instance { get; private set; }

private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(this.gameObject);
}
else
{
Destroy(gameObject);
}
}

public void Update()
{
lock (_executionQueue)
{
while (_executionQueue.Count > 0)
{
_executionQueue.Dequeue().Invoke();
}
}
}

public void Enqueue(IEnumerator action)
{
lock (_executionQueue)
{
_executionQueue.Enqueue(() => { StartCoroutine(action); });
}
}

public void Enqueue(Action action)
{
Enqueue(ActionWrapper(action));
}

IEnumerator ActionWrapper(Action a)
{
a();
yield return null;
}
}
이 문서가 도움이 되었나요?