Treat Telegram references as seller signals

This commit is contained in:
jjbrunton committed 2026-08-09 17:09:41 +01:00
1 parent dc3fc6373b
commit f98c5c732d
6 files changed
+27 -2

No files matched your search

+1 -1
View File
@@ -33,7 +33,7 @@ Never document real values. `.env` is ignored and may contain production credent
- `pollIntervalMs`: legacy/scheduled polling cadence.
- `userAgent`: Reddit JSON request identifier.
- `targetGenders`: allowed parsed values.
- `filterSellers`, `sellerKeywords`, `sellerDomains`: seller policy inputs.
- `filterSellers`, `sellerKeywords`, `sellerDomains`: seller policy inputs. The defaults treat Telegram references, including `t.me` and `telegram.me` links, as seller signals alongside paid-content platforms and payment prompts.
- `prioritizeRecentPosts`, `recentWindowMinutes`: recency/fallback behavior.
- `maxReadyCandidates`: hard ceiling for the active candidate target; valid range 1–500. Runtime lowers the actual target to what authenticated running accounts can send within `recentWindowMinutes` under current rolling-hour and message-spacing limits.
+1 -1
View File
@@ -30,7 +30,7 @@ Configured subreddits have a source type:
- `image`: image-led posts are downloaded and analyzed before an opener is generated.
- `chat`: text-led posts require a parseable self-declared gender and adult age, then use the chat-opener prompt.
Seller filtering combines the candidate post with Reddit profile/about and recent activity evidence. The configured keyword/domain lists are policy inputs, not a substitute for the surrounding screening flow. A profile lookup failure is not itself proof that a person is a seller; network and rate-limit failures must remain distinguishable from a rejection.
Seller filtering combines the candidate post with Reddit profile/about and recent activity evidence. The default policy treats Telegram names and links as seller signals alongside paid-content platforms and payment prompts. The configured keyword/domain lists are policy inputs, not a substitute for the surrounding screening flow. A profile lookup failure is not itself proof that a person is a seller; network and rate-limit failures must remain distinguishable from a rejection.
The system must not manufacture personal facts. Generated messages must not claim shared location or proximity, invite an in-person meeting, invent identity/history, or ignore a conversation boundary. The final outbound safety check is intentionally separate from prompt wording.
+3
View File
@@ -66,6 +66,7 @@ export const ConfigSchema = z.object({
'cashapp',
'venmo',
'paypal',
'telegram',
'subscribe',
'premium snap',
'premiumsnap',
@@ -102,6 +103,8 @@ export const ConfigSchema = z.object({
'allmylinks.com',
'beacons.ai',
'beacons.page',
't.me',
'telegram.me',
'throne.com',
'throne.me',
'fan.ly',
+3
View File
@@ -155,6 +155,9 @@ describe('ConfigSchema', () => {
if (result.success) {
expect(result.data.reddit.sellerKeywords.length).toBeGreaterThan(0);
expect(result.data.reddit.sellerKeywords).toContain('onlyfans');
expect(result.data.reddit.sellerKeywords).toContain('telegram');
expect(result.data.reddit.sellerDomains).toContain('t.me');
expect(result.data.reddit.sellerDomains).toContain('telegram.me');
}
});
+3
View File
@@ -249,6 +249,9 @@ describe('Prompt Testing', () => {
expect(keywords).toContain('manyvids');
expect(keywords).toContain('cash.app');
expect(keywords).toContain('venmo');
expect(keywords).toContain('telegram');
expect(config.reddit.sellerDomains).toContain('t.me');
expect(config.reddit.sellerDomains).toContain('telegram.me');
});
});
});
+16
View File
@@ -304,6 +304,22 @@ describe('RedditApiClient', () => {
expect(get).not.toHaveBeenCalled();
});
it('treats a Telegram reference in the current post as a seller signal', async () => {
const get = vi.fn();
vi.mocked(axios.create).mockReturnValue({ get } as any);
const client2 = new RedditApiClient(getTestConfig(), logger);
const post = {
id: 'post-telegram', name: 't3_post-telegram', subreddit: 'test', author: 'testuser',
title: 'Message me there', selftext: 'More content on t.me/example',
url: 'https://reddit.com/post-telegram', permalink: '/r/test/post-telegram', thumbnail: '',
is_self: true, created_utc: 1, over_18: true, spoiler: false,
};
await expect(client2.isSellerProfile('testuser', ['telegram'], ['t.me', 'telegram.me'], post))
.resolves.toBe(true);
expect(get).not.toHaveBeenCalled();
});
it('detects seller signals in recent profile activity when the bio is clean', async () => {
const get = vi.fn()
.mockResolvedValueOnce({ data: { data: { subreddit: { public_description: 'Just me' } } } })