-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
123 lines (104 loc) · 2.74 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { spawn } from "child_process";
import * as readline from "readline";
import { generateText } from "ai";
import { createOpenAI } from "@ai-sdk/openai";
import dotenv from "dotenv";
import { Langfuse } from "langfuse";
dotenv.config();
const openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });
const langfuse = new Langfuse({
secretKey: process.env.LANGFUSE_SECRET_KEY,
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
baseUrl: process.env.LANGFUSE_BASE_URL,
});
interface JsonRpcRequest {
jsonrpc: string;
method: string;
id: string;
params?: any;
}
interface SignalMessageEnvelope {
source: string;
sourceNumber: string;
sourceUuid: string;
sourceName: string;
sourceDevice: number;
timestamp: number;
dataMessage?: {
timestamp: number;
message: string;
expiresInSeconds: number;
viewOnce: boolean;
mentions: any[];
attachments: any[];
contacts: any[];
};
}
interface SignalMessage {
jsonrpc: string;
method: string;
params: {
envelope: SignalMessageEnvelope;
};
}
const signalCli = spawn(process.env.SIGNAL_CLI_PATH!, [
"-a",
process.env.SIGNAL_CLI_ACCOUNT!,
"jsonRpc",
]);
const rl = readline.createInterface({ input: signalCli.stdout });
signalCli.stderr.on("data", (data) => {
console.error(`stderr: ${data}`);
});
signalCli.on("close", (code) => {
console.log(`child process exited with code ${code}`);
});
rl.on("line", (line) => {
try {
const message: SignalMessage = JSON.parse(line);
if (message.method === "receive") {
handleIncomingMessage(message.params.envelope);
}
} catch (err) {
console.error("Failed to parse message:", err);
}
});
async function handleIncomingMessage(envelope: SignalMessageEnvelope) {
const { source, dataMessage, sourceName } = envelope;
if (!dataMessage) {
console.warn(
`Received a message from ${source} without dataMessage. Skipping.`
);
return;
}
const { message } = dataMessage;
console.log(`Received message from ${source}: ${message}`);
const { text } = await generateText({
model: openai("gpt-4o"),
prompt: `You're a helpful assistant communicating over text message. Use plain text and be brief. <start_user_message> ${message} <end_user_message>`,
});
langfuse.trace({
name: "generated text",
userId: source,
input: {
input: message,
},
metadata: {
name: sourceName,
},
output: text,
});
langfuse.flushAsync().catch((error) => {
console.error("Langfuse flushAsync error:", error);
});
const echoMessage: JsonRpcRequest = {
jsonrpc: "2.0",
method: "send",
id: "echo-message",
params: {
recipient: [source],
message: text,
},
};
signalCli.stdin.write(JSON.stringify(echoMessage) + "\n");
}