คู่มือการดีพลอย RIDM Apps
RIDM Apps คือโฮสติ้งที่บิลด์·ดีพลอยเมื่อเชื่อมต่อ GitHub repository แล้วเผยแพร่ที่ <name>.ridm.ai สมัครได้ที่แอปของฉันในคอนโซล ราคาดูได้ที่หน้าราคา เงื่อนไขการใช้งานกำหนดโดยข้อกำหนดการใช้งาน หมวด 3 (ภาษาเกาหลี) หากอยากเห็นภาพรวมว่ามีอะไรบ้าง ดูได้ที่แนะนำโฮสติ้งแอป
ขั้นตอนการดีพลอย
- สมัคร — เลือกแพลนและที่อยู่ (ซับโดเมน) ในแอปของฉัน ที่อยู่เปลี่ยนภายหลังไม่ได้
- เชื่อมต่อ GitHub — ติดตั้ง GitHub App
ridm-apps-builderจากหน้าจอแอป แล้วเลือก repository และ branch สิทธิ์มีเพียงการอ่าน repository - Push — ทุกครั้งที่ push ไปยัง branch ที่เชื่อมต่อ การบิลด์จะเริ่มขึ้น ประวัติการบิลด์และล็อกที่ล้มเหลวจะแสดงในหน้าจอแอป
- ดีพลอยครั้งแรก — เมื่อบิลด์สำเร็จจะผ่านการตรวจสอบอัตโนมัติแล้วเผยแพร่ทันที (ด้านล่าง) การ push หลังจากนั้นก็จะสะท้อนโดยอัตโนมัติ
ข้อกำหนดของ Dockerfile
- ต้องมี
Dockerfileที่รากของ repository หากไม่มีการบิลด์จะล้มเหลว - แอปต้องตอบสนองด้วย HTTP ที่ พอร์ต 3000 ระบบจะบังคับตั้ง
PORT=3000,HOSTNAME=0.0.0.0หลังคอนเทนเนอร์เริ่มทำงาน ต้องตอบคำขอ/ภายใน 30 วินาที (รหัสสถานะใดก็ได้) หากไม่ตอบภายในเวลานั้นจะถือว่าเริ่มทำงานล้มเหลว และหากเป็นเวอร์ชันใหม่ เวอร์ชันก่อนหน้าจะยังให้บริการต่อไป - หากกำหนดพาธตรวจสอบสถานะ (“พาธตรวจสอบสถานะ” ในหน้าจอแอป เช่น
/api/health) พาธนั้นต้องตอบด้วย 2xx·3xx·404 แทน/จึงจะนับว่าเริ่มทำงานสำเร็จ (หากเป็น 5xx หรือ 4xx อื่นๆ ถือว่าล้มเหลว) หากใช้พาธที่ตรวจไปถึง DB เวอร์ชันที่เปิดแค่พอร์ตแต่ทำงานไม่ถูกต้องจะไม่ถูกนำขึ้น หากเว้นว่างไว้จะใช้กฎข้างต้นตามเดิม - หลังเวอร์ชันใหม่เผยแพร่แล้ว หากรีสตาร์ตตั้งแต่ 3 ครั้งขึ้นไปภายใน 5 นาที (โปรเซสล่มซ้ำ) ระบบจะย้อนกลับไปยังเวอร์ชันก่อนหน้าที่ทำงานปกติโดยอัตโนมัติหนึ่งครั้ง และแจ้งทางอีเมล (รวมล็อกสุดท้ายที่แอปทิ้งไว้) หากเวอร์ชันที่ย้อนกลับก็ยังล่มอยู่ จะไม่ย้อนกลับต่อแต่คงไว้ตามนั้น โปรดแก้โค้ดแล้ว push ใหม่
- คอนเทนเนอร์ทำงานด้วยผู้ใช้ 1000:1000 ไฟล์ของแอปต้องให้ผู้ใช้นี้อ่านได้ (ผู้ใช้
nodeของอิมเมจnode:*-alpineคือ 1000) - ระบบไฟล์เป็นแบบอ่านอย่างเดียว ที่เขียนได้มีเพียง
/tmpและ/app/.next/cache(ทั้งคู่ใช้หน่วยความจำ หายไปเมื่อรีสตาร์ต) ข้อมูลถาวรให้บันทึกใน DB - บิลด์เป็น x86_64 (amd64) ขีดจำกัดเวลาบิลด์คือ 20 นาที
- หากพบค่าลับใน repository การบิลด์จะหยุด: คีย์การเข้าถึง AWS, โทเค็น GitHub, คีย์ live ของ Stripe, บล็อกคีย์ส่วนตัว, URL PostgreSQL ที่มีรหัสผ่าน ค่าลับให้ใส่เป็นตัวแปรสภาพแวดล้อม
สตาร์ตเตอร์ Next.js
ใส่ output: 'standalone' ใน next.config.js แล้ววาง Dockerfile ด้านล่างไว้ที่รากของ repository หากไม่มีโฟลเดอร์ public ให้ลบบรรทัดนั้นออก
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
FROM node:22-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY --from=build --chown=1000:1000 /app/public ./public
COPY --from=build --chown=1000:1000 /app/.next/standalone ./
COPY --from=build --chown=1000:1000 /app/.next/static ./.next/static
USER 1000
EXPOSE 3000
CMD ["node", "server.js"]
ไม่จำเป็นต้องเป็น Next.js คอนเทนเนอร์ใดที่ตอบสนองที่พอร์ต 3000 ก็ทำงานได้ทุกสแตก
สภาพแวดล้อมการทำงาน
- แพลนฟรี เปิดเมื่อมีผู้เยี่ยมชม และหยุดเมื่อไม่มีคำขอ 15 นาที การเยี่ยมชมครั้งแรกหลังหยุดอาจช้าไม่กี่วินาที บอตค้นหา·คำขอมอนิเตอร์·คำขอ HEAD จะไม่ปลุกแอป
- แพลนแบบชำระเงิน ทำงานตลอดเวลา และรีสตาร์ตอัตโนมัติเมื่อแอปล่ม
- หากใช้หน่วยความจำเกิน แอปจะถูกบังคับปิด ขีดจำกัดฮีปของ Node.js ตั้งไว้ที่ 75% ของหน่วยความจำแพลน
- WebSocket ใช้ได้ในแพลนแบบชำระเงิน (แพลนฟรีคำขออัปเกรดจะได้
403) แอปเพียงรับUpgrade: websocketที่พอร์ต 3000 ตามปกติ (พาธ·ซับโปรโตคอล·Origin·X-Forwarded-For·CF-Connecting-IPถูกส่งต่อตามเดิม และการตอบกลับอย่าง 403·429 ที่แอปส่งแทนการอัปเกรดก็ส่งถึงผู้เยี่ยมชมตามเดิม) ขีดจำกัด:- การเชื่อมต่อพร้อมกัน 120 การเชื่อมต่อต่อแอป หากเกิน การเชื่อมต่อใหม่จะถูกปฏิเสธด้วย
503(Retry-After: 10) - ข้อความหนึ่งข้อความ (รวมทุกส่วนย่อย) 64KB หากเกิน การเชื่อมต่อนั้นจะถูกปิดด้วย
1009ไม่ใช้ส่วนขยายการบีบอัด (permessage-deflate) - จำนวนข้อความได้ถึง 2,000 ข้อความต่อวินาทีต่อทิศทางต่อแอป และการเชื่อมต่อของผู้เยี่ยมชมหนึ่งการเชื่อมต่อส่งได้ 60 ข้อความต่อวินาที หากเกินจะไม่ทิ้งแต่ส่งช้าลง
- หากไม่มีเฟรมเป็นเวลา 100 วินาที ส่วนกลาง (Cloudflare) จะตัดการเชื่อมต่อ ให้แอปหรือไคลเอนต์ส่ง ping บ่อยกว่านั้น
- อนุญาตเฉพาะ Origin ของแอปเดียวกัน: การเชื่อมต่อจากเบราว์เซอร์จะเปิดได้เฉพาะเมื่อ
Originเป็นที่อยู่ของแอปนั้น (ชื่อแอป.ridm.aiหรือโดเมนที่เชื่อมต่อกับแอปนั้น) การเชื่อมต่อจากแอปอื่นหรือเว็บไซต์อื่นจะได้403แม้เป็นแอปของพาร์ทเนอร์เดียวกัน แอปต่างกันเชื่อมต่อกันโดยตรงด้วย WebSocket ไม่ได้ - ไคลเอนต์ที่ไม่ใช่เบราว์เซอร์ (เซิร์ฟเวอร์·แอป·CLI) เชื่อมต่อได้โดยไม่มี
Originแต่ในกรณีนั้นCookieจะไม่ถูกส่งต่อไปยังแอป ให้ยืนยันตัวตนด้วยการส่งโทเค็นทางเฮดเดอร์ (Authorization) หรือคิวรีแทนคุกกี้ - ระหว่างที่การเชื่อมต่อเปิดอยู่ แอปจะไม่เข้าสู่โหมดหลับ เมื่อดีพลอยเวอร์ชันใหม่หรือแพลตฟอร์มรีสตาร์ต การเชื่อมต่อจะถูกปิดด้วย
1001จึงควรทำให้ไคลเอนต์เชื่อมต่อใหม่ได้
- การเชื่อมต่อพร้อมกัน 120 การเชื่อมต่อต่อแอป หากเกิน การเชื่อมต่อใหม่จะถูกปฏิเสธด้วย
- ส่งคำขอ HTTPS ออกไปภายนอกได้ พอร์ตส่งอีเมล (SMTP) และเครือข่ายภายในถูกปิดกั้น อีเมลแจ้งเตือนให้ส่งผ่านAPI ส่งอีเมลของแอปด้วย
HRUM_API_KEYหรือใช้บริการอีเมลแบบ HTTPS API - เพื่อความปลอดภัย ระบบบันทึกปลายทางที่แอปเชื่อมต่อออกไปแยกตามแอป: ที่อยู่·พอร์ตที่เชื่อมต่อ ชื่อโดเมนที่แอปค้นหา เวลาที่เห็นครั้งแรก·ครั้งล่าสุด และจำนวนครั้งที่เชื่อมต่อ ไม่บันทึกเนื้อหาคำขอ·การตอบกลับและ URL ทั้งหมด บันทึกนี้เก็บไว้ 3 เดือนแล้วลบ จะเปิดดูเฉพาะเมื่อสอบสวนเหตุละเมิดความปลอดภัยหรือการกระทำต้องห้าม (ข้อกำหนด ข้อ 26 (ภาษาเกาหลี)) หรือมีคำขอตามกฎหมาย
- ล็อกของแอป (stdout·stderr) ผู้ดูแลระบบเปิดดูได้ระหว่างรับมือเหตุขัดข้อง และค่าตัวแปรสภาพแวดล้อม·รหัสผ่าน DB·โทเค็น·อีเมล ฯลฯ จะถูกปิดบังก่อนออกจากโฮสต์ (ข้อกำหนด ข้อ 20)
คุกกี้
เนื่องจากแอปของพาร์ทเนอร์หลายรายอยู่ภายใต้ ridm.ai เกตเวย์จึงผูกคุกกี้ไว้กับที่อยู่ของแอปเท่านั้น โค้ดแอปใช้คุกกี้ได้ตามปกติ แต่:
- คุกกี้จะเป็น
Secure,Path=/เสมอ และแอตทริบิวต์Domainจะถูกละเว้น - ชื่อคุกกี้ต้องไม่เกิน 57 ตัวอักษร คุกกี้ที่ชื่อยาวกว่านั้นจะถูกทิ้ง
- คุกกี้ที่สร้างด้วย JavaScript ในเบราว์เซอร์ (
document.cookie) จะไม่ถูกส่งไปยังเซิร์ฟเวอร์ คุกกี้ที่เซิร์ฟเวอร์ต้องอ่านให้สร้างด้วยSet-Cookieในการตอบกลับของเซิร์ฟเวอร์
ฐานข้อมูล
แต่ละแอปจะมี PostgreSQL DB เฉพาะ และข้อมูลการเชื่อมต่อเข้ามาเป็นตัวแปรสภาพแวดล้อม: DATABASE_URL (ต้องใช้ SSL) และ PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD, PGSSLMODE ขีดจำกัดความจุแตกต่างกันตามแพลน และปริมาณการใช้งานแสดงในหน้าจอแอป
การเชื่อมต่อ DB เป็น TLS ที่ตรวจสอบถึงใบรับรอง ผู้ออกใบรับรอง (Amazon RDS) ติดตั้งไว้ในคอนเทนเนอร์ล่วงหน้าแล้ว (NODE_EXTRA_CA_CERTS·PGSSLROOTCERT) จึงไม่ต้องใส่ตัวเลือก SSL ในโค้ดแยก — new Pool({ connectionString: process.env.DATABASE_URL, max: 2 }) ก็พอ การเชื่อมต่อได้สูงสุด 3 การเชื่อมต่อต่อแอป จึงควรตั้งขนาดพูลไม่เกิน 2
- การเชื่อมต่อพร้อมกันสูงสุด 3 การเชื่อมต่อต่อแอป คิวรีหนึ่งรายการ 10 วินาที และหากว่างอยู่ในทรานแซกชันเกิน 60 วินาทีจะถูกตัด
- เมื่อปริมาณการใช้งานเกิน 80% หรือเกินความจุ จะแจ้งทางอีเมล
- หากเกินความจุต่อเนื่อง 24 ชั่วโมง (หรือทันทีเมื่อเกิน 150%) DB จะกลายเป็นอ่านอย่างเดียว หากต้องการลบข้อมูล ให้รัน
SET default_transaction_read_only = offในการเชื่อมต่อก่อน - หากเกิน 110% ขณะอยู่ในสถานะอ่านอย่างเดียว จะตัดการเชื่อมต่อ DB ไม่ลบข้อมูล และยังสร้างการสำรองข้อมูลได้ต่อไป
- เมื่อลดลงต่ำกว่า 90% ของความจุหรือเปลี่ยนเป็นแพลนที่ใหญ่กว่า จะปลดล็อกภายใน 5 นาที
ตัวแปรสภาพแวดล้อม
- เพิ่ม·ลบได้ที่ "ตัวแปรสภาพแวดล้อม" ในหน้าจอแอป ค่าที่บันทึกจะถูกเข้ารหัสเก็บไว้และดูซ้ำไม่ได้ (แสดงเฉพาะชื่อ) หากต้องการเปลี่ยนให้เขียนทับด้วยค่าใหม่
- เมื่อบันทึก แอปจะรีสตาร์ตด้วยค่าใหม่
- ชื่อใช้ได้เฉพาะตัวพิมพ์ใหญ่·ตัวเลข·ขีดล่าง (ห้ามขึ้นต้นด้วยตัวเลข ไม่เกิน 64 ตัวอักษร) ค่าเป็นบรรทัดเดียวไม่เกิน 2KB สูงสุด 50 ตัวต่อแอป
- ตั้งชื่อที่แพลตฟอร์มใช้ไม่ได้:
PORT,HOSTNAME,NODE_OPTIONS,DATABASE_URLและชื่อที่ขึ้นต้นด้วยRIDM_·PG - ค่าที่แพลตฟอร์มใส่ให้:
RIDM_COMMIT(SHA เต็มของคอมมิตที่ดีพลอย),RIDM_COMMIT_SHORT(7 ตัวแรก),RIDM_DEPLOYED_AT(เวลาที่ดีพลอยเวอร์ชันนั้น, ISO UTC) — ใช้เช่นเมื่อแสดงเวอร์ชันที่กำลังทำงานอยู่ใน/api/healthหากย้อนกลับไปเวอร์ชันก่อนหน้า จะใส่ค่าของเวอร์ชันนั้น HRUM_API_KEY: ใส่คีย์ที่ออกจาก “คีย์ API” ในคอนโซล แอปที่เปิด “เชื่อมต่อ AI” แพลตฟอร์มจะใส่ให้อัตโนมัติจึงใส่เองไม่ได้ และหากมีค่าที่ใส่เองไว้ ต้องลบก่อนเปิด “เชื่อมต่อ AI” ใส่คีย์ของบัญชีอื่นหรือคีย์เฉพาะแอปไม่ได้- แอปที่ยกเลิกแล้วเปลี่ยนตัวแปรสภาพแวดล้อมไม่ได้
- ค่าไม่สามารถอ่านกลับได้จากหน้าจอหรือ API ใดๆ รายการและการตอบกลับ API แสดงเฉพาะชื่อ หากทำค่าหาย ให้ขอใหม่จากผู้ออกเดิม (บริษัทรับชำระเงิน·คอนโซลบริการภายนอก ฯลฯ) แล้วบันทึกใหม่ด้วยชื่อเดิม
ใส่คีย์ลับในคอนโซล (คน)
คนใส่ชื่อใดก็ได้ในคอนโซล ชื่อที่เครื่องมือ AI ใส่ไม่ได้ (ด้านล่าง) ก็ใส่ด้วยวิธีนี้
- เข้าสู่ระบบ console.hrum.ai แล้วเปิดแอปของฉันในเมนูด้านซ้าย
- เลื่อนการ์ดแอปลงไปหาช่องตัวแปรสภาพแวดล้อม ชื่อที่บันทึกไว้ตอนนี้จะแสดงเป็น
••••••••แทนค่า - เขียนชื่อในช่องแรก ชื่อ (เช่น STRIPE_SECRET_KEY) ตัวพิมพ์เล็กหรืออักขระอื่นจะถูกเปลี่ยนเป็นตัวพิมพ์ใหญ่·ขีดล่างขณะพิมพ์
- วางค่าในช่องที่สอง ค่า ช่องกรอกจะถูกปิดบังเหมือนรหัสผ่าน
- กดบันทึก แล้วจะแสดง “บันทึกตัวแปรสภาพแวดล้อมแล้ว: ชื่อ แอปจะรีสตาร์ตในไม่ช้า” หากบันทึกซ้ำด้วยชื่อเดิม ค่าจะเปลี่ยน
- หากจะลบ ให้กดลบในแถวนั้น → ลบในหน้าต่างยืนยัน เมื่อลบแล้วแอปจะรีสตาร์ตและกู้ค่าคืนไม่ได้
สิ่งที่ต้องปฏิบัติระหว่างย้ายค่า:
- คัดลอกค่าจากตัวจัดการรหัสผ่านหรือ Keychain Access ของ macOS แล้ววางทันที อย่าเขียนลงในโน้ต·แชต·อีเมล·เอกสารก่อนแล้วค่อยย้าย
- หลังวางแล้วให้ล้างคลิปบอร์ด (เทอร์มินัล macOS:
pbcopy < /dev/nullหรือคัดลอกตัวอักษรใดก็ได้หนึ่งครั้ง) - หากเบราว์เซอร์ถามว่าจะบันทึกค่าเป็นรหัสผ่านไหม ให้ปฏิเสธ
- อย่าใส่ระหว่างแชร์หน้าจอ·บันทึกหน้าจอ
ใส่คีย์ลับด้วย AI (โทเค็นปฏิบัติการ AI)
หากให้เครื่องมือเขียนโค้ด AI ใส่ตัวแปรสภาพแวดล้อมแทนคน ต้องมีโทเค็นปฏิบัติการ AI คือโทเค็นจัดการคอนโซล (hrum_cm_…, จัดการคอนโซลด้วย AI) ที่คนติ๊กสิทธิ์ hosting_ops ตอนออก หากมีสิทธิ์นี้จะไม่ต้องขอความยินยอมใหม่ทุกงาน การใส่ตัวแปรสภาพแวดล้อมไม่ได้อยู่ใน HRUM MCP เพื่อไม่ให้ค่าผ่านโมเดล AI จึงใช้พาธ HTTP ด้านล่าง
ชื่อที่ใส่ผ่านเส้นทาง AI ได้มีเฉพาะชื่อที่ลงท้ายด้วย _KEY·_SECRET·_TOKEN·_PASSWORD·_PASSWD·_PASS·_SALT·_CLIENT_ID (เช่น STRIPE_SECRET_KEY, MASTER_KEY) และในจำนวนนั้น ชื่อที่เปลี่ยนสภาพแวดล้อมการทำงานหรือที่อยู่การเชื่อมต่อจะถูกปฏิเสธ: ชื่อที่ลงท้ายด้วย _URL·_URI·_ENDPOINT·_HOST·_PROXY, ชื่อที่ขึ้นต้นด้วย NODE_·LD_·DYLD_·PYTHON·JAVA_·_JAVA_·JDK_·RUBY·PERL·GIT_·NPM_CONFIG_·GLOBAL_AGENT_·AWS_ENDPOINT_URL และชื่ออย่าง HTTP_PROXY·HTTPS_PROXY·NODE_TLS_REJECT_UNAUTHORIZED·SSL_CERT_FILE·PATH·OPENAI_API_BASE ชื่ออื่นๆ (เช่น ADMIN_PATH, SMTP_HOST) ให้คนใส่ในคอนโซล การลบทำผ่านเส้นทาง AI ได้ (ยกเว้นชื่อสงวน)
รับโทเค็น — ใช้ได้ 30 วัน
- AI ส่ง
{"action":"token_issue","payload":{"scopes":["hosting_ops"],"label":"My app ops"}}ไปยังPOST https://api.hrum.ai/api/v1/partners/v1/console-ai/consentsโดยไม่ต้องยืนยันตัวตน ในdataของการตอบกลับจะมีconsentUrl·userCode(8 หลัก)·code·pollSecret - AI แสดงให้ผู้ใช้เห็นเพียง
consentUrlและรหัส 8 หลัก ไม่แสดงpollSecret - คนเปิดลิงก์ด้วยเบราว์เซอร์ที่เข้าสู่ระบบคอนโซลไว้ (ภายใน 10 นาที) ใส่รหัส 8 หลักจากหน้าจอเครื่องมือ AI ในช่องรหัสยืนยัน ติ๊ก
hosting_opsแล้วกดยินยอม อ่านคำเตือนใต้ช่องติ๊ก (หากรั่วไหลจะเขียนทับตัวแปรสภาพแวดล้อม·ดีพลอย·รีสตาร์ตได้) ก่อนกด - เมื่อ AI เรียก
GET …/console-ai/consents/{code}พร้อมเฮดเดอร์X-Consent-Poll-Secretหลังการอนุมัติ จะได้โทเค็นจากdata.token.valueในการตอบกลับครั้งแรกเพียงครั้งเดียว อย่าพิมพ์ออกหน้าจอ ให้ใส่ลงที่เก็บความลับทันที (Keychain, ไฟล์สิทธิ์ 600 ฯลฯ) - เมื่อไม่ต้องการแล้ว ให้กดยกเลิกที่ “โทเค็นจัดการคอนโซลด้วย AI” ในหน้าคีย์ APIของคอนโซล จะถูกบล็อกทันที โทเค็นที่ยังใช้งานได้มีได้สูงสุด 10 รายการต่อบัญชี
การเรียก — ที่อยู่พื้นฐาน https://api.hrum.ai เฮดเดอร์ Authorization: Bearer hrum_cm_… id ของแอปคือ data.apps[].id (UUID) ในการตอบกลับของ GET /api/v1/partners/v1/console-ai/hosting
| งาน | คำขอ | การตอบกลับ |
|---|---|---|
| รายการชื่อ | GET /api/v1/partners/v1/console-ai/hosting/apps/{appId}/env | {"success":true,"data":{"env":{"names":[…]}}} — ไม่มีค่า |
| ใส่·เปลี่ยน | PUT …/hosting/apps/{appId}/env/{NAME} เนื้อหา {"value":"…"} | รายการชื่อหลังเปลี่ยน แอปจะรีสตาร์ต |
| ลบ | DELETE …/hosting/apps/{appId}/env/{NAME} | รายการชื่อหลังเปลี่ยน แอปจะรีสตาร์ต |
ตัวอย่าง (bash·zsh) ไม่ส่งค่าและโทเค็นเป็นอาร์กิวเมนต์บรรทัดคำสั่ง แต่ส่งค่าผ่านอินพุตมาตรฐาน เปลี่ยน $APP_ID และชื่อรายการใน Keychain เป็นของคุณเอง
# 1) Read secrets into shell variables (nothing is printed)
HRUM_CM_TOKEN=$(security find-generic-password -s hrum-console-ops -w)
VALUE=$(security find-generic-password -s myapp-STRIPE_SECRET_KEY -w)
# 2) Value goes through stdin, token through a header file: neither shows up in ps or shell history
printf '%s' "$VALUE" | jq -Rs '{value: .}' | curl -s -X PUT \
-H @<(printf 'Authorization: Bearer %s' "$HRUM_CM_TOKEN") \
-H 'Content-Type: application/json' --data-binary @- \
"https://api.hrum.ai/api/v1/partners/v1/console-ai/hosting/apps/$APP_ID/env/STRIPE_SECRET_KEY" \
| jq '.data.env.names // .'
# 3) Forget the value
unset VALUE
เมื่อบันทึกเสร็จ การตอบกลับจะแสดงเพียงรายการชื่อ ตรวจสอบว่าแอปรีสตาร์ตด้วยค่าใหม่แล้วหรือไม่โดยเปิดที่อยู่แอป
ดีพลอยและดูล็อกด้วย AI (โทเค็นปฏิบัติการ AI)
ใช้โทเค็นปฏิบัติการ AI (hosting_ops) เดียวกันเพื่อเริ่มดีพลอย และดูสถานะการดีพลอยกับล็อกที่แอปพิมพ์ออกมาได้ ไม่ต้องเข้าเว็บไซต์
ตั้งแต่ HRUM MCP 0.3.3 ทำแบบเดียวกันได้ด้วยเครื่องมือ MCP: hrum_hosting_deploy (เริ่มดีพลอย)·hrum_hosting_deploys (สถานะการดีพลอย)·hrum_hosting_logs (ล็อกรันไทม์) รับโทเค็นสิทธิ์ hosting_ops ด้วย hrum_ai_connect แล้วเรียกได้เลย id ของแอปดูได้จาก hrum_hosting_status เครื่องมือที่ไม่ใช้ MCP ให้ใช้พาธ HTTP ด้านล่าง
| งาน | คำขอ | การตอบกลับ |
|---|---|---|
| เริ่มดีพลอย | POST …/hosting/apps/{appId}/deploy เนื้อหา {} หรือ {"commit":"sha 40 ตัว"} | {"deployId","commitSha","retried","status":"queued"} บิลด์คอมมิตล่าสุดของ branch ที่เชื่อมต่อเหมือนกับ “ดีพลอยตอนนี้” ในคอนโซล (การตรวจดีพลอยครั้งแรก·กฎของแพลนราคาก็เหมือนกัน) รับ commit เฉพาะเมื่อเป็นคอมมิตล่าสุดนั้น — คอมมิตเก่ายังทำไม่ได้ (400 COMMIT_NOT_BRANCH_HEAD) ได้สูงสุด 2 ครั้งต่อนาที |
| สถานะการดีพลอย | GET …/hosting/apps/{appId}/deploys?limit=20 | เรียงจากล่าสุด id·commitSha·status·queuedAt·startedAt·finishedAt·liveAt·failReason·scanFindings (เฉพาะไฟล์·บรรทัด·กฎที่ติดการตรวจค่าลับ)·logTail (ท้ายล็อกการบิลด์)·startFailReason·startFailLog |
| ขอล็อก | POST …/hosting/apps/{appId}/logs เนื้อหา {"lines":100} (1~200) | 202 {"requestId"} |
| รับล็อก | GET …/hosting/apps/{appId}/logs/{requestId} | หาก status เป็น pending ให้ลองใหม่หลัง 2~3 วินาที หากเป็น delivered จะได้ lines เมื่อผ่านไป 3 นาทีจะเป็น expired |
ล็อกและเหตุผลที่ล้มเหลวจะถูกปิดบังก่อนส่งออก: ค่าตัวแปรสภาพแวดล้อมที่บันทึกไว้ในแอปนั้น และรูปแบบคีย์อย่าง sk-…·AKIA…·Bearer …·JWT·…_live_… จะเปลี่ยนเป็น [redacted] ถึงอย่างนั้น สิ่งแรกที่ควรทำคือไม่ให้แอปพิมพ์ค่าลับลงในล็อก การเรียกทุกครั้ง (รวมที่ถูกปฏิเสธ) จะถูกบันทึกพร้อมโทเค็น·แอป·ผลลัพธ์
เซสชันที่เข้าสู่ระบบคอนโซลหรือเซสชันที่เข้าสู่ระบบ HRUM MCP ก็มีพาธเดียวกัน: POST …/console/hosting/apps/{appId}/deploy-now (MCP เฉพาะเซสชันที่สร้างจากการสมัคร), GET …/console/hosting/apps/{appId}/deploys, POST …/console/hosting/apps/{appId}/logs เนื้อหา {"lines":100} (1~200, MCP เฉพาะเซสชันที่สร้างจากการสมัคร) → GET …/logs/{requestId} ใช้ได้เฉพาะแอปของตัวเอง และบรรทัดล็อกจะถูกปิดบังด้วยกฎเดียวกัน เนื้อหาล็อกที่ดึงมาจะถูกลบหลัง 24 ชั่วโมงนับจากเวลาที่ส่ง (หรือขอ) (ตั้งแต่ 2026-12-01 เป็น 7 วัน, ข้อกำหนดการใช้งาน ข้อ 20 วรรค 5)
HRUM_CM_TOKEN=$(security find-generic-password -s hrum-console-ops -w)
API=https://api.hrum.ai/api/v1/partners/v1/console-ai/hosting/apps/$APP_ID
git push origin main
curl -s -X POST -H @<(printf 'Authorization: Bearer %s' "$HRUM_CM_TOKEN") \
-H 'Content-Type: application/json' -d '{}' "$API/deploy" | jq '.data // .'
curl -s -H @<(printf 'Authorization: Bearer %s' "$HRUM_CM_TOKEN") \
"$API/deploys?limit=3" | jq '.data.deploys[] | {id, commitSha, status, liveAt, failReason}'
กฎความปลอดภัยของคีย์ลับ (สิ่งที่เครื่องมือ AI ต้องปฏิบัติ)
- ไม่ขอให้ผู้ใช้วางค่าในแชต ขอให้ผู้ใช้ใส่ค่าใน Keychain·ตัวจัดการรหัสผ่าน แล้วถามเพียงชื่อรายการ
- แม้ผู้ใช้จะวางค่าในแชตแล้ว ก็ไม่พิมพ์ซ้ำ ค่านั้นค้างอยู่ในประวัติการสนทนาแล้ว จึงแนะนำให้ผู้ใช้ขอออกใหม่จากผู้ออกแล้วเปลี่ยน
- อ่านค่าเป็นตัวแปรเชลล์แล้วส่งผ่านอินพุตมาตรฐาน ไม่ใช้วิธีที่ค่าจะค้างอยู่ในบรรทัดคำสั่ง·ล็อกอย่าง
curl -d "ค่า",echo ค่า,set -x - ไม่เขียนค่าลงในโค้ด·คอมมิต
.env·PROGRESS.md·ล็อก·การแสดงผลบนหน้าจอ รายงานเพียง "ชื่อ + บันทึกแล้วหรือไม่" - ชื่อที่เส้นทาง AI ปฏิเสธ (ด้านบน) ห้ามหาทางเลี่ยง ให้ส่งต่อให้คนใส่ในคอนโซล
- จัดการโทเค็นปฏิบัติการ (
hrum_cm_…) เหมือนกับค่า เมื่อใช้เสร็จให้แจ้งให้ยกเลิกในคอนโซล
เหตุการณ์ที่เกิดขึ้นจริง: เครื่องมือ AI ที่กำลังสร้างแอปจัดการการขายพยายามใส่มาสเตอร์คีย์ของแอปเป็นตัวแปรสภาพแวดล้อม แต่ตอนนั้นไม่มีเส้นทางปฏิบัติการให้ AI ใช้ จึงหยุดอยู่ตรงนั้น ตอนนี้ชื่อที่ลงท้ายด้วย _KEY อย่าง MASTER_KEY ใส่ได้ด้วยโทเค็นปฏิบัติการ AI ส่วนชื่ออื่นๆ ให้คนใส่ในคอนโซล ไม่ว่าทางไหน อย่าให้ค่าถูกส่งผ่านแชต
ข้อผิดพลาดของตัวแปรสภาพแวดล้อม
เนื้อหาข้อผิดพลาดคือ {"success":false,"statusCode":…,"message":"…"} ข้อผิดพลาดของตัวแปรสภาพแวดล้อมไม่มี code จึงแยกด้วยรหัสสถานะและส่วนต้นของข้อความด้านล่าง ข้อความต้นฉบับทั้งหมดอยู่ใน llms.txt
| สถานะ | ส่วนต้นของข้อความ | สาเหตุ → วิธีแก้ |
|---|---|---|
| 400 | 이름은 대문자·숫자·밑줄만 (ชื่อใช้ได้เฉพาะตัวพิมพ์ใหญ่·ตัวเลข·ขีดล่าง) | ผิดกฎการตั้งชื่อ → ตัวพิมพ์ใหญ่·ตัวเลข·ขีดล่าง ห้ามขึ้นต้นด้วยตัวเลข ไม่เกิน 64 ตัวอักษร |
| 400 | 플랫폼이 쓰는 이름이라 (เป็นชื่อที่แพลตฟอร์มใช้) | PORT·HOSTNAME·NODE_OPTIONS·DATABASE_URL, คำนำหน้า RIDM_·PG → ใช้ชื่ออื่น |
| 400 | AI 연결이 자동으로 넣는 이름이라 (เป็นชื่อที่เชื่อมต่อ AI ใส่ให้อัตโนมัติ) | HRUM_API_KEY → แอปนี้เปิด “เชื่อมต่อ AI” ไว้ แพลตฟอร์มจึงใส่ให้ หากจะใส่เองให้ปิด “เชื่อมต่อ AI” |
| 400 | 이 계정에서 발급한 API 키만 넣을 수 있어요 (ใส่ได้เฉพาะคีย์ API ที่ออกจากบัญชีนี้) | ใส่คีย์จาก “คีย์ API” ในคอนโซลของคุณ |
| 400 | AI 연결이 앱마다 만든 키는 넣을 수 없어요 (ใส่คีย์ที่เชื่อมต่อ AI สร้างให้แต่ละแอปไม่ได้) | ใส่คีย์ที่ออกจาก “คีย์ API” ในคอนโซล |
| 400 | 값을 입력해 주세요 (โปรดกรอกค่า) | ค่าว่างเปล่า |
| 400 | 값에 줄바꿈을 넣을 수 없 (ค่ามีการขึ้นบรรทัดใหม่ไม่ได้) | ค่าหลายบรรทัด (คีย์ส่วนตัว PEM ฯลฯ) → แปลงเป็น base64 บรรทัดเดียวแล้วใส่ และถอดรหัสใช้ในแอป |
| 400 | 값은 2048바이트까지 (ค่าได้สูงสุด 2048 ไบต์) | ค่าเกิน 2KB → ค่าขนาดใหญ่ให้เก็บใน DB หรือที่เก็บความลับภายนอก |
| 400 | 실행 환경을 바꾸는 이름이라 AI 경로 (เป็นชื่อที่เปลี่ยนสภาพแวดล้อมการทำงาน ใช้เส้นทาง AI ไม่ได้) | ชื่อที่เส้นทาง AI ปฏิเสธ → ให้คนใส่ในคอนโซล |
| 400 | AI 경로(AI 운영 토큰·MCP)로는 _KEY (เส้นทาง AI ใช้ได้เฉพาะชื่อที่ลงท้ายด้วย _KEY ฯลฯ) | ไม่ได้ลงท้ายด้วยคำต่อท้ายของชื่อลับ → เปลี่ยนชื่อ หรือให้คนใส่ในคอนโซล |
| 400 | Validation failed (uuid is expected) | id ของแอปไม่ใช่ UUID → apps[].id ของ GET /console-ai/hosting |
| 401 | MGMT_TOKEN_INVALID | ไม่มีโทเค็นหรือหมดอายุ·ถูกยกเลิก → ขอออกใหม่ |
| 403 | MGMT_SCOPE_DENIED (scope: "hosting_ops") | โทเค็นไม่มี hosting_ops → ติ๊กแล้วขอออกใหม่ |
| 404 | 앱을 찾을 수 없 (ไม่พบแอป) | เป็นแอปของบัญชีอื่นหรือแอปที่ถูกลบ → ตรวจสอบ id ของแอป |
| 404 | 없는 환경변수 (ตัวแปรสภาพแวดล้อมที่ไม่มีอยู่) | ไม่มีชื่อที่ต้องการลบ → ตรวจสอบรายการชื่อ |
| 409 | 해지된 앱은 환경변수를 바꿀 수 없 (แอปที่ยกเลิกแล้ว) | แอปที่อยู่ระหว่างยกเลิก → เปลี่ยนไม่ได้ |
| 409 | 환경변수는 앱당 50개까지 (สูงสุด 50 ตัวต่อแอป) | ลบชื่อที่ไม่ใช้แล้วลองใหม่ |
| 429 | — | ใส่·ลบได้สูงสุด 30 ครั้งต่อนาที → ลองใหม่ภายหลัง |
| 503 | 환경변수 저장소가 준비되지 않 (ที่เก็บตัวแปรสภาพแวดล้อมยังไม่พร้อม) | ปัญหาฝั่งเซิร์ฟเวอร์ → ลองใหม่ภายหลัง หากยังเกิดต่อเนื่องโปรดติดต่อเรา |
เชื่อมต่อ AI
ฟีเจอร์ที่แพลตฟอร์มใส่คีย์ API ที่ใช้เฉพาะแอปนี้ให้ เพื่อให้แอปเรียก API ซาจู·AI ได้ ใช้ได้ทุกบัญชี
- เปิด — เปิดรายละเอียดแอปในแอปของคอนโซล แล้วเปิด “ใช้การเชื่อมต่อ AI” คีย์เฉพาะแอปจะถูกสร้างและใส่เป็นตัวแปรสภาพแวดล้อม
HRUM_API_KEYแล้วแอปจะรีสตาร์ต - เรียกใช้ — อ่าน
process.env.HRUM_API_KEYในโค้ดเซิร์ฟเวอร์ของแอป แล้วใส่ในเฮดเดอร์X-Partner-Api-Keyค่าคีย์ไม่แสดงแม้ในคอนโซล อย่าใส่ในโค้ดที่ส่งไปยังเบราว์เซอร์
ระหว่างที่เปิดอยู่ ใส่ HRUM_API_KEY เองไม่ได้ หากมีค่าที่ใส่เองไว้ ให้ลบก่อนเปิด (หากไม่ลบจะขึ้น “โปรดลบตัวแปรสภาพแวดล้อม HRUM_API_KEY เดิมก่อน”) ค่าบริการที่ใช้ด้วยคีย์นี้หักจากเครดิตของคุณ และเมื่อถึงขีดจำกัดการใช้งานต่อวันที่กำหนดในรายละเอียดแอป จะหยุดในวันนั้น เมื่อปิด คีย์จะถูกตัดทันที และเมื่อเปิดใหม่จะสร้างคีย์ใหม่ เรียก API การชำระเงินด้วยคีย์นี้ไม่ได้ — รับชำระเงินในแอปให้ใช้คีย์ที่ออกจากคอนโซล
รับชำระเงินในแอป
รับชำระเงินของผู้ใช้แอปผ่านหน้าชำระเงินของ HRUM ได้ การขายจะเปิดหลังจากลงทะเบียนเป็นผู้ขาย (บุคคล·ผู้ประกอบการรายบุคคล·นิติบุคคล) และได้รับอนุมัติแล้ว ลงทะเบียนผู้ขายได้ที่การสรุปยอดและโอนเงินในคอนโซล เงื่อนไขกำหนดโดยข้อกำหนดการใช้งาน ข้อ 32~39 (ภาษาเกาหลี) แอปในแพลนฟรีก็ขายได้ แต่ระหว่างที่การเผยแพร่แอปหยุดเพราะถึงขีดจำกัดการรับส่งข้อมูลรายเดือนหรือถูกระงับ การเปิดการชำระเงินใหม่จะถูกปฏิเสธด้วย 409 APP_NOT_SERVING การชำระเงินที่เปิดไว้แล้ว การตรวจสอบคำสั่งซื้อ·การคืนเงินยังทำได้ตามปกติ
- ใส่คีย์ API — ใส่คีย์ที่ออกจากคีย์ APIในคอนโซลเป็นตัวแปรสภาพแวดล้อม (เช่น
HRUM_PARTNER_KEY) เรียก API การชำระเงินด้วยHRUM_API_KEYที่ “เชื่อมต่อ AI” ใส่ให้ไม่ได้ ใช้คีย์เฉพาะในโค้ดเซิร์ฟเวอร์และอย่าส่งไปยังเบราว์เซอร์ - ลงทะเบียนสินค้า —
POST /api/v1/partners/v1/storefront/skusเนื้อหา{"appId","name","priceWon"}การชำระเงินจะใช้ราคาที่ลงทะเบียนไว้ที่นี่เท่านั้น - เปิดการชำระเงิน — ส่ง
POST /api/v1/partners/v1/storefront/checkoutsเนื้อหา{"appId","skuId","qty","returnUrl"}จากเซิร์ฟเวอร์ แล้วส่งผู้ใช้ไปยังcheckoutUrlในการตอบกลับreturnUrlใช้ได้เฉพาะที่อยู่ https ของแอปนี้ (<name>.ridm.aiหรือโดเมนที่เชื่อมต่อ) - ตรวจสอบผลลัพธ์ — เมื่อชำระเงินเสร็จ ผู้ใช้จะกลับมาที่
returnUrl?orderId=…ตรวจสอบจากเซิร์ฟเวอร์ด้วยGET /api/v1/partners/v1/storefront/orders/{orderId}ว่าstatusเป็นpaidแล้วจึงมอบสินค้า อย่าเชื่อเพียงค่าที่ต่อท้ายที่อยู่
ทุกคำขอต้องมีเฮดเดอร์ X-Partner-Api-Key หากต้องการคืนเงิน โปรดแจ้งพร้อมหมายเลขคำสั่งซื้อที่ [email protected] เมื่อคืนเงินแล้ว status ของคำสั่งซื้อจะเปลี่ยนเป็น canceled หรือ partial_canceled
const res = await fetch("https://api.hrum.ai/api/v1/partners/v1/storefront/checkouts", {
method: "POST",
headers: { "Content-Type": "application/json", "X-Partner-Api-Key": process.env.HRUM_PARTNER_KEY },
body: JSON.stringify({ appId, skuId, qty: 1, returnUrl: "https://myapp.ridm.ai/paid" }),
});
const { checkoutUrl } = (await res.json()).data;
สิ่งที่เรียกได้ตามสิทธิ์ของคีย์
เลือกสิทธิ์ได้ตอนสร้างคีย์ หากเรียกพาธนอกสิทธิ์ที่เลือกจะได้ 403 KEY_SCOPE_MISSING คีย์เดิมที่ไม่ได้เลือกสิทธิ์จะเรียกได้ทุกพาธเหมือนเดิม พาธทั้งหมดอยู่ในเอกสาร OpenAPI
payments— ลงทะเบียนสินค้าPOST /storefront/skus, เปิดการชำระเงินPOST /storefront/checkoutsorders.read— ตรวจสอบคำสั่งซื้อGET /storefront/orders/{orderId}refunds— ผลการคืนเงินรับได้ทางstatusของคำสั่งซื้อและเว็บฮุกorder.refundedsettlement.read— ข้อมูลการสรุปยอดและโอนเงินGET /settlement/sales·/settlement/payouts·/settlement/summarywebhooks— ลงทะเบียนที่อยู่·ประวัติการส่งเว็บฮุกของผู้ขาย
API ข้อมูลการสรุปยอดและโอนเงิน
รับตัวเลขเดียวกับหน้าจอ“การสรุปยอดและโอนเงิน” ในคอนโซลจากเซิร์ฟเวอร์ แสดงเฉพาะข้อมูลของคุณตามคีย์ของคุณ ช่วงเวลา from·to เป็นวันที่ตามเวลาเกาหลี (YYYY-MM-DD รวมทั้งสองฝั่ง) หากเว้นว่างจะเป็นเดือนนี้ ได้สูงสุด 366 วันต่อครั้ง
GET /api/v1/partners/v1/settlement/sales?from=&to=&skuId=&limit=&cursor=— แต่ละรายการขายมียอดชำระ (paidWon) ค่าธรรมเนียมการขายของ HRUM (salesCommissionWon, รวม VAT) ค่าธรรมเนียมต่อการชำระเงิน (perOrderFeeWon) ค่าธรรมเนียมบัตร (pgFeeWon) จำนวนเงินที่จะจ่าย (sellerWon) การคืนเงิน (refundedWon) ทั้งหมดเป็นค่าหลังหักการคืนเงินแล้วtotalsคือยอดรวมของทั้งช่วงเวลา ไม่ใช่ของหน้านี้GET /api/v1/partners/v1/settlement/payouts?from=&to=&status=scheduled|completed|unpaid— แต่ละการจ่ายเงินgrossWon= เงินที่โอน (amountWon) + ค่าธรรมเนียมการจ่ายเงิน (feeWon) + VAT ของค่าธรรมเนียมนั้น (feeVatWon) + ภาษีหัก ณ ที่จ่าย 3.3% ของผู้ขายบุคคล (withholdingWon) ช่วงเวลาอิงตามวันจ่ายเงินGET /api/v1/partners/v1/settlement/summary?from=&to=— ยอดขายรวม ยอดรวมการจ่ายเงินที่กำหนดไว้·ที่เสร็จแล้ว และค่าธรรมเนียมการจ่ายเงินปัจจุบันในครั้งเดียว
const res = await fetch("https://api.hrum.ai/api/v1/partners/v1/settlement/summary?from=2026-11-01&to=2026-11-30", {
headers: { "X-Partner-Api-Key": process.env.HRUM_PARTNER_KEY },
});
const { sales, payouts, payoutFee } = (await res.json()).data;
เว็บฮุกของผู้ขาย
เมื่อมีการชำระเงินเสร็จ·คืนเงิน·จ่ายเงิน ระบบจะแจ้งไปยังเซิร์ฟเวอร์ของคุณ ที่อยู่ต้องเป็น https:// เท่านั้น (พอร์ต 443·8443) และลงทะเบียนที่อยู่ส่วนตัว·ภายในไม่ได้
- ลงทะเบียนที่อยู่ —
PUT /api/v1/partners/v1/webhooks/endpointเนื้อหา{"url":"https://myapp.ridm.ai/hrum/webhook"}secret(whsec_…) ในการตอบกลับจะแสดงเพียงครั้งนี้ครั้งเดียว ให้ใส่ในตัวแปรสภาพแวดล้อมเซิร์ฟเวอร์HRUM_WEBHOOK_SECRETทันที หากต้องการรับใหม่ใช้{"url": …, "rotateSecret": true} - อีเวนต์ —
order.paid(ชำระเงินเสร็จ),order.refunded(คืนเงินหนึ่งรายการ),payout.scheduled(กำหนดการจ่ายเงิน),payout.completed(จ่ายเงินเสร็จ),webhook.test(POST /webhooks/test) เนื้อหาคือ{"id","type","created","data"}และไม่มีข้อมูลผู้ซื้อ เหตุการณ์เดียวกันจะถูกสร้างเพียงครั้งเดียวด้วยidเดียวกัน จึงควรกรองรายการซ้ำด้วยid - สำเนาสำหรับแพลตฟอร์ม — หากลงทะเบียนที่อยู่ด้วยคีย์แพลตฟอร์ม จะได้รับสำเนา
order.paid·order.refundedของคำสั่งซื้อผู้ขายที่เปิดบนแพลตฟอร์มนั้นด้วย เฮดเดอร์·ลายเซ็นเหมือนกัน แต่idต่างจากฝั่งผู้ขาย และในdataจะมีsellerId·spaceIdเพิ่มมา - ตรวจสอบลายเซ็น — เฮดเดอร์
Hrum-Signature: t=<unix วินาที>,v1=<hex>v1คือ HMAC-SHA256 (t + "." + เนื้อหาที่ได้รับตามเดิม) ที่สร้างด้วยค่าลับ ให้ทิ้งtที่เก่ากว่า 5 นาที - ส่งซ้ำ — หากไม่ตอบด้วย 2xx ภายใน 10 วินาที จะส่งซ้ำหลัง 1 นาที·5 นาที·30 นาที·2 ชั่วโมง·12 ชั่วโมง (สูงสุด 6 ครั้ง) ประวัติการส่งคือ
GET /webhooks/deliveriesและการส่งซ้ำคือPOST /webhooks/deliveries/{eventId}/redeliver
const crypto = require("node:crypto");
function verifyHrumWebhook(rawBody, header, secret, toleranceSec = 300) {
const parts = Object.fromEntries(String(header || "").split(",").map((p) => p.trim().split("=")));
const t = Number(parts.t);
if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
const want = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
const got = Buffer.from(parts.v1 || "", "hex");
return got.length === want.length && crypto.timingSafeEqual(got, want);
}
// Express: verify the raw body before parsing it as JSON
app.post("/hrum/webhook", express.raw({ type: "application/json" }), (req, res) => {
const raw = req.body.toString("utf8");
if (!verifyHrumWebhook(raw, req.get("Hrum-Signature"), process.env.HRUM_WEBHOOK_SECRET)) return res.sendStatus(400);
const event = JSON.parse(raw); // if event.id was already handled, just return 200
res.sendStatus(200);
});
การดีพลอยครั้งแรกและการตรวจสอบอัตโนมัติ
เมื่อบิลด์ครั้งแรกสำเร็จ จะผ่านการตรวจสอบอัตโนมัติและได้รับอนุมัติโดยอัตโนมัติ แล้วที่อยู่จะเผยแพร่ทันที ก่อนการดีพลอยครั้งแรกจะเผยแพร่ จะไม่มีการหักค่าบริการแบบชำระเงิน หาก repository มีค่าลับ (คีย์·โทเค็น·รหัสผ่าน) การบิลด์จะล้มเหลว แม้จะพบปลายทางการเชื่อมต่อภายนอกใหม่·รูปแบบเสี่ยงใหม่ หรือเจ้าของ repository เปลี่ยน การดีพลอยก็จะสะท้อนโดยอัตโนมัติ และเนื้อหานั้นจะถูกบันทึก การอนุมัติอัตโนมัติและผลการตรวจสอบทั้งหมดจะถูกบันทึก ผู้ดูแลระบบจะตรวจสอบภายหลัง และหากมีปัญหาอาจระงับการเผยแพร่ได้ เมื่อการเผยแพร่ถูกระงับ จะแจ้งเหตุผลทางอีเมลและหน้าจอแอป การกระทำต้องห้ามดูได้ที่ข้อกำหนด ข้อ 26 (ภาษาเกาหลี)
ราคา·ขีดจำกัด
ราคา·หน่วยความจำ·DB·การรับส่งข้อมูลรายเดือนของแต่ละแพลนอยู่ในหน้าราคา ค่าแพลนแบบชำระเงินหักจากเครดิตที่เติมไว้ทุกเดือน หากยอดคงเหลือไม่พอในวันชำระเงิน แอปจะหยุด และเมื่อเติมเงินจะกลับมาทำงานอัตโนมัติ ปริมาณการรับส่งข้อมูลรายเดือนคือผลรวมของการตอบกลับที่ส่งให้ผู้เยี่ยมชมกับทราฟฟิกที่แอปส่งออกไปภายนอก (รวมการเรียก API ภายนอก·การอัปโหลด·การเขียน DB) WebSocket นับเฟรมที่รับส่งทั้งสองทิศทาง เมื่อถึงขีดจำกัด WebSocket ที่เปิดอยู่ก็จะถูกปิดด้วย 1008 เมื่อถึงขีดจำกัด การเผยแพร่และการทำงานของแอปจะหยุดพร้อมกัน (กลับมาในวันที่ 1 ของเดือนถัดไป) สำหรับแพลนแบบชำระเงิน หากซื้อบล็อกการรับส่งข้อมูลในหน้าจอแอป จะเปิดใหม่ภายในไม่กี่นาที จะแจ้งทางอีเมลเมื่อถึง 80% และเมื่อถึงขีดจำกัด
การสำรองข้อมูล·การยกเลิก
- สร้าง DB dump ได้ด้วย "การสำรองฐานข้อมูล" ในหน้าจอแอป จะได้ที่อยู่ดาวน์โหลดที่ใช้ได้ 1 ชั่วโมง และสร้างได้สูงสุดวันละ 3 ครั้ง
- เมื่อยกเลิก แพลนแบบชำระเงินจะหยุดในวันที่สิ้นสุดระยะเวลาที่ชำระไว้แล้ว และหลังจากนั้น 30 วันยังดาวน์โหลดหรือกู้คืนข้อมูลได้ เมื่อพ้น 30 วัน แอปและ DB จะถูกลบและกู้คืนไม่ได้ ค่าบริการที่หักไปแล้วจะไม่คืนเงิน
ติดต่อ: contact@float.do