cluefolk

Create a company and project

Start here: create your workspace, then give your team access.

Create a company and project

  1. Sign in with Google or email and verify your email. Without a company you land on the companies page (Companies & invitations in the account menu); choose create your own company there.
  2. Complete two steps: Company (enter the Company name and choose Create company) and Project (on Your first project, enter the Project name and choose Create project). The support desk opens in the new project.
  3. For another project, choose change next to the project name at the top of the sidebar, then New project; enter the Name and choose Create project. The new project opens right away. Settings → General shows its name, Project ID and Game icon: upload the same image as the game’s app icon. The team sees it in the project menu and the widget preview, while players see the icon the SDK reads from the game. Only company owners create and rename projects and set the icon.
  4. Give your team access under Settings → Team in each project: press the round + button and enter an email and role. Another company owner is invited under Settings → Members. People join through their invitation; they do not create a separate company.

A game server is not required to create or use the project. Each new project starts with default conversation categories and its own Cluefolk command key; settings are not copied between projects, so configure each project separately.

Sign in and join a company

  1. Open cluefolk.com, choose Sign in, then Google or Continue with email; with email, new people register on the next page. Open the verification link from the email and sign in again if requested.
  2. To join a team, sign in with the exact email address that received the invitation. Open the invitation link and choose Accept invitation, or accept it under Companies & invitations.
  3. Invitations are checked when you sign in or reload. If an owner or administrator has just invited you, reload the page.
  4. Without a company you land on the companies page, also opened by Companies & invitations in your account menu. If it says You haven’t joined a company yet, wait for an invitation or use create your own company to become the owner of a new company.

A Google account or a verified email alone does not grant access to someone else’s company.

Your account, company and project

  1. Your personal account is separate from your role in a company’s projects. You can belong to several companies and have different roles in each project.
  2. Before making changes, check the project name at the top of the sidebar, under the Cluefolk logo. To switch, choose change next to it: a small menu lists the company’s projects with your role and a check mark on the current one; company owners also see New project there. A project is one game’s support space: its players, conversations, settings, server connection and keys belong to it alone and are never shared with other projects.
  3. Below the picker, Support desk holds Inbox, Incidents, Players and Reports, and Views opens the inbox with a ready filter. Project admins and company owners also see Settings at the bottom of the sidebar: the company’s Members and the configuration of the selected project.
  4. To keep development builds and QA apart from real players, create a separate project for them, for example “Space Farm” and “Space Farm QA”. Each project has its own project ID, players and conversations.
  5. To switch companies, open your account menu at the top right (your name). It lists your companies with your role, and a check mark shows the current one; choose another company to open it. The menu also has Account settings, Companies & invitations and Sign out. The book icon next to it opens this user guide.
  6. Account settings holds your personal preferences: Profile (name and email), Appearance with the System, Light or Dark theme, and Privacy with Cookie settings and a link to the cookie policy.
  7. In Profile, enter your first and last name and press Save. Your team sees your full name; players see only your first name on your replies, for example Anna · Support team. Until you save a name, players see Support team.

Access is granted per project. If access is removed, ask a company owner or a project administrator to add you again under Settings → Team.

Company members and owners

  1. Company owners: open Settings at the bottom of the sidebar and choose Members in the section named after your company. The page lists the company’s members and role-based Invitations; members who are not owners do not see it.
  2. Each person’s company role is Owner or Member. Owners have full access to every project. A company can have several owners; the last owner cannot be demoted or removed.
  3. Each member’s project access is shown read-only. To give someone access to a project or change their project role, use that project’s Settings → Team.
  4. In Settings → Members, invite by email and explicitly choose Owner, Admin or Operator. Admin and Operator also require the projects they may access. No role is selected automatically.
  5. Remove and Confirm removal take a person out of the company and all its projects. Their account and access to other companies remain.

Removing project access also takes the person out of that project’s queues and clears their assignments.

Who can do what

Support desk is for daily support work. Settings holds the company’s Members (owners only) and the selected project’s configuration; only company owners and project admins see it, operators have none. Personal preferences are under Account settings in the account menu. Company owners can do everything in every project; members get Admin or Operator per project under Settings → Team.

ActionOwnerAdminOperator
Manage company members and ownersYesNoNo
Create and rename projectsYesNoNo
Configure the project, server connection and giftsYesYesNo
Manage quick repliesYesYesNo
Add operators to the projectYesYesNo
Grant the Admin roleYesNoNo
Approve or decline gift requestsYesYesNo
Reply, ban players, send permitted gifts and manage incidentsYesYesYes
Pass on a conversation you answerYesYesYes
Take or reassign anyone’s conversationYesYesNo
Attach a gift to an incident broadcastYesYesNo
Apply published manual badgesYesYesYes
Export or erase player dataYesYesNo

Configure the project

The owner or an administrator configures each project. Connecting a game server is optional.

Players and sign-in

  1. Select the project you want to configure in the sidebar picker and open Settings → Server connection. Under Players and sign-in, choose Who can contact support.
  2. Everyone. Players signed in through the game are verified; others write anonymously. is the default. The SDK identifies an anonymous player by their app install, so history survives restarts without a game backend.
  3. To verify players, your game backend signs a short-lived ES256 identity token after the player signs in to the game. Paste the backend’s public key (PEM or JWK) under Identity signing keys and choose Add key. The token issuer (iss) and audience (aud) are shown above the keys.
  4. When a player signs in through the game on the same install, their anonymous conversations move to the verified account.
  5. Only players signed in through the game. requires at least one identity key. Players without a valid identity token then cannot open support.

Cluefolk stores only public keys. Rotate a key by adding the new one, switching your server to it, then removing the old one. The last identity key cannot be removed while sign-in is required.

Connect the game server when needed

  1. Open Settings → Server connection. Conversations, anonymous players, identity tokens and manual badges work without a game server URL.
  2. To sync attributes for automatic badges, deliver gifts, receive game events and request notifications, enter the Game server URL: the HTTPS origin, for example https://api.yourgame.com, without a path or query.
  3. Under Profile signing keys, add the public key your server uses to sign attribute snapshots and the connection reply. Connecting requires at least one profile key.
  4. Cluefolk command keys shows the JWKS URL, issuer and audience. Cluefolk signs every request to your server (gifts, profiles, events, push) with ES256, and your server verifies it against the JWKS URL, cached for up to 5 minutes. Rotate command key and Rotate now sign new requests with a new key immediately; the previous key stays published.
  5. Download server config saves cluefolk-server.json with identifiers, issuers, audiences, the JWKS URL and Cluefolk’s public command keys. It contains no secrets; give it to your backend developer together with the integration guide.
  6. The developer implements /cluefolk/connect, /cluefolk/profile, /cluefolk/gifts, /cluefolk/events and /cluefolk/push as needed. Choose Check connection to verify the server and import its signed attribute catalog; after that the button becomes Refresh catalog.

Private keys stay on the game backend: never put them in the app, WebView, a public repository or SDK options. Changing the URL requires a new check.

Game-server contract and signed catalog

Refresh the attribute catalog

  1. Open Settings → Attributes. The Player attributes table shows each attribute’s name, key and type.
  2. Choose Refresh catalog after your developer updates the game server. The accepted catalog appears immediately. The same table is available under Server connection.
  3. The backend supplies the attribute definitions and player values. Cluefolk uses those values for player cards and automatic badges; attributes are not created manually.
  4. Supported types are string, integer, decimal, boolean, datetime and enum. If an existing attribute needs a different type, ask the developer to use a new key.

A failed refresh keeps the last accepted catalog. Missing, stale or restricted data should not be treated as a zero or a confirmed negative value.

Automatic and manual badges

  1. Administrators: open Settings → Badges and press + above the list. Enter the name, icon and color; the key and who on the team sees the badge are under More options.
  2. In How players get it choose Automatically, from game data and describe Who gets it with the game server’s attributes, or An operator sets it on the player card. Check players shows how many players match. Save keeps a draft; Publish makes the badge work.
  3. For a badge the team applies itself, choose An operator sets it on the player card and keep Everyone on the project under More options, then save and publish it. Operators filter the Inbox by badges under Filters → Players.

Automatic badges follow only their rules. Operators cannot assign administrator-only badges. Publishing a switch from manual to automatic removes the badge from players it was given to.

Configure gifts and their limits

  1. Gifts need a connected game server: without it Settings → Gifts only explains how to connect it. Administrators: on Catalog choose + Create a gift and fill in the name and description players see, the command your game server runs and what to grant (JSON), then Create gift. Agree on the command and contents with your game-backend developer.
  2. To change a gift, choose Change → and save a new version; gifts already sent keep the version they were sent with.
  3. Choose Limits & approval →. Operators can send this gift decides whether operators see it at all. Gifts per player (0 = no limit) within Within, days applies to everyone, administrators included.
  4. For operators set Gifts per operator per day (0 = no limit), a hard limit, and optionally Ask an administrator to approve larger volumes: once an operator has sent the chosen number of this gift in 24 hours, further requests wait for approval (0 means every request). A second gift in the same conversation always waits for an administrator. Choose Save limits.

Administrators never need approval. Disable gift prevents new selections; it does not recall an already queued operation. Gifts reach only players signed in through the game.

Approve gifts and review the report

  1. Administrators: open Settings → Gifts → Approvals. The tab counts waiting requests and shows the gift, player, requester and reason.
  2. Choose Approve and send to queue delivery, or enter a Decision note and choose Decline; declining requires a note. Open conversation ↗ shows the context.
  3. Another administrator has to decide on your own request. Per-player limits are checked again when a request is approved.
  4. Open Report and choose a period to see, per operator and gift, how many were granted, pending, declined or failed, and for how many players.

The operator sees the decision in the player’s gift history. A declined request is never delivered.

Add and manage the project team

  1. Select the intended project in the sidebar picker and open Settings → Team, the only place to give access to a project. The page lists company owners (read-only, every project), members with their role and this project’s Invitations.
  2. To add someone, press the round + button (Add to the project), enter the Email address in the dialog, choose the Role and choose Add to project. Someone already in the company gets access right away, without an email (“… now has access.”); anyone else gets an email invitation that expires in 7 days (“Invitation sent to …”). Administrators add operators; only a company owner can add an admin.
  3. An invited person signs in with that email and accepts the invitation; they join the company as a member with access to this project.
  4. Owners can change a member’s role here. Revoke access and Confirm revoke remove access to this project only; Revoke invitation cancels a pending invitation.

An Admin configures the project and can work as an operator. An Operator uses the support desk. Company owners manage the company roster and other owners under Settings → Members.

Queues, categories and support settings

  1. Open Settings → Queues & workflow. Under Queues create a New queue, select its Members, set Open conversations per operator, optionally enable Assign automatically, and choose Save queue. New conversations go to members who have Cluefolk open, the least busy first.
  2. Under Conversation fields add fields for the team, or with Ask the player for the player form. A field’s key and type cannot be changed after creation.
  3. In Support settings configure rating requests, Reopen window, days, Retention, days, Reply SLA, business minutes, Time zone and Business hours (no windows = 24/7).
  4. Player messages limits how many messages a player can send Per minute and Per hour (6 and 60 by default). Messages above the limit are refused, and the widget shows when the player can write again.
  5. Conversation categories are optional for players. Edit labels, reorder with ↑/↓, add a category with a key and label and + Category, or uncheck it to disable it. Saved keys stay fixed; disabled categories remain on existing conversations. Choose Save settings.

The status filter supports multiple choices. All active excludes Resolved; select Resolved to browse history. New unanswered is the initial queue. No conversation opens automatically; × closes only your current view and keeps its draft.

Design the player-facing widget

  1. Open Settings → Widget. Set five base colors for each theme: Accent (header and player messages), Action (buttons and links), Background, Surface (cards and team messages) and Text. Muted text, borders and text on colored buttons are derived for contrast and shown under Derived. The file holds colors and content only. The logo is the game’s own app icon, read by the SDK (see Logo); to see it in the preview, upload the Game icon under Settings → General. Then set up the blocks: welcome, topics and contact.
  2. Each topic opens the chat with one of this project’s conversation categories. Choose its Category; the list comes from Queues & workflow.
  3. Check the live preview in light and dark appearance and choose Save to keep this version for your team.
  4. Download for build saves <ID>_widget.json, where <ID> is the first 16 characters of the Project ID. Your developers ship it inside the game build and pass its text to the SDK; players see a change only in the next build that includes the new file. Import file loads such a file into the editor.

The language menu next to Light/Dark changes only the admin preview. Purchases and Rewards are separate topics; Purchases has a gold outline. Show “Talk to the team” button is off by default and can be enabled in the editor before exporting the theme.

Quick replies

  1. Use Settings → Quick replies for the team’s saved replies: each has a title, a language and a body. Administrators press + above the list to add one and choose a reply in the list to edit or delete it; operators insert them while composing a reply in Inbox.

{{player.id}}, {{conversation.id}} and {{agent.name}} in the text are filled in when the reply is inserted; {{agent.name}} becomes your first name.

Check the project before inviting players

  1. Decide who may contact support under Players and sign-in. If you use a game server, confirm that the connection is verified and the expected attribute keys and types are present.
  2. Publish the gifts and badges the team needs, set gift limits, invite operators and verify queue membership.
  3. Use a test player to send a message, receive a public reply and request a gift. Confirm the actual result in the game, not only the queued status.
  4. Under Server connection, review Game events and Notifications. In Test push, Send test requests a push through your game server for a player signed in through the game who has a public support reply.
  5. Use Reports in the support desk for support activity, including Countries: a map and list of the countries Cloudflare placed players in when their conversations started. Use Settings → Audit to review recorded changes. If you prepared support in a separate project for development builds, configure and check the release project the same way: settings are not copied between projects.

Cluefolk sends notification requests to your game backend. FCM/APNs credentials and device-token handling belong to the game’s integration, not an operator’s browser.

Work as an operator

For operators: short step-by-step instructions for everything you do during a shift.

Start your shift

  1. Sign in at cluefolk.com. At the top of the left panel you see the game you are working on. If it is the wrong one, press change next to its name and pick the right game.
  2. Open Inbox. On the left is the list of conversations, in the middle the open conversation, on the right the player card.
  3. Keep the Cluefolk tab open while you work. If your administrator turned on automatic assignment, new conversations go to people who have Cluefolk open, the least busy first.

The status filter supports multiple choices. All active excludes Resolved; select Resolved to browse history. New unanswered is the initial queue. No conversation opens automatically; × closes only your current view and keeps its draft.

Find a conversation

  1. Statuses: New — no human reply yet; In progress — the first public reply assigned the conversation; Needs a reply and Waiting for player are set manually; Awaiting confirmation — the player is deciding; Resolved — saved, read-only history.
  2. The status filter supports multiple choices. All active excludes Resolved; select Resolved to browse history. New unanswered is the initial queue. No conversation opens automatically; × closes only your current view and keeps its draft.
  3. To search, type the player ID, a word from the messages, or the game or phone system version, for example 2.4 or iOS 17. ⌘K (Mac) or Ctrl K (Windows) jumps to the search box.
  4. Filters changes the order (for example Newest first) and narrows the list by operator, category, priority or tag. Under Players it narrows by who the player is: press + Condition and pick a badge or game data, for example Level At least 10 or ★ VIP Has. Active filters show as chips under the search; × removes one. To keep a set of filters, type a name in Save as a view… — the view appears in the sidebar under Views.

A name with a person icon on a conversation is its operator. No name means the conversation is free.

Answer a player

  1. Open a conversation without an operator and read it. The player card on the right shows who the player is (see “Check the player”).
  2. Make sure the Reply tab is selected above the text box and type your answer. To insert a ready answer, open Quick reply and pick one.
  3. Press Enter or Send reply. Shift+Enter starts a new line.
  4. Your first public reply assigns the conversation to you and sets In progress. Later replies keep the manually selected work status.

Operators see their own conversations and unanswered, unassigned New conversations. Only admins and owners may inspect another operator’s conversation. They must take it over before writing a reply or a private note; they may also transfer it.

Pass a conversation to a colleague

  1. Open a conversation that is yours.
  2. At the top, open Operator and choose a colleague. People marked Owner or Admin can answer players too.
  3. Now only the colleague answers the player. You can still write private notes.
  4. To give the conversation back to the whole team, choose Unassigned.

Owners and admins can take any conversation by choosing You in Operator. An operator cannot take a colleague’s conversation: ask the colleague or an admin to pass it to you.

Write to your team (private note)

  1. Above the text box choose Private note. The box turns yellow: the player does not see this text.
  2. To call a colleague, pick them in Mention. They find the note under Mentioned me.
  3. Press Enter or Add note.

You can write notes in any conversation, even one that belongs to a colleague.

Check the player

  1. The player card is on the right. On a narrow screen, press the person icon at the top of the conversation.
  2. ✓ Verified player — the game confirmed the account. Anonymous — the player wrote without signing in and is shown as Guest with a short code. Player ID (not verified) — the player typed the ID themselves; do not rely on it for account questions.
  3. Under Player you see the platform, system version, device, game version and build, language and country.
  4. Conversations lists all of the player’s conversations, the newest first. Click one to open it.
  5. Game attributes shows data from the game, such as level or purchases. An empty or old value does not mean zero.
  6. Click any value in the card, such as the player ID, to copy it, for example to look the player up in other tools. Copied confirms it.

Mark a player with a badge

  1. In the player card press + Badge and choose a badge. It appears at once.
  2. To remove it, press the cross on the badge.

Badges without a cross are set automatically from game data; you cannot change them. If a badge you need is not in the list, ask your administrator.

Send a gift

  1. Gifts are only for players who signed in through the game (✓ Verified player). In the conversation press Send a gift under the text box.
  2. Choose the gift, write the reason for your team (for example “lost purchase, order 123”) and press Confirm and send gift.
  3. If you see Sent for approval, an administrator approves it first. The decision appears on the Gifts tab of the player card.
  4. The Gifts tab shows whether the game server accepted the gift. Once it accepts, the player sees the gift in the chat; when it appears in the game itself is up to the game.

Do not send the gift again because it is slow: that would be a second gift. If the status is Unknown, press Check delivery again; if it stays stuck, tell your administrator.

Many players with the same problem

  1. When many players write about one problem (for example, the shop does not open), group their conversations into an incident. Open Incidents, press + Create an incident, enter the Incident title and the Automatic acknowledgement — the message players get at once — and press Create incident.
  2. To add a conversation, open it, press + Add to incident, choose the incident and press Add. For a new issue choose New incident…, enter what is wrong and press Create and add. To add several at once, tick them in the conversation list and choose the incident in Add to incident….
  3. Players who have not had an answer yet get the automatic message right away.
  4. To write to all of them, open the incident and use Message affected players.
  5. Admins can broadcast only to active conversations. Resolving an incident asks each player to confirm their solution. A refusal keeps that player’s conversation open. An incident without active conversations has no broadcast form. Delete incident asks for confirmation and preserves conversation history.

Admins can broadcast only to active conversations. Resolving an incident asks each player to confirm their solution. A refusal keeps that player’s conversation open. An incident without active conversations has no broadcast form. Delete incident asks for confirmation and preserves conversation history.

Finish a conversation

  1. Press the separate Resolved button when the issue is solved. The player receives a request to confirm the solution.
  2. If the player agrees, they may submit or skip a rating. The conversation then becomes read-only history; the next message starts a new conversation.
  3. A refusal continues the same conversation, marks it Needs a reply and records the unsuccessful attempt against the operator who proposed resolution. No response within 24 hours resolves it with a separate timeout outcome. A new message before confirmation cancels the proposal.

The status filter supports multiple choices. All active excludes Resolved; select Resolved to browse history. New unanswered is the initial queue. No conversation opens automatically; × closes only your current view and keeps its draft.

Block an abusive player

  1. In the player card press Ban player, write a reason if you like and confirm with Ban player.
  2. The player can no longer write to support in this game. Their conversations stay.
  3. To undo it, press Unban player.

Export or erase player data

  1. Owners and administrators: open Players, choose the player and expand Privacy.
  2. Export player data prepares a file. When the request shows completed, press Download JSON.
  3. To erase, type the ID the page asks for (the game player ID, or the Cluefolk ID for an anonymous player) and press Erase player data.

Erasing removes messages, attributes and images and cannot be undone. The player can write again later as a new player.

Integrate the game client

Connect Android, iOS or Unity to the game’s project by its project ID. Players start anonymously; signing in through the game is optional.

Project, identity and SDK lifecycle

  1. Use the exact project ID shown under Settings → General (Copy copies it; it ships in the game and is not a secret) and in the server config. If you keep a separate project for development builds, those builds use its ID and release builds use the release project’s ID. The widget is built into the SDK, so only the project ID is required; the API defaults to https://cluefolk.com. The widget header shows the game’s app icon; to use another image, pass its resource name (logoResource on Android, logoImageName on iOS, LogoResource in Unity).
  2. Initialize the SDK once and wait for its ready callback. Support then works without any sign-in: the player is anonymous and identified by an install secret kept in protected device storage.
  3. Ship the <ID>_widget.json file from Settings → Widget → Download for build inside the build, load it with the appearance builder (Appearance.Builder(json).build()) and pass it to setAppearance (Unity: SetAppearance) after the ready callback and before the first open. The same builder without a file sets colors, texts and screen rotation in code. Without it the widget uses the default appearance: the server never sends one.
  4. Signing in is optional. After the player signs in to the game, your backend signs a short-lived (at most 5 minutes), one-time ES256 cluefolk-identity+jwt: sub is the game player ID, iss and aud match Players and sign-in. Pass it to loginWithIdentity; this install’s anonymous history moves to the account.
  5. An identity token provider is optional: when it is set, the SDK asks your already authenticated backend for a fresh token whenever it needs a new session (sessions last 30 days and extend with use). If no token arrives, support stays available anonymously and the error callback receives IDENTITY_UNAVAILABLE. If the project requires sign-in, anonymous sessions fail with IDENTITY_REQUIRED.
  6. open shows the support home. openConversation with an empty ID opens the player’s current chat; the first message there starts a conversation. Use unread callbacks for the game’s indicator.
  7. Call logout when the game account signs out or changes; close only closes the support UI.

The examples use app-owned variables such as gameApi, identityToken, recentLogText, supportListener, Activity or view controller. These are supplied by your game, not additional Cluefolk methods. The SDKs are open source under the MIT license: Android on Maven Central, iOS through Swift Package Manager or an XCFramework, Unity from a Git URL (github.com/cluefolk).

Android · Kotlin and Java

  1. Requires Android 7.0 (API 24) or later, compileSdk 34 or later, Android Gradle Plugin 7.4 or later and AndroidX. Add com.cluefolk:android-sdk from Maven Central (below); it brings AndroidX Activity, Core and WebKit and its own R8 rules.
  2. Implement Cluefolk.EventListener and register it before initialization. Its callbacks include onCluefolkReady, onCluefolkUnreadChanged(count), onCluefolkIdentityTokenRequired(requestId) and onCluefolkError(code). Initialize from the UI thread with the Application context.
  3. After onCluefolkReady, or once isReady() is true, the support button can call open(activity) for an anonymous player. If the game has a signed-in player, pass the identity token from the game-login response to loginWithIdentity; a support error must not fail game login.
  4. Initialization loads local credentials asynchronously. Other public methods may be called from any thread; callbacks run on the main looper. Connect push reception and tap handling as described below.
App Gradle configurationkotlin
dependencies {
    implementation("com.cluefolk:android-sdk:0.3.2")
}
Initialize oncekotlin
import com.cluefolk.sdk.Cluefolk

Cluefolk.setEventListener(supportListener)
Cluefolk.initialize(application, Cluefolk.Options(projectId = "YOUR_PROJECT_ID"))
// Optional: only if your game issues Cluefolk identity tokens.
Cluefolk.setIdentityTokenProvider { callback ->
    gameApi.fetchCluefolkIdentity { token, error ->
        callback.complete(token, error)
    }
}
Open support and sign inkotlin
// After onCluefolkReady(); works without sign-in (anonymous player):
Cluefolk.open(activity)
Cluefolk.openConversation(activity, "") // the player's current chat

// Optional, after successful game login:
Cluefolk.loginWithIdentity(identityToken) { error ->
    // Do not fail game login because of support.
}
Cluefolk.setConversationContext("""{"screen":"settings"}""")

// Game account sign-out:
Cluefolk.logout()

Source code, changelog and releases: github.com/cluefolk/android-sdk (MIT license).

iOS · Swift and Objective-C

  1. Requires iOS 15 or later. In Xcode choose File → Add Package Dependencies…, enter https://github.com/cluefolk/ios-sdk and add the Cluefolk library to the app target. Without Swift Package Manager, add Cluefolk.xcframework from the repository's releases with Embed & Sign.
  2. Keep a strong reference to an object implementing CluefolkEventListener; the SDK listener property is weak. Register it and call initialize; the identity-token provider is optional.
  3. Use all public methods on MainActor. Initialization returns while credentials load in the background; wait for onCluefolkReady() or isReady before opening support or signing in.
  4. The support button can then call open(from:) with a currently presented view controller; the player stays anonymous until loginWithIdentity succeeds. onCluefolkUnreadChanged updates the unread indicator.
  5. For Objective-C/Objective-C++, import Cluefolk/Cluefolk-Swift.h; the exposed names are CLFCluefolk, CLFOptions and CLFEventListener. Forward notification events on MainActor.
Swift Package Managerswift
.package(url: "https://github.com/cluefolk/ios-sdk", from: "0.3.2")
Initialize on MainActorswift
import Cluefolk

// MainActor; retain supportListener in your app.
let sdk = Cluefolk.shared
sdk.eventListener = supportListener
try sdk.initialize(CluefolkOptions(projectId: "YOUR_PROJECT_ID"))
// Optional: only if your game issues Cluefolk identity tokens.
sdk.setIdentityTokenProvider { completion in
    gameApi.fetchCluefolkIdentity { token, error in
        completion(token, error)
    }
}
Open support and sign inswift
// After onCluefolkReady(); works without sign-in (anonymous player):
sdk.open(from: presentingViewController)
sdk.openConversation("", from: presentingViewController) // current chat

// Optional, after successful game login:
sdk.loginWithIdentity(identityToken) { error in
    // Do not fail game login because of support.
}
do {
    try sdk.setConversationContext(["screen": "settings"])
} catch {
    // Report a support configuration error to the app.
}

// Game account sign-out:
sdk.logout()

Release builds use trusted HTTPS origins. Source code, changelog and releases: github.com/cluefolk/ios-sdk (MIT license).

Unity 2022.3 LTS and later

  1. In Window → Package Manager choose + → Add package from git URL… and enter https://github.com/cluefolk/unity-sdk.git#0.3.2, or add the line below to Packages/manifest.json.
  2. In Player Settings set Android Minimum API Level to 24 and Target API Level to 34 or higher, and iOS Target minimum iOS Version to 15.0 or higher. Below these the build stops with a message.
  3. Nothing to set up in Gradle or Xcode: Android builds add com.cluefolk:android-sdk of the same version from Maven Central and switch AndroidX on; iOS builds link and embed the bundled Cluefolk.xcframework.
  4. Call the facade from the Unity main thread. Subscribe to Cluefolk.Event, then initialize. The ready event sets Cluefolk.IsReady; after that Open() works for an anonymous player, and LoginWithIdentityAsync optionally links the game account.
  5. SetIdentityTokenProvider is optional. If the provider throws or returns an empty token, the player stays anonymous and Event reports error with code IDENTITY_UNAVAILABLE. Use the unreadChanged payload count for the game indicator; unsubscribe your handler when its owner is destroyed.
  6. Facade methods validate their arguments immediately and throw ArgumentException. Build and test Android/iOS players: Editor and desktop do not open the support WebView, and a C# source compile is not a device or IL2CPP validation.
Packages/manifest.jsonjson
"com.cluefolk.sdk": "https://github.com/cluefolk/unity-sdk.git#0.3.2"
Initialize the facadecsharp
using CluefolkSDK;

Cluefolk.Event += OnCluefolkEvent;
Cluefolk.Initialize(new CluefolkOptions { ProjectId = "YOUR_PROJECT_ID" });
// Optional: only if your game issues Cluefolk identity tokens.
Cluefolk.SetIdentityTokenProvider(
    () => GameApi.GetFreshCluefolkIdentityAsync());
After the ready eventcsharp
// After Event("ready", ...); works without sign-in:
Cluefolk.Open();
Cluefolk.OpenConversation(); // the player's current chat

// Optional, after successful game login:
try {
    await Cluefolk.LoginWithIdentityAsync(identityToken);
} catch (Exception error) {
    // Surface support failure without failing game login.
    Debug.LogWarning(error.GetType().Name);
}
Cluefolk.SetConversationContext(
    new Dictionary<string, object> { ["screen"] = "settings" });

// Game account sign-out:
Cluefolk.Logout();

The Unity package calls the native SDKs; it has no separate WebView, HTTP or session implementation. Source code and releases: github.com/cluefolk/unity-sdk (MIT license).

Push notifications through the game server

  1. The only route is: public support reply → Cluefolk queue → game backend /cluefolk/push → the game’s existing push provider → device. Device tokens, OS permission requests and Firebase/APNs keys stay with the game.
  2. Configure and verify Settings → Server connection. The game handler verifies the ES256 command JWT against the JWKS URL, its purpose, project, expiry and action: push.notify; it deduplicates by the stable eventId and persists its push job before acknowledging.
  3. Copy the signed push.data fields into the mobile notification unchanged. Android receives them as data; iOS receives them as top-level userInfo fields beside aps. playerId is the internal Cluefolk UUID, not the external game user ID.
  4. Notifications are requested only for players signed in through the game, because the game finds devices by its own player ID. Forward reception and taps through the platform calls below; a tap opens the matching conversation only for the configured project and the authenticated player.
  5. In Server connection → Test push, enter the game Player ID of a player with a public support reply, then choose Send test. Check Notifications and then the actual device. At most five tests per minute are accepted.
Notification data: preserve these fieldsjson
{
  "origin": "cluefolk",
  "projectId": "YOUR_PROJECT_ID",
  "playerId": "CLUEFOLK_PLAYER_UUID",
  "conversationId": "CONVERSATION_UUID",
  "messageId": "MESSAGE_UUID",
  "status": "open",
  "count": "1"
}
Android receive / tapkotlin
// Android: receive / notification tap
Cluefolk.handlePush(data)
Cluefolk.openFromPush(activity, data)
iOS receive / tapswift
// iOS: receive / notification tap, on MainActor
Cluefolk.shared.handlePush(userInfo)
Cluefolk.shared.openFromPush(userInfo, from: controller)
Unity receive / tapcsharp
// Unity: receive / notification tap
Cluefolk.HandlePush(data);
Cluefolk.HandlePush(data, opened: true);

Accepted means the game backend durably accepted the event. It does not prove the OS displayed a banner, or that the player read the reply.

Verify the complete integration

  1. Open support without signing in, send a message and check that the operator sees an anonymous player with device/app context. Then sign in through the game on the same install and check that the conversation moves to the verified player ID.
  2. Send a public operator reply, then reopen the game: history and unread count must already be available in SDK state. Open the reply and check unread/read updates; private notes must not be visible to the player.
  3. Connect the backend, refresh the typed catalog and verify an automatic badge against known player data. Separately test an operator-assigned manual badge, a published gift accepted by the game server and a gift that needs approval.
  4. Test a push while the game is active, in background and during a cold start. Verify project separation (a notification from another project, such as the one for development builds, does not open a conversation) and switch to another player before opening an old notification.
  5. Test offline/retry, logout and re-login, image attachments, oversized-image errors, the per-minute message limit and, if enabled, required sign-in. Verify on real Android/iOS players, including the Unity toolchains you ship.

A build or a successful server acknowledgement is only part of this check. Record the device, OS, SDK/adapter versions and the actual end-to-end result.

If something is not working

I can’t type a reply: the box is grey

The conversation belongs to a colleague; the line above the box says who. Write a Private note, or ask the colleague or an administrator to pass the conversation to you.

My reply was not sent: “… answered first”

A colleague answered the player a moment before you, so the conversation is theirs now. Your text is still in the box: switch to Private note to send it to the team, or ask the colleague to pass the conversation to you.

I can’t find a conversation

Choose All statuses, open All conversations under Views and clear the search and Filters. Then search by the player ID, a word from the messages, the game version or the phone system.

A gift has not arrived

Open the Gifts tab of the player card. Pending approval waits for an administrator (Settings → Gifts → Approvals). For Unknown, press Check delivery again. Granted means the game server accepted the gift: if the player still does not see it in the game, ask the game team. Do not send the gift again: that would be a second gift.

A badge is missing

Check that it is published, enabled and visible to the team. For an automatic badge, check current server data; for a manual badge, check that it is on the player.

A player cannot write to support

Check whether the player is banned and the Player messages limits in Queues & workflow: messages above the per-minute or per-hour limit are refused with a retry time. If Players and sign-in allows only players signed in through the game, anonymous players cannot open support.

No company or invitation appears

Check the signed-in email. Reload after the invitation is sent; ask for a new invitation if it has expired. If you are already in the company, an owner or a project administrator adds you under Settings → Team. You can also create your own company under Companies & invitations.

The server is not connected

Support works without a game server: players write anonymously and are identified by their app install. To verify players, use game attributes, gifts or notifications, an owner or administrator sets up the connection under Settings → Server connection.

Check connection or catalog refresh fails

Check the game server URL and that at least one profile signing key is registered, then share the error with the game-backend developer. A changed type needs a new attribute key; the last accepted catalog remains available.