OnePass · Site owner integration guide

Add push notifications to your website with push-sdk.js

No self-hosted push service, no integrating DingTalk, Feishu and email one by one. Your user exchanges an email address for a channel code, and from then on anything worth a reminder on your site can reach the chat app they already use.

1What is worth pushing to your users

Email open rates keep falling, in-site messages wait for the user to come back, and SMS is expensive and easily filtered. Push the things a user must know right away to the DingTalk, Feishu or Telegram they already use.

Content updates

New posts, videos or releases: subscribers get the title and link immediately.

Subscribed topics

Users follow authors, sections or tags and only get what they actually care about.

Back in stock

Shoppers register for a restock alert and get notified when the item is available again.

Price changes

Price drops, membership renewals or a sale starting: tell them the moment the price moves.

Announcements

Maintenance windows, recovery notices and policy changes in one broadcast.

Order and shipping status

Paid, shipped, out for delivery, delivered: key milestones reach the user's phone.

Replies and mentions

Someone replied to a post or liked a comment; no need to keep refreshing the site.

Expiry and renewal

Membership, certificate, domain or trial expiring: remind them a few days ahead.

Events and launches

Reserved livestreams, courses and limited items notify on time.

Security alerts

Login from a new location, password change or binding update: tell the account owner first.

Approvals and tickets

A ticket got a reply, an approval passed or was rejected: push it to the requester.

Cloud drive updates

A subscribed folder or share link gets new files and versions, automatically delivered to the user's chat app.

2What OnePass solves

You only maintain when to push, to whom and what. Delivery is handled for you.

  • Many channels: WeCom group bot, DingTalk bot, Feishu bot, WeCom app messages, Bark (iOS), Telegram, Discord, custom webhooks, browser notifications, plus QQ / 163 / 126 / Sohu / 139 / 189 / Sina / Aliyun mailboxes and the official email service.
  • Aggregated channels: one combo channel can hold multiple sub-channels; a single call reaches the on-call phone, the team group and the mailbox, and the caller only stores one code.
  • No repeated integration: no per-platform bot registration, signature research or token expiry handling. One API call, the differences are absorbed by OnePass.
  • One SDK everywhere: push-sdk.js supports a browser <script> tag, CommonJS and ES modules.
  • Users manage their own receivers: adding a channel or switching devices is done on the site; your code does not change.
  • Delivery records: every push is logged so you can confirm what actually arrived.
In one sentence: you own business events, users own receiver choice, and delivery, retries and multi-client adaptation are handled by OnePass.

3Five-minute setup

Four steps: load the SDK, give the user a channel code, store the code in the user profile, call one push when an event happens.

  1. Load the SDKOne script tag at the bottom of the page; the official CDN is ready to use.
  2. Create an SDK instancePass an mcpSource that identifies your site, so calls can be grouped in the backend.
  3. Give the user a channel codeStart an authorization with the user's email; after they enter the verification code, the SDK hands the channel code back.
  4. PushWhen a business event fires, request /services/push/trigger/<channel-code> and the message goes to the receivers the user configured.

3.1 Load and initialize

<script src="https://push.phprm.com/static/js/push-sdk.js"></script>
<script>
var pushSdk = YfPush.create({
  apiBase: 'https://www.phprm.com',  // default, can be omitted
  mcpSource: 'my-website'            // your site id, used to tell callers apart
});
</script>

Projects with a bundler can import YfPush from './push-sdk.js', and Node can require('./push-sdk.js').

4Trade a user email for a channel code

Users do not need an account on your site or on the OnePass website. With their email you can open a dedicated push channel for them.

4.1 What the user experiences

  1. You start an authorization sessionCall pushSdk.createEmailSession(email) and get an authorization link valid for 10 minutes.
  2. The user opens the linkThe page shows the recipient address and sends a verification-code email.
  3. The user enters the codeThey sign in on the OnePass page with the code from the email.
  4. The SDK collects the channel codePoll pushSdk.pollSession(sessionId); when the status is success you get that user's channel code.
New vs. existing users: if the email is new, signing in automatically opens a channel for the user. If the email is already registered, the existing channel code is returned and reused instead of creating a duplicate.

4.2 The easiest path: mount the built-in authorization card

The SDK ships a complete "one-click setup" card with login-method dropdown, email input, code guidance and polling. You only provide a container:

<div id="auth-slot"></div>

<script src="https://push.phprm.com/static/js/push-sdk.js"></script>
<script>
YfPush.create({ mcpSource: 'my-website' }).mountAuthCard('#auth-slot', {
  title: 'Subscribe to updates',
  desc: 'Get a verification code by email; afterwards new content is pushed to the chat app you use.',
  onSuccess: function (result) {
    // result.channelCode is this user's push channel code
    fetch('/api/save-channel', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ channelCode: result.channelCode })
    });
  }
});
</script>

The card reads the currently supported login methods from the server (Feishu, DingTalk, Gitee, GitHub, email code). When OnePass adds a login method, your code does not change.

4.3 Build your own UI: two manual calls

var pushSdk = YfPush.create({ mcpSource: 'my-website' });

// 1. Create an authorization session with an email
pushSdk.createEmailSession('user@example.com').then(function (session) {
  // session.sessionId / session.authUrl / session.pollInterval / session.expiresIn
  window.open(session.authUrl, '_blank');   // the user enters the email code here

  // 2. Poll at pollInterval until success
  var timer = setInterval(function () {
    pushSdk.pollSession(session.sessionId).then(function (r) {
      if (r.status === 'pending') { return; }

      clearInterval(timer);
      if (r.status === 'success') {
        saveChannelCode(r.channelCode);     // store it in your user profile
      } else {
        // expired / consumed / failed: ask the user to start again
      }
    });
  }, (session.pollInterval || 5) * 1000);
});
StatusMeaningWhat to do
pendingThe user has not finished signing inKeep polling at pollInterval
successThe code is ready and returned onceSave channelCode immediately
expired / consumed / failedThe session expired or was already usedStop polling and ask the user to restart

Recommendation: add a push_channel_code field to your user table. Each user gets their own channel code, so disabling, resetting and checking records stay independent.

5Channel management API and page mapping

These APIs map one-to-one to the buttons on the channel share page. If you do not want to write code yet, click through that page first to understand what each channel manages.

Page actionSDK methodNotes
Refresh / list channelspushSdk.listChannels(code)Returns the parent channel and its sub-channels (name, type, code, status, QR address).
Add a push channelpushSdk.addChannel(code, params)Pick a type and a name. Bots need a webhook and signing secret; WeCom apps need corp ID, agent ID and secret; email needs sender name, address and auth code.
EditpushSdk.editChannel(code, params)Rename, change webhook or config, enable/disable (status 0/1).
DeletepushSdk.deleteChannel(code, targetCode)Delete a sub-channel. The channel bound to the current page is protected by the server.
Reset codepushSdk.resetChannel(code, targetCode)Returns a new channel code; the old one stops working immediately.
TestpushSdk.sendPushMessage(code, message)Send a test message to a channel and confirm the receiver gets it.
Push recordspushSdk.recordsUrl(qrCodeUrl)Turn a channel QR address into its push-record page.
Login-method dropdownpushSdk.listProviders()Returns the supported login methods so you can draw your own form.
One-click cardpushSdk.createAuthSession() + pushSdk.pollSession()Or call mountAuthCard to mount the ready-made card.
Token (automatic)pushSdk.accessToken(code)Exchanges the channel code for a short-lived token (2 hours by default) and retries once on 401/403.
What a channel code is: a 32-character hex string that identifies where to send. A parent code reaches every sub-channel in the group; a sub-channel code reaches only that one receiver.

6Sending messages

With a channel code, a push is one URL request carrying head, body, url and avatar.

6.1 The simplest way: one URL is one push

https://www.phprm.com/services/push/trigger/YOUR_CODE?head=New+post+published&body=How+to+choose+a+push+channel&url=https://your-site.com/post/123&avatar=https://your-site.com/logo.png

Open it in a browser or request it with fetch / $.getJSON; the message reaches the receiver configured for that channel. URL-encode values containing spaces, non-ASCII text or &.

6.2 Server-side cron and background events: use POST

Events such as "item back in stock" or "announcement updated" are easier to send from the server; long bodies also belong in POST.

curl -X POST "https://www.phprm.com/services/push/trigger/YOUR_CODE" \
  -H "Content-Type: application/json" \
  -d '{"head":"Back in stock","body":"The item you follow is available again.","url":"https://your-site.com/item/123","avatar":"https://your-site.com/logo.png"}'

POST only accepts application/json. SDK projects can call pushSdk.sendPushMessage(code, { head, body, url, avatar }) with the same parameters.

ParameterRequiredNotes
headYesTitle. One message, one conclusion; shorter is better.
bodyNoBody, Markdown supported. Use POST when it gets long.
urlNoLink opened when the message is clicked; must be a valid URL.
avatarNoIcon URL (supported by some channels).

6.3 Security notes

  • A channel code is a push credential: do not show it to unrelated people or commit it to a public repository.
  • A combo channel code reaches every sub-channel, so keep it server-side; the front end should only use the current user's own sub-channel code.
  • If you suspect a leak, call resetChannel; the old code stops working immediately.
  • Give every user their own sub-channel so disabling, resetting and record checks stay independent.

7FAQ

The user did not receive the verification email

Ask them to check spam and promotions folders and confirm the address. A session lasts 10 minutes; if it expired, call createEmailSession again.

Polling returns expired / consumed / failed

That session is no longer usable. Stop polling and let the user start over. Do not reuse the old sessionId.

The API says the token is invalid

The SDK refreshes the token once automatically. If it still fails, the page has likely been open too long or the code was reset; refresh the page or obtain the channel code again.

What does a channel code look like

A 32-character hex string, case-insensitive. The QR code is just another representation of it.

The user wants to switch receivers

They can add or edit channels on the OnePass channel management page. Your code does not change and their channel code stays the same.

Do I need my own server as a relay

No. The trigger URL works from anywhere and the SDK talks to the official service directly from the browser. Server-side cron and background events call the same trigger endpoint.

8Related project: AI danmu widget

The open-source teakong/danmu puts real-time bullet chat on any website. It reuses the push channel described here: one danmu is one push message, delivered in real time over WebSocket and rendered by the page.

  • One-line integration: a single script tag loads dependencies, connects the channel and renders danmu; pure front end.
  • Real-time WebSocket: based on Socket.IO; every page subscribed to the same channel sees the danmu at once.
  • AI-generated danmu: at a configured interval it reads the current page and asks a large model to generate danmu.
  • Interaction and plugins: danmu support likes and close; plugins=control opens the bottom-left settings panel, plugins=input opens the send box.
  • Backend filtering: the danMuFilter callback can validate content asynchronously and query like counts.
  • Compatibility: strict ES5, works in IE and GBK pages; falls back to cookies when localStorage is unavailable.

One-line integration

<script src="https://ws.phprm.com/static/customer/js/danmu.js?appName=MySite&channelCode=YOUR_CODE&danMu=1&plugins=control,input"></script>

Sending a danmu is also one line; every page subscribed to the channel sees it immediately:

$.getJSON('https://www.phprm.com/services/push/trigger/YOUR_CODE?head=First+danmu');

More parameters, plugins and backend filtering: github.com/teakong/danmu (Gitee mirror: gitee.com/teakong/danmu).

9SKILL integration: teach an AI assistant to push

The official Agent Skill teakong/push-server makes "push a notification when the task finishes" the AI's default behavior. Pure MCP calls, no script and no runtime dependency; works in Trae, Claude, Cursor, WorkBuddy and other clients.

  • One command to install: npx skills add teakong/push-server, add -g for a global install.
  • Pure MCP: pushes go through the remote push-server MCP server; no generated scripts, no runtime.
  • Push conventions built in: conclusion-first titles, Markdown bodies, single vs. multi-message decisions and link cleanup before sending.
  • Queryable results: token exchange plus message list/detail APIs, so the AI can check what it already pushed and manage channels.
  • Structured payloads: pass JSON as body and a webhook channel forwards it unchanged to your backend.

Install and configure

Installing the skill is not enough: add the remote MCP server (Streamable HTTP) in your AI client and put the channel code in the headers.

# Install into the current project (add -g for global)
npx skills add teakong/push-server
npx skills add teakong/push-server -g
{
  "mcpServers": {
    "push-server": {
      "url": "https://www.phprm.com/services/push/mcp",
      "headers": {
        "X-Push-Channel-Code": "your-32-char-code",
        "X-Mcp-Source": "trae"
      }
    }
  }
}

Choose Streamable HTTP, not SSE. Some clients need "type": "streamable-http"; if the field is rejected, delete it. Keep the channel code in the header only, never in a repository. More: github.com/teakong/push-server and the MCP configuration page.

Try channel management on the OnePass website first

Open a channel with an email, then add, edit and test pushes directly on the page. Once it makes sense, wire the API into your site.

https://push.phprm.com/message/share.html

The page above is only a reference UI; developers can style their own.

push-sdk.js integration guide · OnePass. Every example also works through SKILL with any agent.

push-sdk.js Integration Guide for Site Owners

This guide explains how to use the OnePass browser SDK (push-sdk.js) to send notifications to your own website users. You load one script, exchange a user's email for a 32-character channel code through a verification-code authorization, store that code in your user profile, and then send pushes by requesting the trigger URL or calling the SDK. OnePass handles delivery to DingTalk, Feishu, WeCom, Bark, Telegram, Discord, email and custom webhooks.

Quick start

  • Load https://push.phprm.com/static/js/push-sdk.js and create an instance with your own mcpSource.
  • Mount the built-in authorization card or call createEmailSession and poll pollSession until the status is success.
  • Save the returned channel code, then push with /services/push/trigger/<code> or pushSdk.sendPushMessage.

What you can do on this page

  • Pick a scenario: twelve common website events that justify a push, from content updates and restocks to security alerts.
  • Follow the four-step setup: copy-ready script snippets for loading the SDK and creating an instance.
  • Open a channel with an email: the built-in card, the manual two-call flow, and a status table explaining pending / success / expired.
  • Map the channel API: every channel management method next to the corresponding button on the share page.
  • Send messages: GET URL, JSON POST via curl, the head/body/url/avatar parameter table and security rules.
  • Add related products: the open-source AI danmu widget and the push-server SKILL for AI assistants, both reusing the same channel code.

Note: the documentation is public, but every example needs a real channel code. A channel code is a credential - do not commit it to a public repository.