Skip to content

AI Script Agent

Overview

The AI script generation feature of the Informat platform is an intelligent automated script creation tool. By integrating user requirements with AI models configured by the Informat team, it can quickly generate script code that meets customer needs. This feature is primarily designed for developers, test engineers, and automation operations personnel, aiming to improve work efficiency and reduce repetitive coding work.

Using the AI Script Agent to Generate Scripts

In the [Application Designer]'s [AI] module, click [Script Agent] to switch to the script agent conversation.

Please note that the configured model needs to support function call.

use-ai-general.png

Application Cases

1. Automatically Generate Utility Scripts

  • Use case: Generate some utility methods about users, enabling quick determination of whether someone is a department leader or is in a specified department list
  • Generated script content (partial)
js
/**
 * Check if the current user has specified application roles
 * @param {Array<string>} roleIds - Array of role IDs
 * @returns {boolean} Returns true if the current user has any of the roles, false otherwise
 */
export function isCurrentUserHasRoles(roleIds) {
    try {
        const currentUserId = informat.app.userId();
        if (!currentUserId || !roleIds || !Array.isArray(roleIds)) {
            return false;
        }
        
        // Get current user info
        const user = informat.user.getUser(currentUserId);
        if (!user || !user.roleList) {
            return false;
        }
        
        // Check if user has the specified roles
        return roleIds.some(roleId => user.roleList.includes(roleId));
        
    } catch (error) {
        console.error("Error checking user roles:", error);
        return false;
    }
}
/**
 * Check if the current user is the leader of a specified department
 * @param {string} deptId - Department ID
 * @returns {boolean} Returns true if the user is a department leader, false otherwise
 * @example
 * // Check if the current user is the leader of department "dept123"
 * const isLeader = isCurrentUserDeptLeader("dept123");
 * if (isLeader) {
 *   console.log("Current user is the department leader");
 * } else {
 *   console.log("Current user is not the department leader");
 * }
 */
export function isCurrentUserDeptLeader(deptId) {
    // 
}

/**
 * Get current user information
 * @returns {Object|null} User info object, returns null if retrieval fails
 */
export function getCurrentUserInfo() {
    // 
}

/**
 * Get all leader user information for a specified department
 * @param {string} deptId - Department ID
 * @returns {Array} Array of leader user information
 */
export function getDeptLeaders(deptId) {
    // 
}

/**
 * Check if the current user is in the specified department list
 * @param {Array<string>} deptIds - Array of department IDs
 * @returns {boolean} Returns true if the current user is in any of the departments, false otherwise
 */
export function isCurrentUserInDepts(deptIds) {
    // 
}

2. Read Data Tables Within the Application

AI can automatically read the data table structure within the application and quickly generate scripts for specific business scenarios using the scripting capabilities provided by Informat

  • Use case: Read the employee table and insert salary records for each employee from January to August 2025 into the salary table
  • Generated script content (partial)
js

/**
 * Query the employee table and create salary records for each employee from January to August 2025
 */
export function createStaffSalaryRecordsOptimized() {
    try {
        // Query all employees
        const staffList = informat.table.queryList('staff', {
            pageIndex: 1,
            pageSize: -1,
            includeFields: ['id', 'name', 'salary']
        });
        
        console.log(`Found ${staffList.length} employees`);
        
        let totalCreated = 0;
        let skipped = 0;
        
        // Create salary records for January to August 2025 for each employee
        for (const staff of staffList) {
            const staffId = staff.id;
            const staffName = staff.name;
            const monthlySalary = staff.salary || 0;
            
            console.log(`Processing employee ${staffName}...`);
            
            // Create salary records for months 1-8
            for (let month = 1; month <= 8; month++) {
                // Check if the record already exists
                if (checkSalaryRecordExists(staffId, 2025, month)) {
                    console.log(`- Salary record for ${staffName} in month ${month} already exists, skipping`);
                    skipped++;
                    continue;
                }
                
                const salaryRecord = {
                    staff: staffId,
                    year: 2025,
                    month: month,
                    salary: monthlySalary
                };
                
                // Insert salary record
                const recordId = informat.table.insert('staffSalaryPaymentRecord', salaryRecord);
                
                if (recordId) {
                    totalCreated++;
                    console.log(`✓ Created salary record for ${staffName} in month ${month} successfully`);
                } else {
                    console.log(`✗ Failed to create salary record for ${staffName} in month ${month}`);
                }
            }
        }
        
        console.log(`Salary record creation complete!`);
        console.log(`- Newly created: ${totalCreated} records`);
        console.log(`- Skipped: ${skipped} existing records`);
        
        return {
            success: true,
            message: `Salary record processing complete, created ${totalCreated} new records, skipped ${skipped} existing records`,
            staffCount: staffList.length,
            createdCount: totalCreated,
            skippedCount: skipped
        };
        
    } catch (error) {
        console.error('Error creating salary records:', error);
        return {
            success: false,
            message: `Failed to create salary records: ${error.message}`,
            error: error.message
        };
    }
}
/**
 * Check if a salary record already exists for a given employee, year, and month
 * Prevents duplicate creation
 */
export function checkSalaryRecordExists(staffId, year, month) {
    const existingRecords = informat.table.queryList('staffSalaryPaymentRecord', {
        pageIndex: 1,
        pageSize: 1,
        filter: {
            conditionList: [
                { fieldId: 'staff', opt: 'eq', value: staffId },
                { fieldId: 'year', opt: 'eq', value: year },
                { fieldId: 'month', opt: 'eq', value: month }
            ]
        }
    });
    
    return existingRecords.length > 0;
}

3. Generate Multiple Scripts Simultaneously

AI can read user instructions and automatically generate folders, creating or editing scripts in the specified folders

  • Use case: Create an organization sync directory with scripts for syncing organization structure and members from WeCom, DingTalk, and Feishu to the Informat platform
  • Generated script content (partial)
text
Generated directory structure

Organization Sync
├── Main Sync Script.js
├── WeCom Organization Sync.js
├── Feishu Organization Sync.js
└── DingTalk Organization Sync.js
js
/**
 * Feishu Organization Sync Script
 * Function: Sync organization structure and members from Feishu to the Informat platform
 */

// Get Feishu access token
const feishuToken = informat.app.feishuAccessToken();

// Get Feishu department list
function getFeishuDepartments() {
    const url = `https://open.feishu.cn/open-apis/contact/v3/departments?department_id_type=department_id&fetch_child=true&page_size=100`;
    const request = {
        url: url,
        method: 'GET',
        headers: {
            'Authorization': `Bearer ${feishuToken}`,
            'Content-Type': 'application/json'
        },
        timeout: 10000
    };
    
    const response = informat.http.request(request);
    if (response.statusCode() === 200) {
        const data = JSON.parse(response.body());
        if (data.code === 0) {
            return data.data.items || [];
        } else {
            informat.app.abort(`Failed to get Feishu departments: ${data.msg}`);
        }
    } else {
        informat.app.abort(`HTTP request failed: ${response.statusCode()}`);
    }
}

// Get Feishu department members
function getFeishuDepartmentUsers(departmentId) {
    const url = `https://open.feishu.cn/open-apis/contact/v3/users/find_by_department?department_id_type=department_id&department_id=${departmentId}&page_size=100`;
    const request = {
        url: url,
        method: 'GET',
        headers: {
            'Authorization': `Bearer ${feishuToken}`,
            'Content-Type': 'application/json'
        },
        timeout: 10000
    };
    
    const response = informat.http.request(request);
    if (response.statusCode() === 200) {
        const data = JSON.parse(response.body());
        if (data.code === 0) {
            return data.data.items || [];
        } else {
            console.log(`Failed to get members for department ${departmentId}: ${data.msg}`);
            return [];
        }
    } else {
        console.log(`HTTP request failed: ${response.statusCode()}`);
        return [];
    }
}

// Sync department to Informat
function syncDepartmentToInformat(feishuDept) {
    try {
        // Check if the department already exists
        const existingDepts = informat.dept.queryDeptList({
            filter: {
                conditionList: [
                    { fieldId: 'oid', opt: 'eq', value: feishuDept.department_id }
                ]
            }
        });
        
        let parentId = null;
        if (feishuDept.parent_department_id && feishuDept.parent_department_id !== '0') {
            // Find parent department
            const parentDepts = informat.dept.queryDeptList({
                filter: {
                    conditionList: [
                        { fieldId: 'oid', opt: 'eq', value: feishuDept.parent_department_id }
                    ]
                }
            });
            if (parentDepts.length > 0) {
                parentId = parentDepts[0].id;
            }
        }
        
        const deptData = {
            name: feishuDept.name,
            shortName: feishuDept.name,
            oid: feishuDept.department_id,
            parentId: parentId,
            remark: `Feishu Sync - ID: ${feishuDept.department_id}`
        };
        
        if (existingDepts.length > 0) {
            // Update department
            deptData.id = existingDepts[0].id;
            informat.dept.updateDept(deptData);
            console.log(`Updated department: ${feishuDept.name}`);
            return existingDepts[0].id;
        } else {
            // Create new department
            const deptId = informat.dept.addDept(deptData);
            console.log(`Created department: ${feishuDept.name}`);
            return deptId;
        }
    } catch (error) {
        console.log(`Failed to sync department ${feishuDept.name}: ${error.message}`);
        return null;
    }
}

// Sync user to Informat
function syncUserToInformat(feishuUser, deptId) {
    try {
        // Check if the user already exists
        const existingAccounts = informat.system.queryAccountList({
            filter: {
                conditionList: [
                    { fieldId: 'oid', opt: 'eq', value: feishuUser.user_id }
                ]
            }
        });
        
        let accountId;
        if (existingAccounts.length > 0) {
            // Update account
            const account = existingAccounts[0];
            account.name = feishuUser.name;
            account.mobileNo = feishuUser.mobile || '';
            account.email = feishuUser.email || '';
            account.avatar = feishuUser.avatar || '';
            informat.system.updateAccount(account);
            accountId = account.id;
            console.log(`Updated user: ${feishuUser.name}`);
        } else {
            // Create new account
            const accountData = {
                name: feishuUser.name,
                userName: feishuUser.user_id,
                mobileNo: feishuUser.mobile || '',
                email: feishuUser.email || '',
                avatar: feishuUser.avatar || '',
                oid: feishuUser.user_id,
                needUpdatePassword: true
            };
            accountId = informat.system.addAccount(accountData);
            console.log(`Created user: ${feishuUser.name}`);
        }
        
        // Add to team members
        if (accountId && deptId) {
            try {
                informat.company.addCompanyMember(accountId, [deptId], []);
                console.log(`User ${feishuUser.name} added to department`);
            } catch (error) {
                console.log(`Failed to add user to department: ${error.message}`);
            }
        }
        
        return accountId;
    } catch (error) {
        console.log(`Failed to sync user ${feishuUser.name}: ${error.message}`);
        return null;
    }
}

// Main sync function
function syncFeishuOrganization() {
    console.log('Starting Feishu organization sync...');
    
    try {
        // Get Feishu department list
        const feishuDepartments = getFeishuDepartments();
        console.log(`Retrieved ${feishuDepartments.length} departments`);
        
        // Sync departments
        const deptMap = {};
        for (const dept of feishuDepartments) {
            const deptId = syncDepartmentToInformat(dept);
            if (deptId) {
                deptMap[dept.department_id] = deptId;
            }
        }
        
        // Sync users
        let totalUsers = 0;
        for (const dept of feishuDepartments) {
            const users = getFeishuDepartmentUsers(dept.department_id);
            console.log(`Department ${dept.name} has ${users.length} members`);
            
            for (const user of users) {
                const deptId = deptMap[dept.department_id];
                if (deptId) {
                    syncUserToInformat(user, deptId);
                    totalUsers++;
                }
            }
        }
        
        console.log(`Sync complete! Processed ${totalUsers} users in total`);
        
        // Add operation log
        informat.system.addOptLog({
            module: 'Organization Sync',
            operation: 'Feishu Sync',
            content: `Successfully synced ${feishuDepartments.length} departments and ${totalUsers} users`,
            result: 'Success'
        });
        
    } catch (error) {
        console.log(`Sync failed: ${error.message}`);
        
        // Add error log
        informat.system.addOptLog({
            module: 'Organization Sync',
            operation: 'Feishu Sync',
            content: `Sync failed: ${error.message}`,
            result: 'Failed'
        });
        
        throw error;
    }
}

// Export function for other scripts to call
export { syncFeishuOrganization };

4. Fix Bugs in Existing Scripts

  • Scenario: There are potential bugs in the script, use AI to fix them

Requirement: Find the bugs in the script and fix them

ai-fix-bug.pngai-fix-bug.png

5. Run Script Methods

WARNING

You need to enable [Support Script Execution]. Do not enable this option in production environments to avoid risks from executing insufficiently tested scripts.

  • Scenario: Read the createStaffSalaryRecords method in createStaffSalaryRecords.js and execute it
  • Script content
js
/**
 * Query the employee table and create salary records for each employee from January to August 2025
 */
export function createStaffSalaryRecords() {
    try {
        // Query all employees
        const staffList = informat.table.queryList('staff', {
            pageIndex: 1,
            pageSize: -1, // -1 means query all data
            includeFields: ['id', 'name', 'salary']
        });
        
        console.log(`Found ${staffList.length} employees`);
        
        let totalCreated = 0;
        
        // Create salary records for January to August 2025 for each employee
        for (const staff of staffList) {
            const staffId = staff.id;
            const staffName = staff.name;
            const monthlySalary = staff.salary || 0; // Get employee salary, default to 0 if not set
            
            console.log(`Creating salary records for employee ${staffName}...`);
            
            // Create salary records for months 1-8 (fix: month <= 8 instead of month <= 100)
            for (let month = 1; month <= 8; month++) {
                const salaryRecord = {
                    staff: staffId, // Associate with employee
                    year: 2025,    // Year
                    month: month,  // Month
                    salary: monthlySalary // Salary amount
                };
                
                // Insert salary record
                const recordId = informat.table.insert('staffSalaryPaymentRecord', salaryRecord);
                
                if (recordId) {
                    totalCreated++;
                    console.log(`✓ Created salary record for ${staffName} in month ${month} successfully`);
                } else {
                    console.log(`✗ Failed to create salary record for ${staffName} in month ${month}`);
                }
            }
        }
        
        console.log(`Salary record creation complete! Created ${totalCreated} salary records in total`);
        return {
            success: true,
            message: `Successfully created ${totalCreated} salary records for ${staffList.length} employees`,
            staffCount: staffList.length,
            recordCount: totalCreated
        };
        
    } catch (error) {
        console.error('Error creating salary records:', error);
        return {
            success: false,
            message: `Failed to create salary records: ${error.message}`,
            error: error.message
        };
    }
}

Execution result: ai-run-script.png