lunarflu's picture
lunarflu HF staff
go live, 6 hour ping for testing
f0e4eac verified
raw
history blame
7.54 kB
import discord
import threading
import os
import gradio as gr
from discord.ext import commands
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
import aiojobs
import asyncio
from datetime import datetime, timedelta
from apscheduler.executors.pool import ThreadPoolExecutor
from apscheduler.schedulers.background import BackgroundScheduler
DISCORD_TOKEN = os.getenv('DISCORD_TOKEN')
SLACK_BOT_TOKEN = os.getenv('BOT_USER_OAUTH_TOKEN_HF')
# real = os.getenv('SLACK_CHANNEL_ID_HF')
# test = 'C07B4KNU5BQ'
SLACK_CHANNEL_ID = os.getenv('SLACK_CHANNEL_ID_HF')
SLACK_CHANNEL_ID_TEST = 'C07B4KNU5BQ'
# 1259415803879751700 = test forum
# 1019883044724822016 = ask for help
ASK_FOR_HELP_CHANNEL_ID = 1019883044724822016
GRADIO_CHANNEL_ID = 1025174734427656283
TRIGGERS = {
("discord bot",): "<@U051DB2754M>", # adam
("autotrain",): "<@U01E3LEC2N7>", # abhishek
("auto train",): "<@U01E3LEC2N7>", # abhishek
("competition",): "<@U01E3LEC2N7>", # abhishek
("competitions",): "<@U01E3LEC2N7>", # abhishek
("sentence-transformers",): "<@U04E4DNPWG7>", # tom aarsen
("sentence_transformers",): "<@U04E4DNPWG7>", # tom aarsen
("setfit",): "<@U04E4DNPWG7>", # tom aarsen
("sentence transformers",): "<@U04E4DNPWG7>", # tom aarsen
("argilla",): "<@U076B8C7G3E>", # david berenstein
("distilabel",): "<@U076B8C7G3E>", # david berenstein
("argilla",): "<@U0766H30T7F>", # natalia elvira
("dataset",): "<@U0766H30T7F>", # natalia elvira
("docs",): "<@U02DATT4C5B>", # steven liu
("documentation",): "<@U02DATT4C5B>", # steven liu
("gradio",): "<@U02NMK75F1V>", # abubakar abid
("argilla",): "<@U076MF65WEM>", # sara han diaz lorenzo
("distilabel",): "<@U076MF65WEM>", # sara han diaz lorenzo
("argilla",): "<@U0765RENPNZ>", # sara han diaz lorenzo
("distilabel",): "<@U0765RENPNZ>", # sara han diaz lorenzo
("dataset", "feedback"): "<@U0768RCHCRY>", # ben burtenshaw
}
daily_pings = []
intents = discord.Intents.all()
intents.messages = True
bot = commands.Bot(command_prefix='!', intents=intents)
slack_client = WebClient(token=SLACK_BOT_TOKEN)
thread_mapping = {}
@bot.event
async def on_ready():
print(f'Logged in as {bot.user}')
@bot.event
async def on_message(message):
if message.author == bot.user:
return
# notification bot
print("on_message")
huggingfolks_role = discord.utils.get(message.guild.roles, id=897376942817419265)
bots_role = discord.utils.get(message.guild.roles, id=1258328471609016341)
if huggingfolks_role not in message.author.roles: # no need for ping if we're already discussing
if bots_role not in message.author.roles: # bots shouldn't trigger pings for this
print(" not bot ")
content = message.content.lower()
for trigger, slack_mention in TRIGGERS.items():
if all(word in content for word in trigger):
daily_pings.append({
'author': str(message.author),
'content': message.content,
'channel': message.channel.name,
'url': message.jump_url,
'mention': slack_mention,
'trigger': trigger
})
print(f"daily pings:{daily_pings}")
break
# Check if the message is in a thread
if isinstance(message.channel, discord.Thread):
discord_thread_id = message.channel.id
# Check if there's an existing Slack thread for this Discord thread
# (the only Slack threads created should be for forum channel threads, not just any thread)
if discord_thread_id in thread_mapping:
slack_thread_ts = thread_mapping[discord_thread_id]
# post to slack only if thread already exists
post_to_slack_forum_version(message, SLACK_CHANNEL_ID, message.content, message.author, thread_ts=slack_thread_ts)
@bot.event
async def on_thread_create(thread):
# (discord) must be the child thread of the CORRECT forum channel(s) (not just any thread, or any forum channel)
if isinstance(thread.parent, discord.ForumChannel) and thread.parent.id in {ASK_FOR_HELP_CHANNEL_ID, GRADIO_CHANNEL_ID}:
discord_thread_id = thread.id
slack_thread_ts = post_to_slack_create_thread(
SLACK_CHANNEL_ID,
f"New forum thread started in {thread.parent.name} by {thread.owner}: *{thread.name}*\n"
f"{thread.jump_url}"
)
if slack_thread_ts:
thread_mapping[discord_thread_id] = slack_thread_ts
def post_to_slack_forum_version(message, channel, text, author, thread_ts=None):
if message.attachments:
for attachment in message.attachments:
attachment_url = attachment.url
text += f"\nAttachment: {attachment_url}"
text = f"{author}" + ": " + text
try:
response = slack_client.chat_postMessage(
channel=channel,
text=text,
thread_ts=thread_ts
)
return response['ts'] # Return the Slack message timestamp (thread ID)
except SlackApiError as e:
print(f"Error posting to Slack: {e.response['error']}")
return None
def post_to_slack_create_thread(channel, text, thread_ts=None):
try:
response = slack_client.chat_postMessage(
channel=channel,
text=text,
thread_ts=thread_ts
)
return response['ts'] # Return the Slack message timestamp (thread ID)
except SlackApiError as e:
print(f"Error posting to Slack: {e.response['error']}")
return None
#----------------------------------------------------------------------------------------------
def send_daily_pings():
global daily_pings
if daily_pings:
print("sending daily pings...")
# combine into one message
combined_message = '\n'.join(f"{ping['mention']} (for the keyword -> '{ping['trigger']}')\nFrom {ping['author']} in channel #{ping['channel']}: {ping['content']}\n{ping['url']}" for ping in daily_pings)
#await post_to_slack(None, combined_message, SLACK_CHANNEL_ID_TEST, None, None, None)
response = slack_client.chat_postMessage(
channel=SLACK_CHANNEL_ID,
text=combined_message,
unfurl_links=False,
unfurl_media=False
)
daily_pings = [] # reset after posting
# pings -------------------------------------------------------------------------------------------
async def post_to_slack(author, content, channel, url, slack_mention, trigger):
try:
response = slack_client.chat_postMessage(
channel=SLACK_CHANNEL_ID,
text=f"{slack_mention} (for the keyword -> '{trigger}')\nFrom {author} in channel #{channel}: {content}\n{url}"
)
except SlackApiError as e:
print(f"Error posting to Slack: {e.response['error']}")
executor = ThreadPoolExecutor(max_workers=1)
scheduler = BackgroundScheduler(executors={'default': executor})
scheduler.add_job(send_daily_pings, trigger='interval', hours=6)
scheduler.start()
# runs discord bot in thread = helps avoid blocking calls
def run_bot():
bot.run(DISCORD_TOKEN)
threading.Thread(target=run_bot).start()
def greet(name):
return "Hello " + name + "!"
demo = gr.Interface(fn=greet, inputs="text", outputs="text")
demo.launch()