PortalLoginMethod
Signing a member into the portal through the platform — the button, the handshake the core mints, how the connector completes it from its inbound side, and what the member sees.
Subscriby\Connector\Contracts\Ports\PortalLoginMethod. Bound by portal_login.
A member who bought through the platform has no password. The portal offers one sign-in button per installed connector with this port; the core mints a handshake (a two-sided proof with a token and a lifetime), the connector says how the member presents it on the platform, and the connector's inbound side completes it with the account that answered. The core polls the handshake and signs the member in when it completes.
Methods
| Method | Called when | Returns |
|---|---|---|
button() | The portal's sign-in sheet lists the methods of the project's installed connectors; the kit. | PortalLoginButton |
begin(installation, ProjectRef, HandshakeRef) | The member taps the button: the core has opened the handshake and asks how the sign-in starts. | PortalLoginStart |
button()
PortalLoginButton: label (a translation key, "Continue with Telegram") and icon (a key from Subscriby's connector icon set, usually your connector's own). Both non-empty.
begin()
The HandshakeRef carries the handshake's id, purpose (HandshakePurpose::PortalLogin) and the token the member must present. Answer a PortalLoginStart:
token: echo the token.url: where the member goes to present it, usuallyInstallationLifecycle::startLink($installation, $payload)with the token in the payload.instructions: what to do by hand when the link cannot open (type a command with the token in a chat with the installation).
The installation is the project's live installation on your connector and the ProjectRef names whose portal it is, so a project-bound handshake can only complete through that project's own installation.
Completing it
The core never sees the platform; your inbound handler does. When an account presents the token (opens the deep link, types the command), your handler:
- asks
Core\Identities::isHandshakeToken($token)when the token arrived as a typed word, so a wizard answer that happens to look like a code is left to its wizard; - builds an
IdentityRecordfor the account that answered (whatIdentityResolver::adopt()would file); - calls
Core\Identities::completeHandshake($token, $record, $seenBy)with the installation that heard the account.
The core decides what the handshake was for: for a portal login it finds or creates the account's member in the handshake's project, links the identity, and answers a HandshakeCompletion with the subjectName and a returnUrl the connector may show the member ("Open the portal"). HandshakeRefused is thrown when the token names no pending handshake, the account already belongs to someone else, another project's installation heard it, or the purpose is not completed through this call; tell the member the link expired and offer a fresh start.
The same handshake, other purposes
Creator links (a creator adding an account under Linked accounts), member links from the portal's Connected accounts, recovery relinks and backup identities are the same table and the same completeHandshake() call with other HandshakePurposes. Your inbound handler need not know the purpose: it presents the account, and the core writes the right link.
How Telegram does it
The portal shows the bot's deep link carrying the handshake's auth_ payload; the bot's /start routes it to the customer handler, which offers the chat's identity back to the core. The typed command is the manual route for Telegram Web, where deep links do not always open.
What the kit checks
portal_login.button: button() returns a label and an icon that are both non-empty.
Only the token proves anything
Never sign a member in from a display name, a username or an external id you were told in a message. The handshake token is the proof; the account that presents it in a private conversation with the installation is the account that gets linked.
How is this guide?
SupportRelay
Carrying a support conversation between a member and a creator over the platform — relay modes, replies, group threads and attachments, and where the inbox stays.
RegistersCreators
Creating a creator account from inside the platform — where the sign-up starts, the conversation the connector runs, and the Core API call that creates the email-first account.