Skip to content

Commit 72977a2

Browse files
Feat: gmail trigger for workflows
1 parent 3b7904c commit 72977a2

File tree

15 files changed

+2162
-172
lines changed

15 files changed

+2162
-172
lines changed

api/models/TriggerDeployment.js

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
const mongoose = require('mongoose');
2+
3+
/**
4+
* Schema for storing Pipedream trigger deployment information
5+
*/
6+
const triggerDeploymentSchema = new mongoose.Schema({
7+
// User who deployed the trigger
8+
userId: {
9+
type: mongoose.Schema.Types.ObjectId,
10+
ref: 'User',
11+
required: true,
12+
index: true,
13+
},
14+
15+
// Workflow this trigger belongs to
16+
workflowId: {
17+
type: String,
18+
required: true,
19+
unique: true,
20+
index: true,
21+
},
22+
23+
// Pipedream component information
24+
componentId: {
25+
type: String,
26+
required: true,
27+
},
28+
29+
// Trigger key (e.g., 'new_email_received')
30+
triggerKey: {
31+
type: String,
32+
required: true,
33+
},
34+
35+
// App slug (e.g., 'gmail')
36+
appSlug: {
37+
type: String,
38+
required: true,
39+
},
40+
41+
// Generated webhook URL
42+
webhookUrl: {
43+
type: String,
44+
required: true,
45+
},
46+
47+
// Pipedream deployment ID
48+
deploymentId: {
49+
type: String,
50+
required: true,
51+
},
52+
53+
// Configured properties for the trigger
54+
configuredProps: {
55+
type: mongoose.Schema.Types.Mixed,
56+
default: {},
57+
},
58+
59+
// Deployment status
60+
status: {
61+
type: String,
62+
enum: ['deployed', 'active', 'paused', 'failed', 'deleted'],
63+
default: 'deployed',
64+
index: true,
65+
},
66+
67+
// Deployment timestamp
68+
deployedAt: {
69+
type: Date,
70+
default: Date.now,
71+
},
72+
73+
// Last update timestamp
74+
updatedAt: {
75+
type: Date,
76+
default: Date.now,
77+
},
78+
79+
// Error information (if deployment failed)
80+
error: {
81+
type: String,
82+
default: null,
83+
},
84+
85+
// Metadata
86+
metadata: {
87+
type: mongoose.Schema.Types.Mixed,
88+
default: {},
89+
},
90+
}, {
91+
timestamps: true,
92+
});
93+
94+
// Indexes for efficient querying
95+
triggerDeploymentSchema.index({ userId: 1, workflowId: 1 });
96+
triggerDeploymentSchema.index({ status: 1, deployedAt: 1 });
97+
triggerDeploymentSchema.index({ appSlug: 1, triggerKey: 1 });
98+
99+
const TriggerDeployment = mongoose.model('TriggerDeployment', triggerDeploymentSchema);
100+
101+
/**
102+
* Create a new trigger deployment
103+
* @param {Object} deploymentData - The deployment data
104+
* @returns {Promise<Object>} The created deployment document
105+
*/
106+
async function createTriggerDeployment(deploymentData) {
107+
try {
108+
return await TriggerDeployment.create(deploymentData);
109+
} catch (error) {
110+
throw new Error(`Error creating trigger deployment: ${error.message}`);
111+
}
112+
}
113+
114+
/**
115+
* Get trigger deployment by workflow ID
116+
* @param {string} workflowId - The workflow ID
117+
* @returns {Promise<Object|null>} The deployment document or null if not found
118+
*/
119+
async function getTriggerDeploymentByWorkflow(workflowId) {
120+
try {
121+
return await TriggerDeployment.findOne({ workflowId }).lean();
122+
} catch (error) {
123+
throw new Error(`Error fetching trigger deployment: ${error.message}`);
124+
}
125+
}
126+
127+
/**
128+
* Get trigger deployments by user
129+
* @param {string} userId - The user's ObjectId
130+
* @param {string} [status] - Optional status filter
131+
* @returns {Promise<Array>} Array of deployment documents
132+
*/
133+
async function getTriggerDeploymentsByUser(userId, status = null) {
134+
try {
135+
const query = { userId };
136+
if (status) {
137+
query.status = status;
138+
}
139+
return await TriggerDeployment.find(query).lean();
140+
} catch (error) {
141+
throw new Error(`Error fetching trigger deployments: ${error.message}`);
142+
}
143+
}
144+
145+
/**
146+
* Update trigger deployment
147+
* @param {string} workflowId - The workflow ID
148+
* @param {Object} updateData - The data to update
149+
* @returns {Promise<Object|null>} The updated deployment document or null if not found
150+
*/
151+
async function updateTriggerDeployment(workflowId, updateData) {
152+
try {
153+
return await TriggerDeployment.findOneAndUpdate(
154+
{ workflowId },
155+
{ ...updateData, updatedAt: new Date() },
156+
{ new: true }
157+
).lean();
158+
} catch (error) {
159+
throw new Error(`Error updating trigger deployment: ${error.message}`);
160+
}
161+
}
162+
163+
/**
164+
* Update trigger deployment status
165+
* @param {string} workflowId - The workflow ID
166+
* @param {string} status - The new status
167+
* @returns {Promise<Object|null>} The updated deployment document or null if not found
168+
*/
169+
async function updateTriggerDeploymentStatus(workflowId, status) {
170+
try {
171+
return await TriggerDeployment.findOneAndUpdate(
172+
{ workflowId },
173+
{ status, updatedAt: new Date() },
174+
{ new: true }
175+
).lean();
176+
} catch (error) {
177+
throw new Error(`Error updating trigger deployment status: ${error.message}`);
178+
}
179+
}
180+
181+
/**
182+
* Delete trigger deployment
183+
* @param {string} workflowId - The workflow ID
184+
* @returns {Promise<Object>} The result of the delete operation
185+
*/
186+
async function deleteTriggerDeployment(workflowId) {
187+
try {
188+
return await TriggerDeployment.deleteOne({ workflowId });
189+
} catch (error) {
190+
throw new Error(`Error deleting trigger deployment: ${error.message}`);
191+
}
192+
}
193+
194+
/**
195+
* Delete trigger deployments by user
196+
* @param {string} userId - The user's ObjectId
197+
* @returns {Promise<Object>} The result of the delete operation
198+
*/
199+
async function deleteTriggerDeploymentsByUser(userId) {
200+
try {
201+
return await TriggerDeployment.deleteMany({ userId });
202+
} catch (error) {
203+
throw new Error(`Error deleting trigger deployments: ${error.message}`);
204+
}
205+
}
206+
207+
/**
208+
* Get active trigger deployments (for health checks)
209+
* @returns {Promise<Array>} Array of active deployment documents
210+
*/
211+
async function getActiveTriggerDeployments() {
212+
try {
213+
return await TriggerDeployment.find({
214+
status: { $in: ['deployed', 'active'] }
215+
}).lean();
216+
} catch (error) {
217+
throw new Error(`Error fetching active trigger deployments: ${error.message}`);
218+
}
219+
}
220+
221+
module.exports = {
222+
TriggerDeployment,
223+
createTriggerDeployment,
224+
getTriggerDeploymentByWorkflow,
225+
getTriggerDeploymentsByUser,
226+
updateTriggerDeployment,
227+
updateTriggerDeploymentStatus,
228+
deleteTriggerDeployment,
229+
deleteTriggerDeploymentsByUser,
230+
getActiveTriggerDeployments,
231+
};

api/models/index.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ const {
4747
const UserIntegration = require('./UserIntegration');
4848
const AvailableIntegration = require('./AvailableIntegration');
4949
const AppComponents = require('./AppComponents');
50+
const {
51+
TriggerDeployment,
52+
createTriggerDeployment,
53+
getTriggerDeploymentByWorkflow,
54+
getTriggerDeploymentsByUser,
55+
updateTriggerDeployment,
56+
updateTriggerDeploymentStatus,
57+
deleteTriggerDeployment,
58+
deleteTriggerDeploymentsByUser,
59+
getActiveTriggerDeployments,
60+
} = require('./TriggerDeployment');
5061

5162
module.exports = {
5263
...methods,
@@ -101,4 +112,15 @@ module.exports = {
101112
UserIntegration,
102113
AvailableIntegration,
103114
AppComponents,
115+
116+
// Trigger deployment models
117+
TriggerDeployment,
118+
createTriggerDeployment,
119+
getTriggerDeploymentByWorkflow,
120+
getTriggerDeploymentsByUser,
121+
updateTriggerDeployment,
122+
updateTriggerDeploymentStatus,
123+
deleteTriggerDeployment,
124+
deleteTriggerDeploymentsByUser,
125+
getActiveTriggerDeployments,
104126
};

api/server/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ const startServer = async () => {
128128
app.use('/api/tags', routes.tags);
129129
app.use('/api/scheduler', routes.scheduler);
130130
app.use('/api/workflows', routes.workflows);
131+
app.use('/api/webhooks', routes.webhooks);
131132
app.use('/api/enterprise-contact', routes.enterpriseContact);
132133
app.use('/api/stripe', routes.stripe);
133134
app.use('/api/prompt-assist', routes.promptAssist);

api/server/routes/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const user = require('./user');
3030
const ask = require('./ask');
3131
const scheduler = require('./scheduler');
3232
const workflows = require('./workflows');
33+
const webhooks = require('./webhooks');
3334
const enterpriseContact = require('./enterpriseContact');
3435
const stripe = require('./stripe');
3536
const promptAssist = require('./promptAssist');
@@ -67,6 +68,7 @@ module.exports = {
6768
staticRoute,
6869
scheduler,
6970
workflows,
71+
webhooks,
7072
enterpriseContact,
7173
stripe,
7274
promptAssist,

0 commit comments

Comments
 (0)