# Whatsapp Otp

> Send WhatsApp OTP (one-time password) messages via CMI OmniChannel RCS API. Use when user asks to send verification code, OTP, or authentication code via WhatsApp. This skill requires authentication credentials and uses a pre-configured template.

- Skill: `dvcrn/whatsapp-otp` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add dvcrn/whatsapp-otp`
- Raw SKILL.md: https://api.skillmd.com/api/skills/dvcrn/whatsapp-otp/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: dvcrn (https://skillmd.com/u/dvcrn)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/dvcrn/whatsapp-otp

---


# WhatsApp OTP Sender

## Purpose
Send one-time password (OTP) messages through WhatsApp using the CMI OmniChannel RCS platform.

## Quick Start

When user requests to send a WhatsApp OTP:

1. **Ask for credentials** (if not already provided):
   - AccessKeyId
   - AccessKeySecret
   - ApplicationName (default: "default")
   - ApplicationSecret

2. **Ask for required parameters**:
   - `To`: Recipient phone number with country code, **no** + prefix (e.g., 8613800138000)
   - `otp_code`: The verification code to send (e.g., "123456")

   **Important phone number format**:
   - From (sender): +8618247665684 (with + prefix)
   - To (recipient): 8613800138000 (without + prefix)

3. **Use the script**: Call the Python script to send the message

   ```bash
   python scripts/send_whatsapp_otp.py \
     --access-key-id "$ACCESS_KEY_ID" \
     --access-key-secret "$ACCESS_KEY_SECRET" \
     --app-name "$APPLICATION_NAME" \
     --app-secret "$APPLICATION_SECRET" \
     --to "$TO_NUMBER" \
     --otp "$OTP_CODE"
   ```

## Fixed Configuration

- **Template Name**: `test_otp_cn_111501` (pre-configured in backend)
- **From Number**: `+8618247665684` (with + prefix)
- **Type**: `template`
- **Language**: `zh_CN`
- **Components**:
  - `body`: Contains OTP code parameter
  - `button`: URL button with index 0

## API Endpoint

- **URL**: `https://cpaas-rcs.cmidict.com:7081/singleSend`
- **Method**: `POST`
- **Headers**: `Content-Type: application/json`

## Security Considerations

**Important Notes**:

1. **SSL Certificate Verification**: The script uses a custom SSL adapter with permissive settings (`check_hostname=False`, `verify_mode=CERT_NONE`) to connect to the API endpoint. This is necessary because the CMI OmniChannel RCS API endpoint (`cpaas-rcs.cmidict.com:7081`) has a non-standard SSL/TLS configuration that causes connection failures with standard verification.

2. **Proxy Settings**: The script clears all proxy environment variables (`http_proxy`, `https_proxy`, etc.) to ensure direct connection to the API endpoint. This is required because:
   - The API endpoint may not be accessible through certain proxies
   - Proxy configurations in user environments can cause connection timeouts
   - Direct connection provides more reliable operation

**Security Impact**: These configurations are evaluated as **medium risk**. The script only affects communication with this specific API endpoint and does not impact other connections.

**Recommendation**: Work with your operations team to:
1. Investigate the SSL/TLS configuration of `cpaas-rcs.cmidict.com:7081`
2. Test if the API endpoint is accessible through your corporate proxy
3. Request the API provider to fix their certificate configuration
4. Re-enable standard SSL verification and proxy support once the endpoint is compliant

**Current Workaround**: The script includes inline comments documenting the reasoning for these security settings.

## Authentication

This API uses tenant-based authentication:
- `AccessKeyId`: Tenant identifier (e.g., `PAID_1881A95CE7AEDA00H204B`)
- `AccessKeySecret`: Tenant secret key (Base64 encoded)
- `Timestamp`: **Auto-generated by script** (ISO8601 UTC format, valid for 15 minutes)

**Important**: Do NOT manually provide timestamp. The script will generate it automatically at runtime.

## Response

Successful response (`Code: 0`):
```json
{
  "Code": 0,
  "Message": "OK",
  "Timestamp": "2023-01-01T12:00:00Z",
  "From": "+8618247665684",
  "To": "8613800138000",
  "BizId": "MDPG177BBCFD8301E42FH144E"
}
```

Error response (`Code != 0`):
```json
{
  "Code": 11998,
  "Message": "ERRCODE_invalid_parameter 120",
  "Timestamp": "2023-08-17T10:01:49Z"
}
```

## Usage Example

**User**: "Send a WhatsApp OTP to 8614749386918 with code 123456"

**Assistant**:
"I'll need your API credentials to send the WhatsApp OTP. Please provide:
- AccessKeyId
- AccessKeySecret
- ApplicationName (or use 'default')
- ApplicationSecret"

[User provides credentials]

[Assistant calls the script and reports result]

