| const WebSocket = require('ws') | |
| const axios = require('axios') | |
| class Copilot { | |
| constructor() { | |
| this.conversationId = null | |
| this.headers = { | |
| origin: 'https://copilot.microsoft.com', | |
| 'user-agent': 'Mozilla/5.0 (Linux; Android 15; SM-F958 Build/AP3A.240905.015) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.86 Mobile Safari/537.36' | |
| } | |
| } | |
| async createConversation() { | |
| let { data } = await axios.post('https://copilot.microsoft.com/c/api/conversations', null, { headers: this.headers }) | |
| this.conversationId = data.id | |
| return this.conversationId | |
| } | |
| async chat(message) { | |
| if (!this.conversationId) await this.createConversation() | |
| return new Promise((resolve, reject) => { | |
| const ws = new WebSocket(`wss://copilot.microsoft.com/c/api/chat?api-version=2&features=-,ncedge,edgepagecontext&setflight=-,ncedge,edgepagecontext&ncedge=1`, { headers: this.headers }) | |
| const response = { text: '', citations: [] } | |
| ws.on('open', () => { | |
| ws.send(JSON.stringify({ | |
| event: 'setOptions', | |
| supportedFeatures: ['partial-generated-images'], | |
| supportedCards: ['weather', 'local', 'image', 'sports', 'video', 'ads', 'safetyHelpline', 'quiz', 'finance', 'recipe'], | |
| ads: { supportedTypes: ['text', 'product', 'multimedia', 'tourActivity', 'propertyPromotion'] } | |
| })) | |
| ws.send(JSON.stringify({ | |
| event: 'send', | |
| mode: 'chat', | |
| conversationId: this.conversationId, | |
| content: [{ type: 'text', text: message }], | |
| context: {} | |
| })) | |
| }) | |
| ws.on('message', (chunk) => { | |
| try { | |
| const parsed = JSON.parse(chunk.toString()) | |
| switch (parsed.event) { | |
| case 'appendText': | |
| response.text += parsed.text || '' | |
| break | |
| case 'citation': | |
| response.citations.push({ title: parsed.title, icon: parsed.iconUrl, url: parsed.url }) | |
| break | |
| case 'done': | |
| resolve(response) | |
| ws.close() | |
| break | |
| case 'error': | |
| reject(new Error(parsed.message)) | |
| ws.close() | |
| break | |
| } | |
| } catch (error) { | |
| reject(error.message) | |
| } | |
| }) | |
| ws.on('error', reject) | |
| }) | |
| } | |
| } | |
| const handler = async (req, res) => { | |
| try { | |
| const { text } = req.query | |
| if (!text) { | |
| return res.status(400).json({ | |
| author: 'Herza', | |
| success: false, | |
| msg: 'Missing required parameter: text' | |
| }) | |
| } | |
| const copilot = new Copilot() | |
| const result = await copilot.chat(text) | |
| res.json({ | |
| author: 'Herza', | |
| success: true, | |
| model: 'copilot', | |
| msg: result.text.trim(), | |
| citations: result.citations | |
| }) | |
| } catch (error) { | |
| console.error('Error fetching from Copilot:', error) | |
| res.status(500).json({ | |
| author: 'Herza', | |
| success: false, | |
| msg: 'Terjadi kesalahan saat menghubungi AI.' | |
| }) | |
| } | |
| } | |
| module.exports = { | |
| name: 'Copilot AI', | |
| description: 'Generate responses using Microsoft Copilot', | |
| type: 'GET', | |
| routes: ['api/AI/copilot'], | |
| tags: ['ai', 'copilot'], | |
| parameters: ['text'], | |
| enabled: true, | |
| main: ['AI'], | |
| handler | |
| } |