Chat Webhooks

Use webhooks with Photon Cloud to have more control over your chat applications.
You can persist channel history, filter messages, cancel channel creation and even prohibit certain players from subscribing to chat channels.

Photon Chat webhooks are event-driven HTTP POST requests sent by Photon Cloud to specific URLs.
Each Photon Chat webhook is defined by its own triggers, data and destination path.

Setup

Basic Settings

  • BaseUrl (required)
    The URL for the service hosting your hooks.
    It must not end with a forward slash.
    Callbacks are received at the relative path URIs of the configured hooks.
    Read this if the value you want to configure will contain a query string.
  • CustomHttpHeaders
    JSON string of key/value pairs (string:string) that should be set as HTTP headers in any request made to the configured web service.
    Read more here.

Paths

Configure each path to receive events at the URIs each identifies on your host.
Any path that is left empty will not be hit, you will not receive any callbacks on the affected webhook.
Read this if the value you want to configure will contain a query string.

  • PathChannelCreate
    Called when a new channel is created or when its state needs to be loaded from external service.
  • PathChannelDestroy
    Called when a channel is removed from Photon servers memory.
    If IsPersistent is set to true the channel state is sent.
  • PathChannelSubscribe
    Called when a player subscribes to an already created channel.
  • PathChannelUnsubscribe
    Called when a player unsubscribes from a channel.
  • PathPublishMessage
    Called when the client publishes a message in a channel or sends a private message.
    The client should explicitly choose to HTTP forward the message as a webhook.

Options

Fine-tune the behaviour of your chat webhooks configuration with these options.
An option is considered not configured when not set up or if its value is left empty.

  • FailIfUnavailable
    If set to true, channel creation, subscription and publish message operations will fail when the corresponding hook's configured endpoint is not available.
    An endpoint is considered unavailable when an error occurs during the process of its HTTP request or when the HTTP response is not successful.
    Default is false.
  • IsPersistent
    If set to true, Photon Cloud sends the channel state before destroying it.
    This option is only valid when both PathChannelCreate and PathChannelDestory are properly configured and MaxChannelHistory is greater than 0.
    For more information please read more about ChannelCreate and ChannelDestroy webhooks.
    Default is false.
  • MaxChannelHistory
    Maximum number of messages to be persisted per channel.
    It should be between 1 and 100.
    Default is 100.
  • HasErrorInfo
    If set to true, Chat clients will be notified with an error message when a hook endpoint (PathUnsubscribe or PathChannelDestory excluded) is unavailable but FailIfUnavailable is set to false.
    Default is false.
  • SkipPostCreationFailure
    If set to true, PathUnsubscribe and PathChannelDestory webhooks will not be sent after a channel creation failure.
    Default is false.

クエリ文字列の処理

クエリ文字列パラメータはベースURLまたはパスに含まれています。これを使用する場合は、以下の事柄について理解しておいてください。

  • クエリ文字列パラメータはUTF8エンコードで解析されます。
  • 同じクエリ文字列パラメータの複数同時発生が、同一の設定内で見られる場合は、カンマで各値を区切りながら単一のパラメータが使用されます。
    カンマは%2cを使用してエスケープされます。
  • ベースURLと設定済みのパスで同じパラメータキーが使用されている場合、パス設定の値が使用されます。
  • 値のないパラメータは認められています。
  • キーのないパラメータは認められています。
    キーは空の文字列とみなされます。
    ベースURLと設定済パスの両方でキーが足りないパラメータが見つかった場合、設定済パスのもののみが使用されます。
  • クエリ文字列パラメータはURLエンコードとなります。
  • クエリ文字列パラメータ内でURLタグを使用できます。

例:

  • 設定:

    • ベースURL:
      https://myawesomegame.com/chat/webhooks?clientver={AppVersion}&key=&keyA=valueA&keyA=valueB&keyB=valueB&=value
    • PathChannelCreate: create?key=X&keyA=valueC
    • PathChannelDestroy: destroy?keyB=valueC&keyC=valueC&=valueD&=valueE
  • 生じるURL:

    • PathChannelCreate:
      https://myawesomegame.com/chat/webhooks/create?clientver=1.0&key=X&keyA=valueC&keyB=valueB&=value
    • PathChannelDestroy:
      https://myawesomegame.com/chat/webhooks/destroy?clientver=1.1&key=&keyA=valueA%2cvalueB&keyB=valueC&keyC=valueC&=valueD%2cvalueE

HTTP Headers Considerations

カスタムHTTPヘッダーの使用にあたり、いくつかの留意事項があります:

  • CustomHttpHeaders設定キーの値は、文字列に変更された、文字列以外を含まないプロパティのJSONオブジェクトである必要があります。JSONオブジェクトのプロパティ名は、HTTPリクエストヘッダフィールド名として使用され、プロパティの値はリクエストヘッダーのそれぞれの値として使用されます。
    例:

    • CustomHttpHeaders 値:

      {'X-Secret': 'YWxhZGRpbjpvcGVuc2VzYW1l', 'X-Origin': 'Photon'}
      
    • Webhooks HTTP リクエストヘッダー:

      X-Secret: YWxhZGRpbjpvcGVuc2VzYW1l
      X-Origin: Photon
      
  • カスタムHTTPヘッダーフィールド名は大文字と小文字を区別します。

  • 次のHTTPヘッダーは制限されており、"CustomHttpHeaders"設定値から設定された場合、無視されます。

    • Connection
    • Content-Length
    • Host
    • Range
    • Proxy-Connection
  • Accept
  • Content-Type
  • Date
  • Expect
  • If-Modified-Since
  • Referer
  • Transfer-Encoding
  • User-Agent

URLタグ

ダッシュボードからwebhookまたはWebRpcのベースURLを設定する場合、必要に応じて、クエリ文字列の一部として1つ以上の動的変数 を設定することができます。
これらの変数は、リクエストを送信する前に、バックエンドでそれぞれの値に置き換えられます。

それぞれのアプリケーションのユーザー・セグメントを個別に処理したい場合は、URLのタグを使用します。
Photonは、次のURLのタグに対応しています:

  • {AppVersion} クライアントによって設定されたアプリケーションのバージョンを渡します。
  • {AppId} アプリケーションのIDを渡します。
  • {Region} トリガークライアントが接続されているクラウドリージョンのトークンを渡します。例:"eu"
  • {Cloud} は、トリガークライアントが接続されているクラウドの名前を渡します。例:「public」または「enigmaticenterprise」

URLタグの例

  1. https://{Region}.mydomain.com/{AppId}?version={AppVersion}&cloud={Cloud} 例:パラメータとして渡される異なるホスト、バージョン、およびクラウドに各リージョンをルート。
  2. https://mydomain.com/{Cloud}/{Region}/{AppId}/{AppVersion} 構造化されたURIとしてすべてのタグを渡します。

Common Request Arguments

AppId:
AppId of your application as set from the game client and found in the dashboard.

AppVersion:
Version of your application as set from the game client.

Region:
Has the region to which the game client is connected to and to which the room in question belongs to.

ChannelType:
The channel type: "Public" for public channels and "Private" for private channels.

UserId:
UserID of the player triggering the hook. (Except ChannelDestory)

HistoryCount:
The current count of messages in the channel history. (Except ChannelDestory)

ChannelName:
The name of the channel in which the hook is triggered. (Only public channels)

UsersPair:
Array of two strings containing the UserIDs of the two ends of the private channel. (Only private channels)

Request Arguments List

This table gives you what arguments are available for each webhook for public channels:

Argument ChannelCreate /
ChannelSubscribe
ChannelDestroy PublishMessage ChannelUnsubscribe
AppId
AppVersion
Region
ChannelType ("Public")
ChannelName
HistoryLen
HistoryCount
UserId
ChannelState (conditions apply)
Message

For private channels, there is a single webhook PublishMessage with the following arguments:

  • AppId
  • AppVersion
  • Region
  • ChannelType (set to "Private")
  • UsersPair
  • HistoryCount
  • UserId

Paths in Details

ChannelCreate

This webhook is sent when a channel is about to be created on Photon servers.
If you have a previously saved the ChannelState, you need to return it in the webhooks response to load its history.
See "Return Values" for an example.

Specific Arguments

HistoryLen:
It forwards the parameter with same name set by client in subscribe operation.
It contains the number of messages from the history requested by the client.

Sample Call

text

{
   "AppId":"00000000-0000-0000-0000-000000000000",
   "AppVersion":"1.0",
   "Region":"EU",
   "ChannelType":"Public",
   "ChannelName":"PersistentChannel",
   "HistoryLen":10,
   "UserId":"testClient1"
}

ChannelDestroy

This webhook is sent when a channel is about to be destroyed on Photon servers.
This happens when an empty channel times out.
A channel is considered empty when it does not contain any subscriber, because they left.
Default empty channel timeout value is 5 seconds.
If IsPersistent is set to true and PathChannelDestory is configured properly,
ChannelState will be sent in the webhook body.
In the ChannelState, the History object is just for debugging purposes. You may discard it.
Photon servers use the BinaryHistory to persist data types.
You should save it as is if you want to load channel history later.

Specific Arguments

ChannelState:
A serializable channel state.

Sample Call

text

{
   "AppId":"00000000-0000-0000-0000-000000000000",
   "AppVersion":"1.0",
   "Region":"EU",
   "ChannelType":"Public",
   "ChannelName":"PersistentChannel",
   "HistoryCount":2,
   "ChannelState":{
      "ChannelHistoryCapacity":100,
      "BinaryHistory": "RGl6AAEAAAAAAAN6AANp..",
      "History":{
         "MessageIdBase":2,
         "Entries":[
            {
               "Message":"msg1",
               "Sender":"testClient1",
               "MsgId":1
            },
            {
               "Message":"msg2",
               "Sender":"testClient2",
               "MsgId":2
            }
         ]
      }
   }
}

ChannelSubscribe

This webhook is triggered by client subscription to an already created channel.
The client is either:

  • not the first subscriber. This should be the most frequent case.
  • the first subscriber when the channel is empty and did not time out. This is unlikely because it is a small window.

Specific Arguments

HistoryLen:
It forwards the parameter with same name set by client in subscribe operation.
It contains the number of messages from the history requested by the client.

Sample Call

text

{
   "AppId":"00000000-0000-0000-0000-000000000000",
   "AppVersion":"1.0",
   "Region":"EU",
   "ChannelType":"Public",
   "ChannelName":"PersistentChannel",
   "HistoryLen":-1,
   "HistoryCount": 1,
   "UserId":"testClient2"
}

ChannelUnsubscribe

This webhook is triggered when a client disconnects from a channel, which can be caused by any of the following reasons:

  • explicit call to unsubscribe operation.
  • explicit disconnection.
  • timeout disconnection.
  • channel creation failure and SkipPostCreationFailure is set to false.
  • subscription failure.

Specific Arguments

ChannelUnsubscribe has no extra arguments.

Sample Call

text

{
   "AppId":"00000000-0000-0000-0000-000000000000",
   "AppVersion":"1.0",
   "Region":"EU",
   "ChannelType":"Public",
   "ChannelName":"PersistentChannel",
   "HistoryCount":2,
   "UserId":"testClient2"
}

PublishMessage

This webhook is triggered when a client publishes a message into the channel or sends a private message to a user.
The client should explicitly choose to HTTP forward the message as a webhook using the appropriate WebFlag.
If you want to replace the message to be published you can return the new one in Data parameter.
The value of the returned webhook response's Data property will be published inside the channel instead of the original message content sent by the client.
See "Return Values" for an example.

You can choose any type of data as long as it is supported by Photon serialization.
One use case for this could be data polling from the web server.
Also making use of the Data return parameter may result in a behavior that could be compared to Photon Realtime's WebRPC.

Specific Arguments

Message: Message to be published to all subscribers of the channel. Forwarded as sent from client.

Public Channel: Sample Call

text

{
   "AppId":"00000000-0000-0000-0000-000000000000",
   "AppVersion":"1.0",
   "Region":"EU",
   "ChannelType":"Public",
   "ChannelName":"PersistentChannel",
   "HistoryCount":1,
   "UserId":"testClient2",
   "Message":"msg2"
}

Private Channel: Sample Call

text

{
   "AppId":"00000000-0000-0000-0000-000000000000",
   "AppVersion":"1.0",
   "Region":"EU",
   "ChannelType":"Private",
   "UsersPair":["testClient1", "testClient2"],
   "HistoryCount":1,
   "UserId":"testClient2",
   "Message":"msg2"
}

Return Values

All webhooks expect a JSON object containing a ResultCode which can be:

  • 0 for success.

Sample Success Response

text

{
   "ResultCode":0,
   "DebugMessage":"OK"
}
  • any other integer for failure.

Sample Failure Response

text

{
   "ResultCode":1,
   "DebugMessage":"A nice self-explanatory error message"
}

"PublishMessage" webhook supports an extra property from the web server which is Data.

Sample "Full" PublishMessage Response

text

{
   "ResultCode":0,
   "DebugMessage":"Message Will Be Overridden By Server",
   "Data": "Anything you want and supported by Photon Serialization"
}

"ChannelCreate" webhook supports an extra property from web server which is the ChannelState.

Sample "Full" ChannelCreate Response

text

{
   "ResultCode":0,
   "DebugMessage":"ChannelState Loaded Successfully",
   "ChannelState":{
      "ChannelHistoryCapacity":100,
      "BinaryHistory": "RGl6AAEAAAAAAAN6AANp..",
      "History":{
         "MessageIdBase":2,
         "Entries":[
            {
               "Message":"msg1",
               "Sender":"testClient1",
               "MsgId":1
            },
            {
               "Message":"msg2",
               "Sender":"testClient2",
               "MsgId":2
            }
         ]
      }
   }
}

Since "History" is not required for loading the state as it's useful for debugging, you may discard it when saving the state or when loading it.

Sample "Stripped" ChannelCreate Response

text

{
   "ResultCode":0,
   "DebugMessage":"ChannelState Loaded Successfully",
   "ChannelState":{
      "ChannelHistoryCapacity":100,
      "BinaryHistory": "RGl6AAEAAAAAAAN6AANp.."
   }
}

It is considered a best practice to:

  • have a list of reserved ResultCode values per custom user error type.
  • return a DebugMessage string which can be useful for debugging.

Response Arguments List

This table gives you what response arguments are supported for each webhook for public channels:

Argument ChannelCreate PublishMessage others
ResultCode
DebugMessage (optional) (optional) (optional)
Data (optional)
ChannelState (optional)

Cancelable Operations

The table below shows which chat operations could be canceled or aborted using webhooks.
To do so you need to return a ResultCode other than 0 and optionally a DebugMessage that you can find in the OperationResponse's DebugMessage.

Webhook Can Be Canceled
ChannelCreate
ChannelDestory
ChannelSubscribe
ChannelUnsubscribe
PublishMessage

データ型の変換

ここでは、Photon ServerとWebサービス間で通信するデータ型のみを説明します。
クライアントとPhoton Server間で通信するデータ型の詳細は、Photonのシリアライゼーションをご覧ください。

Photon Server -> Webサービス

C# / .NET (Photon supported types) JavaScript / JSON
byte number
short
int
long
double
bool bool
string string
byte[] (byte array length < short.MaxValue) string (Base64 encoded)
T[] (array of supported type T, length < short.MaxValue) array
Hashtable (of supported types, count < short.MaxValue, preferably Photon implementation) object
Dictionary (keys and values of supported types, count < short.MaxValue) object
null null

リクエストデータ(型を連結済み)のサンプル

Photon Serverからの送信

JSON

{
    "(Dictionary<String,Object>)Dictionary":{
        "(Int32)dk_int":"1",
        "(String)dk_str":"dv2",
        "(Boolean)dk_bool":"True"
    },
    "(Hashtable)Hashtable":{
        "(Byte)hk_byte":"255",
        "(Object[])hk_array":[
            "(Int32)0",
            "(String)xy",
            "(Boolean)False"
        ],
        "hk_null":"null"
    },
    "null":"null",
    "(String[])string[]":[
        "PUN",
        "TB",
        "RT",
        "Bolt",
        "Chat"
    ],
    "(Byte[])byte[]":[
        "255",
        "0"
    ],
    "(Int16[])short[]":[
        "-32768",
        "32767"
    ],
    "(Int32[])int[]":[
        "-2147483648",
        "2147483647"
    ],
    "(Int64[])long[]":[
        "-9223372036854775808",
        "9223372036854775807"
    ],
    "(Single[])float[]":[
        "-3.402823E+38",
        "3.402823E+38"
    ],
    "(Double[])double[]":[
        "-1.79769313486232E+308",
        "1.79769313486232E+308"
    ],
    "(Boolean[])bool[]":[
        "True",
        "False"
    ]
}

Webサービスでの読み込み

JSON

{
    "(object)Dictionary":{
        "dk_int":"(number)1",
        "dk_str":"(string)dv2",
        "dk_bool":"(boolean)true"
    },
    "(object)Hashtable":{
        "(number)hk_byte":"255",
        "(array)hk_array":[
            "(number)0",
            "(string)xy",
            "(boolean)false"
        ],
        "hk_null":null
    },
    "null":null,
    "(array)string[]":[
        "(string)PUN",
        "(string)TB",
        "(string)RT",
        "(string)Bolt",
        "(string)Chat"
    ],
    "byte[]":"(string)/wA=",
    "(array)short[]":[
        "(number)-32768",
        "(number)32767"
    ],
    "(array)int[]":[
        "(number)-2147483648",
        "(number)2147483647"
    ],
    "(array)long[]":[
        "(number)-9223372036854776000",
        "(number)9223372036854776000"
    ],
    "(array)float[]":[
        "(number)-3.40282347e+38",
        "(number)3.40282347e+38"
    ],
    "(array)double[]":[
        "(number)-1.7976931348623157e+308",
        "(number)1.7976931348623157e+308"
    ],
    "(array)bool[]":[
        "(boolean)true",
        "(boolean)false"
    ]
}

Webサービス -> Photon Server

JavaScript/JSONの型と、C#/.Netの型との対応表は、以下の通りです。

JavaScript / JSON C# / .Net
object Dictionary
array object[] (array of objects)
number (integral) long
number (floating) double
string string
boolean bool
null (not a type) null
undefined (when sent) null

レスポンスデータ(型を連結済み)のサンプル

Webサービスからの送信

JSON

{
    "(object)number": {
        "(number)MAX_VALUE": "1.7976931348623157e+308",
        "(number)MIN_VALUE": "5e-324"
    },
    "(object)object": {
        "(string)string": "xyz",
        "null": null,
        "(boolean)bool": "false",
        "(undefined)undefined": "undefined",
        "(number)float": "-3.14",
        "(number)integer": "123456"
    },
    "(array)array": [
        "(string)xyz",
        "(number)0",
        "(boolean)true",
        null,
        "(undefined)undefined"
    ]
}

Photon Serverでの読み込み

JSON

{
    "(Dictionary<String,Object>)number":{
        "(Double)MAX_VALUE":"1.79769313486232E+308",
        "(Double)MIN_VALUE":"4.94065645841247E-324"
    },
    "(Dictionary<String,Object>)object":{
        "(String)string":"xyz",
        "null":"null",
        "(Boolean)bool":"False",
        "(Double)float":"-3.14",
        "(Int64)integer":"123456"
    },
    "(Object[])array":[ 
        "(String)xyz",
        "(Int64)0",
        "(Boolean)True",
        "null",
        "null"
    ]
}

Webhookを保護する

HTTPSと最新のTLSバージョンの使用だけでなく、カスタムHTTPリクエストヘッダクエリ文字列パラメータを使用してwebhookセキュリティを強化できます。
受信するHTTPリクエストがPhoton Serverで生成されいることがわかるように、Photonのダッシュボードで1つもしくは複数の「秘密」(「トークン」、「キー」など)を設定します。

Back to top