
Research
/Security News
11 Malicious NuGet Tools Pose as Game Cheats to Drop a Windows Host-Surveillance Payload
11 malicious NuGet tools pose as game cheats to deploy Windows payloads, track hosts, and use Google Sheets for telemetry and control.
@sohu-bpd/wechat
Advanced tools
WeChat JS-SDK utility library with initialization helpers and SPA support.
config() and share() APIs for common tasksnpm install @sohu-bpd/wechat
# or
pnpm add @sohu-bpd/wechat
# or
yarn add @sohu-bpd/wechat
First, include the WeChat JS-SDK script in your HTML:
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
Option A: Zero Configuration (Sohu Domains Only)
If you're on https://act.go.sohu.com or https://test.r.ads.sohu.com, you can skip configuration entirely:
import { share } from '@sohu-bpd/wechat'
// No config needed! Just use it directly
await share({
title: 'My Page Title',
desc: 'Share description',
imgUrl: 'https://example.com/image.jpg',
})
Option B: Custom Configuration (Sohu Domains)
Or customize settings on supported domains:
import { config } from '@sohu-bpd/wechat'
// No need to provide getSignature on supported domains
config({
debug: false,
spa: true, // Enable SPA mode (default)
})
Option C: Custom Signature Function (Other Domains)
For other domains or custom backends:
import { config } from '@sohu-bpd/wechat'
config({
getSignature: async (url) => {
// Fetch signature from your backend
const response = await fetch(`/api/wechat/signature?url=${encodeURIComponent(url)}`)
return response.json()
},
debug: false,
spa: true, // Enable SPA mode (default)
})
import { share } from '@sohu-bpd/wechat'
// Set share content
await share({
title: 'My Page Title',
desc: 'Share description',
imgUrl: 'https://example.com/image.jpg',
link: 'https://example.com/page', // optional, defaults to current URL
})
import { config, share } from '@sohu-bpd/wechat'
// or
const { config, share } = require('@sohu-bpd/wechat')
<!-- Load WeChat JS-SDK first -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<!-- Then load this library -->
<script src="https://unpkg.com/@sohu-bpd/wechat/dist/index.global.js"></script>
<script>
const { config, share } = SohuWechat
config({
getSignature: async (url) => {
const res = await fetch('/api/wechat/signature?url=' + encodeURIComponent(url))
return res.json()
}
})
share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg'
})
</script>
Set global configuration for WeChat JS-SDK.
Note:
https://act.go.sohu.com or https://test.r.ads.sohu.com, calling config() is optional - the library will auto-configure with defaults when you use features like share()interface GlobalConfig {
/**
* Function to fetch signature, receives current URL
* - Optional on https://act.go.sohu.com or https://test.r.ads.sohu.com
* - Will auto-use built-in signature (requests /wechat/ticket) if not provided
* - Required on other domains
*/
getSignature?: (url: string) => Promise<SignatureResult>
/** Enable debug mode, default false */
debug?: boolean
/** Enable SPA mode (auto re-init on URL change), default true */
spa?: boolean
}
function config(options?: GlobalConfig): void
Example - No configuration needed (Sohu domains):
import { share } from '@sohu-bpd/wechat'
// Just use it directly!
await share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg',
})
Example - Custom signature function:
config({
getSignature: async (url) => {
const res = await fetch(`/api/wechat/signature?url=${encodeURIComponent(url)}`)
return res.json()
},
debug: process.env.NODE_ENV === 'development',
spa: true,
})
Example - Custom settings with built-in signature (Sohu domains):
// On https://act.go.sohu.com or https://test.r.ads.sohu.com
config({
debug: true,
spa: true,
})
Set WeChat share content for both friends and moments.
interface ShareOptions {
/** Share title */
title: string
/** Share description (for friends) */
desc?: string
/** Share link, defaults to current URL */
link?: string
/** Share image URL */
imgUrl: string
}
function share(options: ShareOptions): Promise<void>
Example:
await share({
title: 'Amazing Product',
desc: 'Check out this amazing product!',
imgUrl: 'https://example.com/product.jpg',
link: 'https://example.com/product/123',
})
Get current global configuration (throws if not configured).
function getConfig(): GlobalConfig
Check if global configuration has been set.
function isConfigured(): boolean
For advanced use cases, you can use the low-level APIs:
Check if the current environment is WeChat browser.
function isWechat(): boolean
Example:
import { isWechat, share } from '@sohu-bpd/wechat'
// Conditionally show share UI only in WeChat
if (isWechat()) {
showShareButton()
}
// Or just call share() - it will silently do nothing outside WeChat
await share({
title: 'My Page',
imgUrl: 'https://example.com/image.jpg',
})
Initialize WeChat SDK (automatically called by high-level APIs).
Note: Requires WeChat JS-SDK to be loaded globally first. Silently returns in non-WeChat environments.
function initSDK(): Promise<void>
Get the global wx object after SDK is loaded. Returns null in non-WeChat environments or if wx is not available.
function getWx(): WxSDK | null
Reset SDK state (useful for testing or manual re-initialization).
function resetSDK(): void
For use cases that don't need global configuration.
Note: Requires WeChat JS-SDK to be loaded globally first.
interface InitConfig {
/** Public account appId */
appId: string
/** Signature timestamp */
timestamp: number | string
/** Signature nonce string */
nonceStr: string
/** Signature */
signature: string
/** JS API list to use */
jsApiList: string[]
/** Enable debug mode */
debug?: boolean
}
function init(config: InitConfig): Promise<void>
By default, spa: true is enabled, which means:
share()), the SDK is initialized with the current URLTo disable SPA mode:
config({
// ...
spa: false, // Only initialize once
})
On specific Sohu domains, the library provides built-in signature functionality:
https://act.go.sohu.comhttps://test.r.ads.sohu.comWhen you call config() without providing getSignature on a supported domain:
/wechat/ticketSignatureResult formatThe built-in signature function sends a GET request to:
/wechat/ticket?url={encoded_current_url}
Parameters:
url (query parameter): The current page URL (URL-encoded)Example Request:
GET /wechat/ticket?url=https%3A%2F%2Fact.go.sohu.com%2Fpage%3Fid%3D123
The built-in signature endpoint /wechat/ticket should return:
{
code: number // 0 for success
data: {
app_id: string // Converted to appId
timestamp: number // Kept as timestamp
nonce_str: string // Converted to nonceStr
signature: string // Kept as signature
}
message: string // Error message if code !== 0
}
Notes:
fetch API if available (modern browsers)XMLHttpRequest in older environmentsSignatureResult interfaceZero Configuration (Recommended):
import { share } from '@sohu-bpd/wechat'
// No config() needed on supported domains!
await share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg',
})
With Custom Settings:
import { config, share } from '@sohu-bpd/wechat'
// Optional: customize settings
config({
debug: true,
spa: true,
})
// Then use normally
await share({
title: 'My Page',
desc: 'Description',
imgUrl: 'https://example.com/image.jpg',
})
Even on supported domains, you can provide your own getSignature function:
config({
getSignature: async (url) => {
// Your custom implementation
return await fetchSignatureFromCustomAPI(url)
},
})
For domains not in the built-in list, or to customize built-in domains, use the domainConfigs option:
import { config } from '@sohu-bpd/wechat'
config({
domainConfigs: {
'https://your-domain.com': {
endpoint: '/api/wechat/signature',
urlParamKey: 'url',
}
}
})
If your backend returns a different response format:
config({
domainConfigs: {
'https://your-domain.com': {
endpoint: '/api/sign',
urlParamKey: 'pageUrl',
transformResponse: (response) => {
// Convert your custom format to standard SignatureResult
return {
appId: response.appid, // Map from your field names
timestamp: response.ts,
nonceStr: response.nonce,
signature: response.sign
}
}
}
}
})
The library uses the following priority order (highest to lowest):
getSignature function - Complete overridedomainConfigs for current domain - Per-domain customizationExample - Priority demonstration:
// Priority 1: getSignature always takes precedence
config({
getSignature: async (url) => {
// This will be used, domainConfigs ignored
return await fetchFromCustomAPI(url)
},
domainConfigs: {
'https://act.go.sohu.com': {
endpoint: '/ignored' // This won't be used
}
}
})
// Priority 2: domainConfigs overrides built-in defaults
config({
domainConfigs: {
'https://act.go.sohu.com': {
endpoint: '/custom/ticket', // Overrides default /wechat/ticket
urlParamKey: 'targetUrl' // Overrides default 'url'
}
}
})
// Priority 3: Built-in defaults (no config needed)
// On https://act.go.sohu.com or https://test.r.ads.sohu.com
await share({
title: 'My Page',
imgUrl: 'https://example.com/image.jpg'
})
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
| endpoint | string | No | '/wechat/ticket' | Signature API endpoint path |
| urlParamKey | string | No | 'url' | Query parameter name for URL |
| transformResponse | function | No | Built-in transform | Response format converter |
Your signature endpoint should:
url)Option A: Use built-in format (no transformResponse needed):
{
"code": 0,
"data": {
"app_id": "wx123456",
"timestamp": 1234567890,
"nonce_str": "abc123",
"signature": "sha1signature"
},
"message": "success"
}
Option B: Use custom format with transformResponse:
{
"appid": "wx123456",
"ts": 1234567890,
"nonce": "abc123",
"sign": "sha1signature"
}
With config:
transformResponse: (res) => ({
appId: res.appid,
timestamp: res.ts,
nonceStr: res.nonce,
signature: res.sign
})
All APIs are safe to call in non-WeChat environments (desktop browsers, other mobile browsers, SSR, etc.). They will silently return without throwing errors, so your application works normally:
import { share, init, initSDK, isWechat } from '@sohu-bpd/wechat'
// These all work safely in any environment:
// share() resolves immediately in non-WeChat
await share({
title: 'My Page',
imgUrl: 'https://example.com/image.jpg',
})
// init() resolves immediately in non-WeChat
await init({
appId: 'wx123',
timestamp: 123,
nonceStr: 'abc',
signature: 'sig',
jsApiList: [],
})
// initSDK() resolves immediately in non-WeChat
await initSDK()
// Use isWechat() to conditionally show WeChat-specific UI
if (isWechat()) {
showWeChatShareButton()
}
This design allows you to integrate WeChat sharing without wrapping every call in environment checks.
On iOS WeChat, the signature URL should be the first entry URL of the app, not the current URL. This library handles this automatically:
You don't need to do anything special - it just works.
Your backend should provide an endpoint that generates WeChat JS-SDK signatures. Here's an example implementation:
// Node.js + Express example
app.get('/api/wechat/signature', async (req, res) => {
const url = req.query.url as string
// Generate signature using WeChat's algorithm
const signature = await generateWeChatSignature(url)
res.json({
appId: 'your-app-id',
timestamp: signature.timestamp,
nonceStr: signature.nonceStr,
signature: signature.signature,
})
})
Refer to WeChat JS-SDK Documentation for signature generation details.
Full TypeScript definitions are included:
import type {
GlobalConfig,
SignatureResult,
ShareOptions
} from '@sohu-bpd/wechat'
const config: GlobalConfig = {
sdkUrl: '...',
getSignature: async (url: string): Promise<SignatureResult> => {
// ...
}
}
.mjs) - Modern JavaScript modules.js) - Node.js and bundlers.global.js) - Browser <script> tag with global SohuWechatisWechat() function to check if running in WeChat browsergetWx() now returns WxSDK | null instead of throwing errorsshare(), init(), and initSDK() resolve immediately in non-WeChat environmentshttps://act.go.sohu.com and https://test.r.ads.sohu.com, you can now use the library without calling config() at allgetSignature is now optional on supported domains/wechat/ticket?url={current_url} endpoint on supported domainsfetch API with automatic fallback to XMLHttpRequest for older browserssdkUrl configuration option from GlobalConfigloadSDK() export from public APIconfig() and share() APIsMIT
FAQs
WeChat JS-SDK utility library
We found that @sohu-bpd/wechat demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
11 malicious NuGet tools pose as game cheats to deploy Windows payloads, track hosts, and use Google Sheets for telemetry and control.

Research
/Security News
4 compromised asyncapi packages deliver miasma botnet loader on macOS, Linux and Windows.

Research
/Security News
A compromised jscrambler npm release added a malicious preinstall hook that runs hidden native binaries on Linux, macOS, and Windows.