init server python để điều khiển adb

This commit is contained in:
Victor Phan
2026-07-21 08:54:30 +07:00
parent d36007d989
commit 7625bdd37b
1557 changed files with 326 additions and 53 deletions
+5
View File
@@ -0,0 +1,5 @@
{
"tabWidth": 4,
"printWidth": 120,
"semi": true
}
+163
View File
@@ -0,0 +1,163 @@
# Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement through:
- **GitHub Issues**: Create a private issue with the `[CONDUCT]` label
- **GitHub Discussions**: Use the "Community" category for general concerns
- **Direct Contact**: Reach out to any team member through GitHub
- **Team Members**:
- [@RFS-ADRENO](https://github.com/RFS-ADRENO)
- [@truong9c2208](https://github.com/truong9c2208)
- [@JustKemForFun](https://github.com/JustKemForFun)
All complaints will be reviewed and investigated promptly and fairly by the team.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
## Special Considerations for zca-js
Given that zca-js is an unofficial API library for Zalo, we have additional
guidelines specific to our project:
### Responsible Usage
* **Respect Zalo's Terms of Service**: While this is an unofficial library,
users should be aware of and respect Zalo's terms of service
* **Account Safety**: Do not encourage or provide guidance on circumventing
Zalo's security measures
* **Privacy**: Respect user privacy and do not share personal information
obtained through the API
* **Rate Limiting**: Encourage responsible usage that doesn't overload Zalo's
servers
### Technical Discussions
* **Security**: When discussing security-related topics, use appropriate
channels and follow responsible disclosure practices
* **Bugs and Issues**: Report bugs and issues through proper channels
* **Documentation**: Help improve documentation and examples for the community
---
**Note**: This Code of Conduct is a living document and may be updated as our
community grows and evolves.
+470
View File
@@ -0,0 +1,470 @@
# Contributing to zca-js
Thank you for your interest in contributing to zca-js! This project is maintained by the community and we welcome all contributions.
## Table of Contents
- [Code of Conduct](#code-of-conduct)
- [Getting Started](#getting-started)
- [Development Setup](#development-setup)
- [How to Contribute](#how-to-contribute)
- [Pull Request Process](#pull-request-process)
- [Code Style Guidelines](#code-style-guidelines)
- [Testing Guidelines](#testing-guidelines)
- [Documentation Guidelines](#documentation-guidelines)
- [Security Guidelines](#security-guidelines)
- [Release Process](#release-process)
- [Getting Help](#getting-help)
## Code of Conduct
This project adheres to our [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you agree to abide by these rules.
## Getting Started
### Prerequisites
- Node.js >= 18.0.0
- Bun (recommended) or npm
- Git
### Fork and Clone
1. Fork this repository
2. Clone your fork:
```bash
git clone https://github.com/YOUR_USERNAME/zca-js.git
cd zca-js
```
3. Add upstream remote:
```bash
git remote add upstream https://github.com/RFS-ADRENO/zca-js.git
```
## Development Setup
### Install Dependencies
```bash
# Using Bun (recommended)
bun install
# Or using npm
npm install
```
### Build Project
```bash
# Build both ESM and CJS
bun run build
# Build ESM only
bun run build:esm
# Build CJS only
bun run build:cjs
```
### Run Tests
```bash
# Run feature tests
bun run test:feat
# Run specific test file
bun run test/test.ts
```
### Code Formatting
```bash
# Format code with Prettier
bun run prettier
```
## How to Contribute
### Types of Contributions
We welcome the following types of contributions:
- 🐛 **Bug Reports**: Report bugs and issues
- ✨ **Feature Requests**: Suggest new features
- 🔧 **Code Contributions**: Fix bugs and add features
- 📚 **Documentation**: Improve docs and examples
- 🧪 **Tests**: Add or improve tests
- 🔒 **Security**: Report security vulnerabilities
- 🌐 **Translations**: Translate docs to other languages
### Before You Start
1. **Check existing issues**: Search for existing issues before creating new ones
2. **Discuss major changes**: Create an issue to discuss major changes
3. **Follow the roadmap**: Check the current roadmap and priorities
## Pull Request Process
### Creating a Pull Request
1. **Create a feature branch**:
```bash
git checkout -b feature/your-feature-name
# or
git checkout -b fix/your-bug-fix
```
2. **Make your changes**:
- Follow code style guidelines
- Add tests for new functionality
- Update documentation if needed
3. **Test your changes**:
```bash
bun run build
bun run test:feat
```
4. **Commit your changes**:
```bash
git add .
git commit -m "feat: add new API method for group management"
```
5. **Push to your fork**:
```bash
git push origin feature/your-feature-name
```
6. **Create a Pull Request**:
- Use the provided PR template
- Link related issues
- Provide clear description of changes
### PR Review Process
1. **Automated checks** must pass
2. **Code review** by at least one maintainer
3. **Security review** for security-related changes
4. **Documentation review** for API changes
5. **Final approval** before merge
## Code Style Guidelines
### TypeScript Guidelines
- Use TypeScript strict mode
- Prefer interfaces over types for object shapes
- Use meaningful variable and function names
- Add JSDoc comments for public APIs
- Use async/await over Promises when possible
### Code Organization
The project follows a modular structure for better maintainability and organization:
```
zca-js/
├── src/ # Source code directory
│ ├── apis/ # API methods (100+ files)
│ │ ├── sendMessage.ts # Core messaging functionality
│ │ ├── login.ts # Authentication methods
│ │ ├── loginQR.ts # QR code login
│ │ ├── listen.ts # Event listening
│ │ ├── sendVideo.ts # Video sending
│ │ ├── sendVoice.ts # Voice sending
│ │ ├── sendSticker.ts # Sticker sending
│ │ ├── createGroup.ts # Group management
│ │ ├── addReaction.ts # Message reactions
│ │ ├── uploadAttachment.ts # File uploads
│ │ └── ... # 90+ other API methods
│ ├── models/ # TypeScript interfaces and types
│ │ ├── Message.ts # Message interface
│ │ ├── Attachment.ts # File attachment types
│ │ ├── Reaction.ts # Reaction types
│ │ ├── FriendEvent.ts # Friend event types
│ │ ├── GroupEvent.ts # Group event types
│ │ ├── Typing.ts # Typing indicators
│ │ ├── SeenMessage.ts # Message seen events
│ │ ├── DeliveredMessage.ts # Message delivery events
│ │ ├── Undo.ts # Undo functionality
│ │ ├── Enum.ts # Enumerations
│ │ └── index.ts # Model exports
│ ├── Errors/ # Error handling
│ │ ├── ZaloApiError.ts # Custom API error class
│ │ └── index.ts # Error exports
│ ├── context.ts # Context management and state
│ ├── utils.ts # Utility functions and helpers
│ ├── zalo.ts # Main Zalo class implementation
│ ├── update.ts # Update checking functionality
│ └── index.ts # Public API exports
├── examples/ # Usage examples
│ └── echobot.ts # Echo bot example
├── test/ # Test files
│ ├── feat.ts # Feature tests
│ ├── feat.test.ts # Feature test suite
│ ├── test.ts # General tests
│ └── a.png # Test assets
├── .github/ # GitHub configuration
│ └── ISSUE_TEMPLATE/ # Issue templates
├── .dev/ # Development tools (developer generated)
├── dist/ # Build output (generated)
├── node_modules/ # Dependencies (generated)
├── package.json # Project configuration
├── tsconfig.json # TypeScript configuration
├── rollup.config.js # Build configuration
├── README.md # Project documentation
├── CONTRIBUTING.md # Contribution guidelines
├── SECURITY.md # Security policy
├── CODE_OF_CONDUCT.md # Community guidelines
└── LICENSE # MIT License
```
### Key Directories Explained
- **`src/apis/`**: Contains all API method implementations (~100 files)
- **`src/models/`**: TypeScript interfaces and type definitions
- Core data structures for messages, events, and API responses
- Ensures type safety across the application
- **`src/Errors/`**: Custom error handling
- `ZaloApiError.ts`: Handles API-specific errors
- Provides consistent error handling across the library
- **`examples/`**: Usage examples and demonstrations
- `echobot.ts`: Complete example of a Zalo bot implementation
- **`test/`**: Test suites and test assets
- Feature tests for core functionality
- Integration tests for API methods
### Naming Conventions
- **Files**: camelCase (e.g., `sendMessage.ts`)
- **Classes**: PascalCase (e.g., `ZaloApiError`)
- **Functions**: camelCase (e.g., `sendMessage`)
- **Constants**: UPPER_SNAKE_CASE (e.g., `API_BASE_URL`)
- **Interfaces**: PascalCase with `I` prefix (e.g., `IMessage`)
### Error Handling
```typescript
// Good
try {
const result = await api.sendMessage(message);
return result;
} catch (error) {
if (error instanceof ZaloApiError) {
throw error;
}
throw new ZaloApiError(`Failed to send message: ${error.message}`);
}
// Bad
try {
const result = await api.sendMessage(message);
return result;
} catch (error) {
console.error(error);
return null;
}
```
## Testing Guidelines
### Test Structure
```typescript
describe('API Method', () => {
beforeEach(() => {
// Setup
});
afterEach(() => {
// Cleanup
});
it('should handle success case', async () => {
// Test implementation
});
it('should handle error case', async () => {
// Test error handling
});
});
```
### Testing Best Practices
- Test both success and failure scenarios
- Mock external dependencies
- Use descriptive test names
- Keep tests independent
- Test edge cases and error conditions
### Running Tests
```bash
# Run all tests
bun run test:feat
# Run specific test
bun run test/test.ts
# Run with coverage (if available)
bun run test:coverage
```
## Documentation Guidelines
### API Documentation
- Document all public methods with JSDoc
- Include parameter types and descriptions
- Provide usage examples
- Document error conditions
```typescript
/**
* Sends a message to a specific thread
* @param message - The message object containing content and metadata
* @param threadId - The ID of the thread to send the message to
* @param threadType - The type of thread (User or Group)
* @returns Promise<Message> - The sent message object
* @throws {ZaloApiError} When the API request fails
* @example
* ```typescript
* const message = await api.sendMessage(
* { msg: "Hello, world!" },
* "123456789",
* ThreadType.User
* );
* ```
*/
async sendMessage(message: IMessage, threadId: string, threadType: ThreadType): Promise<Message>
```
### README Updates
- Update README.md for new features
- Add examples for new APIs
- Update installation instructions if needed
- Keep the table of contents updated
## Security Guidelines
### Security Best Practices
- Never commit sensitive data (tokens, passwords, etc.)
- Use environment variables for configuration
- Validate all user inputs
- Follow the principle of least privilege
- Report security issues privately
### Security Reporting
If you discover a security vulnerability:
1. **DO NOT** create a public issue
2. Use the [SECURITY.md](SECURITY.md) reporting process
3. Create a private issue with `[SECURITY]` label
4. Contact team members directly for urgent issues
### Code Security
```typescript
// Good - Validate inputs
function sendMessage(content: string, threadId: string) {
if (!content || typeof content !== 'string') {
throw new ZaloApiError('Content must be a non-empty string');
}
if (!threadId || typeof threadId !== 'string') {
throw new ZaloApiError('ThreadId must be a non-empty string');
}
// Implementation
}
// Bad - No validation
function sendMessage(content: any, threadId: any) {
// Implementation without validation
}
```
## Release Process
### Versioning
We follow [Semantic Versioning](https://semver.org/):
- **MAJOR**: Breaking changes
- **MINOR**: New features (backward compatible)
- **PATCH**: Bug fixes (backward compatible)
### Release Checklist
- [ ] All tests pass
- [ ] Documentation is updated
- [ ] Version is bumped in package.json
- [ ] Build is successful
- [ ] Release notes are prepared
### Publishing
```bash
# Build the project
bun run build
# Run tests
bun run test:feat
# Publish to npm
npm publish
```
## Getting Help
### Communication Channels
- **GitHub Issues**: For bug reports and feature requests
- **GitHub Discussions**: For questions and general discussion
- **Pull Requests**: For code contributions
- **Security Issues**: Use `[SECURITY]` label
### Team Members
- [@RFS-ADRENO](https://github.com/RFS-ADRENO)
- [@truong9c2208](https://github.com/truong9c2208)
- [@JustKemForFun](https://github.com/JustKemForFun)
### Resources
- [API Documentation](https://zca-js.tdung.com)
- [Examples](examples/)
- [Security Policy](SECURITY.md)
- [Code of Conduct](CODE_OF_CONDUCT.md)
## Special Considerations for zca-js
### Unofficial API Library
> [!IMPORTANT]
> ⚠️ zca-js is an unofficial API library for Zalo. Please be aware of:
- **Account Risk**: Using this API may result in account suspension
- **Terms of Service**: Respect Zalo's ToS in your contributions
- **Rate Limiting**: Be mindful of API usage limits
- **Privacy**: Protect user privacy and data
### Responsible Development
- Test changes thoroughly before submitting
- Avoid introducing features that could harm users
- Consider the impact on Zalo's infrastructure
- Document any risks or limitations
---
**Thank you for contributing to zca-js!** 🚀
Your contributions help make this library better for the entire community.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 - 2025 RFS-ADRENO, truong9c2208, JustKemForFun
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+225
View File
@@ -0,0 +1,225 @@
# ZCA-JS
> [!NOTE]
> This is an unofficial Zalo API for personal account. It work by simulating the browser to interact with Zalo Web.
> [!WARNING]
> Using this API could get your account locked or banned. We are not responsible for any issues that may happen. Use it at your own risk.
---
## Table of Contents
- [Installation](#installation)
- [Migrate to V2](#migrate-to-v2)
- [Documentation](#documentation)
- [Basic Usages](#basic-usages)
- [Login](#login)
- [Listen for new messages](#listen-for-new-messages)
- [Send a message](#send-a-message)
- [Get/Send a sticker](#getsend-a-sticker)
- [Example](#example)
- [Projects & Useful Resources](#projects--useful-resources)
- [Contributing](#contributing)
- [License](#license)
- [Support Us](#support-us)
## Installation
```bash
bun add zca-js # or npm install zca-js
```
### Migrate to V2
Since official version 2.0.0, `zca-js` has removed sharp dependency for image metadata extraction. It now requires users to provide their own `imageMetadataGetter` function when initializing the `Zalo` class if they want to send images/gifs by file path.
Example of custom `imageMetadataGetter` using `sharp`:
```bash
bun add sharp # or npm install sharp
```
```javascript
import { Zalo } from "zca-js";
import sharp from "sharp";
import fs from "node:fs";
async function imageMetadataGetter(filePath) {
const data = await fs.promises.readFile(filePath);
const metadata = await sharp(data).metadata();
return {
height: metadata.height,
width: metadata.width,
size: metadata.size || data.length,
};
}
const zalo = new Zalo({
imageMetadataGetter,
});
```
---
## Documentation
See [API Documentation](https://zca-js.tdung.com) for more details.
---
## Basic Usages
### Login
```javascript
import { Zalo } from "zca-js";
const zalo = new Zalo();
const api = await zalo.loginQR();
```
### Listen for new messages
```javascript
import { Zalo, ThreadType } from "zca-js";
const zalo = new Zalo();
const api = await zalo.loginQR();
api.listener.on("message", (message) => {
const isPlainText = typeof message.data.content === "string";
switch (message.type) {
case ThreadType.User: {
if (isPlainText) {
// received plain text direct message
}
break;
}
case ThreadType.Group: {
if (isPlainText) {
// received plain text group message
}
break;
}
}
});
api.listener.start();
```
> [!IMPORTANT]
> Only one web listener can run per account at a time. If you open Zalo in the browser while the listener is active, the listener will be automatically stopped.
### Send a message
```javascript
import { Zalo, ThreadType } from "zca-js";
const zalo = new Zalo();
const api = await zalo.loginQR();
// Echo bot
api.listener.on("message", (message) => {
const isPlainText = typeof message.data.content === "string";
if (message.isSelf || !isPlainText) return;
switch (message.type) {
case ThreadType.User: {
api.sendMessage(
{
msg: "echo: " + message.data.content,
quote: message.data, // the message to reply to (optional)
},
message.threadId,
message.type, // ThreadType.User
);
break;
}
case ThreadType.Group: {
api.sendMessage(
{
msg: "echo: " + message.data.content,
quote: message.data, // the message to reply to (optional)
},
message.threadId,
message.type, // ThreadType.Group
);
break;
}
}
});
api.listener.start();
```
### Get/Send a sticker
```javascript
api.getStickers("hello").then(async (stickerIds) => {
// Get the first sticker
const stickerObject = await api.getStickersDetail(stickerIds[0]);
api.sendMessageSticker(
stickerObject,
message.threadId,
message.type, // ThreadType.User or ThreadType.Group
);
});
```
---
## Example
See [examples](examples) folder for more details.
---
## Projects & Useful Resources
<div align="center">
| Repository | Description |
| :--- | :--- |
| [**ZaloDataExtractor**](https://github.com/JustKemForFun/ZaloDataExtractor) | A browser `Extension` to extract IMEI, cookies, and user agent from Zalo Web. |
| [**MultiZlogin**](https://github.com/ChickenAI/multizlogin) | A multi-account Zalo management system that lets you log in to and manage multiple accounts simultaneously, with proxy and webhook integration. |
| [**n8n-nodes-zalo-tools**](https://github.com/ChickenAI/zalo-node) | N8N node for personal Zalo account. |
| [**Zalo-F12**](https://github.com/ElectroHeavenVN/Zalo-F12) | A collection of JavaScript code snippets to paste into DevTools to change how Zalo Web/PC works. |
| [**Zalo-F12-Tools**](https://github.com/JustKemForFun/Zalo-F12-Tools) | Toggle hidden modes for Zalo Web. |
</div>
---
## Contributing
We welcome contributions from the community! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details on how to:
- 🐛 Report bugs and issues
- ✨ Suggest new features
- 🔧 Submit code contributions
- 📚 Improve documentation
- 🧪 Add or improve tests
- 🔒 Report security vulnerabilities
For more information, please read our [Code of Conduct](CODE_OF_CONDUCT.md) and [Security Policy](SECURITY.md) before participating.
---
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
---
## **Support Us**
-**Star our repositories** if you find them useful!
- 🔄 **Share** with your network to help us grow
- 💡 **Contribute** your ideas and code
-**A coffee**:
- [Buy Me a Coffee](https://ko-fi.com/grosse)
- [Paypal](https://www.paypal.com/paypalme/dungto213)
- [VietQR](https://github.com/user-attachments/assets/e1f319d6-9d11-4082-8248-55b55e645caa)
- [Momo](https://me.momo.vn/gMIMulsaUqsbf6iAiXt3)
+83
View File
@@ -0,0 +1,83 @@
# Security Policy
## Supported Versions
We actively maintain and provide security updates for the following versions:
| Version | Supported |
| ------- | ------------------ |
| 2.0.x | :white_check_mark: |
| 1.x.x | :x: |
| < 1.0 | :x: |
## Reporting a Vulnerability
We take security vulnerabilities seriously. If you discover a security vulnerability in zca-js, please follow these steps:
### 1. **DO NOT** create a public GitHub issue
Security vulnerabilities should be reported privately to prevent potential exploitation.
### 2. Report the vulnerability
Send an email to the maintainers with the following information:
- **Subject**: `[SECURITY] zca-js vulnerability report`
- **Description**: Detailed description of the vulnerability
- **Steps to reproduce**: Clear steps to reproduce the issue
- **Impact assessment**: Potential impact of the vulnerability
- **Suggested fix** (if available): Any suggestions for fixing the issue
### 3. Response timeline
- **Initial response**: Within 48 hours
- **Status update**: Within 1 week
- **Resolution**: As soon as possible, typically within 30 days
## Security Considerations
### Important Warnings
⚠️ **This is an unofficial API library** that simulates browser interactions with Zalo Web. Please be aware of the following security considerations:
1. **Account Risk**: Using this API may result in your Zalo account being locked or banned. Use at your own risk.
2. **Authentication**: The library handles sensitive authentication data. Ensure proper security measures when storing or transmitting this information.
3. **Rate Limiting**: Respect Zalo's rate limits to avoid triggering security measures.
4. **Data Privacy**: Be mindful of user privacy and comply with relevant data protection regulations.
### Best Practices
1. **Environment Variables**: Store sensitive configuration in environment variables, not in code
2. **HTTPS Only**: Always use HTTPS when transmitting data
3. **Input Validation**: Validate all inputs before processing
4. **Error Handling**: Implement proper error handling to avoid information disclosure
5. **Regular Updates**: Keep the library updated to the latest version
### Known Limitations
- This library is not officially supported by Zalo
- API endpoints and behavior may change without notice
- No guarantee of service availability or stability
- May break with Zalo Web updates
## Security Updates
Security updates will be released as patch versions (e.g., 2.0.1, 2.0.2) and will be clearly marked in the changelog.
## Contact Information
For security-related issues, please contact:
- **GitHub Issues**: Create a private issue with the `[SECURITY]` label
- **GitHub Discussions**: Use the "Security" category for general security questions
- **Team Members**:
- [@RFS-ADRENO](https://github.com/RFS-ADRENO)
- [@truong9c2208](https://github.com/truong9c2208)
- [@JustKemForFun](https://github.com/JustKemForFun)
- **Alternative**: Contact any team member through GitHub for urgent security matters
## Acknowledgments
We appreciate security researchers and community members who responsibly disclose vulnerabilities. Contributors will be acknowledged in our security advisories unless they prefer to remain anonymous.
---
**Note**: This security policy is subject to change. Please check back regularly for updates.
+4
View File
@@ -0,0 +1,4 @@
export declare class ZaloApiError extends Error {
code: number | null;
constructor(message: string, code?: number);
}
+7
View File
@@ -0,0 +1,7 @@
export class ZaloApiError extends Error {
constructor(message, code) {
super(message);
this.name = "ZcaApiError";
this.code = code || null;
}
}
+4
View File
@@ -0,0 +1,4 @@
import { ZaloApiError } from "./ZaloApiError.js";
export declare class ZaloApiLoginQRAborted extends ZaloApiError {
constructor(message?: string);
}
+7
View File
@@ -0,0 +1,7 @@
import { ZaloApiError } from "./ZaloApiError.js";
export class ZaloApiLoginQRAborted extends ZaloApiError {
constructor(message = "Operation aborted") {
super(message);
this.name = "ZaloApiLoginQRAborted";
}
}
@@ -0,0 +1,4 @@
import { ZaloApiError } from "./ZaloApiError.js";
export declare class ZaloApiLoginQRDeclined extends ZaloApiError {
constructor(message?: string);
}
+7
View File
@@ -0,0 +1,7 @@
import { ZaloApiError } from "./ZaloApiError.js";
export class ZaloApiLoginQRDeclined extends ZaloApiError {
constructor(message = "Login QR request declined") {
super(message);
this.name = "ZaloApiLoginQRDeclined";
}
}
@@ -0,0 +1,4 @@
import { ZaloApiError } from "./ZaloApiError.js";
export declare class ZaloApiMissingImageMetadataGetter extends ZaloApiError {
constructor();
}
@@ -0,0 +1,7 @@
import { ZaloApiError } from "./ZaloApiError.js";
export class ZaloApiMissingImageMetadataGetter extends ZaloApiError {
constructor() {
super("Missing `imageMetadataGetter`. Please provide it in the Zalo object options.");
this.name = "ZaloApiMissingImageMetadataGetter";
}
}
+4
View File
@@ -0,0 +1,4 @@
export * from "./ZaloApiError.js";
export * from "./ZaloApiMissingImageMetadataGetter.js";
export * from "./ZaloApiLoginQRAborted.js";
export * from "./ZaloApiLoginQRDeclined.js";
+4
View File
@@ -0,0 +1,4 @@
export * from "./ZaloApiError.js";
export * from "./ZaloApiMissingImageMetadataGetter.js";
export * from "./ZaloApiLoginQRAborted.js";
export * from "./ZaloApiLoginQRDeclined.js";
+299
View File
@@ -0,0 +1,299 @@
import { Listener } from "./apis/listen.js";
import { acceptFriendRequestFactory } from "./apis/acceptFriendRequest.js";
import { addGroupBlockedMemberFactory } from "./apis/addGroupBlockedMember.js";
import { addGroupDeputyFactory } from "./apis/addGroupDeputy.js";
import { addPollOptionsFactory } from "./apis/addPollOptions.js";
import { addQuickMessageFactory } from "./apis/addQuickMessage.js";
import { addReactionFactory } from "./apis/addReaction.js";
import { addUnreadMarkFactory } from "./apis/addUnreadMark.js";
import { addUserToGroupFactory } from "./apis/addUserToGroup.js";
import { blockUserFactory } from "./apis/blockUser.js";
import { blockViewFeedFactory } from "./apis/blockViewFeed.js";
import { changeAccountAvatarFactory } from "./apis/changeAccountAvatar.js";
import { changeFriendAliasFactory } from "./apis/changeFriendAlias.js";
import { changeGroupAvatarFactory } from "./apis/changeGroupAvatar.js";
import { changeGroupNameFactory } from "./apis/changeGroupName.js";
import { changeGroupOwnerFactory } from "./apis/changeGroupOwner.js";
import { createAutoReplyFactory } from "./apis/createAutoReply.js";
import { createCatalogFactory } from "./apis/createCatalog.js";
import { createGroupFactory } from "./apis/createGroup.js";
import { createNoteFactory } from "./apis/createNote.js";
import { createPollFactory } from "./apis/createPoll.js";
import { createProductCatalogFactory } from "./apis/createProductCatalog.js";
import { createReminderFactory } from "./apis/createReminder.js";
import { deleteAutoReplyFactory } from "./apis/deleteAutoReply.js";
import { deleteAvatarFactory } from "./apis/deleteAvatar.js";
import { deleteCatalogFactory } from "./apis/deleteCatalog.js";
import { deleteChatFactory } from "./apis/deleteChat.js";
import { deleteGroupInviteBoxFactory } from "./apis/deleteGroupInviteBox.js";
import { deleteMessageFactory } from "./apis/deleteMessage.js";
import { deleteProductCatalogFactory } from "./apis/deleteProductCatalog.js";
import { disableGroupLinkFactory } from "./apis/disableGroupLink.js";
import { disperseGroupFactory } from "./apis/disperseGroup.js";
import { editNoteFactory } from "./apis/editNote.js";
import { editReminderFactory } from "./apis/editReminder.js";
import { enableGroupLinkFactory } from "./apis/enableGroupLink.js";
import { fetchAccountInfoFactory } from "./apis/fetchAccountInfo.js";
import { findUserFactory } from "./apis/findUser.js";
import { findUserByUsernameFactory } from "./apis/findUserByUsername.js";
import { forwardMessageFactory } from "./apis/forwardMessage.js";
import { getAliasListFactory } from "./apis/getAliasList.js";
import { getAllFriendsFactory } from "./apis/getAllFriends.js";
import { getAllGroupsFactory } from "./apis/getAllGroups.js";
import { getArchivedChatListFactory } from "./apis/getArchivedChatList.js";
import { getAutoDeleteChatFactory } from "./apis/getAutoDeleteChat.js";
import { getAutoReplyListFactory } from "./apis/getAutoReplyList.js";
import { getAvatarListFactory } from "./apis/getAvatarList.js";
import { getAvatarUrlProfileFactory } from "./apis/getAvatarUrlProfile.js";
import { getBizAccountFactory } from "./apis/getBizAccount.js";
import { getCatalogListFactory } from "./apis/getCatalogList.js";
import { getCloseFriendsFactory } from "./apis/getCloseFriends.js";
import { getContextFactory } from "./apis/getContext.js";
import { getCookieFactory } from "./apis/getCookie.js";
import { getFriendBoardListFactory } from "./apis/getFriendBoardList.js";
import { getFriendOnlinesFactory } from "./apis/getFriendOnlines.js";
import { getFriendRecommendationsFactory } from "./apis/getFriendRecommendations.js";
import { getFriendRequestStatusFactory } from "./apis/getFriendRequestStatus.js";
import { getFullAvatarFactory } from "./apis/getFullAvatar.js";
import { getGroupBlockedMemberFactory } from "./apis/getGroupBlockedMember.js";
import { getGroupChatHistoryFactory } from "./apis/getGroupChatHistory.js";
import { getGroupInfoFactory } from "./apis/getGroupInfo.js";
import { getGroupInviteBoxInfoFactory } from "./apis/getGroupInviteBoxInfo.js";
import { getGroupInviteBoxListFactory } from "./apis/getGroupInviteBoxList.js";
import { getGroupLinkDetailFactory } from "./apis/getGroupLinkDetail.js";
import { getGroupLinkInfoFactory } from "./apis/getGroupLinkInfo.js";
import { getGroupMembersInfoFactory } from "./apis/getGroupMembersInfo.js";
import { getHiddenConversationsFactory } from "./apis/getHiddenConversations.js";
import { getLabelsFactory } from "./apis/getLabels.js";
import { getListBoardFactory } from "./apis/getListBoard.js";
import { getListReminderFactory } from "./apis/getListReminder.js";
import { getMultiUsersByPhonesFactory } from "./apis/getMultiUsersByPhones.js";
import { getMuteFactory } from "./apis/getMute.js";
import { getOwnIdFactory } from "./apis/getOwnId.js";
import { getPendingGroupMembersFactory } from "./apis/getPendingGroupMembers.js";
import { getPinConversationsFactory } from "./apis/getPinConversations.js";
import { getPollDetailFactory } from "./apis/getPollDetail.js";
import { getProductCatalogListFactory } from "./apis/getProductCatalogList.js";
import { getQRFactory } from "./apis/getQR.js";
import { getQuickMessageListFactory } from "./apis/getQuickMessageList.js";
import { getRelatedFriendGroupFactory } from "./apis/getRelatedFriendGroup.js";
import { getReminderFactory } from "./apis/getReminder.js";
import { getReminderResponsesFactory } from "./apis/getReminderResponses.js";
import { getSentFriendRequestFactory } from "./apis/getSentFriendRequest.js";
import { getSettingsFactory } from "./apis/getSettings.js";
import { getStickerCategoryDetailFactory } from "./apis/getStickerCategoryDetail.js";
import { getStickersFactory } from "./apis/getStickers.js";
import { getStickersDetailFactory } from "./apis/getStickersDetail.js";
import { getUnreadMarkFactory } from "./apis/getUnreadMark.js";
import { getUserInfoFactory } from "./apis/getUserInfo.js";
import { inviteUserToGroupsFactory } from "./apis/inviteUserToGroups.js";
import { joinGroupInviteBoxFactory } from "./apis/joinGroupInviteBox.js";
import { joinGroupLinkFactory } from "./apis/joinGroupLink.js";
import { keepAliveFactory } from "./apis/keepAlive.js";
import { lastOnlineFactory } from "./apis/lastOnline.js";
import { leaveGroupFactory } from "./apis/leaveGroup.js";
import { lockPollFactory } from "./apis/lockPoll.js";
import { parseLinkFactory } from "./apis/parseLink.js";
import { rejectFriendRequestFactory } from "./apis/rejectFriendRequest.js";
import { removeFriendFactory } from "./apis/removeFriend.js";
import { removeFriendAliasFactory } from "./apis/removeFriendAlias.js";
import { removeGroupBlockedMemberFactory } from "./apis/removeGroupBlockedMember.js";
import { removeGroupDeputyFactory } from "./apis/removeGroupDeputy.js";
import { removeQuickMessageFactory } from "./apis/removeQuickMessage.js";
import { removeReminderFactory } from "./apis/removeReminder.js";
import { removeUnreadMarkFactory } from "./apis/removeUnreadMark.js";
import { removeUserFromGroupFactory } from "./apis/removeUserFromGroup.js";
import { resetHiddenConversPinFactory } from "./apis/resetHiddenConversPin.js";
import { reuseAvatarFactory } from "./apis/reuseAvatar.js";
import { reviewPendingMemberRequestFactory } from "./apis/reviewPendingMemberRequest.js";
import { searchStickerFactory } from "./apis/searchSticker.js";
import { sendBankCardFactory } from "./apis/sendBankCard.js";
import { sendCardFactory } from "./apis/sendCard.js";
import { sendDeliveredEventFactory } from "./apis/sendDeliveredEvent.js";
import { sendFriendRequestFactory } from "./apis/sendFriendRequest.js";
import { sendLinkFactory } from "./apis/sendLink.js";
import { sendMessageFactory } from "./apis/sendMessage.js";
import { sendReportFactory } from "./apis/sendReport.js";
import { sendSeenEventFactory } from "./apis/sendSeenEvent.js";
import { sendStickerFactory } from "./apis/sendSticker.js";
import { sendTypingEventFactory } from "./apis/sendTypingEvent.js";
import { sendVideoFactory } from "./apis/sendVideo.js";
import { sendVoiceFactory } from "./apis/sendVoice.js";
import { setHiddenConversationsFactory } from "./apis/setHiddenConversations.js";
import { setMuteFactory } from "./apis/setMute.js";
import { setPinnedConversationsFactory } from "./apis/setPinnedConversations.js";
import { sharePollFactory } from "./apis/sharePoll.js";
import { unblockUserFactory } from "./apis/unblockUser.js";
import { undoFactory } from "./apis/undo.js";
import { undoFriendRequestFactory } from "./apis/undoFriendRequest.js";
import { updateActiveStatusFactory } from "./apis/updateActiveStatus.js";
import { updateArchivedChatListFactory } from "./apis/updateArchivedChatList.js";
import { updateAutoDeleteChatFactory } from "./apis/updateAutoDeleteChat.js";
import { updateAutoReplyFactory } from "./apis/updateAutoReply.js";
import { updateCatalogFactory } from "./apis/updateCatalog.js";
import { updateGroupSettingsFactory } from "./apis/updateGroupSettings.js";
import { updateHiddenConversPinFactory } from "./apis/updateHiddenConversPin.js";
import { updateLabelsFactory } from "./apis/updateLabels.js";
import { updateLangFactory } from "./apis/updateLang.js";
import { updateProductCatalogFactory } from "./apis/updateProductCatalog.js";
import { updateProfileFactory } from "./apis/updateProfile.js";
import { updateProfileBioFactory } from "./apis/updateProfileBio.js";
import { updateQuickMessageFactory } from "./apis/updateQuickMessage.js";
import { updateSettingsFactory } from "./apis/updateSettings.js";
import { upgradeGroupToCommunityFactory } from "./apis/upgradeGroupToCommunity.js";
import { uploadAttachmentFactory } from "./apis/uploadAttachment.js";
import { uploadProductPhotoFactory } from "./apis/uploadProductPhoto.js";
import { votePollFactory } from "./apis/votePoll.js";
import { customFactory } from "./apis/custom.js";
import type { ZPWServiceMap, ContextSession } from "./context.js";
export declare class API {
zpwServiceMap: ZPWServiceMap;
listener: Listener;
acceptFriendRequest: ReturnType<typeof acceptFriendRequestFactory>;
addGroupBlockedMember: ReturnType<typeof addGroupBlockedMemberFactory>;
addGroupDeputy: ReturnType<typeof addGroupDeputyFactory>;
addPollOptions: ReturnType<typeof addPollOptionsFactory>;
addQuickMessage: ReturnType<typeof addQuickMessageFactory>;
addReaction: ReturnType<typeof addReactionFactory>;
addUnreadMark: ReturnType<typeof addUnreadMarkFactory>;
addUserToGroup: ReturnType<typeof addUserToGroupFactory>;
blockUser: ReturnType<typeof blockUserFactory>;
blockViewFeed: ReturnType<typeof blockViewFeedFactory>;
changeAccountAvatar: ReturnType<typeof changeAccountAvatarFactory>;
changeFriendAlias: ReturnType<typeof changeFriendAliasFactory>;
changeGroupAvatar: ReturnType<typeof changeGroupAvatarFactory>;
changeGroupName: ReturnType<typeof changeGroupNameFactory>;
changeGroupOwner: ReturnType<typeof changeGroupOwnerFactory>;
createAutoReply: ReturnType<typeof createAutoReplyFactory>;
createCatalog: ReturnType<typeof createCatalogFactory>;
createGroup: ReturnType<typeof createGroupFactory>;
createNote: ReturnType<typeof createNoteFactory>;
createPoll: ReturnType<typeof createPollFactory>;
createProductCatalog: ReturnType<typeof createProductCatalogFactory>;
createReminder: ReturnType<typeof createReminderFactory>;
deleteAutoReply: ReturnType<typeof deleteAutoReplyFactory>;
deleteAvatar: ReturnType<typeof deleteAvatarFactory>;
deleteCatalog: ReturnType<typeof deleteCatalogFactory>;
deleteChat: ReturnType<typeof deleteChatFactory>;
deleteGroupInviteBox: ReturnType<typeof deleteGroupInviteBoxFactory>;
deleteMessage: ReturnType<typeof deleteMessageFactory>;
deleteProductCatalog: ReturnType<typeof deleteProductCatalogFactory>;
disableGroupLink: ReturnType<typeof disableGroupLinkFactory>;
disperseGroup: ReturnType<typeof disperseGroupFactory>;
editNote: ReturnType<typeof editNoteFactory>;
editReminder: ReturnType<typeof editReminderFactory>;
enableGroupLink: ReturnType<typeof enableGroupLinkFactory>;
fetchAccountInfo: ReturnType<typeof fetchAccountInfoFactory>;
findUser: ReturnType<typeof findUserFactory>;
findUserByUsername: ReturnType<typeof findUserByUsernameFactory>;
forwardMessage: ReturnType<typeof forwardMessageFactory>;
getAliasList: ReturnType<typeof getAliasListFactory>;
getAllFriends: ReturnType<typeof getAllFriendsFactory>;
getAllGroups: ReturnType<typeof getAllGroupsFactory>;
getArchivedChatList: ReturnType<typeof getArchivedChatListFactory>;
getAutoDeleteChat: ReturnType<typeof getAutoDeleteChatFactory>;
getAutoReplyList: ReturnType<typeof getAutoReplyListFactory>;
getAvatarList: ReturnType<typeof getAvatarListFactory>;
getAvatarUrlProfile: ReturnType<typeof getAvatarUrlProfileFactory>;
getBizAccount: ReturnType<typeof getBizAccountFactory>;
getCatalogList: ReturnType<typeof getCatalogListFactory>;
getCloseFriends: ReturnType<typeof getCloseFriendsFactory>;
getContext: ReturnType<typeof getContextFactory>;
getCookie: ReturnType<typeof getCookieFactory>;
getFriendBoardList: ReturnType<typeof getFriendBoardListFactory>;
getFriendOnlines: ReturnType<typeof getFriendOnlinesFactory>;
getFriendRecommendations: ReturnType<typeof getFriendRecommendationsFactory>;
getFriendRequestStatus: ReturnType<typeof getFriendRequestStatusFactory>;
getFullAvatar: ReturnType<typeof getFullAvatarFactory>;
getGroupBlockedMember: ReturnType<typeof getGroupBlockedMemberFactory>;
getGroupChatHistory: ReturnType<typeof getGroupChatHistoryFactory>;
getGroupInfo: ReturnType<typeof getGroupInfoFactory>;
getGroupInviteBoxInfo: ReturnType<typeof getGroupInviteBoxInfoFactory>;
getGroupInviteBoxList: ReturnType<typeof getGroupInviteBoxListFactory>;
getGroupLinkDetail: ReturnType<typeof getGroupLinkDetailFactory>;
getGroupLinkInfo: ReturnType<typeof getGroupLinkInfoFactory>;
getGroupMembersInfo: ReturnType<typeof getGroupMembersInfoFactory>;
getHiddenConversations: ReturnType<typeof getHiddenConversationsFactory>;
getLabels: ReturnType<typeof getLabelsFactory>;
getListBoard: ReturnType<typeof getListBoardFactory>;
getListReminder: ReturnType<typeof getListReminderFactory>;
getMultiUsersByPhones: ReturnType<typeof getMultiUsersByPhonesFactory>;
getMute: ReturnType<typeof getMuteFactory>;
getOwnId: ReturnType<typeof getOwnIdFactory>;
getPendingGroupMembers: ReturnType<typeof getPendingGroupMembersFactory>;
getPinConversations: ReturnType<typeof getPinConversationsFactory>;
getPollDetail: ReturnType<typeof getPollDetailFactory>;
getProductCatalogList: ReturnType<typeof getProductCatalogListFactory>;
getQR: ReturnType<typeof getQRFactory>;
getQuickMessageList: ReturnType<typeof getQuickMessageListFactory>;
getRelatedFriendGroup: ReturnType<typeof getRelatedFriendGroupFactory>;
getReminder: ReturnType<typeof getReminderFactory>;
getReminderResponses: ReturnType<typeof getReminderResponsesFactory>;
getSentFriendRequest: ReturnType<typeof getSentFriendRequestFactory>;
getSettings: ReturnType<typeof getSettingsFactory>;
getStickerCategoryDetail: ReturnType<typeof getStickerCategoryDetailFactory>;
getStickers: ReturnType<typeof getStickersFactory>;
getStickersDetail: ReturnType<typeof getStickersDetailFactory>;
getUnreadMark: ReturnType<typeof getUnreadMarkFactory>;
getUserInfo: ReturnType<typeof getUserInfoFactory>;
inviteUserToGroups: ReturnType<typeof inviteUserToGroupsFactory>;
joinGroupInviteBox: ReturnType<typeof joinGroupInviteBoxFactory>;
joinGroupLink: ReturnType<typeof joinGroupLinkFactory>;
keepAlive: ReturnType<typeof keepAliveFactory>;
lastOnline: ReturnType<typeof lastOnlineFactory>;
leaveGroup: ReturnType<typeof leaveGroupFactory>;
lockPoll: ReturnType<typeof lockPollFactory>;
parseLink: ReturnType<typeof parseLinkFactory>;
rejectFriendRequest: ReturnType<typeof rejectFriendRequestFactory>;
removeFriend: ReturnType<typeof removeFriendFactory>;
removeFriendAlias: ReturnType<typeof removeFriendAliasFactory>;
removeGroupBlockedMember: ReturnType<typeof removeGroupBlockedMemberFactory>;
removeGroupDeputy: ReturnType<typeof removeGroupDeputyFactory>;
removeQuickMessage: ReturnType<typeof removeQuickMessageFactory>;
removeReminder: ReturnType<typeof removeReminderFactory>;
removeUnreadMark: ReturnType<typeof removeUnreadMarkFactory>;
removeUserFromGroup: ReturnType<typeof removeUserFromGroupFactory>;
resetHiddenConversPin: ReturnType<typeof resetHiddenConversPinFactory>;
reuseAvatar: ReturnType<typeof reuseAvatarFactory>;
reviewPendingMemberRequest: ReturnType<typeof reviewPendingMemberRequestFactory>;
searchSticker: ReturnType<typeof searchStickerFactory>;
sendBankCard: ReturnType<typeof sendBankCardFactory>;
sendCard: ReturnType<typeof sendCardFactory>;
sendDeliveredEvent: ReturnType<typeof sendDeliveredEventFactory>;
sendFriendRequest: ReturnType<typeof sendFriendRequestFactory>;
sendLink: ReturnType<typeof sendLinkFactory>;
sendMessage: ReturnType<typeof sendMessageFactory>;
sendReport: ReturnType<typeof sendReportFactory>;
sendSeenEvent: ReturnType<typeof sendSeenEventFactory>;
sendSticker: ReturnType<typeof sendStickerFactory>;
sendTypingEvent: ReturnType<typeof sendTypingEventFactory>;
sendVideo: ReturnType<typeof sendVideoFactory>;
sendVoice: ReturnType<typeof sendVoiceFactory>;
setHiddenConversations: ReturnType<typeof setHiddenConversationsFactory>;
setMute: ReturnType<typeof setMuteFactory>;
setPinnedConversations: ReturnType<typeof setPinnedConversationsFactory>;
sharePoll: ReturnType<typeof sharePollFactory>;
unblockUser: ReturnType<typeof unblockUserFactory>;
undo: ReturnType<typeof undoFactory>;
undoFriendRequest: ReturnType<typeof undoFriendRequestFactory>;
updateActiveStatus: ReturnType<typeof updateActiveStatusFactory>;
updateArchivedChatList: ReturnType<typeof updateArchivedChatListFactory>;
updateAutoDeleteChat: ReturnType<typeof updateAutoDeleteChatFactory>;
updateAutoReply: ReturnType<typeof updateAutoReplyFactory>;
updateCatalog: ReturnType<typeof updateCatalogFactory>;
updateGroupSettings: ReturnType<typeof updateGroupSettingsFactory>;
updateHiddenConversPin: ReturnType<typeof updateHiddenConversPinFactory>;
updateLabels: ReturnType<typeof updateLabelsFactory>;
updateLang: ReturnType<typeof updateLangFactory>;
updateProductCatalog: ReturnType<typeof updateProductCatalogFactory>;
updateProfile: ReturnType<typeof updateProfileFactory>;
updateProfileBio: ReturnType<typeof updateProfileBioFactory>;
updateQuickMessage: ReturnType<typeof updateQuickMessageFactory>;
updateSettings: ReturnType<typeof updateSettingsFactory>;
upgradeGroupToCommunity: ReturnType<typeof upgradeGroupToCommunityFactory>;
uploadAttachment: ReturnType<typeof uploadAttachmentFactory>;
uploadProductPhoto: ReturnType<typeof uploadProductPhotoFactory>;
votePoll: ReturnType<typeof votePollFactory>;
custom: ReturnType<typeof customFactory>;
constructor(ctx: ContextSession, zpwServiceMap: ZPWServiceMap, wsUrls: string[]);
}
+299
View File
@@ -0,0 +1,299 @@
import { Listener } from "./apis/listen.js";
import { acceptFriendRequestFactory } from "./apis/acceptFriendRequest.js";
import { addGroupBlockedMemberFactory } from "./apis/addGroupBlockedMember.js";
import { addGroupDeputyFactory } from "./apis/addGroupDeputy.js";
import { addPollOptionsFactory } from "./apis/addPollOptions.js";
import { addQuickMessageFactory } from "./apis/addQuickMessage.js";
import { addReactionFactory } from "./apis/addReaction.js";
import { addUnreadMarkFactory } from "./apis/addUnreadMark.js";
import { addUserToGroupFactory } from "./apis/addUserToGroup.js";
import { blockUserFactory } from "./apis/blockUser.js";
import { blockViewFeedFactory } from "./apis/blockViewFeed.js";
import { changeAccountAvatarFactory } from "./apis/changeAccountAvatar.js";
import { changeFriendAliasFactory } from "./apis/changeFriendAlias.js";
import { changeGroupAvatarFactory } from "./apis/changeGroupAvatar.js";
import { changeGroupNameFactory } from "./apis/changeGroupName.js";
import { changeGroupOwnerFactory } from "./apis/changeGroupOwner.js";
import { createAutoReplyFactory } from "./apis/createAutoReply.js";
import { createCatalogFactory } from "./apis/createCatalog.js";
import { createGroupFactory } from "./apis/createGroup.js";
import { createNoteFactory } from "./apis/createNote.js";
import { createPollFactory } from "./apis/createPoll.js";
import { createProductCatalogFactory } from "./apis/createProductCatalog.js";
import { createReminderFactory } from "./apis/createReminder.js";
import { deleteAutoReplyFactory } from "./apis/deleteAutoReply.js";
import { deleteAvatarFactory } from "./apis/deleteAvatar.js";
import { deleteCatalogFactory } from "./apis/deleteCatalog.js";
import { deleteChatFactory } from "./apis/deleteChat.js";
import { deleteGroupInviteBoxFactory } from "./apis/deleteGroupInviteBox.js";
import { deleteMessageFactory } from "./apis/deleteMessage.js";
import { deleteProductCatalogFactory } from "./apis/deleteProductCatalog.js";
import { disableGroupLinkFactory } from "./apis/disableGroupLink.js";
import { disperseGroupFactory } from "./apis/disperseGroup.js";
import { editNoteFactory } from "./apis/editNote.js";
import { editReminderFactory } from "./apis/editReminder.js";
import { enableGroupLinkFactory } from "./apis/enableGroupLink.js";
import { fetchAccountInfoFactory } from "./apis/fetchAccountInfo.js";
import { findUserFactory } from "./apis/findUser.js";
import { findUserByUsernameFactory } from "./apis/findUserByUsername.js";
import { forwardMessageFactory } from "./apis/forwardMessage.js";
import { getAliasListFactory } from "./apis/getAliasList.js";
import { getAllFriendsFactory } from "./apis/getAllFriends.js";
import { getAllGroupsFactory } from "./apis/getAllGroups.js";
import { getArchivedChatListFactory } from "./apis/getArchivedChatList.js";
import { getAutoDeleteChatFactory } from "./apis/getAutoDeleteChat.js";
import { getAutoReplyListFactory } from "./apis/getAutoReplyList.js";
import { getAvatarListFactory } from "./apis/getAvatarList.js";
import { getAvatarUrlProfileFactory } from "./apis/getAvatarUrlProfile.js";
import { getBizAccountFactory } from "./apis/getBizAccount.js";
import { getCatalogListFactory } from "./apis/getCatalogList.js";
import { getCloseFriendsFactory } from "./apis/getCloseFriends.js";
import { getContextFactory } from "./apis/getContext.js";
import { getCookieFactory } from "./apis/getCookie.js";
import { getFriendBoardListFactory } from "./apis/getFriendBoardList.js";
import { getFriendOnlinesFactory } from "./apis/getFriendOnlines.js";
import { getFriendRecommendationsFactory } from "./apis/getFriendRecommendations.js";
import { getFriendRequestStatusFactory } from "./apis/getFriendRequestStatus.js";
import { getFullAvatarFactory } from "./apis/getFullAvatar.js";
import { getGroupBlockedMemberFactory } from "./apis/getGroupBlockedMember.js";
import { getGroupChatHistoryFactory } from "./apis/getGroupChatHistory.js";
import { getGroupInfoFactory } from "./apis/getGroupInfo.js";
import { getGroupInviteBoxInfoFactory } from "./apis/getGroupInviteBoxInfo.js";
import { getGroupInviteBoxListFactory } from "./apis/getGroupInviteBoxList.js";
import { getGroupLinkDetailFactory } from "./apis/getGroupLinkDetail.js";
import { getGroupLinkInfoFactory } from "./apis/getGroupLinkInfo.js";
import { getGroupMembersInfoFactory } from "./apis/getGroupMembersInfo.js";
import { getHiddenConversationsFactory } from "./apis/getHiddenConversations.js";
import { getLabelsFactory } from "./apis/getLabels.js";
import { getListBoardFactory } from "./apis/getListBoard.js";
import { getListReminderFactory } from "./apis/getListReminder.js";
import { getMultiUsersByPhonesFactory } from "./apis/getMultiUsersByPhones.js";
import { getMuteFactory } from "./apis/getMute.js";
import { getOwnIdFactory } from "./apis/getOwnId.js";
import { getPendingGroupMembersFactory } from "./apis/getPendingGroupMembers.js";
import { getPinConversationsFactory } from "./apis/getPinConversations.js";
import { getPollDetailFactory } from "./apis/getPollDetail.js";
import { getProductCatalogListFactory } from "./apis/getProductCatalogList.js";
import { getQRFactory } from "./apis/getQR.js";
import { getQuickMessageListFactory } from "./apis/getQuickMessageList.js";
import { getRelatedFriendGroupFactory } from "./apis/getRelatedFriendGroup.js";
import { getReminderFactory } from "./apis/getReminder.js";
import { getReminderResponsesFactory } from "./apis/getReminderResponses.js";
import { getSentFriendRequestFactory } from "./apis/getSentFriendRequest.js";
import { getSettingsFactory } from "./apis/getSettings.js";
import { getStickerCategoryDetailFactory } from "./apis/getStickerCategoryDetail.js";
import { getStickersFactory } from "./apis/getStickers.js";
import { getStickersDetailFactory } from "./apis/getStickersDetail.js";
import { getUnreadMarkFactory } from "./apis/getUnreadMark.js";
import { getUserInfoFactory } from "./apis/getUserInfo.js";
import { inviteUserToGroupsFactory } from "./apis/inviteUserToGroups.js";
import { joinGroupInviteBoxFactory } from "./apis/joinGroupInviteBox.js";
import { joinGroupLinkFactory } from "./apis/joinGroupLink.js";
import { keepAliveFactory } from "./apis/keepAlive.js";
import { lastOnlineFactory } from "./apis/lastOnline.js";
import { leaveGroupFactory } from "./apis/leaveGroup.js";
import { lockPollFactory } from "./apis/lockPoll.js";
import { parseLinkFactory } from "./apis/parseLink.js";
import { rejectFriendRequestFactory } from "./apis/rejectFriendRequest.js";
import { removeFriendFactory } from "./apis/removeFriend.js";
import { removeFriendAliasFactory } from "./apis/removeFriendAlias.js";
import { removeGroupBlockedMemberFactory } from "./apis/removeGroupBlockedMember.js";
import { removeGroupDeputyFactory } from "./apis/removeGroupDeputy.js";
import { removeQuickMessageFactory } from "./apis/removeQuickMessage.js";
import { removeReminderFactory } from "./apis/removeReminder.js";
import { removeUnreadMarkFactory } from "./apis/removeUnreadMark.js";
import { removeUserFromGroupFactory } from "./apis/removeUserFromGroup.js";
import { resetHiddenConversPinFactory } from "./apis/resetHiddenConversPin.js";
import { reuseAvatarFactory } from "./apis/reuseAvatar.js";
import { reviewPendingMemberRequestFactory } from "./apis/reviewPendingMemberRequest.js";
import { searchStickerFactory } from "./apis/searchSticker.js";
import { sendBankCardFactory } from "./apis/sendBankCard.js";
import { sendCardFactory } from "./apis/sendCard.js";
import { sendDeliveredEventFactory } from "./apis/sendDeliveredEvent.js";
import { sendFriendRequestFactory } from "./apis/sendFriendRequest.js";
import { sendLinkFactory } from "./apis/sendLink.js";
import { sendMessageFactory } from "./apis/sendMessage.js";
import { sendReportFactory } from "./apis/sendReport.js";
import { sendSeenEventFactory } from "./apis/sendSeenEvent.js";
import { sendStickerFactory } from "./apis/sendSticker.js";
import { sendTypingEventFactory } from "./apis/sendTypingEvent.js";
import { sendVideoFactory } from "./apis/sendVideo.js";
import { sendVoiceFactory } from "./apis/sendVoice.js";
import { setHiddenConversationsFactory } from "./apis/setHiddenConversations.js";
import { setMuteFactory } from "./apis/setMute.js";
import { setPinnedConversationsFactory } from "./apis/setPinnedConversations.js";
import { sharePollFactory } from "./apis/sharePoll.js";
import { unblockUserFactory } from "./apis/unblockUser.js";
import { undoFactory } from "./apis/undo.js";
import { undoFriendRequestFactory } from "./apis/undoFriendRequest.js";
import { updateActiveStatusFactory } from "./apis/updateActiveStatus.js";
import { updateArchivedChatListFactory } from "./apis/updateArchivedChatList.js";
import { updateAutoDeleteChatFactory } from "./apis/updateAutoDeleteChat.js";
import { updateAutoReplyFactory } from "./apis/updateAutoReply.js";
import { updateCatalogFactory } from "./apis/updateCatalog.js";
import { updateGroupSettingsFactory } from "./apis/updateGroupSettings.js";
import { updateHiddenConversPinFactory } from "./apis/updateHiddenConversPin.js";
import { updateLabelsFactory } from "./apis/updateLabels.js";
import { updateLangFactory } from "./apis/updateLang.js";
import { updateProductCatalogFactory } from "./apis/updateProductCatalog.js";
import { updateProfileFactory } from "./apis/updateProfile.js";
import { updateProfileBioFactory } from "./apis/updateProfileBio.js";
import { updateQuickMessageFactory } from "./apis/updateQuickMessage.js";
import { updateSettingsFactory } from "./apis/updateSettings.js";
import { upgradeGroupToCommunityFactory } from "./apis/upgradeGroupToCommunity.js";
import { uploadAttachmentFactory } from "./apis/uploadAttachment.js";
import { uploadProductPhotoFactory } from "./apis/uploadProductPhoto.js";
import { votePollFactory } from "./apis/votePoll.js";
import { customFactory } from "./apis/custom.js";
export class API {
constructor(ctx, zpwServiceMap, wsUrls) {
this.zpwServiceMap = zpwServiceMap;
this.listener = new Listener(ctx, wsUrls);
this.acceptFriendRequest = acceptFriendRequestFactory(ctx, this);
this.addGroupBlockedMember = addGroupBlockedMemberFactory(ctx, this);
this.addGroupDeputy = addGroupDeputyFactory(ctx, this);
this.addPollOptions = addPollOptionsFactory(ctx, this);
this.addQuickMessage = addQuickMessageFactory(ctx, this);
this.addReaction = addReactionFactory(ctx, this);
this.addUnreadMark = addUnreadMarkFactory(ctx, this);
this.addUserToGroup = addUserToGroupFactory(ctx, this);
this.blockUser = blockUserFactory(ctx, this);
this.blockViewFeed = blockViewFeedFactory(ctx, this);
this.changeAccountAvatar = changeAccountAvatarFactory(ctx, this);
this.changeFriendAlias = changeFriendAliasFactory(ctx, this);
this.changeGroupAvatar = changeGroupAvatarFactory(ctx, this);
this.changeGroupName = changeGroupNameFactory(ctx, this);
this.changeGroupOwner = changeGroupOwnerFactory(ctx, this);
this.createAutoReply = createAutoReplyFactory(ctx, this);
this.createCatalog = createCatalogFactory(ctx, this);
this.createGroup = createGroupFactory(ctx, this);
this.createNote = createNoteFactory(ctx, this);
this.createPoll = createPollFactory(ctx, this);
this.createProductCatalog = createProductCatalogFactory(ctx, this);
this.createReminder = createReminderFactory(ctx, this);
this.deleteAutoReply = deleteAutoReplyFactory(ctx, this);
this.deleteAvatar = deleteAvatarFactory(ctx, this);
this.deleteCatalog = deleteCatalogFactory(ctx, this);
this.deleteChat = deleteChatFactory(ctx, this);
this.deleteGroupInviteBox = deleteGroupInviteBoxFactory(ctx, this);
this.deleteMessage = deleteMessageFactory(ctx, this);
this.deleteProductCatalog = deleteProductCatalogFactory(ctx, this);
this.disableGroupLink = disableGroupLinkFactory(ctx, this);
this.disperseGroup = disperseGroupFactory(ctx, this);
this.editNote = editNoteFactory(ctx, this);
this.editReminder = editReminderFactory(ctx, this);
this.enableGroupLink = enableGroupLinkFactory(ctx, this);
this.fetchAccountInfo = fetchAccountInfoFactory(ctx, this);
this.findUser = findUserFactory(ctx, this);
this.findUserByUsername = findUserByUsernameFactory(ctx, this);
this.forwardMessage = forwardMessageFactory(ctx, this);
this.getAliasList = getAliasListFactory(ctx, this);
this.getAllFriends = getAllFriendsFactory(ctx, this);
this.getAllGroups = getAllGroupsFactory(ctx, this);
this.getArchivedChatList = getArchivedChatListFactory(ctx, this);
this.getAutoDeleteChat = getAutoDeleteChatFactory(ctx, this);
this.getAutoReplyList = getAutoReplyListFactory(ctx, this);
this.getAvatarList = getAvatarListFactory(ctx, this);
this.getAvatarUrlProfile = getAvatarUrlProfileFactory(ctx, this);
this.getBizAccount = getBizAccountFactory(ctx, this);
this.getCatalogList = getCatalogListFactory(ctx, this);
this.getCloseFriends = getCloseFriendsFactory(ctx, this);
this.getContext = getContextFactory(ctx, this);
this.getCookie = getCookieFactory(ctx, this);
this.getFriendBoardList = getFriendBoardListFactory(ctx, this);
this.getFriendOnlines = getFriendOnlinesFactory(ctx, this);
this.getFriendRecommendations = getFriendRecommendationsFactory(ctx, this);
this.getFriendRequestStatus = getFriendRequestStatusFactory(ctx, this);
this.getFullAvatar = getFullAvatarFactory(ctx, this);
this.getGroupBlockedMember = getGroupBlockedMemberFactory(ctx, this);
this.getGroupChatHistory = getGroupChatHistoryFactory(ctx, this);
this.getGroupInfo = getGroupInfoFactory(ctx, this);
this.getGroupInviteBoxInfo = getGroupInviteBoxInfoFactory(ctx, this);
this.getGroupInviteBoxList = getGroupInviteBoxListFactory(ctx, this);
this.getGroupLinkDetail = getGroupLinkDetailFactory(ctx, this);
this.getGroupLinkInfo = getGroupLinkInfoFactory(ctx, this);
this.getGroupMembersInfo = getGroupMembersInfoFactory(ctx, this);
this.getHiddenConversations = getHiddenConversationsFactory(ctx, this);
this.getLabels = getLabelsFactory(ctx, this);
this.getListBoard = getListBoardFactory(ctx, this);
this.getListReminder = getListReminderFactory(ctx, this);
this.getMultiUsersByPhones = getMultiUsersByPhonesFactory(ctx, this);
this.getMute = getMuteFactory(ctx, this);
this.getOwnId = getOwnIdFactory(ctx, this);
this.getPendingGroupMembers = getPendingGroupMembersFactory(ctx, this);
this.getPinConversations = getPinConversationsFactory(ctx, this);
this.getPollDetail = getPollDetailFactory(ctx, this);
this.getProductCatalogList = getProductCatalogListFactory(ctx, this);
this.getQR = getQRFactory(ctx, this);
this.getQuickMessageList = getQuickMessageListFactory(ctx, this);
this.getRelatedFriendGroup = getRelatedFriendGroupFactory(ctx, this);
this.getReminder = getReminderFactory(ctx, this);
this.getReminderResponses = getReminderResponsesFactory(ctx, this);
this.getSentFriendRequest = getSentFriendRequestFactory(ctx, this);
this.getSettings = getSettingsFactory(ctx, this);
this.getStickerCategoryDetail = getStickerCategoryDetailFactory(ctx, this);
this.getStickers = getStickersFactory(ctx, this);
this.getStickersDetail = getStickersDetailFactory(ctx, this);
this.getUnreadMark = getUnreadMarkFactory(ctx, this);
this.getUserInfo = getUserInfoFactory(ctx, this);
this.inviteUserToGroups = inviteUserToGroupsFactory(ctx, this);
this.joinGroupInviteBox = joinGroupInviteBoxFactory(ctx, this);
this.joinGroupLink = joinGroupLinkFactory(ctx, this);
this.keepAlive = keepAliveFactory(ctx, this);
this.lastOnline = lastOnlineFactory(ctx, this);
this.leaveGroup = leaveGroupFactory(ctx, this);
this.lockPoll = lockPollFactory(ctx, this);
this.parseLink = parseLinkFactory(ctx, this);
this.rejectFriendRequest = rejectFriendRequestFactory(ctx, this);
this.removeFriend = removeFriendFactory(ctx, this);
this.removeFriendAlias = removeFriendAliasFactory(ctx, this);
this.removeGroupBlockedMember = removeGroupBlockedMemberFactory(ctx, this);
this.removeGroupDeputy = removeGroupDeputyFactory(ctx, this);
this.removeQuickMessage = removeQuickMessageFactory(ctx, this);
this.removeReminder = removeReminderFactory(ctx, this);
this.removeUnreadMark = removeUnreadMarkFactory(ctx, this);
this.removeUserFromGroup = removeUserFromGroupFactory(ctx, this);
this.resetHiddenConversPin = resetHiddenConversPinFactory(ctx, this);
this.reuseAvatar = reuseAvatarFactory(ctx, this);
this.reviewPendingMemberRequest = reviewPendingMemberRequestFactory(ctx, this);
this.searchSticker = searchStickerFactory(ctx, this);
this.sendBankCard = sendBankCardFactory(ctx, this);
this.sendCard = sendCardFactory(ctx, this);
this.sendDeliveredEvent = sendDeliveredEventFactory(ctx, this);
this.sendFriendRequest = sendFriendRequestFactory(ctx, this);
this.sendLink = sendLinkFactory(ctx, this);
this.sendMessage = sendMessageFactory(ctx, this);
this.sendReport = sendReportFactory(ctx, this);
this.sendSeenEvent = sendSeenEventFactory(ctx, this);
this.sendSticker = sendStickerFactory(ctx, this);
this.sendTypingEvent = sendTypingEventFactory(ctx, this);
this.sendVideo = sendVideoFactory(ctx, this);
this.sendVoice = sendVoiceFactory(ctx, this);
this.setHiddenConversations = setHiddenConversationsFactory(ctx, this);
this.setMute = setMuteFactory(ctx, this);
this.setPinnedConversations = setPinnedConversationsFactory(ctx, this);
this.sharePoll = sharePollFactory(ctx, this);
this.unblockUser = unblockUserFactory(ctx, this);
this.undo = undoFactory(ctx, this);
this.undoFriendRequest = undoFriendRequestFactory(ctx, this);
this.updateActiveStatus = updateActiveStatusFactory(ctx, this);
this.updateArchivedChatList = updateArchivedChatListFactory(ctx, this);
this.updateAutoDeleteChat = updateAutoDeleteChatFactory(ctx, this);
this.updateAutoReply = updateAutoReplyFactory(ctx, this);
this.updateCatalog = updateCatalogFactory(ctx, this);
this.updateGroupSettings = updateGroupSettingsFactory(ctx, this);
this.updateHiddenConversPin = updateHiddenConversPinFactory(ctx, this);
this.updateLabels = updateLabelsFactory(ctx, this);
this.updateLang = updateLangFactory(ctx, this);
this.updateProductCatalog = updateProductCatalogFactory(ctx, this);
this.updateProfile = updateProfileFactory(ctx, this);
this.updateProfileBio = updateProfileBioFactory(ctx, this);
this.updateQuickMessage = updateQuickMessageFactory(ctx, this);
this.updateSettings = updateSettingsFactory(ctx, this);
this.upgradeGroupToCommunity = upgradeGroupToCommunityFactory(ctx, this);
this.uploadAttachment = uploadAttachmentFactory(ctx, this);
this.uploadProductPhoto = uploadProductPhotoFactory(ctx, this);
this.votePoll = votePollFactory(ctx, this);
this.custom = customFactory(ctx, this);
}
}
+2
View File
@@ -0,0 +1,2 @@
export type AcceptFriendRequestResponse = "";
export declare const acceptFriendRequestFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (friendId: string) => Promise<"">;
+28
View File
@@ -0,0 +1,28 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const acceptFriendRequestFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/accept`);
/**
* Accept a friend request from a User
*
* @param friendId The friend ID to user request is accept
*
* @throws {ZaloApiError}
*/
return async function acceptFriendRequest(friendId) {
const params = {
fid: friendId,
language: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+2
View File
@@ -0,0 +1,2 @@
export type AddGroupBlockedMemberResponse = "";
export declare const addGroupBlockedMemberFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (memberId: string | string[], groupId: string) => Promise<"">;
+28
View File
@@ -0,0 +1,28 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const addGroupBlockedMemberFactory = apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/blockedmems/add`);
/**
* Add group blocked member
*
* @param memberId member id(s)
* @param groupId group id
*
* @throws {ZaloApiError}
*/
return async function addGroupBlockedMember(memberId, groupId) {
if (!Array.isArray(memberId))
memberId = [memberId];
const params = {
grid: groupId,
members: memberId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+2
View File
@@ -0,0 +1,2 @@
export type AddGroupDeputyResponse = "";
export declare const addGroupDeputyFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (memberId: string | string[], groupId: string) => Promise<"">;
+30
View File
@@ -0,0 +1,30 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const addGroupDeputyFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/admins/add`);
/**
* Add group deputy
*
* @param memberId user Id or list of user Ids
* @param groupId group Id
*
* @throws {ZaloApiError}
*
*/
return async function addGroupDeputy(memberId, groupId) {
if (!Array.isArray(memberId))
memberId = [memberId];
const params = {
grid: groupId,
members: memberId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+14
View File
@@ -0,0 +1,14 @@
import type { PollOptions } from "../models/index.js";
export type AddPollOptionsOption = {
voted: boolean;
content: string;
};
export type AddPollOptionsPayload = {
pollId: number;
options: AddPollOptionsOption[];
votedOptionIds: number[];
};
export type AddPollOptionsResponse = {
options: PollOptions[];
};
export declare const addPollOptionsFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (payload: AddPollOptionsPayload) => Promise<AddPollOptionsResponse>;
+26
View File
@@ -0,0 +1,26 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const addPollOptionsFactory = apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/poll/option/add`);
/**
* Add new option to poll
*
* @param payload
*
* @throws {ZaloApiError}
*/
return async function addPollOptions(payload) {
const params = {
poll_id: payload.pollId,
new_options: JSON.stringify(payload.options),
voted_option_ids: payload.votedOptionIds,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+11
View File
@@ -0,0 +1,11 @@
import type { QuickMessage, AttachmentSource } from "../models/index.js";
export type AddQuickMessagePayload = {
keyword: string;
title: string;
media?: AttachmentSource;
};
export type AddQuickMessageResponse = {
item: QuickMessage;
version: number;
};
export declare const addQuickMessageFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (addPayload: AddQuickMessagePayload) => Promise<AddQuickMessageResponse>;
+60
View File
@@ -0,0 +1,60 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const addQuickMessageFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.quick_message[0]}/api/quickmessage/create`);
/**
* Add quick message
*
* @param addPayload - The payload containing data to add the quick message
*
* @note Zalo might throw an error with code 821 if you have reached the limit of quick messages.
*
* @throws {ZaloApiError}
*/
return async function addQuickMessage(addPayload) {
const isType = !addPayload.media ? 0 : 1;
const params = {
keyword: addPayload.keyword,
message: {
title: addPayload.title,
params: "",
},
type: isType,
imei: ctx.imei,
};
if (isType === 1) {
if (!addPayload.media)
throw new ZaloApiError("Media is required");
const uploadMedia = await api.uploadProductPhoto({
file: addPayload.media,
});
const photoId = uploadMedia.photoId;
const thumbUrl = uploadMedia.thumbUrl;
const normalUrl = uploadMedia.normalUrl;
const hdUrl = uploadMedia.hdUrl;
params.media = {
items: [
{
type: 0,
photoId: photoId,
title: "",
width: "",
height: "",
previewThumb: thumbUrl,
rawUrl: normalUrl || hdUrl,
thumbUrl: thumbUrl,
normalUrl: normalUrl || hdUrl,
hdUrl: hdUrl || normalUrl,
},
],
};
}
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+18
View File
@@ -0,0 +1,18 @@
import { ThreadType, Reactions } from "../models/index.js";
export type AddReactionResponse = {
msgIds: number[];
};
export type CustomReaction = {
rType: number;
source: number;
icon: string;
};
export type AddReactionDestination = {
data: {
msgId: string;
cliMsgId: string;
};
threadId: string;
type: ThreadType;
};
export declare const addReactionFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (icon: Reactions | CustomReaction, dest: AddReactionDestination) => Promise<AddReactionResponse>;
+294
View File
@@ -0,0 +1,294 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { ThreadType, Reactions } from "../models/index.js";
import { apiFactory } from "../utils.js";
export const addReactionFactory = apiFactory()((api, ctx, utils) => {
const serviceURLs = {
[ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.reaction[0]}/api/message/reaction`),
[ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.reaction[0]}/api/group/reaction`),
};
/**
* Add reaction to a message
*
* @param icon Reaction icon
* @param dest Destination data including message IDs and thread information
*
* @throws {ZaloApiError}
*/
return async function addReaction(icon, dest) {
const serviceURL = serviceURLs[dest.type];
let rType, source;
if (typeof icon == "object") {
rType = icon.rType;
source = icon.source;
}
else
switch (icon) {
case Reactions.HAHA:
rType = 0;
source = 6;
break;
case Reactions.LIKE:
rType = 3;
source = 6;
break;
case Reactions.HEART:
rType = 5;
source = 6;
break;
case Reactions.WOW:
rType = 32;
source = 6;
break;
case Reactions.CRY:
rType = 2;
source = 6;
break;
case Reactions.ANGRY:
rType = 20;
source = 6;
break;
case Reactions.KISS:
rType = 8;
source = 6;
break;
case Reactions.TEARS_OF_JOY:
rType = 7;
source = 6;
break;
case Reactions.SHIT:
rType = 66;
source = 6;
break;
case Reactions.ROSE:
rType = 120;
source = 6;
break;
case Reactions.BROKEN_HEART:
rType = 65;
source = 6;
break;
case Reactions.DISLIKE:
rType = 4;
source = 6;
break;
case Reactions.LOVE:
rType = 29;
source = 6;
break;
case Reactions.CONFUSED:
rType = 51;
source = 6;
break;
case Reactions.WINK:
rType = 45;
source = 6;
break;
case Reactions.FADE:
rType = 121;
source = 6;
break;
case Reactions.SUN:
rType = 67;
source = 6;
break;
case Reactions.BIRTHDAY:
rType = 126;
source = 6;
break;
case Reactions.BOMB:
rType = 127;
source = 6;
break;
case Reactions.OK:
rType = 68;
source = 6;
break;
case Reactions.PEACE:
rType = 69;
source = 6;
break;
case Reactions.THANKS:
rType = 70;
source = 6;
break;
case Reactions.PUNCH:
rType = 71;
source = 6;
break;
case Reactions.SHARE:
rType = 72;
source = 6;
break;
case Reactions.PRAY:
rType = 73;
source = 6;
break;
case Reactions.NO:
rType = 131;
source = 6;
break;
case Reactions.BAD:
rType = 132;
source = 6;
break;
case Reactions.LOVE_YOU:
rType = 133;
source = 6;
break;
case Reactions.SAD:
rType = 1;
source = 6;
break;
case Reactions.VERY_SAD:
rType = 16;
source = 6;
break;
case Reactions.COOL:
rType = 21;
source = 6;
break;
case Reactions.NERD:
rType = 22;
source = 6;
break;
case Reactions.BIG_SMILE:
rType = 23;
source = 6;
break;
case Reactions.SUNGLASSES:
rType = 26;
source = 6;
break;
case Reactions.NEUTRAL:
rType = 30;
source = 6;
break;
case Reactions.SAD_FACE:
rType = 35;
source = 6;
break;
case Reactions.BYE:
rType = 36;
source = 6;
break;
case Reactions.SLEEPY:
rType = 38;
source = 6;
break;
case Reactions.WIPE:
rType = 39;
source = 6;
break;
case Reactions.DIG:
rType = 42;
source = 6;
break;
case Reactions.ANGUISH:
rType = 44;
source = 6;
break;
case Reactions.HANDCLAP:
rType = 46;
source = 6;
break;
case Reactions.ANGRY_FACE:
rType = 47;
source = 6;
break;
case Reactions.F_CHAIR:
rType = 48;
source = 6;
break;
case Reactions.L_CHAIR:
rType = 49;
source = 6;
break;
case Reactions.R_CHAIR:
rType = 50;
source = 6;
break;
case Reactions.SILENT:
rType = 52;
source = 6;
break;
case Reactions.SURPRISE:
rType = 53;
source = 6;
break;
case Reactions.EMBARRASSED:
rType = 54;
source = 6;
break;
case Reactions.AFRAID:
rType = 60;
source = 6;
break;
case Reactions.SAD2:
rType = 61;
source = 6;
break;
case Reactions.BIG_LAUGH:
rType = 62;
source = 6;
break;
case Reactions.RICH:
rType = 63;
source = 6;
break;
case Reactions.BEER:
rType = 99;
source = 6;
break;
default:
rType = -1;
source = 6;
}
const rIcon = typeof icon == "object" ? icon.icon : icon;
if (rType == undefined || source == undefined || rIcon == undefined) {
throw new ZaloApiError("Invalid reaction");
}
const params = {
react_list: [
{
message: JSON.stringify({
rMsg: [
{
gMsgID: parseInt(dest.data.msgId),
cMsgID: parseInt(dest.data.cliMsgId),
msgType: 1,
},
],
rIcon,
rType,
source,
}),
clientId: Date.now(),
},
],
};
if (dest.type == ThreadType.User) {
params.toid = dest.threadId;
}
else {
params.grid = dest.threadId;
params.imei = ctx.imei;
}
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt message");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response, (result) => {
if (typeof result.data.msgIds === "string") {
return {
msgIds: JSON.parse(result.data.msgIds),
};
}
return result.data;
});
};
});
+8
View File
@@ -0,0 +1,8 @@
import { ThreadType } from "../models/index.js";
export type AddUnreadMarkResponse = {
data: {
updateId: number;
};
status: number;
};
export declare const addUnreadMarkFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (threadId: string, type?: ThreadType) => Promise<AddUnreadMarkResponse>;
+52
View File
@@ -0,0 +1,52 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { ThreadType } from "../models/index.js";
import { apiFactory } from "../utils.js";
export const addUnreadMarkFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.conversation[0]}/api/conv/addUnreadMark`);
/**
* Add unread mark to conversation
*
* @param threadId Thread ID
* @param type Thread type (User/Group)
*
* @throws {ZaloApiError}
*/
return async function addUnreadMark(threadId, type = ThreadType.User) {
const timestamp = Date.now();
const timestampString = timestamp.toString();
const isGroup = type === ThreadType.Group;
const requestParams = {
param: JSON.stringify({
[isGroup ? "convsGroup" : "convsUser"]: [
{
id: threadId,
cliMsgId: timestampString,
fromUid: "0",
ts: timestamp,
},
],
[isGroup ? "convsUser" : "convsGroup"]: [],
imei: ctx.imei,
}),
};
const encryptedParams = utils.encodeAES(JSON.stringify(requestParams));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response, (result) => {
const data = result.data;
if (typeof data.data === "string") {
return {
data: JSON.parse(data.data),
status: data.status,
};
}
return result.data;
});
};
});
+5
View File
@@ -0,0 +1,5 @@
export type AddUserToGroupResponse = {
errorMembers: string[];
error_data: Record<string, string[]>;
};
export declare const addUserToGroupFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (memberId: string | string[], groupId: string) => Promise<AddUserToGroupResponse>;
+34
View File
@@ -0,0 +1,34 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const addUserToGroupFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/invite/v2`);
/**
* Add user to existing group
*
* @param memberId User ID or list of user IDs to add
* @param groupId Group ID
*
* @throws {ZaloApiError}
*/
return async function addUserToGroup(memberId, groupId) {
if (!Array.isArray(memberId))
memberId = [memberId];
const params = {
grid: groupId,
members: memberId,
memberTypes: memberId.map(() => -1),
imei: ctx.imei,
clientLang: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+2
View File
@@ -0,0 +1,2 @@
export type BlockUserResponse = "";
export declare const blockUserFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (userId: string) => Promise<"">;
+28
View File
@@ -0,0 +1,28 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const blockUserFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/block`);
/**
* Block a User
*
* @param userId The ID of the User to block
*
* @throws {ZaloApiError}
*/
return async function blockUser(userId) {
const params = {
fid: userId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+2
View File
@@ -0,0 +1,2 @@
export type BlockViewFeedResponse = "";
export declare const blockViewFeedFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (isBlockFeed: boolean, userId: string) => Promise<"">;
+30
View File
@@ -0,0 +1,30 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const blockViewFeedFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/feed/block`);
/**
* Block/Unblock friend view feed by ID
*
* @param isBlockFeed Boolean to block/unblock view feed
* @param userId User ID to block/unblock view feed
*
* @throws {ZaloApiError}
*/
return async function blockViewFeed(isBlockFeed, userId) {
const params = {
fid: userId,
isBlockFeed: isBlockFeed ? 1 : 0,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+3
View File
@@ -0,0 +1,3 @@
import type { AttachmentSource } from "../models/index.js";
export type ChangeAccountAvatarResponse = "";
export declare const changeAccountAvatarFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (avatarSource: AttachmentSource) => Promise<"">;
+52
View File
@@ -0,0 +1,52 @@
import FormData from "form-data";
import fs from "node:fs";
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory, formatTime, getImageMetaData } from "../utils.js";
export const changeAccountAvatarFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.file[0]}/api/profile/upavatar`);
/**
* Change account avatar
*
* @param avatarSource Attachment source, can be a file path or an Attachment object
*
* @throws {ZaloApiError | ZaloApiMissingImageMetadataGetter}
*/
return async function changeAccountAvatar(avatarSource) {
const isSourceFilePath = typeof avatarSource == "string";
const imageMetaData = isSourceFilePath ? await getImageMetaData(ctx, avatarSource) : avatarSource.metadata;
const fileSize = imageMetaData.totalSize || 0;
const params = {
avatarSize: 120,
clientId: String(ctx.uid + formatTime("%H:%M %d/%m/%Y")),
language: ctx.language,
metaData: JSON.stringify({
origin: {
width: imageMetaData.width || 1080,
height: imageMetaData.height || 1080,
},
processed: {
width: imageMetaData.width || 1080,
height: imageMetaData.height || 1080,
size: fileSize,
},
}),
};
const avatarData = isSourceFilePath ? fs.readFileSync(avatarSource) : avatarSource.data;
const formData = new FormData();
formData.append("fileContent", avatarData, {
filename: "blob",
contentType: "image/jpeg",
});
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, {
params: encryptedParams,
}), {
method: "POST",
headers: formData.getHeaders(),
body: formData.getBuffer(),
});
return utils.resolve(response);
};
});
+2
View File
@@ -0,0 +1,2 @@
export type ChangeFriendAliasResponse = "";
export declare const changeFriendAliasFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (alias: string, friendId: string) => Promise<"">;
+27
View File
@@ -0,0 +1,27 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const changeFriendAliasFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.alias[0]}/api/alias/update`);
/**
* Change friend's alias
*
* @param alias new alias (nickname - bietdanh)
* @param friendId friend id
*
* @throws {ZaloApiError}
*/
return async function changeFriendAlias(alias, friendId) {
const params = {
friendId: friendId,
alias: alias,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+3
View File
@@ -0,0 +1,3 @@
import type { AttachmentSource } from "../models/index.js";
export type ChangeGroupAvatarResponse = "";
export declare const changeGroupAvatarFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (avatarSource: AttachmentSource, groupId: string) => Promise<"">;
+44
View File
@@ -0,0 +1,44 @@
import FormData from "form-data";
import fs from "node:fs";
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory, getFullTimeFromMillisecond, getImageMetaData } from "../utils.js";
export const changeGroupAvatarFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.file[0]}/api/group/upavatar`);
/**
* Change group avatar
*
* @param avatarSource Attachment source, can be a file path or an Attachment object
* @param groupId Group ID
*
* @throws {ZaloApiError | ZaloApiMissingImageMetadataGetter}
*/
return async function changeGroupAvatar(avatarSource, groupId) {
const params = {
grid: groupId,
avatarSize: 120,
clientId: `g${groupId}${getFullTimeFromMillisecond(new Date().getTime())}`,
imei: ctx.imei,
};
const isSourceFilePath = typeof avatarSource == "string";
const imageMetaData = isSourceFilePath ? await getImageMetaData(ctx, avatarSource) : avatarSource.metadata;
params.originWidth = imageMetaData.width || 1080;
params.originHeight = imageMetaData.height || 1080;
const avatarData = isSourceFilePath ? fs.readFileSync(avatarSource) : avatarSource.data;
const formData = new FormData();
formData.append("fileContent", avatarData, {
filename: "blob",
contentType: "image/jpeg",
});
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, {
params: encryptedParams,
}), {
method: "POST",
headers: formData.getHeaders(),
body: formData.getBuffer(),
});
return utils.resolve(response);
};
});
+4
View File
@@ -0,0 +1,4 @@
export type ChangeGroupNameResponse = {
status: number;
};
export declare const changeGroupNameFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (name: string, groupId: string) => Promise<ChangeGroupNameResponse>;
+32
View File
@@ -0,0 +1,32 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const changeGroupNameFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/updateinfo`);
/**
* Change group name
*
* @param name New group name
* @param groupId Group ID
*
* @throws {ZaloApiError}
*/
return async function changeGroupName(name, groupId) {
if (name.length == 0)
name = Date.now().toString();
const params = {
grid: groupId,
gname: name,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+4
View File
@@ -0,0 +1,4 @@
export type ChangeGroupOwnerResponse = {
time: number;
};
export declare const changeGroupOwnerFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (memberId: string, groupId: string) => Promise<ChangeGroupOwnerResponse>;
+30
View File
@@ -0,0 +1,30 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const changeGroupOwnerFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/change-owner`);
/**
* Change group owner
*
* @param memberId User Id of new group owner
* @param groupId Group Id
* @note Be careful when changing the key, as it will result in losing group admin rights
*
* @throws {ZaloApiError}
*
*/
return async function changeGroupOwner(memberId, groupId) {
const params = {
grid: groupId,
newAdminId: memberId,
imei: ctx.imei,
language: ctx.language,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+14
View File
@@ -0,0 +1,14 @@
import type { AutoReplyItem, AutoReplyScope } from "../models/index.js";
export type CreateAutoReplyPayload = {
content: string;
isEnable: boolean;
startTime: number;
endTime: number;
scope: AutoReplyScope;
uids?: string | string[];
};
export type CreateAutoReplyResponse = {
item: AutoReplyItem;
version: number;
};
export declare const createAutoReplyFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (payload: CreateAutoReplyPayload) => Promise<CreateAutoReplyResponse>;
+37
View File
@@ -0,0 +1,37 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const createAutoReplyFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.auto_reply[0]}/api/autoreply/create`);
/**
* Create auto reply
*
* @param payload payload
*
* @note this API used for zBusiness
* @throws {ZaloApiError}
*/
return async function createAutoReply(payload) {
const uids = Array.isArray(payload.uids) ? payload.uids : [payload.uids];
const resultUids = (payload.scope === 2 || payload.scope === 3) ? uids : [];
const params = {
cliLang: ctx.language,
enable: payload.isEnable,
content: payload.content,
startTime: payload.startTime,
endTime: payload.endTime,
recurrence: ["RRULE:FREQ=DAILY;"],
scope: payload.scope,
uids: resultUids,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+7
View File
@@ -0,0 +1,7 @@
import type { CatalogItem } from "../models/index.js";
export type CreateCatalogResponse = {
item: CatalogItem;
version_ls_catalog: number;
version_catalog: number;
};
export declare const createCatalogFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (catalogName: string) => Promise<CreateCatalogResponse>;
+29
View File
@@ -0,0 +1,29 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const createCatalogFactory = apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.catalog[0]}/api/prodcatalog/catalog/create`);
/**
* Create catalog?
*
* @param catalogName catalog name
*
* @note this API is used for zBusiness
* @throws {ZaloApiError}
*/
return async function createCatalog(catalogName) {
const params = {
catalog_name: catalogName,
catalog_photo: "",
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+28
View File
@@ -0,0 +1,28 @@
import type { AttachmentSource } from "../models/index.js";
export type CreateGroupResponse = {
groupType: number;
sucessMembers: string[];
groupId: string;
errorMembers: string[];
error_data: Record<string, unknown>;
};
export type CreateGroupOptions = {
/**
* Group name
*/
name?: string;
/**
* List of member IDs to add to the group
*/
members: string[];
/**
* Avatar source, can be a file path or an Attachment object
*/
avatarSource?: AttachmentSource;
/**
* Path to the avatar image file
* @deprecated Use `avatarSource` instead
*/
avatarPath?: string;
};
export declare const createGroupFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (options: CreateGroupOptions) => Promise<CreateGroupResponse>;
+43
View File
@@ -0,0 +1,43 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const createGroupFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/create/v2`);
/**
* Create a new group
*
* @param options Group options
*
* @throws {ZaloApiError}
*/
return async function createGroup(options) {
if (options.members.length == 0)
throw new ZaloApiError("Group must have at least one member");
const params = {
clientId: Date.now(),
gname: String(Date.now()),
gdesc: null,
members: options.members,
membersTypes: options.members.map(() => -1),
nameChanged: 0,
createLink: 1,
clientLang: ctx.language,
imei: ctx.imei,
zsource: 601,
};
if (options.name && options.name.length > 0) {
params.gname = options.name;
params.nameChanged = 1;
}
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt message");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "POST",
});
const data = await utils.resolve(response);
options.avatarSource = options.avatarSource || options.avatarPath;
if (options.avatarSource)
await api.changeGroupAvatar(options.avatarSource, data.groupId).catch(utils.logger.error);
return data;
};
});
+7
View File
@@ -0,0 +1,7 @@
import type { NoteDetail } from "../models/index.js";
export type CreateNoteOptions = {
title: string;
pinAct?: boolean;
};
export type CreateNoteResponse = NoteDetail;
export declare const createNoteFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (options: CreateNoteOptions, groupId: string) => Promise<NoteDetail>;
+47
View File
@@ -0,0 +1,47 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const createNoteFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/topic/createv2`);
/**
* Create a note in a group
*
* @param options note options
* @param options.title note title
* @param options.pinAct pin action (pin note)
* @param groupId group id
*
* @throws {ZaloApiError}
*/
return async function createNote(options, groupId) {
const params = {
grid: groupId,
type: 0,
color: -16777216,
emoji: "",
startTime: -1,
duration: -1,
params: JSON.stringify({
title: options.title,
}),
repeat: 0,
src: 1,
imei: ctx.imei,
pinAct: options.pinAct ? 1 : 0,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response, (result) => {
if (typeof result.data.params === "string") {
result.data.params = JSON.parse(result.data.params);
}
return result.data;
});
};
});
+36
View File
@@ -0,0 +1,36 @@
import type { PollDetail } from "../models/index.js";
/**
* Options for creating a poll.
*/
export type CreatePollOptions = {
/**
* Question for the poll.
*/
question: string;
/**
* List of options for the poll.
*/
options: string[];
/**
* Poll expiration time in milliseconds (0 = no expiration).
*/
expiredTime?: number;
/**
* Allows multiple choices in the poll.
*/
allowMultiChoices?: boolean;
/**
* Allows members to add new options to the poll.
*/
allowAddNewOption?: boolean;
/**
* Hides voting results until the user has voted.
*/
hideVotePreview?: boolean;
/**
* Hides poll voters (anonymous poll).
*/
isAnonymous?: boolean;
};
export type CreatePollResponse = PollDetail;
export declare const createPollFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (options: CreatePollOptions, groupId: string) => Promise<PollDetail>;
+40
View File
@@ -0,0 +1,40 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const createPollFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/poll/create`);
/**
* Create a poll in a group.
*
* @param options Poll options
* @param groupId Group ID to create poll from
*
* @throws {ZaloApiError}
*/
return async function createPoll(options, groupId) {
var _a;
const params = {
group_id: groupId,
question: options.question,
options: options.options,
expired_time: (_a = options.expiredTime) !== null && _a !== void 0 ? _a : 0,
pinAct: false,
allow_multi_choices: !!options.allowMultiChoices,
allow_add_new_option: !!options.allowAddNewOption,
is_hide_vote_preview: !!options.hideVotePreview,
is_anonymous: !!options.isAnonymous,
poll_type: 0,
src: 1,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+23
View File
@@ -0,0 +1,23 @@
import type { AttachmentSource, ProductCatalogItem } from "../models/index.js";
export type CreateProductCatalogPayload = {
catalogId: string;
productName: string;
price: string;
description: string;
/**
* Upto 5 media files are allowed, will be ignored if product_photos is provided
*/
files?: AttachmentSource[];
/**
* List of product photo URLs, upto 5
*
* You can manually get the URL using `uploadProductPhoto` api
*/
product_photos?: string[];
};
export type CreateProductCatalogResponse = {
item: ProductCatalogItem;
version_ls_catalog: number;
version_catalog: number;
};
export declare const createProductCatalogFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (payload: CreateProductCatalogPayload) => Promise<CreateProductCatalogResponse>;
+50
View File
@@ -0,0 +1,50 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const createProductCatalogFactory = apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.catalog[0]}/api/prodcatalog/product/create`);
/**
* Create product catalog?
*
* @param payload payload
*
* @note this API is used for zBussiness - Maximum 5 media files are supported
* @throws {ZaloApiError}
*/
return async function createProductCatalog(payload) {
const productPhoto = payload.product_photos || [];
if (payload.files && payload.files.length == 0) {
if (payload.files.length > 5) {
throw new ZaloApiError("Maximum 5 media files are allowed");
}
for (const mediaFile of payload.files) {
const uploadMedia = await api.uploadProductPhoto({
file: mediaFile,
});
const url = uploadMedia.normalUrl || uploadMedia.hdUrl;
productPhoto.push(url);
}
}
if (productPhoto.length > 5) {
throw new ZaloApiError("Maximum 5 media files are allowed");
}
const params = {
product_name: payload.productName,
price: payload.price,
description: payload.description,
product_photos: productPhoto,
catalog_id: payload.catalogId,
currency_unit: "₫", // $
create_time: Date.now(),
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+12
View File
@@ -0,0 +1,12 @@
import type { ReminderGroup, ReminderUser } from "../models/index.js";
import { ReminderRepeatMode, ThreadType } from "../models/index.js";
export type CreateReminderOptions = {
title: string;
emoji?: string;
startTime?: number;
repeat?: ReminderRepeatMode;
};
export type CreateReminderUser = ReminderUser;
export type CreateReminderGroup = Omit<ReminderGroup, "responseMem">;
export type CreateReminderResponse = CreateReminderUser | CreateReminderGroup;
export declare const createReminderFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (options: CreateReminderOptions, threadId: string, type?: ThreadType) => Promise<CreateReminderResponse>;
+63
View File
@@ -0,0 +1,63 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { ReminderRepeatMode, ThreadType } from "../models/index.js";
import { apiFactory } from "../utils.js";
export const createReminderFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = {
[ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/oneone/create`),
[ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/topic/createv2`),
};
/**
* Create a reminder in a group
*
* @param options reminder options
* @param threadId Group ID to create note from
* @param type Thread type (User or Group)
*
* @throws {ZaloApiError}
*/
return async function createReminder(options, threadId, type = ThreadType.User) {
var _a, _b, _c, _d, _e, _f;
const params = type === ThreadType.User
? {
objectData: JSON.stringify({
toUid: threadId,
type: 0,
color: -16245706,
emoji: (_a = options.emoji) !== null && _a !== void 0 ? _a : "⏰",
startTime: (_b = options.startTime) !== null && _b !== void 0 ? _b : Date.now(),
duration: -1,
params: { title: options.title },
needPin: false,
repeat: (_c = options.repeat) !== null && _c !== void 0 ? _c : ReminderRepeatMode.None,
creatorUid: ctx.uid, // Note: for some reason, you can put any valid UID here instead of your own and it still works, atleast for mobile
src: 1,
}),
imei: ctx.imei,
}
: {
grid: threadId,
type: 0,
color: -16245706,
emoji: (_d = options.emoji) !== null && _d !== void 0 ? _d : "⏰",
startTime: (_e = options.startTime) !== null && _e !== void 0 ? _e : Date.now(),
duration: -1,
params: JSON.stringify({
title: options.title,
}),
repeat: (_f = options.repeat) !== null && _f !== void 0 ? _f : ReminderRepeatMode.None,
src: 1,
imei: ctx.imei,
pinAct: 0,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL[type], {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+9
View File
@@ -0,0 +1,9 @@
import { type ContextSession } from "../context.js";
import { type FactoryUtils } from "../utils.js";
export type CustomAPIProps<T, K> = {
ctx: ContextSession;
utils: FactoryUtils<T>;
props: K;
};
export type CustomAPICallback<T, K> = (props: CustomAPIProps<T, K>) => T | Promise<T>;
export declare const customFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => <T, K = any>(name: string, callback: CustomAPICallback<T, K>) => void;
+15
View File
@@ -0,0 +1,15 @@
import {} from "../context.js";
import { apiFactory } from "../utils.js";
/* eslint-disable */
export const customFactory = apiFactory()((api, ctx, utils) => {
return function custom(name, callback) {
Object.defineProperty(api, name, {
value: function (props) {
return callback({ ctx, utils, props });
},
writable: false,
enumerable: false,
configurable: false,
});
};
});
+5
View File
@@ -0,0 +1,5 @@
export type DeleteAutoReplyResponse = {
item: number;
version: number;
};
export declare const deleteAutoReplyFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (id: number) => Promise<DeleteAutoReplyResponse>;
+29
View File
@@ -0,0 +1,29 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const deleteAutoReplyFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.auto_reply[0]}/api/autoreply/delete`);
/**
* Delete auto reply
*
* @param id id of auto reply
*
* @note this API used for zBusiness
* @throws {ZaloApiError}
*/
return async function deleteAutoReply(id) {
const params = {
cliLang: ctx.language,
id: id,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+9
View File
@@ -0,0 +1,9 @@
export type DeleteAvatarResponse = {
delPhotoIds: string[];
errMap: {
[key: string]: {
err: number;
};
};
};
export declare const deleteAvatarFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (photoId: string | string[]) => Promise<DeleteAvatarResponse>;
+27
View File
@@ -0,0 +1,27 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const deleteAvatarFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/del-avatars`);
/**
* Delete avatar from avatar list
*
* @param photoId avatar photo ID(s) to delete - can be a single string or array of strings
*
* @throws {ZaloApiError}
*/
return async function deleteAvatar(photoId) {
const photoIds = Array.isArray(photoId) ? photoId : [photoId];
const delPhotos = photoIds.map((id) => ({ photoId: id }));
const params = {
delPhotos: JSON.stringify(delPhotos),
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+2
View File
@@ -0,0 +1,2 @@
export type DeleteCatalogResponse = "";
export declare const deleteCatalogFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (catalogId: string) => Promise<"">;
+28
View File
@@ -0,0 +1,28 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const deleteCatalogFactory = apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.catalog[0]}/api/prodcatalog/catalog/delete`);
/**
* Delete catalog?
*
* @param catalogId catalog id
*
* @note this API is used for zBusiness
* @throws {ZaloApiError}
*/
return async function deleteCatalog(catalogId) {
const params = {
catalog_id: catalogId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+19
View File
@@ -0,0 +1,19 @@
import { ThreadType } from "../models/index.js";
export type DeleteChatResponse = {
status: number;
};
export type DeleteChatLastMessage = {
/**
* Last message owner ID to delete backwards
*/
ownerId: string;
/**
* Last message client ID to delete backwards
*/
cliMsgId: string;
/**
* Last message global ID to delete backwards
*/
globalMsgId: string;
};
export declare const deleteChatFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (lastMessage: DeleteChatLastMessage, threadId: string, type?: ThreadType) => Promise<DeleteChatResponse>;
+50
View File
@@ -0,0 +1,50 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { ThreadType } from "../models/index.js";
import { apiFactory } from "../utils.js";
export const deleteChatFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = {
[ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.chat[0]}/api/message/deleteconver`, {
nretry: 0,
}),
[ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/deleteconver`, {
nretry: 0,
}),
};
/**
* Delete chat
*
* @param lastMessage Last message info
* @param threadId Thread ID
* @param type Thread type
*
* @throws {ZaloApiError}
*/
return async function deleteChat(lastMessage, threadId, type = ThreadType.User) {
const timestampString = Date.now().toString();
const params = type === ThreadType.User
? {
toid: threadId,
cliMsgId: timestampString,
conver: lastMessage,
onlyMe: 1,
imei: ctx.imei,
}
: {
grid: threadId,
cliMsgId: timestampString,
conver: lastMessage,
onlyMe: 1,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL[type], {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+9
View File
@@ -0,0 +1,9 @@
export type DeleteGroupInviteBoxResponse = {
delInvitaionIds: string[];
errMap: {
[groupId: string]: {
err: number;
};
};
};
export declare const deleteGroupInviteBoxFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (groupId: string | string[], blockFutureInvite?: boolean) => Promise<DeleteGroupInviteBoxResponse>;
+27
View File
@@ -0,0 +1,27 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const deleteGroupInviteBoxFactory = apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/inv-box/mdel-inv`);
/**
* Delete group invite box
*
* @param groupId - The group id
* @param blockFutureInvite - Whether to block future invites from this group
*
* @throws {ZaloApiError}
*/
return async function deleteGroupInviteBox(groupId, blockFutureInvite = false) {
const grids = Array.isArray(groupId) ? groupId : [groupId];
const params = {
invitations: JSON.stringify(grids.map((grid) => ({ grid }))),
block: blockFutureInvite ? 1 : 0,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+14
View File
@@ -0,0 +1,14 @@
import { ThreadType } from "../models/index.js";
export type DeleteMessageResponse = {
status: number;
};
export type DeleteMessageDestination = {
data: {
cliMsgId: string;
msgId: string;
uidFrom: string;
};
threadId: string;
type?: ThreadType;
};
export declare const deleteMessageFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (dest: DeleteMessageDestination, onlyMe?: boolean) => Promise<DeleteMessageResponse>;
+52
View File
@@ -0,0 +1,52 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { ThreadType } from "../models/index.js";
import { apiFactory } from "../utils.js";
export const deleteMessageFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = {
[ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.chat[0]}/api/message/delete`),
[ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/deletemsg`),
};
/**
* Delete a message
*
* @param dest Delete target
* @param onlyMe Delete message for only you
*
* @throws {ZaloApiError}
*/
return async function deleteMessage(dest, onlyMe = false) {
const { threadId, type = ThreadType.User, data } = dest;
const isGroup = type === ThreadType.Group;
const isSelf = ctx.uid == data.uidFrom;
if (isSelf && onlyMe === false)
throw new ZaloApiError("To delete your message for everyone, use undo api instead");
if (!isGroup && onlyMe === false)
throw new ZaloApiError("Can't delete message for everyone in a private chat");
const params = {
[isGroup ? "grid" : "toid"]: threadId,
cliMsgId: Date.now(),
msgs: [
{
cliMsgId: data.cliMsgId,
globalMsgId: data.msgId,
ownerId: data.uidFrom,
destId: threadId,
},
],
onlyMe: onlyMe ? 1 : 0,
};
if (!isGroup) {
params.imei = ctx.imei;
}
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt message");
const response = await utils.request(serviceURL[type], {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+10
View File
@@ -0,0 +1,10 @@
export type DeleteProductCatalogPayload = {
productIds: string | string[];
catalogId: string;
};
export type DeleteProductCatalogResponse = {
item: number[];
version_ls_catalog: number;
version_catalog: number;
};
export declare const deleteProductCatalogFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (payload: DeleteProductCatalogPayload) => Promise<DeleteProductCatalogResponse>;
+31
View File
@@ -0,0 +1,31 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const deleteProductCatalogFactory = apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.catalog[0]}/api/prodcatalog/product/mdelete`);
/**
* Delete product catalog?
*
* @param payload payload
*
* @note this API is used for zBusiness
* @throws {ZaloApiError}
*/
return async function deleteProductCatalog(payload) {
if (!Array.isArray(payload.productIds))
payload.productIds = [payload.productIds];
const params = {
product_ids: payload.productIds,
catalog_id: payload.catalogId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+2
View File
@@ -0,0 +1,2 @@
export type DisableGroupLinkResponse = "";
export declare const disableGroupLinkFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (groupId: string) => Promise<"">;
+24
View File
@@ -0,0 +1,24 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const disableGroupLinkFactory = apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/link/disable`);
/**
* Disable group link
*
* @param groupId The group id
*
* @throws {ZaloApiError}
*/
return async function disableGroupLink(groupId) {
const params = {
grid: groupId,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+2
View File
@@ -0,0 +1,2 @@
export type DisperseGroupResponse = "";
export declare const disperseGroupFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (groupId: string) => Promise<"">;
+28
View File
@@ -0,0 +1,28 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const disperseGroupFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/disperse`);
/**
* Disperse Group
*
* @param groupId Group ID to disperse Group from
*
* @throws {ZaloApiError}
*/
return async function disperseGroup(groupId) {
const params = {
grid: groupId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+17
View File
@@ -0,0 +1,17 @@
import type { NoteDetail } from "../models/index.js";
export type EditNoteOptions = {
/**
* New note title
*/
title: string;
/**
* Topic ID to edit note from
*/
topicId: string;
/**
* Should the note be pinned?
*/
pinAct?: boolean;
};
export type EditNoteResponse = NoteDetail;
export declare const editNoteFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (options: EditNoteOptions, groupId: string) => Promise<NoteDetail>;
+46
View File
@@ -0,0 +1,46 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const editNoteFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/topic/updatev2`);
/**
* Edit an existing note in a group
*
* @param options Options for editing the note
* @param groupId Group ID to create note from
*
* @throws {ZaloApiError}
*/
return async function editNote(options, groupId) {
const params = {
grid: groupId,
type: 0,
color: -16777216,
emoji: "",
startTime: -1,
duration: -1,
params: JSON.stringify({
title: options.title,
}),
topicId: options.topicId,
repeat: 0,
imei: ctx.imei,
pinAct: options.pinAct ? 1 : 2,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL, {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response, (result) => {
const data = result.data;
if (typeof data.params == "string") {
data.params = JSON.parse(data.params);
}
return data;
});
};
});
+13
View File
@@ -0,0 +1,13 @@
import type { ReminderRepeatMode, ReminderGroup, ReminderUser } from "../models/index.js";
import { ThreadType } from "../models/index.js";
export type EditReminderOptions = {
title: string;
topicId: string;
emoji?: string;
startTime?: number;
repeat?: ReminderRepeatMode;
};
export type EditReminderUser = ReminderUser;
export type EditReminderGroup = Omit<ReminderGroup, "responseMem">;
export type EditReminderResponse = EditReminderUser | EditReminderGroup;
export declare const editReminderFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (options: EditReminderOptions, threadId: string, type?: ThreadType) => Promise<EditReminderResponse>;
+61
View File
@@ -0,0 +1,61 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { ThreadType } from "../models/index.js";
import { apiFactory } from "../utils.js";
export const editReminderFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = {
[ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/oneone/update`),
[ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.group_board[0]}/api/board/topic/updatev2`),
};
/**
* Edit an existing reminder
*
* @param options Reminder parameters
* @param threadId Thread ID
* @param type Thread type (User/Group)
*
* @throws {ZaloApiError}
*/
return async function editReminder(options, threadId, type = ThreadType.User) {
var _a, _b, _c, _d, _e, _f;
const requestParams = type === ThreadType.User
? {
objectData: JSON.stringify({
toUid: threadId,
type: 0,
color: -16777216,
emoji: (_a = options.emoji) !== null && _a !== void 0 ? _a : "",
startTime: (_b = options.startTime) !== null && _b !== void 0 ? _b : Date.now(),
duration: -1,
params: { title: options.title },
needPin: false,
reminderId: options.topicId,
repeat: (_c = options.repeat) !== null && _c !== void 0 ? _c : 0,
}),
}
: {
grid: threadId,
type: 0,
color: -16777216,
emoji: (_d = options.emoji) !== null && _d !== void 0 ? _d : "",
startTime: (_e = options.startTime) !== null && _e !== void 0 ? _e : Date.now(),
duration: -1,
params: JSON.stringify({
title: options.title,
}),
topicId: options.topicId,
repeat: (_f = options.repeat) !== null && _f !== void 0 ? _f : 0,
imei: ctx.imei,
pinAct: 2,
};
const encryptedParams = utils.encodeAES(JSON.stringify(requestParams));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL[type], {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+6
View File
@@ -0,0 +1,6 @@
export type EnableGroupLinkResponse = {
link: string;
expiration_date: number;
enabled: number;
};
export declare const enableGroupLinkFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (groupId: string) => Promise<EnableGroupLinkResponse>;
+25
View File
@@ -0,0 +1,25 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const enableGroupLinkFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.group[0]}/api/group/link/new`);
/**
* Enable and create new group link
*
* @param groupId The group id
*
* @throws {ZaloApiError}
*/
return async function enableGroupLink(groupId) {
const params = {
grid: groupId,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+5
View File
@@ -0,0 +1,5 @@
import type { User } from "../models/index.js";
export type FetchAccountInfoResponse = {
profile: User;
};
export declare const fetchAccountInfoFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => () => Promise<FetchAccountInfoResponse>;
+10
View File
@@ -0,0 +1,10 @@
import { apiFactory } from "../utils.js";
export const fetchAccountInfoFactory = apiFactory()((api, _, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/profile/me-v2`);
return async function fetchAccountInfo() {
const response = await utils.request(serviceURL, {
method: "GET",
});
return utils.resolve(response);
};
});
+3
View File
@@ -0,0 +1,3 @@
import { AvatarSize, type UserBasic } from "../models/index.js";
export type FindUserResponse = UserBasic;
export declare const findUserFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (phoneNumber: string, avatarSize?: AvatarSize) => Promise<UserBasic>;
+42
View File
@@ -0,0 +1,42 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
import { AvatarSize } from "../models/index.js";
export const findUserFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/profile/get`);
/**
* Find user by phone number
*
* @param phoneNumber Phone number
* @param avatarSize Avatar size (default: AvatarSize.Large)
*
* @throws {ZaloApiError}
*/
return async function findUser(phoneNumber, avatarSize = AvatarSize.Large) {
if (!phoneNumber)
throw new ZaloApiError("Missing phoneNumber");
if (phoneNumber.startsWith("0")) {
if (ctx.language == "vi")
phoneNumber = "84" + phoneNumber.slice(1);
}
const params = {
phone: phoneNumber,
avatar_size: avatarSize,
language: ctx.language,
imei: ctx.imei,
reqSrc: 40,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt message");
const finalServiceUrl = new URL(serviceURL);
finalServiceUrl.searchParams.append("params", encryptedParams);
const response = await utils.request(utils.makeURL(finalServiceUrl.toString(), {
params: encryptedParams,
}));
return utils.resolve(response, (result) => {
if (result.error && result.error.code != 216)
throw new ZaloApiError(result.error.message, result.error.code);
return result.data;
});
};
});
+3
View File
@@ -0,0 +1,3 @@
import { AvatarSize, type UserBasic } from "../models/index.js";
export type FindUserByUsernameResponse = UserBasic;
export declare const findUserByUsernameFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (username: string, avatarSize?: AvatarSize) => Promise<UserBasic>;
+27
View File
@@ -0,0 +1,27 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
import { AvatarSize } from "../models/index.js";
export const findUserByUsernameFactory = apiFactory()((api, _ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.friend[0]}/api/friend/search/by-user-name`);
/**
* Find user by username
*
* @param username username for find
* @param avatarSize Avatar size (default: AvatarSize.Large)
*
* @throws {ZaloApiError}
*/
return async function findUserByUsername(username, avatarSize = AvatarSize.Large) {
const params = {
user_name: username,
avatar_size: avatarSize,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+24
View File
@@ -0,0 +1,24 @@
import { ThreadType } from "../models/index.js";
export type ForwardMessagePayload = {
message: string;
ttl?: number;
reference?: {
id: string;
ts: number;
logSrcType: number;
fwLvl: number;
};
};
export type ForwardMessageSuccess = {
clientId: string;
msgId: string;
};
export type ForwardMessageFail = {
clientId: string;
error_code: string;
};
export type ForwardMessageResponse = {
success: ForwardMessageSuccess[];
fail: ForwardMessageFail[];
};
export declare const forwardMessageFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (payload: ForwardMessagePayload, threadIds: string[], type?: ThreadType) => Promise<ForwardMessageResponse>;
+99
View File
@@ -0,0 +1,99 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { ThreadType } from "../models/index.js";
import { apiFactory } from "../utils.js";
export const forwardMessageFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = {
[ThreadType.User]: utils.makeURL(`${api.zpwServiceMap.file[0]}/api/message/mforward`),
[ThreadType.Group]: utils.makeURL(`${api.zpwServiceMap.file[0]}/api/group/mforward`),
};
/**
* Forward message to multiple threads
*
* @param payload Forward message payload
* @param threadId Thread ID(s)
* @param type Thread type (User/Group)
*
* @throws {ZaloApiError}
*/
return async function forwardMessage(payload, threadIds, type = ThreadType.User) {
var _a, _b;
if (!payload.message)
throw new ZaloApiError("Missing message content");
if (!threadIds || threadIds.length === 0)
throw new ZaloApiError("Missing thread IDs");
const timestamp = Date.now();
const clientId = timestamp.toString();
const msgInfo = {
message: payload.message,
reference: payload.reference
? JSON.stringify({
type: 3,
data: JSON.stringify(payload.reference),
})
: undefined,
};
const decorLog = payload.reference
? {
fw: {
pmsg: {
st: 1,
ts: payload.reference.ts,
id: payload.reference.id,
},
rmsg: {
st: 1,
ts: payload.reference.ts,
id: payload.reference.id,
},
fwLvl: payload.reference.fwLvl,
},
}
: null;
let params;
if (type === ThreadType.User) {
params = {
toIds: threadIds.map((threadId) => {
var _a;
return ({
clientId,
toUid: threadId,
ttl: (_a = payload.ttl) !== null && _a !== void 0 ? _a : 0,
});
}),
imei: ctx.imei,
ttl: (_a = payload.ttl) !== null && _a !== void 0 ? _a : 0,
msgType: "1",
totalIds: threadIds.length,
msgInfo: JSON.stringify(msgInfo),
decorLog: JSON.stringify(decorLog),
};
}
else {
params = {
grids: threadIds.map((threadId) => {
var _a;
return ({
clientId,
grid: threadId,
ttl: (_a = payload.ttl) !== null && _a !== void 0 ? _a : 0,
});
}),
ttl: (_b = payload.ttl) !== null && _b !== void 0 ? _b : 0,
msgType: "1",
totalIds: threadIds.length,
msgInfo: JSON.stringify(msgInfo),
decorLog: JSON.stringify(decorLog),
};
}
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(serviceURL[type], {
method: "POST",
body: new URLSearchParams({
params: encryptedParams,
}),
});
return utils.resolve(response);
};
});
+8
View File
@@ -0,0 +1,8 @@
export type GetAliasListResponse = {
items: {
userId: string;
alias: string;
}[];
updateTime: string;
};
export declare const getAliasListFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (count?: number, page?: number) => Promise<GetAliasListResponse>;
+27
View File
@@ -0,0 +1,27 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
export const getAliasListFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.alias[0]}/api/alias/list`);
/**
* Get alias list
*
* @param count Page size (default: 100)
* @param page Page number (default: 1)
*
* @throws {ZaloApiError}
*/
return async function getAliasList(count = 100, page = 1) {
const params = {
page,
count,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt params");
const response = await utils.request(utils.makeURL(serviceURL, { params: encryptedParams }), {
method: "GET",
});
return utils.resolve(response);
};
});
+3
View File
@@ -0,0 +1,3 @@
import { AvatarSize, type User } from "../models/index.js";
export type GetAllFriendsResponse = User[];
export declare const getAllFriendsFactory: (ctx: import("../context.js").ContextBase, api: import("../apis.js").API) => (count?: number, page?: number, avatarSize?: AvatarSize) => Promise<GetAllFriendsResponse>;
+34
View File
@@ -0,0 +1,34 @@
import { ZaloApiError } from "../Errors/ZaloApiError.js";
import { apiFactory } from "../utils.js";
import { AvatarSize } from "../models/index.js";
export const getAllFriendsFactory = apiFactory()((api, ctx, utils) => {
const serviceURL = utils.makeURL(`${api.zpwServiceMap.profile[0]}/api/social/friend/getfriends`);
/**
* Get all friends
*
* @param count Page size (default: 20000)
* @param page Page number (default: 1)
* @param avatarSize Avatar size (default: AvatarSize.Small)
*
* @throws {ZaloApiError}
*/
return async function getAllFriends(count = 20000, page = 1, avatarSize = AvatarSize.Small) {
const params = {
incInvalid: 1,
page,
count,
avatar_size: avatarSize,
actiontime: 0,
imei: ctx.imei,
};
const encryptedParams = utils.encodeAES(JSON.stringify(params));
if (!encryptedParams)
throw new ZaloApiError("Failed to encrypt message");
const response = await utils.request(utils.makeURL(serviceURL, {
params: encryptedParams,
}), {
method: "GET",
});
return utils.resolve(response);
};
});

Some files were not shown because too many files have changed in this diff Show More