Show Sidebar

Webhooks

Use webhooks with Photon Cloud to extend your application, allow players to rejoin games and to persist player and game data.

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

Read what's new in webhooks 1.2 here.

Content

Setup

To set up webhooks with Photon Cloud, follow the Manage link from the application list on your dashboard. Add new or change existing within the Webhooks section.

From the webhooks configuration page you can select one of the predefined presets using the dropdown list. The "Demo" preset should be used in development only. Its purpose is to give you a quick preview of the different settings available and how to use them.

Configuration is done by defining key/value pairs of strings. The maximum length allowed for each key is 256 characters, values are allowed 1024 chars, each.

Basic Settings

  • BaseUrl (required)
    The URL for the service hosting your hooks as well as any method that should be called via WebRPC. It must not end with a forward slash. Callbacks are received at the relative path URIs that are set up below.
  • CustomHttpHeaders
    JSON object that contains key/value pairs that should be set as HTTP headers in any request made to the configured web service.

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.

  • PathCreate
    Called when a new room is created or when its state needs to be loaded from external service.
  • PathClose
    Called when a room is removed from Photon servers memory. If IsPersistent is set to true the room state is sent.
  • PathJoin
    Called when a player joins a room when it is in Photon servers memory.
  • PathLeave
    Called when a player leaves the room.
  • PathEvent
    Called when the client raises an event in the room with the web flag HttpForward set.
  • PathGameProperties
    Called when the client sets a room or a player property with the web flag HttpForward set.

Options

Finetune the behaviour of your webhooks configuration with these options. An option is considered not configured when not set up or if its value is left empty. The default value for each option is false and applies for each which is not set.

  • HasErrorInfo
    If set to true, clients will be notified with an ErrorEvent when a call to a hook fails.
  • IsPersistent
    If set to true, Photon Cloud sends the state before removing a room from memory. This option is only valid when both PathCreate and PathClose are properly configured. For more information please read more about GameCreate and GameClose webhooks.
  • AsyncJoin If set to true, join operations that fail to find room by name on server will be forwarded to web service as webhook. This option is only valid when PathCreate is properly configured.

Turnkey Solutions

Find the latest available turnkey installations for Parse, Webscript.io, Microsoft Azure and Heroku on our github page. There is also a third-party solution for Photon Webhooks using Java available on bitbucket.

Common Criteria

All Photon webhooks share the base URL to POST to, the ability to return an eventual error that could happen on the web server and baseline data that is sent with each.

Common Arguments to All Webhooks

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.

GameId: ID or name of the room

Type: Type of the webhook, it's always "Event" in GameEvent webhook, "Join" in GameJoin webhook and can have multiple values in all the other webhooks.

Common arguments to all Webhooks except GameClose

ActorNr: number of the actor triggering the hook.

UserId: UserId of the actor triggering the hook.

NickName: name of the actor triggering the hook as set from the client SDK.

Return Values

Expected Response

When sending the webhooks, Photon Cloud will in most cases expect only a response that has a JSON object with a ResultCode property set to 0. The zero ResultCode is an acknowledgment for the reception of the webhook request from and for successful processing on the web server.

Any webhook call with a return object that has a ResultCode different than zero is considered as failed. If HasErrorInfo is set to true in the configuration; an ErrorInfo event will be broadcast to clients still joined to the room. Other than GameCreate, the server continues normal execution, despite this. The event also contains ParameterCode.Info. See the API doc for your SDK for additional info.

The only case where Photon expects more is when a player is trying to rejoin a Room that has been closed by Photon Cloud and already removed from memory. For more details about this, please refer to the GameCreate section.

Best Practices

Always check the arguments needed in each webhook. Return a error code with an optional, yet useful human readable message in case a required argument is missing. The suggested format of the JSON return object of a webhook is { 'ResultCode' : x, 'Message' : 'xxx' }.

A very good way to handle return values is by implementing helper routines in the backends logic for your webhooks. The following is just a non-exhaustive list of examples of webhooks return objects.

  • Default return object for success

    { 'ResultCode' : 0 }
    { 'ResultCode' : 0, 'Message' : 'OK' }

  • Error on protocol level, either on Photon side or on web server

    { 'ResultCode' : 1, 'Message' : 'Missing Webhook Argument: <argument name>.' }

  • Application specific errors

    { 'ResultCode' : 2, 'Message' : 'Game with GameId=<gameId> already exists.' }
    { 'ResultCode' : 3, 'Message' : 'Could not load the State, Reason=<reason>.' }

Paths in Details

GameCreate

This webhook is triggered every time a room is created at server level. In case the room is created using OpCreateRoom, the webhook will have its Type argument set to Create. Most of the RoomOptions along with the TypedLobby used when creating the room will be sent as CreateOptions. The value of the ActorNr will be 1 and the actor will auto join the room without firing additional webhooks.

If an actor tries to join or rejoin a room that was previously created but removed from Photon Cloud, the Type will be set to Load. The web server should return the serialized State of the same room. The backend logic will need to fetch the previously saved, serialized version of the room state.

In case the state is found, the web server should return a JSON object as { 'State' : state, 'ResultCode' : 0 }. If the state cannot be found for some reason, the web service should check the value of CreateIfNotExists to allow or disallow room creation with new state. If CreateIfNotExists is true, you can return an empty room state (e.g. { 'State' : '', 'ResultCode' : 0 }) to allow creation of a room with provided room options if any or default ones. With its value being false Photon Cloud should be informed that the web server failed to load the state by returning a ResultCode other than 0. Consider adding a human readable error message with the cause.

If "IsPersistent" is set to true and both "PathCreate" and "PathClose" are configured, room creation, asynchronous join or rejoin will fail when:
  • "PathCreate" is unreachable or returns HTTP error.
  • "PathCreate" returns ResultCode other than 0.
  • Photon Server fails to parse or set received room state.

Specific Arguments

GameCreate, Type "Create"

CreateOptions: The options used when creating the room. It contains information from the RoomOptions class as set from the Client with details about the used TypedLobby. All its properties can be retrieved later from the State as it will be copied there as is.

The following table has a comparison between CreateOptions and RoomOptions.

Property or Field CreateOptions RoomOptions Notes
IsVisible x Can be retrieved later from room State.
IsOpen x Can be retrieved later from room State.
MaxPlayers
PlayerTtl
EmptyRoomTtl
CheckUserOnJoin This should be set to true if you have unique ID per player.
SuppressRoomEvents If set to true, no room events are sent to the clients on join and leave. Default is false and sent.
DeleteCacheOnLeave This is called CleanupCacheOnLeave in RoomOptions.
LobbyType x The type of the room's lobby as set by game client in TypedLobby.Type. See the API doc for your SDK for additional info.
LobbyId x The name of the room's lobby as set by game client in TypedLobby.Name. See the API doc for your SDK for additional info.
CustomProperties x Contains only the initial custom properties of the room that should be public, i.e. visible to the lobby.
CustomRoomProperties x Contains all initial custom properties of the room.
CustomRoomPropertiesForLobby x Contains the keys of the custom properties of the room that should be public, i.e. visible to the lobby.
PublishUserId x Defines if the UserIDs of players get "published" in the room.
Can be retrieved later from room State.
Read more about it here.

GameCreate, Type "Load"

CreateIfNotExists: A flag used to indicate if a new room should be created if its state could not be found from web service.

Properties of the room's State other than those found in CreateOptions:

  • ActorCounter: The ActorNr of the last joined actor.
  • ActorList: An array of information entries about each actor present in the room (active or inactive). Each entry has the following properties:
    • ActorNr: Number of the actor in the room.
    • UserId: UserID of the actor.
    • NickName: NickName of the actor.
    • IsActive: Indicates if the actor is joined to the room or not. It is not sent in State argument of GameClose.
    • DeactivationTime: Timestamp of room leave event. Sent only in State argument of GameClose.
    • Binary*: Base64 encoded actor properties.
    • DEBUG_BINARY**: readable form of the actor properties.
  • Slice: the cache slice index.
  • Binary *: Base64 encoded room properties and cached events.
  • DebugInfo **: readable form of the binary data.
    • DEBUG_PROPERTIES_18**: readable form of the room properties.
    • DEBUG_EVENTS_19**: readable form of the cached events.
    • DEBUG_GROUPS_20**: readable form of the interest groups.
  • ExpectedUsers: Array of UserIDs of players expected to join the room. Read more about Slot Reservation.

* : The Binary properties exist because of the nature of the protocol used by Photon.
**: The Debug properties should be disabled for applications in production environment. Make sure to use these properties for debugging only.

Sample Call

GameJoin

If an actor joins or rejoins a room that was not removed from Photon Cloud this webhook will be fired. The Type argument is set to Join.

Specific Arguments

GameJoin has no extra arguments.

Sample Call

GameProperties

This webhook is fired every time the user sets the custom properties of either the room or the player from the client side if the right overload method is used with the HttpForward web flag set. The Type argument sent with the webhook will be set accordingly to Game or Actor.

Specific Arguments

Properties: a set of updated properties as sent from client SDK.
State: a serialized snapshot of the room's full state. It's sent only if SendState webflag is set when calling OpSetCustomProperties.
AuthCookie: an encrypted object invisible to client, optionally returned by web service upon successful custom authentication. It's sent only if SendAuthCookie webflag is set when calling OpSetCustomProperties.

GameProperties, Type="Actor"
TargetActor: the number of the actor whose properties are updated.

Sample Call

GameEvent

Fired every time the user raises a custom event from the client side if the right overload method is used with the HttpForward web flag set. The custom event code and the event data will be sent with the webhook.

Specific Arguments

EvCode: custom event code.
Data: custom event data as sent from client SDK.
State: a serialized snapshot of the room's full state. It's sent only if SendState webflag is set when calling OpRaiseEvent.
AuthCookie: an encrypted object invisible to client, optionally returned by web service upon successful custom authentication. It's sent only if SendAuthCookie webflag is set when calling OpRaiseEvent.

Sample Call

GameLeave

This hook is triggered whenever an actor is disconnected from Photon game servers. A disconnect could happen for several reasons. The webhook itself tells you about that reason in a human readable form within its Type and in a coded way, see Reason.

Specific Arguments

Type: readable form of the reason that could be one of the following values:

  • ClientDisconnect: Indicates that the client called OpLeaveRoom() or Disconnect().
  • ClientTimeoutDisconnect: Indicates that client has timed-out server. This is valid only when using UDP/ENET.
  • ManagedDisconnect: Indicates client is too slow to handle data sent.
  • ServerDisconnect: Indicates low level protocol error which can be caused by data corruption.
  • TimeoutDisconnect: Indicates that the server has timed-out client. Find additional info in the client connection handling page or the doc on analyzing disconnects .

  • LeaveRequest: Indicates that the client explicitly abandoned the room by calling OpLeaveRoom() OpLeaveRoom(false).

  • PlayerTtlTimedOut: Indicates that the inactive actor timed-out, meaning the PlayerTtL of the room expired for that actor. See the API doc for your SDK for additional info.
  • PeerLastTouchTimedOut: Indicates a very unusual scenario where the actor did not send anything to Photon Servers for 5 minutes. Normally peers timeout long before that but Photon does a check for every connected peer's timestamp of the last exchange with the servers (called LastTouch) every 5 minutes.
  • PluginRequest: Indicates that the actor was removed from ActorList by plugin.
  • PluginFailedJoin: Indicates an internal error in Photon Cloud webhooks implementation.

IsInactive: Refers to the state of the actor before leaving the Room. If set to true then the actor can rejoin the game. If set to false, then the actor left for good and is removed from ActorList and can't rejoin the game.

Reason: Code of the Reason

The tables below match each type to its code and explain how the webhook is produced and how the player presence in the room is affected.

RoomOptions.PlayerTTL set to 0 upon Room Creation

Actors of a room where RoomOptions.PlayerTTL == 0 can never be in the inactive state and will be removed from the ActorList as soon as they leave. IsPersistent option will be ignored as by design room state should be saved only if the room contains at least one inactive actor.

Any event that triggers the GameLeave webhook will result in removing the respective actor from the room. Do not try and check if such actor is active or not ;) OpLeaveRoom(true) will no longer be of use and PlayerTtlTimedOut type of GameLeave can not happen in this situation.

Type Reason Trigger Actor in ActorList
ClientDisconnect 0 a call to Disconnect() or OpLeaveRoom(true) false
ClientTimeoutDisconnect 1 called by Photon server false
ManagedDisconnect 2 called by Photon server false
ServerDisconnect 3 called by Photon server false
TimeoutDisconnect 4 called by Photon server false
LeaveRequest 101 a call to OpLeaveRoom() or OpLeaveRoom(false) false
PlayerTtlTimedOut 102 N/A N/A
PeerLastTouchTimedout 103 called by Photon server false
PluginRequest 104 called by plugin false
PluginFailedJoin 105 called by Photon server false
RoomOptions.PlayerTTL != 0 upon Room Creation
Type Reason Trigger IsComingBack or IsInactive Actor in ActorList
ClientDisconnect 0 a call to Disconnect() or OpLeaveRoom(true) true true
ClientTimeoutDisconnect 1 called by Photon server true true
ManagedDisconnect 2 called by Photon server true true
ServerDisconnect 3 called by Photon server true true
TimeoutDisconnect 4 called by Photon server true true
LeaveRequest 101 a call to OpLeaveRoom() or OpLeaveRoom(false) false false
PlayerTtlTimedOut 102 called by Photon server false false
PeerLastTouchTimedout 103 called by Photon server false false
PluginRequest 104 called by plugin false false
PluginFailedJoin 105 called by Photon server false false

Sample Call

GameClose

This hook is fired just before removing a room instance from memory in the Photon Cloud. This happens only when the EmptyRoomTTL has expired. EmptyRoomTTL is set when creating the room and it is a timer that starts when the room becomes empty. A room is considered empty when the last active actor in the room leaves it.

In case IsPersistent is set to true, Photon Cloud will send the State which is a serialized snapshot of the room that contains its properties and information about the actors and cached events. In this case, the Type of the webhook will have the Save value.

In case IsPersistent is set to false, which is the default state, the Type is Close and the State is not sent and the room is lost for ever.

Specific Arguments

ActorCount: the number of inactive actors. If 0 then Type should be "Close".

GameClose, Type: "Save"

State: a serialized snapshot of the room's full state

Sample Call

URL Tags

In Webhooks and WebRPC URLs, you can optionally set one or more "dynamic variables". Those variables will be replaced with their respective values in our backend before sending out any requests.

URL tags come in handy if you want to handle user segments of your application differently, each. Photon supports the following URL tags:

  • {AppVersion} will pass the application version as set by the client.
  • {AppId} will pass the ID of your application.
  • {Region} will pass the token for the cloud region the triggering client is connected to, e.g. "eu".
  • {Cloud} will pass the name of the cloud the triggering client is connected to, e.g. "public" or "enigmaticenterprise".

Examples of URL Tags use cases

  1. https://{Region}.mydomain.com/{AppId}?version={AppVersion}&cloud={Cloud} to e.g. route each region to different hosts, version and cloud passed as query parameters.
  2. https://mydomain.com/{Cloud}/{Region}/{AppId}/{AppVersion} passes all tags as well structured URI.

Stripping Room State

If the size of the room state is a concern for you, you can do few tricks to shrink it and not lose any data. When saving the room state in your web service you can reduce its size by:

  1. Removing some fields that are made for read only debug purpose and will not be used during reconstruction of the room state when loading the room. These fields are: CustomProperties, DebugInfo and every DEBUG_BINARY and NickName of each actor inside ActorList. These fields are safe to remove as they are ignored when deserializing the room state.

Here is a full room state returned in GameCreate, Type="Load" webhook:

Here is a stripped version of the room state that could be returned in the same webhook:

2. Removing some fields that are considered in your application logic as constants and should not be changed during room lifetime or can be injected by code before returning the state to Photon Servers when loading the room. These fields should be added back to their original value before returning the state to Photon Servers. Otherwise the state may become broken.

Those fields could be any of these:

  • ActorCounter
  • CheckUserOnJoin
  • DeleteCacheOnLeave
  • EmptyRoomTTL
  • IsOpen
  • IsVisible
  • MaxPlayers
  • LobbyId
  • LobbyType
  • LobbyProperties
  • PlayerTTL
  • SuppressRoomEvents
  • Slice

 To Document Top