サーバーから収集する
サーバー上で、Flipで分析するために必要なデータを収集する方法を紹介します。
1. 関数を定義する
初めに、後のステップで利用する関数を定義します。これらの関数はHTTP APIをベースに作成されています。
- 下のコードを、適当なファイルにコピー&ペーストして下さい。
class Flip {
INGESTION_KEY = "プロジェクトの収集キー"; // プロジェクトの設定画面に表示されている値に変更して下さい
TRACK_ENDPOINT = "https://app.flip.inc/v1/track";
IDENTIFY_ENDPOINT = "https://app.flip.inc/v1/identify";
track({ name, userId, anonymousId, properties, userProperties }) {
this.post(this.TRACK_ENDPOINT, {
name,
originalUserId: userId,
anonymousId,
properties,
userProperties: {
...userProperties,
platform: "server",
},
});
}
identify({ userId, anonymousId, properties }) {
this.post(this.IDENTIFY_ENDPOINT, {
originalUserId: userId,
anonymousId,
properties: {
...properties,
platform: "server",
},
});
}
async post(endpoint, requestBody) {
try {
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...requestBody,
ingestionKey: this.INGESTION_KEY,
}),
});
if (!response.ok) {
const responseBody = await response.json();
console.error(`[Flip] ${response.status} ${responseBody.message}`);
}
} catch (err) {
console.error(`[Flip] ${err.message}`);
}
}
}
class Flip {
INGESTION_KEY = "プロジェクトの収集キー"; // プロジェクトの設定画面に表示されている値に変更して下さい
TRACK_ENDPOINT = "https://app.flip.inc/v1/track";
IDENTIFY_ENDPOINT = "https://app.flip.inc/v1/identify";
track({
name,
userId,
anonymousId,
properties,
userProperties,
}: {
name: string;
userId?: string;
anonymousId?: string;
properties?: Record<string, any>;
userProperties?: Record<string, any>;
}) {
this.post(this.TRACK_ENDPOINT, {
name,
originalUserId: userId,
anonymousId,
properties,
userProperties: {
...userProperties,
platform: "server",
},
});
}
identify({
userId,
anonymousId,
properties,
}: {
userId?: string;
anonymousId?: string;
properties?: Record<string, any>;
}) {
this.post(this.IDENTIFY_ENDPOINT, {
originalUserId: userId,
anonymousId,
properties: {
...properties,
platform: "server",
},
});
}
async post(endpoint: string, requestBody: Record<string, any>) {
try {
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
...requestBody,
ingestionKey: this.INGESTION_KEY,
}),
});
if (!response.ok) {
const responseBody = await response.json();
console.error(`[Flip] ${response.status} ${responseBody.message}`);
}
} catch (err: any) {
console.error(`[Flip] ${err.message}`);
}
}
}
import requests
import json
class Flip:
INGESTION_KEY = "プロジェクトの収集キー" # プロジェクトの設定画面に表示されている値に変更して下さい
TRACK_ENDPOINT = "https://app.flip.inc/v1/track"
IDENTIFY_ENDPOINT = "https://app.flip.inc/v1/identify"
def track(self, name, user_id=None, anonymous_id=None, properties=None, user_properties=None):
if user_properties is None:
user_properties = {}
user_properties["platform"] = "server"
self._post_to_flip(
self.TRACK_ENDPOINT,
{
"name": name,
"originalUserId": user_id,
"anonymousId": anonymous_id,
"properties": properties,
"userProperties": user_properties,
}
)
def identify(self, user_id=None, anonymous_id=None, properties=None):
if properties is None:
properties = {}
properties["platform"] = "server"
self._post_to_flip(
self.IDENTIFY_ENDPOINT,
{
"originalUserId": user_id,
"anonymousId": anonymous_id,
"properties": properties,
}
)
def _post_to_flip(self, endpoint, request_body):
headers = {"Content-Type": "application/json"}
request_body["ingestionKey"] = self.INGESTION_KEY
try:
response = requests.post(endpoint, headers=headers, data=json.dumps(request_body))
response.raise_for_status()
except requests.HTTPError as e:
print(f"[Flip] {response.status_code} {response.json().get('message', '')}")
except Exception as e:
print(f"[Flip] {e}")
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
const (
ingestionKey = "プロジェクトの収集キー" // プロジェクトの設定画面に表示されている値に変更して下さい
trackEndpoint = "https://app.flip.inc/v1/track"
identifyEndpoint = "https://app.flip.inc/v1/identify"
)
type TrackParams struct {
Name string `json:"name"`
UserId *string `json:"userId,omitempty"`
AnonymousId *string `json:"anonymousId,omitempty"`
Properties map[string]interface{} `json:"properties,omitempty"`
UserProperties map[string]interface{} `json:"userProperties,omitempty"`
}
type IdentifyParams struct {
UserId *string `json:"userId,omitempty"`
AnonymousId *string `json:"anonymousId,omitempty"`
Properties map[string]interface{} `json:"properties,omitempty"`
}
func getStringPointer(s string) *string {
return &s
}
func postToFlip(endpoint string, requestBody map[string]interface{}) {
requestBody["ingestionKey"] = ingestionKey
data, err := json.Marshal(requestBody)
if err != nil {
fmt.Printf("[Flip] %s\n", err)
return
}
req, err := http.NewRequest("POST", endpoint, bytes.NewBuffer(data))
if err != nil {
fmt.Printf("[Flip] %s\n", err)
return
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("[Flip] %s\n", err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("[Flip] %s\n", err)
return
}
var responseBody map[string]interface{}
err = json.Unmarshal(body, &responseBody)
if err != nil {
fmt.Printf("[Flip] %s\n", err)
return
}
message, ok := responseBody["message"].(string)
if !ok {
message = "Error message cannot be parsed as string"
}
fmt.Printf("[Flip] %d %s\n", resp.StatusCode, message)
}
}
func Track(params TrackParams) {
body := map[string]interface{}{
"name": params.Name,
"originalUserId": params.UserId,
"anonymousId": params.AnonymousId,
"properties": params.Properties,
"userProperties": params.UserProperties,
}
if body["userProperties"] == nil {
body["userProperties"] = make(map[string]interface{})
}
body["userProperties"].(map[string]interface{})["platform"] = "server"
postToFlip(trackEndpoint, body)
}
func Identify(params IdentifyParams) {
body := map[string]interface{}{
"originalUserId": params.UserId,
"anonymousId": params.AnonymousId,
"properties": params.Properties,
}
if body["properties"] == nil {
body["properties"] = make(map[string]interface{})
}
body["properties"].(map[string]interface{})["platform"] = "server"
postToFlip(identifyEndpoint, body)
}
require 'net/http'
require 'json'
require 'uri'
module Flip
INGESTION_KEY = "プロジェクトの収集キー" # プロジェクトの設定画面に表示されている値に変更して下さい
TRACK_ENDPOINT = "https://app.flip.inc/v1/track"
IDENTIFY_ENDPOINT = "https://app.flip.inc/v1/identify"
class << self
def track(name:, user_id: nil, anonymous_id: nil, properties: nil, user_properties: nil)
user_properties ||= {}
user_properties[:platform] = "server"
post_to_flip(TRACK_ENDPOINT, {
name: name,
originalUserId: user_id,
anonymousId: anonymous_id,
properties: properties,
userProperties: user_properties
})
end
def identify(user_id: nil, anonymous_id: nil, properties: nil)
properties ||= {}
properties[:platform] = "server"
post_to_flip(IDENTIFY_ENDPOINT, {
originalUserId: user_id,
anonymousId: anonymous_id,
properties: properties
})
end
private
def post_to_flip(endpoint, request_body)
request_body[:ingestionKey] = INGESTION_KEY
uri = URI.parse(endpoint)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme == 'https'
headers = {
'Content-Type' => 'application/json'
}
request = Net::HTTP::Post.new(uri.path, headers)
request.body = JSON.generate(request_body)
begin
response = http.request(request)
if response.code.to_i != 200
response_body = JSON.parse(response.body)
puts "[Flip] #{response.code} #{response_body['message']}"
end
rescue => err
puts "[Flip] #{err}"
end
end
end
end
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.OutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.json.JSONObject;
public class Flip {
private static final String INGESTION_KEY = "プロジェクトの収集キー"; // プロジェクトの設定画面に表示されている値に変更して下さい
private static final String TRACK_ENDPOINT = "https://app.flip.inc/v1/track";
private static final String IDENTIFY_ENDPOINT = "https://app.flip.inc/v1/identify";
public static void track(
String name,
String userId,
String anonymousId,
JSONObject properties,
JSONObject userProperties
) {
JSONObject requestBody = new JSONObject();
requestBody.put("name", name);
requestBody.put("originalUserId", userId);
requestBody.put("anonymousId", anonymousId);
requestBody.put("properties", properties);
if (userProperties == null) {
userProperties = new JSONObject();
}
userProperties.put("platform", "server");
requestBody.put("userProperties", userProperties);
post(TRACK_ENDPOINT, requestBody);
}
public static void identify(
String userId,
String anonymousId,
JSONObject properties
) {
JSONObject requestBody = new JSONObject();
requestBody.put("originalUserId", userId);
requestBody.put("anonymousId", anonymousId);
requestBody.put("properties", properties);
if (properties == null) {
properties = new JSONObject();
}
properties.put("platform", "server");
requestBody.put("properties", properties);
post(IDENTIFY_ENDPOINT, requestBody);
}
private static void post(String endpoint, JSONObject requestBody) {
try {
requestBody.put("ingestionKey", INGESTION_KEY);
URL url = new URL(endpoint);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
connection.setDoOutput(true);
try (OutputStream os = connection.getOutputStream()) {
byte[] input = requestBody.toString().getBytes("utf-8");
os.write(input, 0, input.length);
}
int responseCode = connection.getResponseCode();
if (responseCode != HttpURLConnection.HTTP_OK) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getErrorStream(), "utf-8"))) {
StringBuilder response = new StringBuilder();
String responseLine;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
JSONObject jsonResponse = new JSONObject(response.toString());
System.err.println("[Flip] " + responseCode + " " + jsonResponse.getString("message"));
}
}
connection.disconnect();
} catch (Exception e) {
System.err.println("[Flip] " + e.getMessage());
}
}
}
class Flip {
private const INGESTION_KEY = "プロジェクトの収集キー"; // プロジェクトの設定画面に表示されている値に変更して下さい
private const TRACK_ENDPOINT = "https://app.flip.inc/v1/track";
private const IDENTIFY_ENDPOINT = "https://app.flip.inc/v1/identify";
public function track($data) {
$defaults = [
'name' => '',
'userId' => null,
'anonymousId' => null,
'properties' => [],
'userProperties' => [],
];
$data = array_merge($defaults, $data);
$this->post(self::TRACK_ENDPOINT, [
'name' => $data['name'],
'originalUserId' => $data['userId'],
'anonymousId' => $data['anonymousId'],
'properties' => $data['properties'],
'userProperties' => array_merge($data['userProperties'], ['platform' => 'server']),
]);
}
public function identify($data) {
$defaults = [
'userId' => null,
'anonymousId' => null,
'properties' => [],
];
$data = array_merge($defaults, $data);
$this->post(self::IDENTIFY_ENDPOINT, [
'originalUserId' => $data['userId'],
'anonymousId' => $data['anonymousId'],
'properties' => array_merge($data['properties'], ['platform' => 'server']),
]);
}
private function post($endpoint, $requestBody) {
$requestBody['ingestionKey'] = self::INGESTION_KEY;
$body = json_encode($requestBody);
$opts = [
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $body,
],
];
$context = stream_context_create($opts);
$result = @file_get_contents($endpoint, false, $context);
if ($result === false) {
$error = error_get_last();
echo "[Flip] " . $error['message'];
}
}
}
2. イベントを収集する
イベントを収集することで、ユーザーの一つ一つの操作を記録できるようになります。各引数の具体的な役割に関しては、HTTP APIを参考にして下さい。
- ユーザーが特定の操作を実行した直後(例. 機能を利用)に、次のコードが呼ばれるようにペーストして下さい。コードの内容は自由に変更して構いません。
const flip = new Flip();
flip.track({
name: "message_sent",
userId: "usr_GXfryD0JQivyGa97TgGsT",
properties: {
message_type: "画像付きテキスト",
character_count: 32,
},
userProperties: {
email: "[email protected]",
name: "Tanaka Masaki",
position: "プロダクトマネージャー",
},
});
flip = Flip()
flip.track(
name="message_sent",
user_id="usr_GXfryD0JQivyGa97TgGsT",
properties={
"message_type": "画像付きテキスト",
"character_count": 32,
},
user_properties={
"email": "[email protected]",
"name": "Tanaka Masaki",
"position": "プロダクトマネージャー",
},
)
trackParams := TrackParams{
Name: "message_sent",
UserId: getStringPointer("usr_GXfryD0JQivyGa97TgGsT"),
Properties: map[string]interface{}{
"message_type": "画像付きテキスト",
"character_count": 32,
},
UserProperties: map[string]interface{}{
"email": "[email protected]",
"name": "Tanaka Masaki",
"position": "プロダクトマネージャー",
},
}
Track(trackParams)
Flip.track(
name: "message_sent",
user_id: "usr_GXfryD0JQivyGa97TgGsT",
properties: {
message_type: "画像付きテキスト",
character_count: 32
},
user_properties: {
email: "[email protected]",
name: "Tanaka Masaki",
position: "プロダクトマネージャー"
}
)
JSONObject properties = new JSONObject();
properties.put("message_type", "画像付きテキスト");
properties.put("character_count", 32);
JSONObject userProperties = new JSONObject();
userProperties.put("email", "[email protected]");
userProperties.put("name", "Tanaka Masaki");
userProperties.put("position", "プロダクトマネージャー");
Flip.track(
"message_sent",
"usr_GXfryD0JQivyGa97TgGsT",
null,
properties,
userProperties
);
$flip = new Flip();
$flip->track([
"name" => "message_sent",
"userId" => "usr_GXfryD0JQivyGa97TgGsT",
"properties" => [
"message_type" => "画像付きテキスト",
"character_count" => 32
],
"userProperties" => [
"email" => "[email protected]",
"name" => "Tanaka Masaki",
"position" => "プロダクトマネージャー"
]
]);
3. ユーザー情報を更新する
下のコードを追加することで、イベントを収集することなく、特定のユーザーの情報を更新できます。各引数の具体的な役割に関しては、HTTP APIを参考にして下さい。
- ユーザーの情報が変更された直後(例. 新規登録・オンボーディング)に、次のコードが呼ばれるように下のコードをペーストして下さい。コードの内容は自由に変更して構いません。
const flip = new Flip();
flip.identify({
userId: "usr_GXfryD0JQivyGa97TgGsT",
properties: {
email: "[email protected]",
name: "Tanaka Masaki",
position: "プロダクトマネージャー",
},
});
flip = Flip()
flip.identify(
user_id="usr_GXfryD0JQivyGa97TgGsT",
properties={
"email": "[email protected]",
"name": "Tanaka Masaki",
"position": "プロダクトマネージャー",
}
)
identifyParams := IdentifyParams{
UserId: getStringPointer("usr_GXfryD0JQivyGa97TgGsT"),
Properties: map[string]interface{}{
"email": "[email protected]",
"name": "Tanaka Masaki",
"position": "プロダクトマネージャー",
},
}
Identify(identifyParams)
Flip.identify(
user_id: "usr_GXfryD0JQivyGa97TgGsT",
properties: {
email: "[email protected]",
name: "Tanaka Masaki",
position: "プロダクトマネージャー"
}
)
JSONObject properties = new JSONObject();
properties.put("email", "[email protected]");
properties.put("name", "Tanaka Masaki");
properties.put("position", "プロダクトマネージャー");
Flip.identify(
"usr_GXfryD0JQivyGa97TgGsT",
null,
userProperties
);
$flip = new Flip();
$flip->identify([
"userId" => "usr_GXfryD0JQivyGa97TgGsT",
"properties" => [
"email" => "[email protected]",
"name" => "Tanaka Masaki",
"position" => "プロダクトマネージャー"
]
]);
Updated about 2 months ago