-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathapp.js
176 lines (150 loc) · 5.28 KB
/
app.js
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import express from "express";
import bodyParser from "body-parser";
import { Telegraf } from "telegraf";
import "dotenv/config";
import userModel from "./src/models/User.js";
import eventModel from "./src/models/Event.js";
import connectDb from "./src/config/db.js";
import { GoogleGenerativeAI } from "@google/generative-ai";
// Initialize Express and specify a port
const app = express();
const port = 3000;
// Use bodyParser middleware to parse JSON requests
app.use(bodyParser.json());
// Initialize the bot using the Telegraf library
const bot = new Telegraf(process.env.BOT_TOKEN);
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_GEN_AI_KEY);
const model = genAI.getGenerativeModel({ model: "gemini-pro" });
// Connect to the database
try {
connectDb();
console.log("db connected");
} catch (error) {
console.log("error", error);
process.kill(process.pid, "SIGTERM");
}
// Define bot start command
bot.start(async (ctx) => {
console.log("Bot starting up at:", new Date().toISOString());
const from = ctx.update.message.from;
try {
await userModel.findOneAndUpdate(
{ tgId: from.id },
{
$setOnInsert: {
firstName: from.first_name,
lastName: from.last_name,
userName: from.username,
isBot: from.is_bot,
},
},
{
upsert: true,
new: true,
}
);
await ctx.reply(`
Hey!, ${from.first_name}, Welcome. I will be writing highly engagin social media posts for you. Just keep feeding me with the events throught the day. Let's shine on social media.`);
} catch (error) {
console.log(error);
await ctx.reply("Something went wrong. Please try again later");
}
});
bot.help(async (ctx) => {
await ctx.reply(
"For support contact @rohit_ck or hmu on twitter https://twitter.com/whyrohitwhy"
);
});
bot.command("generate", async (ctx) => {
const from = ctx.update.message.from;
const { message_id: waitingmessageId } = await ctx.reply(
`Hey!, ${from.first_name}, Kindly wait for a moment. I am curating posts for you.`
);
const { message_id: loadingStickerId } = await ctx.replyWithSticker(
"CAACAgIAAxkBAANoZgf4AavMVeZYkDzPSGjpfZPjLLAAAgIBAAJWnb0KTuJsgctA5P80BA"
);
const startOfDay = new Date();
startOfDay.setHours(0, 0, 0, 0);
const endOfDay = new Date();
endOfDay.setHours(23, 59, 59, 999);
const events = await eventModel.find({
tgId: from.id,
createdAt: { $gte: startOfDay, $lte: endOfDay },
});
if (events.length === 0) {
await ctx.deleteMessage(loadingStickerId);
await ctx.deleteMessage(waitingmessageId);
await ctx.reply("No events found. Please try again later");
return;
}
try {
const prompt = `Act as a senior copywriter, you write highly engaging posts for linkedin, facebook and twitter using provided thoughts/events throughout the day.
Write like a human, for humans. Craft three engaging social media posts tailored for linkedin, Facebook, and twitter audiences. Use simple language. Use given time labels just to understand the order of events, don't mention the time in posts. Each posts should creatively highlight the following events. Ensure the tone is conversational and impactful. Use relevant emojis if possible. Focus on engaging the respective platform's audience, encouraging interaction, and driving interest in the events:
${events.map((event) => event.text).join("\n")}
,
Use all of the above events, not just top 3 events and create 3 seperate posts for linkedin, twitter and facebook, where all 3 posts should contain data of all the events above mentioned.
`;
const result = await model.generateContent(prompt);
const response = await result.response;
const text = response.text();
//store token count in user model
await userModel.findOneAndUpdate(
{ tgId: from.id },
{
$inc: {
promptTokens: 1,
completionTokens: 1,
},
}
);
await ctx.deleteMessage(loadingStickerId);
await ctx.deleteMessage(waitingmessageId);
await ctx.replyWithHTML(text);
} catch (error) {
console.log(error);
await ctx.reply("Something went wrong. Please try again later");
}
// send response
});
// bot.on("sticker", async (ctx) => {
// const from = ctx.update.message.from;
// console.log("sticker", ctx.update.message);
// await ctx.reply("Stickers are not supported");
// });
bot.on("text", async (ctx) => {
const from = ctx.update.message.from;
const message = ctx.update.message.text;
try {
await eventModel.create({
text: message,
tgId: from.id,
});
await ctx.reply(
"Noted, Keep texting me your thoughts. To generate the posts, just enter the command: /generate"
);
} catch (error) {
console.log(error);
await ctx.reply("Something went wrong. Please try again later");
}
});
// Set the bot to use webhook instead of polling
bot.telegram.setWebhook(
`${process.env.WEBHOOK_URL}/bot${process.env.BOT_TOKEN}`
);
// Define the route to handle webhook requests
app.post(`/bot${process.env.BOT_TOKEN}`, (req, res) => {
bot.handleUpdate(req.body, res);
});
// Start the Express server
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
// Shutdown function for graceful shutdown
const shutdown = async () => {
console.log("Shutting down bot...");
await bot.stop("SIGTERM received");
process.exit(0);
};
// Handle shutdown signals
process.on("SIGTERM", shutdown);
process.on("SIGINT", shutdown);