DEV Community

Cover image for วิธีใช้ Make (Integromat) API
Thanawat Wongchai
Thanawat Wongchai

Posted on • Originally published at apidog.com

วิธีใช้ Make (Integromat) API

สรุปสาระสำคัญ

API ของ Make (เดิมชื่อ Integromat) ช่วยให้นักพัฒนาสามารถทำให้เวิร์กโฟลว์เป็นอัตโนมัติ จัดการสถานการณ์ (scenarios) และดำเนินการรวมระบบด้วยโปรแกรมได้ ใช้การรับรองความถูกต้องด้วย OAuth 2.0 และ API key โดยมีเอนด์พอยต์แบบ RESTful สำหรับ scenarios, executions, webhooks และ teams พร้อมด้วยการจำกัดอัตรา (rate limits) ที่ 60-600 คำขอต่อนาที ขึ้นอยู่กับแผนบริการ คู่มือนี้ครอบคลุมการตั้งค่าการรับรองความถูกต้อง การจัดการ scenarios การทริกเกอร์ webhook การตรวจสอบการดำเนินการ และกลยุทธ์การทำ automation สำหรับการใช้งานจริง

ทดลองใช้ Apidog วันนี้

บทนำ

Make (Integromat) ประมวลผลการทำงานมากกว่า 2 พันล้านรายการต่อเดือนสำหรับผู้ใช้งานกว่า 1 ล้านคนในกว่า 100 ประเทศ สำหรับนักพัฒนาที่สร้างเครื่องมืออัตโนมัติ จัดการเวิร์กโฟลว์ของลูกค้า หรือผสานรวมกับแอปพลิเคชันกว่า 1,000 รายการ การผสานรวม API ของ Make ไม่ใช่ทางเลือก—แต่เป็นสิ่งจำเป็นสำหรับการทำ automation ที่ปรับขนาดได้

นี่คือความเป็นจริง: เอเจนซี่ที่จัดการ automation ของลูกค้ามากกว่า 50 รายการ ต้องเสียเวลา 15-25 ชั่วโมงต่อสัปดาห์ไปกับการอัปเดต scenarios ด้วยตนเอง การตรวจสอบการดำเนินการ และการรายงานลูกค้า การผสานรวม API ของ Make ที่มีประสิทธิภาพจะช่วยให้การปรับใช้ scenarios การติดตามการดำเนินการ การจัดการข้อผิดพลาด และการรายงานแบบ white-label เป็นไปโดยอัตโนมัติ

คู่มือนี้จะนำเสนอขั้นตอนการผสานรวม API ของ Make อย่างครบถ้วน คุณจะได้เรียนรู้การรับรองความถูกต้องด้วย OAuth 2.0 และ API key การจัดการ scenarios การทริกเกอร์ webhook การตรวจสอบการดำเนินการ การจัดการทีม และกลยุทธ์การปรับใช้สำหรับการใช้งานจริง เมื่ออ่านจบ คุณจะมีความรู้พร้อมสำหรับการผสานรวม Make ที่พร้อมใช้งานในระดับโปรดักชัน

💡Apidog ช่วยให้การทดสอบการผสานรวม API ง่ายขึ้น ทดสอบเอนด์พอยต์ของ Make ตรวจสอบความถูกต้องของโฟลว์ OAuth ตรวจสอบการตอบสนองของการดำเนินการ และดีบักปัญหา automation ในพื้นที่ทำงานเดียว นำเข้าข้อมูลจำเพาะ API สร้างการตอบกลับจำลอง และแบ่งปัน scenarios การทดสอบกับทีมของคุณ

Make API คืออะไร?

Make มี RESTful API สำหรับการจัดการเวิร์กโฟลว์ automation ด้วยโปรแกรม API จัดการสิ่งเหล่านี้:

  • การสร้าง อัปเดต และลบ scenarios
  • การดำเนินการ scenarios (การทริกเกอร์ด้วยตนเอง)
  • ประวัติการดำเนินการและการตรวจสอบ
  • การจัดการ Webhook
  • การจัดการทีมและผู้ใช้
  • การจัดการการเชื่อมต่อและแอป
  • การตั้งค่าองค์กรและพื้นที่ทำงาน

คุณสมบัติหลัก

คุณสมบัติ คำอธิบาย
RESTful API เอนด์พอยต์แบบ JSON
OAuth 2.0 + API Keys การรับรองความถูกต้องที่ยืดหยุ่น
Webhooks การแจ้งเตือนการดำเนินการแบบเรียลไทม์
การจำกัดอัตรา (Rate Limiting) 60-600 คำขอ/นาที ตามแผนบริการ
การจัดการ Scenario การดำเนินการ CRUD เต็มรูปแบบ
การควบคุมการดำเนินการ เริ่ม, หยุด, ตรวจสอบการทำงาน
Team API การจัดการผู้ใช้และสิทธิ์

แผนบริการของ Make และการเข้าถึง API

แผนบริการ การเข้าถึง API การจำกัดอัตรา เหมาะสำหรับ
Free (ฟรี) จำกัด 60/นาที การทดสอบ, การเรียนรู้
Core API เต็มรูปแบบ 120/นาที ธุรกิจขนาดเล็ก
Pro API เต็มรูปแบบ + Priority 300/นาที ทีมที่กำลังเติบโต
Teams API เต็มรูปแบบ + ผู้ดูแลระบบ 600/นาที เอเจนซี่, องค์กรขนาดใหญ่
Enterprise ขีดจำกัดที่กำหนดเอง กำหนดเอง องค์กรขนาดใหญ่

ภาพรวมสถาปัตยกรรม API

Make ใช้โครงสร้าง API แบบ RESTful:

https://api.make.com/api/v2/
Enter fullscreen mode Exit fullscreen mode

เวอร์ชัน API

เวอร์ชัน สถานะ กรณีการใช้งาน
v2 ปัจจุบัน การผสานรวมใหม่ทั้งหมด
v1 เลิกใช้งานแล้ว การผสานรวมแบบเดิม (ย้ายข้อมูล)

เริ่มต้นใช้งาน: การตั้งค่าการรับรองความถูกต้อง

ขั้นตอนที่ 1: สร้างบัญชี Make

  1. เยี่ยมชม Make.com
  2. ลงทะเบียนบัญชี
  3. ไปที่ Settings > Developer settings
  4. สร้างข้อมูลรับรอง API

ขั้นตอนที่ 2: เลือกวิธีการรับรองความถูกต้อง

Make รองรับวิธีการรับรองความถูกต้องสองวิธี:

วิธี เหมาะสำหรับ ระดับความปลอดภัย
API Key การผสานรวมภายใน, สคริปต์ สูง (จัดเก็บอย่างปลอดภัย)
OAuth 2.0 แอปพลิเคชันแบบ Multi-tenant, การผสานรวมกับลูกค้า สูงกว่า (โทเค็นที่จำกัดขอบเขตผู้ใช้)

ขั้นตอนที่ 3: รับ API Key (วิธีที่ง่ายที่สุด)

  1. ไปที่ Settings > Developer settings
  2. คลิก Create API key
  3. คัดลอกและจัดเก็บอย่างปลอดภัย
# .env file
MAKE_API_KEY="your_api_key_here"
MAKE_ORGANIZATION_ID="your_org_id"
Enter fullscreen mode Exit fullscreen mode

ขั้นตอนที่ 4: ตั้งค่า OAuth 2.0 (สำหรับแอปพลิเคชันแบบ Multi-Tenant)

  1. ไปที่ Settings > Developer settings > OAuth apps
  2. คลิก Create OAuth app
  3. กำหนดค่า redirect URI
  4. รับข้อมูลรับรองไคลเอ็นต์
const MAKE_CLIENT_ID = process.env.MAKE_CLIENT_ID;
const MAKE_CLIENT_SECRET = process.env.MAKE_CLIENT_SECRET;
const MAKE_REDIRECT_URI = process.env.MAKE_REDIRECT_URI;

// Build authorization URL
const getAuthUrl = (state) => {
  const params = new URLSearchParams({
    client_id: MAKE_CLIENT_ID,
    redirect_uri: MAKE_REDIRECT_URI,
    scope: 'read write execute',
    state: state,
    response_type: 'code'
  });

  return `https://www.make.com/oauth/authorize?${params.toString()}`;
};
Enter fullscreen mode Exit fullscreen mode

ขั้นตอนที่ 5: แลกเปลี่ยนรหัสสำหรับ Access Token

const exchangeCodeForToken = async (code) => {
  const response = await fetch('https://www.make.com/oauth/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      client_id: MAKE_CLIENT_ID,
      client_secret: MAKE_CLIENT_SECRET,
      redirect_uri: MAKE_REDIRECT_URI,
      code: code
    })
  });

  const data = await response.json();

  return {
    accessToken: data.access_token,
    refreshToken: data.refresh_token,
    expiresIn: data.expires_in
  };
};

// Handle callback
app.get('/oauth/callback', async (req, res) => {
  const { code, state } = req.query;

  try {
    const tokens = await exchangeCodeForToken(code);

    // Store tokens securely
    await db.integrations.create({
      userId: req.session.userId,
      accessToken: tokens.accessToken,
      refreshToken: tokens.refreshToken,
      tokenExpiry: Date.now() + (tokens.expiresIn * 1000)
    });

    res.redirect('/success');
  } catch (error) {
    console.error('OAuth error:', error);
    res.status(500).send('Authentication failed');
  }
});
Enter fullscreen mode Exit fullscreen mode

ขั้นตอนที่ 6: เรียกใช้ API ที่ได้รับการรับรองความถูกต้อง

สร้างไคลเอ็นต์ API ที่นำไปใช้ซ้ำได้ เช่น

const MAKE_BASE_URL = 'https://api.make.com/api/v2';

const makeRequest = async (endpoint, options = {}) => {
  const apiKey = options.useOAuth ? await getOAuthToken() : process.env.MAKE_API_KEY;

  const response = await fetch(`${MAKE_BASE_URL}${endpoint}`, {
    ...options,
    headers: {
      'Authorization': `Token ${apiKey}`,
      'Content-Type': 'application/json',
      ...options.headers
    }
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Make API Error: ${error.message}`);
  }

  return response.json();
};

// Usage
const scenarios = await makeRequest('/scenarios');
console.log(`Found ${scenarios.data.length} scenarios`);
Enter fullscreen mode Exit fullscreen mode

การจัดการ Scenario

การแสดงรายการ Scenario

const listScenarios = async (filters = {}) => {
  const params = new URLSearchParams({
    limit: filters.limit || 50,
    offset: filters.offset || 0
  });

  if (filters.folder) {
    params.append('folder', filters.folder);
  }

  const response = await makeRequest(`/scenarios?${params.toString()}`);
  return response;
};

// Usage
const scenarios = await listScenarios({ limit: 100 });
scenarios.data.forEach(scenario => {
  console.log(`${scenario.name} - ${scenario.active ? 'Active' : 'Paused'}`);
  console.log(`  Last run: ${scenario.lastRunDate || 'Never'}`);
});
Enter fullscreen mode Exit fullscreen mode

การดูรายละเอียด Scenario

const getScenario = async (scenarioId) => {
  const response = await makeRequest(`/scenarios/${scenarioId}`);
  return response;
};

// Usage
const scenario = await getScenario('12345');
console.log(`Name: ${scenario.name}`);
console.log(`Modules: ${scenario.modules.length}`);
console.log(`Schedule: ${scenario.schedule?.cronExpression || 'Manual'}`);
Enter fullscreen mode Exit fullscreen mode

การสร้าง Scenario

const createScenario = async (scenarioData) => {
  const scenario = {
    name: scenarioData.name,
    blueprint: scenarioData.blueprint, // Scenario JSON blueprint
    active: scenarioData.active || false,
    priority: scenarioData.priority || 1,
    maxErrors: scenarioData.maxErrors || 3,
    autoCommit: scenarioData.autoCommit || true,
    description: scenarioData.description || ''
  };

  const response = await makeRequest('/scenarios', {
    method: 'POST',
    body: JSON.stringify(scenario)
  });

  return response;
};

// Usage - Create from blueprint
const newScenario = await createScenario({
  name: 'Lead Sync to CRM',
  blueprint: {
    // Scenario blueprint JSON
    // Export from Make editor or build programmatically
    modules: [
      {
        id: 1,
        app: 'webhooks',
        action: 'customWebhook',
        parameters: { /* ... */ }
      },
      {
        id: 2,
        app: 'salesforce',
        action: 'createRecord',
        parameters: { /* ... */ }
      }
    ],
    connections: [
      { from: 1, to: 2 }
    ]
  },
  active: true,
  description: 'Sync webhook leads to Salesforce'
});

console.log(`Scenario created: ${newScenario.id}`);
Enter fullscreen mode Exit fullscreen mode

การอัปเดต Scenario

const updateScenario = async (scenarioId, updates) => {
  const response = await makeRequest(`/scenarios/${scenarioId}`, {
    method: 'PATCH',
    body: JSON.stringify(updates)
  });

  return response;
};

// Usage - Pause scenario
await updateScenario('12345', { active: false });

// Usage - Update schedule
await updateScenario('12345', {
  schedule: {
    cronExpression: '0 */6 * * *', // Every 6 hours
    timezone: 'America/New_York'
  }
});
Enter fullscreen mode Exit fullscreen mode

การลบ Scenario

const deleteScenario = async (scenarioId) => {
  await makeRequest(`/scenarios/${scenarioId}`, {
    method: 'DELETE'
  });

  console.log(`Scenario ${scenarioId} deleted`);
};
Enter fullscreen mode Exit fullscreen mode

การจัดการการดำเนินการ

การทริกเกอร์การดำเนินการ Scenario

const executeScenario = async (scenarioId, inputData = null) => {
  const response = await makeRequest(`/scenarios/${scenarioId}/execute`, {
    method: 'POST',
    body: inputData ? JSON.stringify(inputData) : undefined
  });

  return response;
};

// Usage - Run without input
const execution = await executeScenario('12345');
console.log(`Execution started: ${execution.id}`);

// Usage - Run with input data
const executionWithData = await executeScenario('12345', {
  lead: {
    email: 'prospect@example.com',
    name: 'John Doe',
    company: 'Acme Corp'
  }
});
Enter fullscreen mode Exit fullscreen mode

การดูประวัติการดำเนินการ

const getExecutionHistory = async (scenarioId, filters = {}) => {
  const params = new URLSearchParams({
    limit: filters.limit || 50,
    from: filters.from,
    to: filters.to,
    status: filters.status // 'success', 'error', 'running'
  });

  const response = await makeRequest(`/scenarios/${scenarioId}/executions?${params.toString()}`);
  return response;
};

// Usage - Get failed executions from last 24 hours
const failedExecutions = await getExecutionHistory('12345', {
  from: new Date(Date.now() - 86400000).toISOString(),
  status: 'error',
  limit: 100
});

failedExecutions.data.forEach(exec => {
  console.log(`Execution ${exec.id}: ${exec.error?.message}`);
});
Enter fullscreen mode Exit fullscreen mode

การดูรายละเอียดการดำเนินการ

const getExecution = async (executionId) => {
  const response = await makeRequest(`/executions/${executionId}`);
  return response;
};

// Usage
const execution = await getExecution('98765');
console.log(`Status: ${execution.status}`);
console.log(`Duration: ${execution.duration}ms`);
console.log(`Modules executed: ${execution.modulesExecuted}`);
Enter fullscreen mode Exit fullscreen mode

การหยุดการดำเนินการที่กำลังทำงานอยู่

const stopExecution = async (executionId) => {
  await makeRequest(`/executions/${executionId}`, {
    method: 'DELETE'
  });

  console.log(`Execution ${executionId} stopped`);
};
Enter fullscreen mode Exit fullscreen mode

การจัดการ Webhook

การสร้าง Webhook

const createWebhook = async (webhookData) => {
  const webhook = {
    name: webhookData.name,
    scenarioId: webhookData.scenarioId,
    type: 'custom', // 'custom' or 'raw'
    hookType: 'HEAD', // 'HEAD' or 'GET'
    security: {
      type: 'none' // 'none', 'basic', 'token'
    }
  };

  const response = await makeRequest('/webhooks', {
    method: 'POST',
    body: JSON.stringify(webhook)
  });

  return response;
};

// Usage
const webhook = await createWebhook({
  name: 'Lead Capture Webhook',
  scenarioId: '12345',
  type: 'custom',
  hookType: 'HEAD',
  security: { type: 'none' }
});

console.log(`Webhook URL: ${hook.url}`);
Enter fullscreen mode Exit fullscreen mode

การแสดงรายการ Webhook

const listWebhooks = async () => {
  const response = await makeRequest('/webhooks');
  return response;
};

// Usage
const webhooks = await listWebhooks();
webhooks.data.forEach(webhook => {
  console.log(`${webhook.name}: ${webhook.url}`);
});
Enter fullscreen mode Exit fullscreen mode

การลบ Webhook

const deleteWebhook = async (webhookId) => {
  await makeRequest(`/webhooks/${webhookId}`, {
    method: 'DELETE'
  });

  console.log(`Webhook ${webhookId} deleted`);
};
Enter fullscreen mode Exit fullscreen mode

การจัดการทีมและผู้ใช้

การแสดงรายการสมาชิกทีม

const listTeamMembers = async (organizationId) => {
  const response = await makeRequest(`/organizations/${organizationId}/users`);
  return response;
};

// Usage
const members = await listTeamMembers('org-123');
members.data.forEach(member => {
  console.log(`${member.email} - ${member.role}`);
});
Enter fullscreen mode Exit fullscreen mode

การเพิ่มสมาชิกทีม

const addTeamMember = async (organizationId, email, role) => {
  const response = await makeRequest(`/organizations/${organizationId}/users`, {
    method: 'POST',
    body: JSON.stringify({
      email: email,
      role: role // 'viewer', 'builder', 'manager', 'admin'
    })
  });

  return response;
};

// Usage
await addTeamMember('org-123', 'newuser@example.com', 'builder');
Enter fullscreen mode Exit fullscreen mode

การอัปเดตบทบาทผู้ใช้

const updateUserRole = async (organizationId, userId, newRole) => {
  await makeRequest(`/organizations/${organizationId}/users/${userId}`, {
    method: 'PATCH',
    body: JSON.stringify({ role: newRole })
  });

  console.log(`User ${userId} role updated to ${newRole}`);
};
Enter fullscreen mode Exit fullscreen mode

บทบาทผู้ใช้

บทบาท สิทธิ์
Viewer (ผู้ดู) ดู scenarios, ไม่สามารถแก้ไขได้
Builder (ผู้สร้าง) สร้าง/แก้ไข scenarios
Manager (ผู้จัดการ) จัดการทีม, การเรียกเก็บเงิน
Admin (ผู้ดูแลระบบ) การเข้าถึงองค์กรเต็มรูปแบบ

การจำกัดอัตรา (Rate Limiting)

ทำความเข้าใจการจำกัดอัตรา

Make บังคับใช้การจำกัดอัตราตามแผนบริการ:

แผนบริการ คำขอ/นาที ขีดจำกัดสูงสุดชั่วคราว
Free (ฟรี) 60 100
Core 120 200
Pro 300 500
Teams 600 1000
Enterprise กำหนดเอง กำหนดเอง

เฮดเดอร์การจำกัดอัตรา

เฮดเดอร์ คำอธิบาย
X-RateLimit-Limit จำนวนคำขอสูงสุดต่อนาที
X-RateLimit-Remaining จำนวนคำขอที่เหลืออยู่
X-RateLimit-Reset จำนวนวินาทีจนกว่าจะรีเซ็ต

การนำการจัดการการจำกัดอัตราไปใช้

const makeRateLimitedRequest = async (endpoint, options = {}, maxRetries = 3) => {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await makeRequest(endpoint, options);

      const remaining = response.headers.get('X-RateLimit-Remaining');
      if (remaining < 10) {
        console.warn(`Low rate limit: ${remaining} remaining`);
      }

      return response;
    } catch (error) {
      if (error.message.includes('429') && attempt < maxRetries) {
        const delay = Math.pow(2, attempt) * 1000;
        console.log(`Rate limited. Retrying in ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error;
      }
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

รายการตรวจสอบสำหรับการปรับใช้จริง

ก่อนใช้งานจริง:

  • [ ] ใช้ API key สำหรับการผสานรวมภายใน, OAuth สำหรับการผสานรวมกับลูกค้า
  • [ ] จัดเก็บข้อมูลรับรองอย่างปลอดภัย (ฐานข้อมูลที่เข้ารหัส)
  • [ ] ใช้การจำกัดอัตราและการจัดคิวคำขอ
  • [ ] ตั้งค่าการตรวจสอบการดำเนินการและการแจ้งเตือน
  • [ ] กำหนดค่าการแจ้งเตือนข้อผิดพลาด (อีเมล, Slack)
  • [ ] ใช้ตรรกะการลองใหม่ (retry logic) สำหรับการดำเนินการที่ล้มเหลว
  • [ ] เพิ่มการบันทึกข้อมูลที่ครอบคลุม
  • [ ] สร้างการสำรอง/ส่งออก scenarios ที่สำคัญ

กรณีการใช้งานจริง

การจัดการลูกค้าของเอเจนซี่

ความท้าทาย: การอัปเดต scenarios ด้วยตนเองในบัญชีลูกค้าหลายราย

วิธีแก้ปัญหา: แดชบอร์ดกลางที่ใช้ Make API

ผลลัพธ์: ประหยัดเวลา 70%, การปรับใช้ที่สอดคล้องกัน

การนำไปใช้งานที่สำคัญ:

  • การผสานรวม OAuth หลายบัญชี
  • การปรับใช้ scenarios เป็นจำนวนมาก
  • การรายงานการใช้งานของลูกค้า

การประมวลผลคำสั่งซื้ออีคอมเมิร์ซ

ความท้าทาย: การป้อนคำสั่งซื้อด้วยตนเองเข้าสู่ระบบคลังสินค้า

วิธีแก้ปัญหา: Scenario ของ Make ที่ทริกเกอร์ด้วย Webhook

ผลลัพธ์: ไม่ต้องป้อนข้อมูลด้วยตนเองเลย, ความแม่นยำ 99.9%

การนำไปใช้งานที่สำคัญ:

  • Webhook ของ Shopify ไปยัง Make
  • Scenario ประมวลผลคำสั่งซื้อ, อัปเดตคลังสินค้า
  • การจัดการข้อผิดพลาดพร้อมตรรกะการลองใหม่

บทสรุป

Make API มอบความสามารถในการทำ automation เวิร์กโฟลว์ที่ครอบคลุม ประเด็นสำคัญที่ควรจดจำ:

  • API key สำหรับการใช้งานภายใน, OAuth 2.0 สำหรับแอปพลิเคชันแบบ multi-tenant
  • การดำเนินการ CRUD เต็มรูปแบบสำหรับ scenarios, executions, webhooks
  • การจัดการทีมสำหรับการควบคุมองค์กร
  • การจำกัดอัตราแตกต่างกันไปตามแผนบริการ (60-600 คำขอต่อนาที)
  • การตรวจสอบการดำเนินการเป็นสิ่งจำเป็นสำหรับการใช้งานจริง
  • Apidog ช่วยลดความซับซ้อนในการทดสอบ API และการทำงานร่วมกันของทีม

ฉันจะรับรองความถูกต้องกับ Make API ได้อย่างไร?

ใช้ API key จาก Developer settings (การตั้งค่านักพัฒนา) สำหรับการผสานรวมภายใน หรือ OAuth 2.0 สำหรับแอปพลิเคชันแบบ multi-tenant

ฉันสามารถทริกเกอร์ scenarios ด้วยโปรแกรมได้หรือไม่?

ได้ คุณสามารถใช้เอนด์พอยต์ /scenarios/{id}/execute เพื่อทริกเกอร์การทำงานของ scenario ด้วยตนเองพร้อมข้อมูลอินพุตเพิ่มเติมได้

การจำกัดอัตราของ Make คืออะไร?

การจำกัดอัตรามีตั้งแต่ 60 คำขอ/นาที (แผน Free) ถึง 600 คำขอ/นาที (แผน Teams/Enterprise)

ฉันจะดูบันทึกการดำเนินการได้อย่างไร?

ใช้ /scenarios/{id}/executions เพื่อดึงข้อมูลประวัติการดำเนินการพร้อมตัวกรองตามวันที่และสถานะ

ฉันสามารถสร้าง webhooks ผ่าน API ได้หรือไม่?

ได้ คุณสามารถใช้เอนด์พอยต์ /webhooks เพื่อสร้าง แสดงรายการ และลบ webhooks สำหรับ scenarios ได้

Top comments (0)