[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F8MRD3JJZP9THQ88JG5AFT":3,"skill-same:01M6F8MRD3JJZP9THQ88JG5AFT":80},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":57,"commitSha":58,"skillDirectory":59,"forksCount":60,"repositoryHtmlUrl":61,"repositoryHomepageUrl":62,"ownerHtmlUrl":63,"ownerBlogUrl":6,"ownerDescription":64,"updatedAt":65,"install":66,"resources":79},"01M6F8MRD3JJZP9THQ88JG5AFT","clickhouse-webhooks-events",null,"Ingest data into ClickHouse from webhooks, Kafka, and streaming sources\nwith batching, dedup, and exactly-once patterns.\nUse when building data ingestion pipelines, consuming webhook payloads,\nor integrating Kafka topics into ClickHouse.\nTrigger: \"clickhouse ingestion\", \"clickhouse webhook\", \"clickhouse Kafka\",\n\"stream data to clickhouse\", \"clickhouse data pipeline\".","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",66,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fclickhouse-webhooks-events\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"clickhouse webhooks events","events","clickhouse","webhooks","read","sources","io","webhook","ingestion","edit","write","code","Bash","pipeline","data","data ingestion","streaming","olap","database","data pipeline","2026-11-10 10:12:30",false,"---\nname: clickhouse-webhooks-events\ndescription: |\n  Ingest data into ClickHouse from webhooks, Kafka, and streaming sources\n  with batching, dedup, and exactly-once patterns.\n  Use when building data ingestion pipelines, consuming webhook payloads,\n  or integrating Kafka topics into ClickHouse.\n  Trigger: \"clickhouse ingestion\", \"clickhouse webhook\", \"clickhouse Kafka\",\n  \"stream data to clickhouse\", \"clickhouse data pipeline\".\nallowed-tools: Read, Write, Edit, Bash(curl:*)\nversion: 1.0.0\nlicense: MIT\nauthor: Jeremy Longshore \u003Cjeremy@intentsolutions.io>\ntags: [saas, database, analytics, clickhouse, olap]\ncompatible-with: claude-code\n---\n\n# ClickHouse Data Ingestion\n\n## Overview\n\nBuild data ingestion pipelines into ClickHouse from HTTP webhooks, Kafka,\nand streaming sources with proper batching, deduplication, and error handling.\n\n## Prerequisites\n\n- ClickHouse table with appropriate engine (see `clickhouse-core-workflow-a`)\n- `@clickhouse\u002Fclient` connected\n\n## Instructions\n\n### Step 1: Webhook Receiver with Batched Inserts\n\n```typescript\nimport express from 'express';\nimport { createClient } from '@clickhouse\u002Fclient';\n\nconst client = createClient({ url: process.env.CLICKHOUSE_HOST! });\nconst app = express();\napp.use(express.json());\n\n\u002F\u002F Buffer for batching — ClickHouse hates one-row-at-a-time inserts\nconst buffer: Record\u003Cstring, unknown>[] = [];\nconst BATCH_SIZE = 5_000;\nconst FLUSH_INTERVAL_MS = 5_000;\n\nasync function flushBuffer() {\n  if (buffer.length === 0) return;\n  const batch = buffer.splice(0, buffer.length);\n\n  try {\n    await client.insert({\n      table: 'analytics.events',\n      values: batch,\n      format: 'JSONEachRow',\n    });\n    console.log(`Flushed ${batch.length} events to ClickHouse`);\n  } catch (err) {\n    console.error('Insert failed, re-queuing:', (err as Error).message);\n    buffer.unshift(...batch);  \u002F\u002F Put back at front for retry\n  }\n}\n\n\u002F\u002F Flush periodically\nsetInterval(flushBuffer, FLUSH_INTERVAL_MS);\n\n\u002F\u002F Webhook endpoint\napp.post('\u002Fingest', async (req, res) => {\n  const events = Array.isArray(req.body) ? req.body : [req.body];\n\n  for (const event of events) {\n    buffer.push({\n      event_type: event.type ?? 'unknown',\n      user_id: event.userId ?? 0,\n      properties: JSON.stringify(event.properties ?? {}),\n      created_at: new Date().toISOString().replace('T', ' ').slice(0, 19),\n    });\n  }\n\n  if (buffer.length >= BATCH_SIZE) {\n    await flushBuffer();\n  }\n\n  res.status(202).json({ queued: events.length, buffer_size: buffer.length });\n});\n```\n\n### Step 2: Kafka Table Engine (Server-Side Ingestion)\n\n```sql\n-- Create a Kafka engine table (consumes messages automatically)\nCREATE TABLE analytics.events_kafka (\n    event_type  String,\n    user_id     UInt64,\n    properties  String,\n    timestamp   DateTime\n)\nENGINE = Kafka()\nSETTINGS\n    kafka_broker_list = 'kafka:9092',\n    kafka_topic_list = 'events',\n    kafka_group_name = 'clickhouse_consumer',\n    kafka_format = 'JSONEachRow',\n    kafka_num_consumers = 2,\n    kafka_max_block_size = 65536;\n\n-- Materialized view pipes Kafka → MergeTree automatically\nCREATE MATERIALIZED VIEW analytics.events_kafka_mv\nTO analytics.events\nAS SELECT\n    event_type,\n    user_id,\n    properties,\n    timestamp AS created_at\nFROM analytics.events_kafka;\n\n-- ClickHouse now consumes from Kafka continuously!\n-- Check lag:\nSELECT * FROM system.kafka_consumers;\n```\n\n### Step 3: ClickPipes (ClickHouse Cloud Managed Ingestion)\n\nClickHouse Cloud offers **ClickPipes** — a managed ingestion service that\nconnects to Kafka, Confluent, Amazon MSK, S3, and GCS without code.\n\n```\nClickPipes Configuration (Cloud Console):\n1. Source: Amazon MSK \u002F Confluent Cloud \u002F Apache Kafka\n2. Topic: events\n3. Format: JSONEachRow\n4. Target: analytics.events\n5. Scaling: 2 consumers (auto-scales)\n```\n\n### Step 4: HTTP Interface Bulk Insert\n\n```bash\n# Insert from CSV file via HTTP (no client needed)\ncurl 'http:\u002F\u002Flocalhost:8123\u002F?query=INSERT+INTO+analytics.events+FORMAT+CSVWithNames' \\\n  --data-binary @events.csv\n\n# Insert from NDJSON file\ncurl 'http:\u002F\u002Flocalhost:8123\u002F?query=INSERT+INTO+analytics.events+FORMAT+JSONEachRow' \\\n  --data-binary @events.ndjson\n\n# Insert from Parquet file\ncurl 'http:\u002F\u002Flocalhost:8123\u002F?query=INSERT+INTO+analytics.events+FORMAT+Parquet' \\\n  --data-binary @events.parquet\n\n# Insert from remote URL (ClickHouse fetches it)\nINSERT INTO analytics.events\nSELECT * FROM url('https:\u002F\u002Fdata.example.com\u002Fevents.csv', CSVWithNames);\n\n# Insert from S3\nINSERT INTO analytics.events\nSELECT * FROM s3(\n    'https:\u002F\u002Fmy-bucket.s3.amazonaws.com\u002Fevents\u002F*.parquet',\n    'ACCESS_KEY', 'SECRET_KEY',\n    'Parquet'\n);\n```\n\n### Step 5: Deduplication with ReplacingMergeTree\n\n```sql\n-- For idempotent ingestion (webhook retries, Kafka reprocessing)\nCREATE TABLE analytics.events_dedup (\n    event_id    String,           -- Unique event identifier\n    event_type  LowCardinality(String),\n    user_id     UInt64,\n    properties  String,\n    created_at  DateTime,\n    _version    UInt64 DEFAULT toUnixTimestamp(now())\n)\nENGINE = ReplacingMergeTree(_version)\nORDER BY event_id;               -- Dedup key\n\n-- Insert duplicate-safe: same event_id keeps latest _version\n-- Query with FINAL for deduplicated results\nSELECT * FROM analytics.events_dedup FINAL\nWHERE created_at >= today() - 7;\n```\n\n### Step 6: Insert Monitoring\n\n```sql\n-- Track insert throughput\nSELECT\n    toStartOfMinute(event_time) AS minute,\n    count() AS inserts,\n    sum(written_rows) AS rows_inserted,\n    formatReadableSize(sum(written_bytes)) AS bytes_inserted\nFROM system.query_log\nWHERE type = 'QueryFinish'\n  AND query_kind = 'Insert'\n  AND event_time >= now() - INTERVAL 1 HOUR\nGROUP BY minute\nORDER BY minute;\n\n-- Check for insert errors\nSELECT event_time, exception, substring(query, 1, 200)\nFROM system.query_log\nWHERE type = 'ExceptionWhileProcessing'\n  AND query_kind = 'Insert'\n  AND event_time >= now() - INTERVAL 1 HOUR\nORDER BY event_time DESC;\n```\n\n## Insert Best Practices\n\n| Practice | Why |\n|----------|-----|\n| Batch 10K-100K rows per INSERT | Fewer parts, faster merges |\n| Buffer 1-5 seconds for real-time | Balances latency vs throughput |\n| Use `JSONEachRow` format | Client handles serialization |\n| Compress with `ZSTD` on wire | Reduces network transfer |\n| Use `ReplacingMergeTree` for retries | Handles duplicate delivery |\n| Use `async_insert=1` for small batches | Server-side batching |\n\n## Error Handling\n\n| Error | Cause | Solution |\n|-------|-------|----------|\n| `Too many parts` | Single-row inserts | Batch inserts (10K+ rows) |\n| `Cannot parse input` | Wrong format | Match format to data structure |\n| `TIMEOUT` on large insert | Slow network | Enable compression, split batch |\n| Duplicate events | Webhook retries | Use ReplacingMergeTree + event_id |\n\n## Resources\n\n- [Kafka Integration](https:\u002F\u002Fclickhouse.com\u002Fdocs\u002Fintegrations\u002Fkafka)\n- [ClickPipes](https:\u002F\u002Fclickhouse.com\u002Fcloud\u002Fclickpipes)\n- [HTTP Interface](https:\u002F\u002Fclickhouse.com\u002Fdocs\u002Finterfaces\u002Fhttp)\n- [S3 Table Function](https:\u002F\u002Fclickhouse.com\u002Fdocs\u002Fsql-reference\u002Ftable-functions\u002Fs3)\n\n## Next Steps\n\nFor query and server performance, see `clickhouse-performance-tuning`.\n\n","# ClickHouse Data Ingestion\n\n## Overview\n\nBuild data ingestion pipelines into ClickHouse from HTTP webhooks, Kafka,\nand streaming sources with proper batching, deduplication, and error handling.\n\n## Prerequisites\n\n- ClickHouse table with appropriate engine (see `clickhouse-core-workflow-a`)\n- `@clickhouse\u002Fclient` connected\n\n## Instructions\n\n### Step 1: Webhook Receiver with Batched Inserts\n\n```typescript\nimport express from 'express';\nimport { createClient } from '@clickhouse\u002Fclient';\n\nconst client = createClient({ url: process.env.CLICKHOUSE_HOST! });\nconst app = express();\napp.use(express.json());\n\n\u002F\u002F Buffer for batching — ClickHouse hates one-row-at-a-time inserts\nconst buffer: Record\u003Cstring, unknown>[] = [];\nconst BATCH_SIZE = 5_000;\nconst FLUSH_INTERVAL_MS = 5_000;\n\nasync function flushBuffer() {\n  if (buffer.length === 0) return;\n  const batch = buffer.splice(0, buffer.length);\n\n  try {\n    await client.insert({\n      table: 'analytics.events',\n      values: batch,\n      format: 'JSONEachRow',\n    });\n    console.log(`Flushed ${batch.length} events to ClickHouse`);\n  } catch (err) {\n    console.error('Insert failed, re-queuing:', (err as Error).message);\n    buffer.unshift(...batch);  \u002F\u002F Put back at front for retry\n  }\n}\n\n\u002F\u002F Flush periodically\nsetInterval(flushBuffer, FLUSH_INTERVAL_MS);\n\n\u002F\u002F Webhook endpoint\napp.post('\u002Fingest', async (req, res) => {\n  const events = Array.isArray(req.body) ? req.body : [req.body];\n\n  for (const event of events) {\n    buffer.push({\n      event_type: event.type ?? 'unknown',\n      user_id: event.userId ?? 0,\n      properties: JSON.stringify(event.properties ?? {}),\n      created_at: new Date().toISOString().replace('T', ' ').slice(0, 19),\n    });\n  }\n\n  if (buffer.length >= BATCH_SIZE) {\n    await flushBuffer();\n  }\n\n  res.status(202).json({ queued: events.length, buffer_size: buffer.length });\n});\n```\n\n### Step 2: Kafka Table Engine (Server-Side Ingestion)\n\n```sql\n-- Create a Kafka engine table (consumes messages automatically)\nCREATE TABLE analytics.events_kafka (\n    event_type  String,\n    user_id     UInt64,\n    properties  String,\n    timestamp   DateTime\n)\nENGINE = Kafka()\nSETTINGS\n    kafka_broker_list = 'kafka:9092',\n    kafka_topic_list = 'events',\n    kafka_group_name = 'clickhouse_consumer',\n    kafka_format = 'JSONEachRow',\n    kafka_num_consumers = 2,\n    kafka_max_block_size = 65536;\n\n-- Materialized view pipes Kafka → MergeTree automatically\nCREATE MATERIALIZED VIEW analytics.events_kafka_mv\nTO analytics.events\nAS SELECT\n    event_type,\n    user_id,\n    properties,\n    timestamp AS created_at\nFROM analytics.events_kafka;\n\n-- ClickHouse now consumes from Kafka continuously!\n-- Check lag:\nSELECT * FROM system.kafka_consumers;\n```\n\n### Step 3: ClickPipes (ClickHouse Cloud Managed Ingestion)\n\nClickHouse Cloud offers **ClickPipes** — a managed ingestion service that\nconnects to Kafka, Confluent, Amazon MSK, S3, and GCS without code.\n\n```\nClickPipes Configuration (Cloud Console):\n1. Source: Amazon MSK \u002F Confluent Cloud \u002F Apache Kafka\n2. Topic: events\n3. Format: JSONEachRow\n4. Target: analytics.events\n5. Scaling: 2 consumers (auto-scales)\n```\n\n### Step 4: HTTP Interface Bulk Insert\n\n```bash\n# Insert from CSV file via HTTP (no client needed)\ncurl 'http:\u002F\u002Flocalhost:8123\u002F?query=INSERT+INTO+analytics.events+FORMAT+CSVWithNames' \\\n  --data-binary @events.csv\n\n# Insert from NDJSON file\ncurl 'http:\u002F\u002Flocalhost:8123\u002F?query=INSERT+INTO+analytics.events+FORMAT+JSONEachRow' \\\n  --data-binary @events.ndjson\n\n# Insert from Parquet file\ncurl 'http:\u002F\u002Flocalhost:8123\u002F?query=INSERT+INTO+analytics.events+FORMAT+Parquet' \\\n  --data-binary @events.parquet\n\n# Insert from remote URL (ClickHouse fetches it)\nINSERT INTO analytics.events\nSELECT * FROM url('https:\u002F\u002Fdata.example.com\u002Fevents.csv', CSVWithNames);\n\n# Insert from S3\nINSERT INTO analytics.events\nSELECT * FROM s3(\n    'https:\u002F\u002Fmy-bucket.s3.amazonaws.com\u002Fevents\u002F*.parquet',\n    'ACCESS_KEY', 'SECRET_KEY',\n    'Parquet'\n);\n```\n\n### Step 5: Deduplication with ReplacingMergeTree\n\n```sql\n-- For idempotent ingestion (webhook retries, Kafka reprocessing)\nCREATE TABLE analytics.events_dedup (\n    event_id    String,           -- Unique event identifier\n    event_type  LowCardinality(String),\n    user_id     UInt64,\n    properties  String,\n    created_at  DateTime,\n    _version    UInt64 DEFAULT toUnixTimestamp(now())\n)\nENGINE = ReplacingMergeTree(_version)\nORDER BY event_id;               -- Dedup key\n\n-- Insert duplicate-safe: same event_id keeps latest _version\n-- Query with FINAL for deduplicated results\nSELECT * FROM analytics.events_dedup FINAL\nWHERE created_at >= today() - 7;\n```\n\n### Step 6: Insert Monitoring\n\n```sql\n-- Track insert throughput\nSELECT\n    toStartOfMinute(event_time) AS minute,\n    count() AS inserts,\n    sum(written_rows) AS rows_inserted,\n    formatReadableSize(sum(written_bytes)) AS bytes_inserted\nFROM system.query_log\nWHERE type = 'QueryFinish'\n  AND query_kind = 'Insert'\n  AND event_time >= now() - INTERVAL 1 HOUR\nGROUP BY minute\nORDER BY minute;\n\n-- Check for insert errors\nSELECT event_time, exception, substring(query, 1, 200)\nFROM system.query_log\nWHERE type = 'ExceptionWhileProcessing'\n  AND query_kind = 'Insert'\n  AND event_time >= now() - INTERVAL 1 HOUR\nORDER BY event_time DESC;\n```\n\n## Insert Best Practices\n\n| Practice | Why |\n|----------|-----|\n| Batch 10K-100K rows per INSERT | Fewer parts, faster merges |\n| Buffer 1-5 seconds for real-time | Balances latency vs throughput |\n| Use `JSONEachRow` format | Client handles serialization |\n| Compress with `ZSTD` on wire | Reduces network transfer |\n| Use `ReplacingMergeTree` for retries | Handles duplicate delivery |\n| Use `async_insert=1` for small batches | Server-side batching |\n\n## Error Handling\n\n| Error | Cause | Solution |\n|-------|-------|----------|\n| `Too many parts` | Single-row inserts | Batch inserts (10K+ rows) |\n| `Cannot parse input` | Wrong format | Match format to data structure |\n| `TIMEOUT` on large insert | Slow network | Enable compression, split batch |\n| Duplicate events | Webhook retries | Use ReplacingMergeTree + event_id |\n\n## Resources\n\n- [Kafka Integration](https:\u002F\u002Fclickhouse.com\u002Fdocs\u002Fintegrations\u002Fkafka)\n- [ClickPipes](https:\u002F\u002Fclickhouse.com\u002Fcloud\u002Fclickpipes)\n- [HTTP Interface](https:\u002F\u002Fclickhouse.com\u002Fdocs\u002Finterfaces\u002Fhttp)\n- [S3 Table Function](https:\u002F\u002Fclickhouse.com\u002Fdocs\u002Fsql-reference\u002Ftable-functions\u002Fs3)\n\n## Next Steps\n\nFor query and server performance, see `clickhouse-performance-tuning`.\n\n",{"name":5,"tags":49,"author":52,"license":15,"version":53,"description":54,"allowed-tools":55,"compatible-with":56},[50,42,51,26,41],"saas","analytics","Jeremy Longshore \u003Cjeremy@intentsolutions.io>","1.0.0","Ingest data into ClickHouse from webhooks, Kafka, and streaming sources\nwith batching, dedup, and exactly-once patterns.\nUse when building data ingestion pipelines, consuming webhook payloads,\nor integrating Kafka topics into ClickHouse.\nTrigger: \"clickhouse ingestion\", \"clickhouse webhook\", \"clickhouse Kafka\",\n\"stream data to clickhouse\", \"clickhouse data pipeline\".\n","Read, Write, Edit, Bash(curl:*)","claude-code","main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fclickhouse-webhooks-events",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":67,"prompt":77,"zipAvailable":78},[68,71,74],{"tool":69,"command":70},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill clickhouse-webhooks-events",{"tool":72,"command":73},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill clickhouse-webhooks-events",{"tool":75,"command":76},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill clickhouse-webhooks-events","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fjeremylongshore\u002Fclaude-code-plugins-plus-skills\u002Fclickhouse-webhooks-events\u002FSKILL.md",true,[],[81,95,105,114,120,127],{"skillNo":82,"name":83,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":91,"publishedAt":44},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[86],{"categoryNo":87,"categoryName":88,"taxonomyType":89,"taxonomyTypeDesc":90},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[92,93,94],"model","model hierarchy","model hierarchy skill",{"skillNo":96,"name":97,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":101,"publishedAt":44},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[100],{"categoryNo":87,"categoryName":88,"taxonomyType":89,"taxonomyTypeDesc":90},[102,103,104],"MCP","zoom","zoom mcp",{"skillNo":106,"name":107,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":110,"publishedAt":44},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[111,112,113,103],"sdk","zoom apps sdk","apps",{"skillNo":115,"name":116,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":44},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[116],{"skillNo":121,"name":122,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":126,"publishedAt":44},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[125],{"categoryNo":87,"categoryName":88,"taxonomyType":89,"taxonomyTypeDesc":90},[122],{"skillNo":128,"name":129,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":130,"categories":131,"keywords":132,"publishedAt":44},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[129]]