forked from wotschofsky/slack-to-socials
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.ts
104 lines (91 loc) · 3.13 KB
/
main.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
import '@std/dotenv/load';
import { ConversationsHistoryResponse, WebClient } from 'npm:@slack/web-api';
import {
uniqueNamesGenerator,
adjectives,
colors,
animals,
} from 'npm:unique-names-generator';
import redis from './redis.ts';
import { postToTwitter } from './twitter.ts';
import { postToNostr } from './nostr.ts';
const slackToken = Deno.env.get('SLACK_USER_TOKEN');
const channelId = Deno.env.get('SLACK_CHANNEL_ID');
if (!slackToken || !channelId) {
throw new Error('Missing Slack token or channel ID');
}
const slackClient = new WebClient(slackToken);
async function resolveUserTags(text: string): Promise<string> {
const userTagRegex = /<@([A-Z0-9]+)>/g;
const userTags = text.match(userTagRegex) || [];
for (const tag of userTags) {
const userId = tag.match(/<@([A-Z0-9]+)>/)?.[1];
if (!userId) continue;
let userAlias = await redis.get(`user_alias:${userId}`);
if (!userAlias) {
userAlias = uniqueNamesGenerator({
dictionaries: [adjectives, colors, animals],
style: 'capital',
separator: ' ',
});
await redis.set(`user_alias:${userId}`, userAlias);
}
text = text.replace(tag, userAlias);
}
return text.replace(/\(at\)/g, '@');
}
async function pollSlackAndPost() {
async function poll() {
try {
let lastTimestamp = (await redis.get('last_timestamp')) || '0';
const result = (await slackClient.conversations.history({
channel: channelId!,
oldest: lastTimestamp,
limit: 10,
})) as ConversationsHistoryResponse;
if (result.messages && result.messages.length > 0) {
for (const message of result.messages.reverse()) {
if (
message.ts &&
parseFloat(message.ts) > parseFloat(lastTimestamp)
) {
if (
message.type === 'message' &&
message.subtype === undefined &&
message.text
) {
const resolvedText = await resolveUserTags(message.text);
const tweetResult = await postToTwitter(resolvedText);
const nostrResult = await postToNostr(resolvedText);
// Post a reply with the tweet result
await slackClient.chat.postMessage({
channel: channelId!,
thread_ts: message.ts,
text:
tweetResult.success && nostrResult.success
? `Tweet posted: ${tweetResult.message} \nNostr posted: ${nostrResult.message}`
: `Failed to post tweet: ${tweetResult.message} \n Failed to post nostr: ${nostrResult.message}`,
});
}
lastTimestamp = message.ts;
}
}
await redis.set('last_timestamp', lastTimestamp);
}
} catch (error) {
console.error('Error in poll:', error);
}
// Schedule the next poll after 5 seconds
setTimeout(poll, 5000);
}
// Start the polling loop
poll();
}
async function main() {
try {
await pollSlackAndPost();
} catch (error) {
console.error('Uncaught error in main:', error);
}
}
main().catch((error) => console.error('Error in main:', error));