การตั้งค่า WorkSpace
การตั้งค่าธีม
การตั้งค่า Space ช่วยให้ผู้ดูแลระบบองค์กรสามารถปรับแต่งสีธีมของพื้นที่ทำงานให้ตรงกับสีของแบรนด์ตนเองได้
การตั้งค่าการเชื่อมต่อ
GPTBots ช่วยให้คุณฝัง workspace ทั้งระบบลงในแอปมือถือขององค์กร เพื่อให้พนักงานสามารถเข้าใช้งาน โดยไม่ต้องเข้าสู่ระบบ
การเข้ารหัส AiToken สำหรับพนักงาน
- เข้ารหัสอีเมลของพนักงานด้วย RSA public key (
publicKey) ของ workspace และเข้ารหัสผลลัพธ์ด้วย Base64 - นำ
projectIdของคุณมาต่อกับ ciphertext ที่เข้ารหัส Base64 ด้วยเครื่องหมายโคลอน:{projectId}:{base64-encoded-ciphertext}
จากนั้นเข้ารหัสสตริงทั้งหมดด้วย Base64 อีกครั้ง ผลลัพธ์ที่ได้คือAiTokenที่เข้ารหัสแล้ว - สร้าง URL สำหรับล็อกอินเฉพาะพนักงาน:
{workspace-integration-url}?{AiToken} - เมื่อพนักงานเปิด URL นี้ผ่านแอปมือถือ ระบบ workspace จะเปิดใช้งาน โดยไม่ต้องกรอกข้อมูลเข้าสู่ระบบ
- ตัวอย่างโค้ดเข้ารหัส JAVA
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
public class Main {
private static final String RSA_ALGORITHM = "RSA";
private static final String RSA_TRANSFORMATION = "RSA/ECB/PKCS1Padding";
/**
* เข้ารหัสข้อมูลด้วย RSA public key
*
* @param data ข้อมูลที่ต้องการเข้ารหัส
* @param publicKeyStr RSA public key ที่เข้ารหัสด้วย Base64
* @return ข้อมูลที่เข้ารหัสแล้ว (byte array)
*/
public static byte[] encrypt(byte[] data, String publicKeyStr) throws Exception {
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
PublicKey publicKey = keyFactory.generatePublic(keySpec);
Cipher cipher = Cipher.getInstance(RSA_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* สร้าง login key โดยเข้ารหัสอีเมลและรวมกับ projectId
*
* @param projectId รหัสโปรเจกต์
* @param email อีเมลผู้ใช้
* @param publicKey RSA public key ที่เข้ารหัสด้วย Base64
* @return สตริง login key สุดท้าย
* @throws Exception หากเข้ารหัสล้มเหลว
*/
public static String generateLoginKey(String projectId, String email, String publicKey) throws Exception {
byte[] emailEncrypted = encrypt(email.getBytes(StandardCharsets.UTF_8), publicKey);
String emailRSAStr = Base64.getEncoder().encodeToString(emailEncrypted);
String keyStr = projectId + ":" + emailRSAStr;
return Base64.getEncoder().encodeToString(keyStr.getBytes(StandardCharsets.UTF_8));
}
public static void main(String[] args) {
String projectId = "your project ID";
String email = "your email";
String publicKey = "your public key";
try {
String key = generateLoginKey(projectId, email, publicKey);
System.out.println(key);
} catch (Exception e) {
System.err.println("สร้าง login key ไม่สำเร็จ: " + e.getMessage());
}
}
}
- ตัวอย่างโค้ดเข้ารหัส TypeScript
import * as forge from 'node-forge';
/**
* เข้ารหัสข้อมูลด้วย RSA public key
* @param data ข้อมูลที่ต้องการเข้ารหัส
* @param publicKeyStr สตริง public key ที่เข้ารหัสด้วย Base64
* @returns byte array ที่เข้ารหัสแล้ว
*/
export function encrypt(data: string, publicKeyStr: string): Uint8Array {
try {
// ถอดรหัส Base64 public key
const publicKeyBytes = forge.util.decode64(publicKeyStr);
// สร้างอ็อบเจกต์ public key
const publicKey = forge.pki.publicKeyFromAsn1(forge.asn1.fromDer(publicKeyBytes));
// ใช้การเข้ารหัส RSA พร้อม PKCS1 padding (เหมือนกับ Java)
const encrypted = publicKey.encrypt(data, 'RSAES-PKCS1-V1_5');
// แปลง byte string ของ forge เป็น Uint8Array
const bytes = new Uint8Array(encrypted.length);
for (let i = 0; i < encrypted.length; i++) {
bytes[i] = encrypted.charCodeAt(i) & 0xff;
}
return bytes;
} catch (error) {
throw new Error(`RSA encryption failed: ${error}`);
}
}
/**
* แปลง byte array เป็นสตริง Base64
* @param bytes byte array
* @returns สตริง Base64
*/
export function bytesToBase64(bytes: Uint8Array): string {
// แปลง Uint8Array เป็น string แล้วใช้ forge.encode64
const binaryString = Array.from(bytes, byte => String.fromCharCode(byte)).join('');
return forge.util.encode64(binaryString);
}
/**
* แปลง string เป็น Base64
* @param str สตริงที่ต้องการเข้ารหัส
* @returns สตริง Base64
*/
export function stringToBase64(str: string): string {
return forge.util.encode64(str);
}
/**
* ฟังก์ชันหลัก - สร้างสตริง key ที่เข้ารหัสแล้ว
* @param projectId รหัสโปรเจกต์
* @param email อีเมล
* @param publicKey RSA public key ที่เข้ารหัสด้วย Base64
* @returns สตริง Base64 สุดท้ายที่เข้ารหัสแล้ว
*/
export function generateEncryptedKey(projectId: string, email: string, publicKey: string): string {
// ใช้ RSA เข้ารหัสอีเมล
const emailRSAEncrypt = encrypt(email, publicKey);
// แปลงผลลัพธ์การเข้ารหัสเป็น Base64
const emailRSAStr = bytesToBase64(emailRSAEncrypt);
// รวม projectId กับอีเมลที่เข้ารหัส
const keyStr = `${projectId}:${emailRSAStr}`;
// เข้ารหัสสตริงทั้งหมดด้วย Base64
const result = stringToBase64(keyStr);
return result;
}
// ตัวอย่างการสร้าง AiToken
// generateEncryptedKey(projectId, email, publicKey)
การเชื่อมต่อ Workspace กับ APP
หากองค์กรต้องการฝัง workspace ลงในแอปมือถือ สามารถสื่อสารระหว่าง native app กับหน้า H5 ได้ผ่าน WebViewBridge โดยดำเนินการตามขั้นตอนดังนี้
WebViewBridge คืออินเทอร์เฟซสำหรับเชื่อมต่อสองทางระหว่าง native application กับหน้า H5 ให้โปรโตคอลและวิธีการสื่อสารที่เป็นมาตรฐาน เพื่อให้ native code กับ H5 page เรียกใช้งานและส่งข้อมูลหากันได้อย่างสะดวก
- สำหรับคำแนะนำการเชื่อมต่อ APP โดยละเอียด กรุณาดู เอกสาร Android Workspace Integration และ เอกสาร iOS Workspace Integration
- เมื่อพนักงานองค์กรเข้าใช้งาน workspace ผ่าน APP ควรเปิด workspace ด้วยตัวตนของพนักงานนั้น กติกาการสร้าง URL สำหรับเข้าใช้งานคือ:
https://gptbots.ai/space/h5/home?AiToken={encryptedAiToken}&hideClose=trueโดย {encryptedAiToken} คือ AiToken ที่เข้ารหัสด้วย RSA public key ซึ่งจะมี รหัสองค์กร และ อีเมลบัญชีพนักงาน อยู่ในนั้น
- การตั้งค่าพารามิเตอร์ hideClose
hideCloseเป็นพารามิเตอร์เสริม ใช้ควบคุมว่าจะซ่อนปุ่ม "Close" หรือไม่ หากตั้งค่าเป็นtrueปุ่ม "Close" จะไม่แสดงบนหน้า webview- โดยปกติแล้ว ปุ่ม "Close" จะแสดงบนหน้า หากคลิกปุ่มนี้ จะมีการส่งข้อความแจ้งเตือน action ปิดหน้า ผ่าน WebViewBridge เมื่อ APP ได้รับแจ้งเตือนนี้จะสามารถปิดหน้า workspace ได้ ข้อมูล JSON สำหรับแจ้งเตือน action ปิดหน้ามีดังนี้:
{
"eventType": "click",
"data": {
"value": "close",
"timestamp": Date.now(),//เวลาปัจจุบัน (มิลลิวินาที)
"extendedData": {} // ข้อมูลเสริม (ถ้ามี)
}
}
eventType: String, ประเภทของ event ใช้ระบุการเรียกใช้งานฟังก์ชันต่าง ๆ
data: อ็อบเจกต์ JSON ที่มีข้อมูล parameter ของ event ซึ่งอาจมีฟิลด์ต่าง ๆ ตามประเภท eventType
| ประเภท Event | ค่าคงที่ | คำอธิบาย | พารามิเตอร์ |
|---|---|---|---|
| click | EVENT_CLICK | เหตุการณ์คลิกในหน้า Webview | data: ข้อมูลเสริม (ถ้ามี) รูปแบบ JSON โดยปกติจะมีฟิลด์: value (ประเภท event เช่น "click"), timestamp (เวลามิลลิวินาที) |
| message | EVENT_MESSAGE | เหตุการณ์ message ในหน้า Webview | data: ข้อมูลเสริม (ถ้ามี) รูปแบบ JSON โดยปกติจะมีฟิลด์: value (ประเภท event เช่น "message"), timestamp (เวลามิลลิวินาที) |
