Files
Basalt/examples/discordCC.lua
2022-07-25 21:35:54 +02:00

291 lines
10 KiB
Lua

local bot_id = "" -- put the bot id between the ""!
local servers = { -- setup the server/channels here, look at the example.
[""] = {
"",
},
--[[ Example:
["SERVER_ID"] = {
"CHANNEL_ID",
"CHANNEL_ID",
"CHANNEL_ID",
},
["SERVER_ID"] = {
"CHANNEL_ID",
"CHANNEL_ID",
"CHANNEL_ID",
},
]]
}
if(bot_id=="")then
error("Please setup the bot id and servers/channels first!")
end
local filePath = "basalt"
if not(fs.exists(filePath))then
shell.run("pastebin run ESs1mg7P packed true "..filePath)
end
local basalt = require(filePath) -- UI Library
local main = basalt.createFrame():setBackground(colors.lightGray)
local loginFrame = main:addFrame():setBackground(colors.lightGray)
local messageFrameList = main:addFrame():setPosition("parent.w+1", 1):setBackground(colors.black):setScrollable(true):setImportantScroll(true)
local refreshRate = 2
local messageFrames = {}
local availableGuilds = {}
local channel_id = ""
for k,v in pairs(servers)do
if(v[1]~=nil)then
channel_id = v[1]
end
break
end
local function getAllGuilds(bot)
local content = http.get("https://discord.com/api/users/@me/guilds", {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
if(content~=nil)then
return textutils.unserializeJSON(content.readAll())
end
end
local function getAllChannels(bot, guild)
local content = http.get("https://discord.com/api/guilds/"..guild.."/channels", {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
if(content~=nil)then
local t = {}
for k,v in pairs(textutils.unserializeJSON(content.readAll()))do
table.insert(t, v.position, v)
end
return t
end
end
local splitString = function(str, sep)
if sep == nil then
sep = "%s"
end
local t={}
for v in string.gmatch(str, "([^"..sep.."]+)") do
table.insert(t, v)
end
if(#t==0)then table.insert(t,str) end
return t
end
local function createText(str, width)
local uniqueLines = splitString(str, "\n")
local lines = {}
for k,v in pairs(uniqueLines)do
local line = ""
local words = splitString(v, " ")
for a,b in pairs(words)do
if(#line+#b <= width)then
line = line=="" and b or line.." "..b
if(a==#words)then table.insert(lines, line) end
else
table.insert(lines, line)
line = b:sub(1,width)
if(a==#words)then table.insert(lines, line) end
end
end
end
return lines
end
local maxOffset = 0
local autoOffset = true
local function newMessage(position, msg, username, sendTime)
local lines = createText(msg, messageFrameList:getWidth()-5)
if(messageFrames[position]==nil)then
if(messageFrames[position-1]~=nil)then
messageFrames[position] = messageFrameList:addFrame("message"..tostring(position)):setPosition(2, "message"..(position-1)..".y + message"..(position-1)..".h")
else
messageFrames[position] = messageFrameList:addFrame("message"..tostring(position)):setPosition(2, 1)
end
messageFrames[position]:addLabel("title")
messageFrames[position]:addLabel("body")
end
maxOffset = maxOffset + #lines+3
if(autoOffset)then
messageFrameList:setOffset(0, maxOffset - messageFrameList:getHeight()+1)
end
messageFrames[position]:setSize("parent.w-1", #lines+3):setBackground(colors.black)
messageFrames[position]:getObject("title"):setSize("parent.w-2", 1):setPosition(2,1):setText(username):setForeground(colors.lightGray):setBackground(colors.gray)
messageFrames[position]:getObject("body"):setSize("parent.w-2", #lines+1):setPosition(2,3):setText(msg):setForeground(colors.lightGray)
end
local function updateDiscordMessages(channel, bot)
if(channel~=nil)and(bot~=nil)then
currentMessages = {}
local content = http.get("https://discord.com/api/channels/"..channel.."/messages?limit=25", {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
if(content~=nil)then
local t = textutils.unserializeJSON(content.readAll())
local tR = {}
for i=#t, 1, -1 do
tR[#tR+1] = t[i]
end
for k,v in pairs(tR)do
newMessage(k, v.content, v.author.username, v.time)
end
end
end
end
local animations = {}
local function offsetAnimation(obj, x, y, t)
if(animations[obj:getName()]~=nil)then animations[obj:getName()]:cancel() end
animations[obj:getName()] = main:addAnimation():setAutoDestroy(true):setObject(obj):offset(x, y, t or 1):play()
end
local function positionAnimation(obj, x, y, t)
if(animations[obj:getName()]~=nil)then animations[obj:getName()]:cancel() end
animations[obj:getName()] = main:addAnimation():setAutoDestroy(true):setObject(obj):move(x, y, t or 1):play()
end
local sideBar = messageFrameList:addFrame():setPosition(-18, 1):setSize(20, "parent.h"):setZIndex(17):ignoreOffset():setScrollable(true):setImportantScroll(true)
sideBar:addButton():setText("Back"):setForeground(colors.lightGray):setBackground(colors.black):setPosition(3,2):setSize("parent.w - 4", 3):onClick(function()
offsetAnimation(main, 0, 0)
positionAnimation(sideBar, -18, 1)
end)
sideBar:addLabel():setText("Channels:"):setForeground(colors.black):setPosition(2,6)
sideBar:onClick(function(self, event)
if(event=="mouse_click")then
positionAnimation(self, 1, 1)
messageFrameList:setImportantScroll(false)
end
end)
sideBar:onLoseFocus(function()
positionAnimation(sideBar, -18, 1)
messageFrameList:setImportantScroll(true)
end)
local newTextFrame = messageFrameList:addFrame():setSize("parent.w - 4", 10):setPosition(3, 1):setZIndex(16):ignoreOffset():setBackground(colors.gray):setAnchor("bottomLeft")
local msgInfo = newTextFrame:addLabel():setText("Click here to write a message")
local messageField = newTextFrame:addTextfield():setSize("parent.w-2", "parent.h-4"):setPosition(2,3):setBackground(colors.lightGray)
newTextFrame:onClick(function(self, event)
if(event=="mouse_click")then
positionAnimation(self, 3, -8, 0.5)
messageFrameList:setImportantScroll(false)
msgInfo:setText("New Message:")
end
end)
messageFrameList:onScroll(function()
local xO, yO = messageFrameList:getOffset()
messageFrameList:getMaxScroll()
if(yO==messageFrameList:getMaxScroll())then
autoOffset = true
else
autoOffset = false
end
end)
local function messageBoxLoseFocus()
positionAnimation(newTextFrame, 3, 1, 0.5)
messageFrameList:setImportantScroll(true)
msgInfo:setText("Click here to write a message")
messageField:clear()
end
newTextFrame:addButton():setText("Cancel"):setAnchor("bottomLeft"):setBackground(colors.black):setForeground(colors.lightGray):setSize(12,1):setPosition(2,1):onClick(function()
messageBoxLoseFocus()
end)
newTextFrame:onLoseFocus(messageBoxLoseFocus)
loginFrame:addLabel():setAnchor("center"):setPosition(-2, -1):setText("Username:")
local nameInput = loginFrame:addInput():setAnchor("center"):setPosition(3,0):setBackground(colors.black):setForeground(colors.lightGray):setSize(16,1):setDefaultText("Username...", colors.gray)
local serverList = loginFrame:addList():setPosition(3, 6):setSize(16, 10)
local channelRadio = sideBar:addRadio():setForeground(colors.black):setBackground(colors.gray):setSelectedItem(colors.gray, colors.lightGray):setActiveSymbol(" ")
local channelObjects = {}
local updateChannels = basalt.shedule(function()
if(bot_id~=nil)then
for k,v in pairs(channelObjects)do
sideBar:removeObject(v)
end
channelObjects = {}
if(serverList:getValue().args~=nil)then
local y = 8
local maxScroll = 2
for k,v in pairs(servers[serverList:getValue().args[1]])do
local content = http.get("https://discord.com/api/channels/"..v, {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot_id})
local channel = textutils.unserializeJSON(content.readAll())
if(channel~=nil)then
channelRadio:addItem("#"..channel.name,1, y, nil,nil,v)
y = y + 1
maxScroll = maxScroll + 1
end
end
end
end
end)
serverList:onChange(updateChannels)
basalt.shedule(function()
if(bot_id~=nil)then
for k,v in pairs(servers)do
local content = http.get("https://discord.com/api/guilds/"..k, {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot_id})
local guild = textutils.unserializeJSON(content.readAll())
if(guild~=nil)then
serverList:addItem(guild.name,nil,nil,k)
end
end
end
end)()
updateChannels()
channelRadio:onChange(function(self)
local val = self:getValue()
if(val~=nil)and(val.args[1]~=nil)then
channel_id = val.args[1]
end
end)
loginFrame:addButton():setAnchor("bottomRight"):setPosition(-10, -2):setSize(11,3):setText("Login"):onClick(function()
offsetAnimation(main, main:getWidth(), 0)
end)
loginFrame:addLabel():setPosition(3, 5):setText("Servers:")
local function sendDiscordMessage(msg, channel, bot)
if(channel~=nil)and(bot~=nil)then
if(nameInput:getValue()~="")then
msg = string.gsub(msg, "\n", "\\n")
http.post("https://discord.com/api/channels/"..channel.."/messages", '{ "content": "['..nameInput:getValue()..']: '..msg..'" }', {["Content-Type"] = "application/json", ["Authorization"] = "Bot "..bot})
end
end
end
newTextFrame:addButton():setText("Send"):setAnchor("bottomRight"):setBackground(colors.black):setForeground(colors.lightGray):setSize(12,1):setPosition(-11,1)
:onClick(function()
local msg = table.concat(messageField:getLines(), "\n")
if(#msg>0)then
sendDiscordMessage(msg, channel_id, bot_id)
end
messageBoxLoseFocus()
end)
local function refreshMessages()
while true do
maxOffset = 0
updateDiscordMessages(channel_id, bot_id)
maxOffset = maxOffset - messageFrameList:getHeight()+1
messageFrameList:setMaxScroll(maxOffset)
sleep(refreshRate)
end
end
local thread = main:addThread():start(refreshMessages)
basalt.autoUpdate()