WeCom Plugin
This guide uses a WeCom self-built application and an enterprise administrator able to configure the app, visibility, domains, and trusted IPs. Use the self-built application's Secret, rather than a group webhook or the directory synchronization assistant's Secret.
1. Create The Application
- Sign in to the WeCom administration console and create an application under App Management → Self-built
- Copy CorpId from My Enterprise → Enterprise Information
- Copy AgentId and the application's Secret from its details
- Include required members and departments in the application visibility scope. For a complete department tree, authorize the whole enterprise as supported by the console
WeCom self-built applications do not use Feishu contact:* or DingTalk qyapi_* permission codes. Available calls depend on the app type, Secret, visibility scope, enterprise settings, and endpoint rules.
| Feature | Provider preparation | Actual endpoint |
|---|---|---|
| Departments and members | Self-built app directory read access and visibility, plus server trusted IP | /cgi-bin/department/list, /cgi-bin/user/list |
| Confirm full department scope | Read application details; visibility includes the root department | /cgi-bin/agent/get |
| Personal application messages | Current app's AgentId and Secret, recipient visibility, server trusted IP | /cgi-bin/message/send |
| Authorized sign-in | Web authorization trusted domain, application home entry, and member consent for email and other sensitive data | Web authorization, /cgi-bin/auth/getuserinfo, /cgi-bin/user/get, /cgi-bin/auth/getuserdetail |
Server endpoints use https://qyapi.weixin.qq.com. Structure synchronization changes Soln data and does not need permission to write to WeCom contacts.
2. Prepare HTTPS And The Verification File
Use a tenant HTTPS address accessible to members and WeCom, such as https://workspace.example.com. Local development can use a stable HTTPS tunnel domain that meets WeCom's domain and verification requirements.
- Download the domain verification file from the app's Web Authorization and JS-SDK settings, for example
WW_verify_abcdef.txt - Keep its name and original text. Enter them separately in the plugin's Trusted domain verification filename and Trusted domain verification content fields
- Once the plugin is active, check that
https://workspace.example.com/WW_verify_abcdef.txtreturns the original text, not a login page or frontend HTML - Return to WeCom to complete domain verification and save
If WeCom provides the file before verification, download it, install the plugin, then complete verification. The plugin serves the configured file; uploading it to a business form or editing frontend directories is unnecessary.
3. Install The Soln Plugin
- Open Integration → Apps → Plugins and install WeCom
- Enter CorpId, AgentId, application Secret, verification filename, and verification content
- Normally select Match enabled tenant members by email. Explicit email allowlist also requires the allowlist; an allowlist does not create members
- After activation, copy the Identity Provider Redirect URL and Single Sign-On Entry URL from App Information
4. Configure Domains, Entry URLs, And Trusted IP Separately
| Setting | Location and format | Example |
|---|---|---|
| Web authorization trusted domain | App → Web Authorization and JS-SDK → Trusted Domain; enter a domain and complete verification | workspace.example.com |
| Web sign-in callback domain | When enabling WeCom Authorized Login → Web, set the callback domain, without the full callback path | workspace.example.com |
| Application home / desktop home | Use Soln's complete Single Sign-On Entry URL, including query parameters | Copy from Soln |
| Enterprise trusted IP | The self-built app's Enterprise Trusted IP; use the server's actual public outbound IP | 203.0.113.10 illustrates IPv4 syntax only; do not copy it |
The displayed callback may be https://workspace.example.com/plugins/wecom/callback. Fields asking for a trusted or callback domain take only workspace.example.com. The full URL is used by the authorization protocol and is not the application home URL.
Find The Trusted IP For Local Deployment
Query the public outbound address on the machine running the tenant plugin, for example:
curl -4 https://api.ipify.org
If Docker, a proxy, VPN, NAT, or relay changes the route, confirm the plugin's actual outbound address against the IP reported by WeCom. A host browser or terminal can use a different route from the plugin.
Do not enter 127.0.0.1, private 192.168.* or 10.* addresses, a tunnel hostname, its DNS IP, or the tunnel entry server's IP, unless that server is also the actual outbound route. Update trusted IP when the outbound address changes.
5. Fetch The Directory
Open Organization Mapping → Fetch Directory and review organizations, departments, and users separately. A returned organization alone does not establish successful department or member access; inspect app visibility, the Secret, and endpoint errors.
WeCom may restrict email, enterprise email, and phone fields in ordinary directory responses. Expanding app visibility is different from obtaining member consent for sensitive information. An empty email column is not a reason to repeatedly replace secrets or bind users merely by matching names.
6. Add Member Bindings Through Authorized Sign-In
When manually preparing hundreds of mappings is impractical, members can sign in through WeCom once to establish a verified binding.
- Enable the available Email and Enterprise Email fields under the app's Member Sensitive Information Authorization settings, completing any provider approval
- Populate the member's WeCom email to match an enabled Soln member. Create or import the Soln members first
- Confirm the WeCom connection is enabled in Account Center → SSO and the application's home points to the Soln sign-in entry
- The member opens the application from the WeCom client and confirms the requested email authorization. The plugin requests
snsapi_privateinfoand needs a provider-issueduser_ticket - After successful sign-in resolves the Soln member, the system adds the plugin binding for that CorpId and
userid. An authorized email is also added to the directory snapshot when available - Refresh Organization Mapping → Users, inspect the binding, then verify a personal notification
Every successful sign-in checks the mapping. Only missing bindings are added; existing conflicting bindings are not overwritten. An external userid already bound to another member, or a member already bound to another external account, requires administrator review.
This does not create Soln members or bypass seat and activation rules. Correct consent and profile data if email or user_ticket is missing, or no enabled member matches. A personal WeChat account, non-enterprise user, or unsupported entry cannot replace the WeCom enterprise-member authorization flow.
7. Configure Notifications And Structure Synchronization
| Requirement | Action |
|---|---|
| Approval, task, and ordinary reminders only | Bind available members, then add, select templates, save, and enable a business app under Message Push → Push Configuration |
| Structure synchronization | Fetch the directory, review existing-object bindings, configure fields under Sync Organization Structure, and enable separately |
| Missing external departments | Select keep, disable, or delete at the bottom of the sync dialog; processing requires confirmed enterprise-wide department scope |
Messages use the AgentId and Secret already configured in the plugin. No DingTalk AgentId is needed in push configuration. The plugin sends application text cards and Soln detail links rather than native WeCom approval instances.
See Enterprise Identity Plugins for the full workflow and seat rules.
Read The WeCom Lists
See Enterprise Identity Plugin Lists And Actions for columns, search, pagination, export, automatic binding, and delivery logs. Returned fields depend on application access, member consent, and populated profiles.
Organizations And Departments
| List or field | Meaning and values |
|---|---|
Organization external ID / corpid | Enterprise CorpId, distinct from root department 1; this row does not prove department/member access |
| Organization name | Readable root department name, or CorpId if unavailable |
Department id / parentid | Department / parent ID. Root is normally 1; parent 0 denotes the provider root level |
name / name_en | Name / English name of the same department |
department_leader | Leader userid array, without granting Soln permissions |
order | Ordering among siblings, not member count |
Users
| Field | Meaning and values |
|---|---|
userid / open_userid | Enterprise / service-provider-scoped ID; current binding and messages use userid |
name / alias / english_name | Name / alias / English name; do not identify people solely by name |
department / main_department | Department ID array / primary department; can differ from the internal member assignment |
order / is_leader_in_dept | Ordering / leader flags corresponding to departments. Leader flags use 1 yes and 0 no in the department array order |
status | 1 activated, 2 disabled, 4 not activated, 5 left enterprise; separate from binding state and Soln seats |
email / biz_mail | Email / enterprise email; ordinary directory calls can omit these. Authorized sign-in can supplement the snapshot and binding |
mobile / telephone | Mobile / landline, depending on endpoint access and consent |
gender | 0 undefined, 1 male, 2 female |
position / direct_leader | Position / direct manager userid array |
avatar / thumb_avatar | Avatar / thumbnail URL, displayed as an address |
address / qr_code | Address / personal QR code URL, when returned |
extattr.attrs | Custom profile attributes with names, types, and values |
extattr.attrs[].type | 0 text, 1 web. Inspect text.value or web.url and web.title accordingly |
external_position / external_profile | Public position / public profile, unrelated to internal permission assignments |
external_profile.external_corp_name | Public enterprise short name |
external_profile.external_attr | Public custom fields. type is 0 text, 1 web, or 2 mini program; inspect the corresponding structure |
external_profile.wechat_channels | Channels information. Its status is 0 confirmed/available or 1 pending, not an account activation state |
A row showing automatic binding despite an earlier empty email can result from WeCom authorized sign-in. It does not establish ordinary directory permission to read every member's email. Use View to verify userid, the bound member, and current email.
Provider message IDs in logs come from the application-send response. For unavailable recipients, first check userid, binding validity, and app visibility, then trusted IP and Secret. Substituting open_userid is not the solution.
Troubleshooting
| Symptom | Action |
|---|---|
| Outbound IP not allowed | Verify the plugin's public outbound path and add that IP to the current app's trusted IPs; checking the tunnel domain alone is insufficient |
| Organization returned but no departments or users | Check visibility, app Secret, member data, and endpoint errors. CorpId in the organization row does not prove member access |
| Directory has no email | Ordinary calls may omit sensitive fields. Enable sensitive-information authorization and have members complete authorized sign-in |
Missing user_ticket | Check sensitive-information authorization, trusted domain, member consent, and a WeCom entry supporting the flow |
| Authorized but no matching Soln member | Check the returned email, enabled member, CorpId, and existing login or plugin mapping conflicts |
| Message failed or recipient unavailable | Check this app's userid binding, visibility, AgentId/Secret, and trusted IP; do not use a userid from another enterprise |
| Verification file opens a login page | Check the tenant public route, proxy, and verification-file settings; the root URL must serve the original text |
| Tunnel domain changed | Update the tenant public origin, trusted domain, web sign-in callback domain, and application home. Change trusted IP only if outbound routing also changed |