3
3
import axios from 'axios'
4
4
import Snoowrap from 'snoowrap'
5
5
import { CommentStream } from 'snoostorm'
6
- import { sendNotification } from './notifications'
6
+ import { sendNotification } from '.. /notifications'
7
7
import prisma from '@/lib/db'
8
+ import { logger } from '@/lib/logger'
9
+ import { upsertJob } from './jobs'
8
10
9
11
// Initialize Reddit API client with environment variables
10
12
export const redditClient = new Snoowrap ( {
@@ -35,7 +37,7 @@ function isPrivateMessage(
35
37
*/
36
38
export async function storeMessages ( items : Array < Snoowrap . PrivateMessage | Snoowrap . Comment > ) {
37
39
const newMessages = [ ]
38
- console . debug ( `Processing ${ items . length } message(s)` )
40
+ logger . debug ( `Processing ${ items . length } message(s)` )
39
41
40
42
const subscriptions = await prisma . subscription . findMany ( )
41
43
@@ -49,7 +51,7 @@ export async function storeMessages(items: Array<Snoowrap.PrivateMessage | Snoow
49
51
} )
50
52
51
53
if ( existing ) {
52
- console . debug ( `Skipping duplicate ${ type } [${ item . name } ]` )
54
+ //logger .debug(`Skipping duplicate ${type} [${item.name}]`)
53
55
continue
54
56
}
55
57
@@ -83,10 +85,10 @@ export async function storeMessages(items: Array<Snoowrap.PrivateMessage | Snoow
83
85
)
84
86
await Promise . all ( notificationPromises )
85
87
86
- console . debug ( `Stored new ${ type } [${ createdMsg . redditId } ] from /u/${ createdMsg . author } ` )
88
+ logger . debug ( `Stored new ${ type } [${ createdMsg . redditId } ] from /u/${ createdMsg . author } ` )
87
89
newMessages . push ( createdMsg )
88
90
} catch ( error : any ) {
89
- console . error ( `Error processing message ${ item . name } :` , error . message )
91
+ logger . error ( `Error processing message ${ item . name } :` , error . message )
90
92
}
91
93
}
92
94
@@ -99,17 +101,17 @@ export async function storeMessages(items: Array<Snoowrap.PrivateMessage | Snoow
99
101
*/
100
102
export async function checkRedditMessages ( ) {
101
103
try {
102
- console . debug ( 'Fetching Reddit inbox...' )
104
+ logger . debug ( 'Fetching Reddit inbox...' )
103
105
104
106
const [ commentReplies , messages ] = await Promise . all ( [
105
107
redditClient . getInbox ( { filter : 'comments' } ) ,
106
108
redditClient . getInbox ( { filter : 'messages' } ) ,
107
109
] )
108
110
109
- console . debug ( `Found ${ commentReplies . length } comment(s), ${ messages . length } message(s)` )
111
+ logger . debug ( `Found ${ commentReplies . length } comment(s), ${ messages . length } message(s)` )
110
112
return await storeMessages ( [ ...commentReplies , ...messages ] )
111
113
} catch ( error : any ) {
112
- console . error ( 'Reddit API Error:' , error . message , error . stack )
114
+ logger . error ( 'Reddit API Error:' , error . message , error . stack )
113
115
throw new Error ( `Failed to fetch messages: ${ error . message } ` )
114
116
}
115
117
}
@@ -119,9 +121,9 @@ export async function checkRedditMessages() {
119
121
* @returns A promise that resolves to an array of unread messages.
120
122
*/
121
123
export const getUnreadMessages = async ( ) => {
122
- console . debug ( 'Fetching unread messages...' )
124
+ logger . debug ( 'Fetching unread messages...' )
123
125
const messages = await redditClient . getUnreadMessages ( { limit : 25 } )
124
- console . debug ( `Found ${ messages . length } unread message(s)` )
126
+ //logger .debug(`Found ${messages.length} unread message(s)`)
125
127
return messages
126
128
}
127
129
@@ -131,10 +133,10 @@ export const getUnreadMessages = async () => {
131
133
*/
132
134
export const markMessageRead = ( messageId : string ) => {
133
135
try {
134
- console . debug ( `Marking message ${ messageId } as read...` )
136
+ logger . debug ( `Marking message ${ messageId } as read...` )
135
137
return redditClient . getMessage ( messageId ) . markAsRead ( )
136
138
} catch ( error : any ) {
137
- console . error ( `Error marking message ${ messageId } as read:` , error . message )
139
+ logger . error ( `Error marking message ${ messageId } as read:` , error . message )
138
140
}
139
141
}
140
142
@@ -145,11 +147,11 @@ export const markMessageRead = (messageId: string) => {
145
147
*/
146
148
export const fetchRedditPosts = async ( subreddits : string [ ] ) => {
147
149
const allPosts = [ ]
148
- console . debug ( `Fetching posts from ${ subreddits . length } subreddit(s)` )
150
+ logger . debug ( `Fetching posts from ${ subreddits . length } subreddit(s)` )
149
151
150
152
for ( const subreddit of subreddits ) {
151
153
try {
152
- console . debug ( `Fetching /r/${ subreddit } ...` )
154
+ logger . debug ( `Fetching /r/${ subreddit } ...` )
153
155
const response = await axios . get ( `https://www.reddit.com/r/${ subreddit } /new.json?limit=10` , {
154
156
timeout : 5000 ,
155
157
} )
@@ -168,46 +170,61 @@ export const fetchRedditPosts = async (subreddits: string[]) => {
168
170
downvotes : child . data . downs ,
169
171
} ) )
170
172
171
- console . debug ( `Found ${ subredditPosts . length } post(s) in /r/${ subreddit } ` )
173
+ logger . debug ( `Found ${ subredditPosts . length } post(s) in /r/${ subreddit } ` )
172
174
allPosts . push ( ...subredditPosts )
173
175
} catch ( error : any ) {
174
- console . error ( `Error fetching /r/${ subreddit } :` , error . message )
176
+ logger . error ( `Error fetching /r/${ subreddit } :` , error . message )
175
177
}
176
178
}
177
179
178
180
return allPosts
179
181
}
180
182
181
183
/**
182
- * Stores an array of Reddit posts in the database, preventing duplicates
183
- * and sending notifications for new items .
184
+ * Stores an array of Reddit posts in the unified jobs table using the upsertJob function.
185
+ * This replaces the old storePosts function to use the new unified jobs architecture .
184
186
* @param posts Array of post objects from `fetchRedditPosts`.
185
- * @returns A promise that resolves to an array of newly created database records.
187
+ * @returns A promise that resolves to an array of newly created/updated job records.
186
188
*/
187
- export async function storePosts ( posts : Array < any > ) {
188
- const newPosts = [ ]
189
- console . debug ( `Processing ${ posts . length } post(s)` )
189
+ export async function storeRedditJobPosts ( posts : Array < any > ) {
190
+ const newJobs = [ ]
191
+ logger . debug ( `Processing ${ posts . length } Reddit post(s) for jobs table ` )
190
192
191
193
const subscriptions = await prisma . subscription . findMany ( )
192
194
193
195
for ( const post of posts ) {
194
196
try {
195
- const existing = await prisma . redditPost . findUnique ( {
196
- where : { url : post . url } ,
197
- } )
198
-
199
- if ( existing ) {
200
- console . debug ( `Skipping duplicate post [${ post . url } ]` )
201
- continue
197
+ const jobInput = {
198
+ title : post . title ,
199
+ company : '' , // Reddit posts don't have company info
200
+ author : post . author ,
201
+ location : '' , // Reddit posts don't have structured location
202
+ url : post . url ,
203
+ postedAt : post . postedAt ,
204
+ description : post . body || '' ,
205
+ isRemote : null , // Can't determine from Reddit posts
206
+ tags : [ post . subreddit ] , // Use subreddit as a tag
207
+ metadata : {
208
+ subreddit : post . subreddit ,
209
+ bodyHtml : post . bodyHtml || '' ,
210
+ upvotes : post . upvotes ? String ( post . upvotes ) : '0' ,
211
+ downvotes : post . downvotes ? String ( post . downvotes ) : '0' ,
212
+ } ,
213
+ source : {
214
+ name : 'reddit' ,
215
+ externalId : post . url , // Use URL as external ID since Reddit doesn't provide a better ID
216
+ rawUrl : post . url ,
217
+ data : post ,
218
+ } ,
202
219
}
203
220
204
- // This will now work correctly because the `post` object has the `postedAt` field.
205
- const createdPost = await prisma . redditPost . create ( { data : post } )
206
-
221
+ const upsertedJob = await upsertJob ( jobInput )
222
+
223
+ // Send notifications for new jobs
207
224
const notificationPayload = {
208
- title : `${ createdPost . title } (${ createdPost . subreddit } )` ,
209
- body : `Posted by /u/${ createdPost . author } ` ,
210
- url : createdPost . url ,
225
+ title : `${ post . title } (${ post . subreddit } )` ,
226
+ body : `Posted by /u/${ post . author } ` ,
227
+ url : post . url ,
211
228
icon : 'https://new.codebuilder.org/images/logo2.png' ,
212
229
badge : 'https://new.codebuilder.org/images/logo2.png' ,
213
230
}
@@ -217,12 +234,12 @@ export async function storePosts(posts: Array<any>) {
217
234
)
218
235
await Promise . all ( notificationPromises )
219
236
220
- console . debug ( `Stored new post [${ createdPost . url } ] from /u/${ createdPost . author } ` )
221
- newPosts . push ( createdPost )
237
+ logger . debug ( `Stored new job [${ post . url } ] from /u/${ post . author } ` )
238
+ newJobs . push ( upsertedJob )
222
239
} catch ( error : any ) {
223
- console . error ( `Error processing post ${ post . url } :` , error )
240
+ logger . error ( `Error processing Reddit post ${ post . url } :` , error )
224
241
}
225
242
}
226
243
227
- return newPosts
244
+ return newJobs
228
245
}
0 commit comments