I am trying to make a bot for my server on discord using Discordia, but when I try to use member:send(str), all I get is Uncaught Error: C:/luvit/deps/coro-channel.lua:62: C:/luvit/deps/discordia/libs/containers/User.lua:91: attempt to call method 'getPrivateChannel' (a nil value)
it does send the dm, but then the code breaks and the bot doesn't run anymore, how can I fix this?
member is a variable that gets the member from message
local member = message.member
I am able to recreate the issue, albeit with a different error that I suspect is due to me not having all your code to debug with.
The bot will send the DM and post a message, then crash due to error.
You have this code:
if message.content:lower() == prefix..'createdm' then
message.channel:send("<#!"..memberid.."> ".. "Sent!")
message.member:send("test") --message.member is able to inherit the send method from message.author
end
I don't know how you find memberid, so I defined it like this:
memberid = message.member:__hash()
It is called every time a message is sent, and it sends a message. This means the bot is going to call this and read its own messages. While the bot will not continue into the if statement because its message is not <prefix>createdm, it will still try to get memberid and evaluate the if statement. I do not know how bot users differ from human users in their account metadata, but I strongly suspect there is some difference and this is your issue.
I believe adding this to your code, at the beginning of your message callback (before your do anything else to evaluate a message) will fix your problem.
if message.author == client.user then
return
end
client here is whatever you assigned discordia.Client() to.
if message.content:lower() == prefix..'createdm' then
message.channel:send("<#!"..memberid.."> ".. "Sent!") -- member.id !!!
message.member:send("test") --message.member is able to inherit the send method from message.author
end
Related
Trying to get Hammerspoon to quit (kill) the Music app in OS X whenever it opens. (This application has been installed by Apple in such a way as to make it very difficult to alter and it launches whenever a bluetooth device is connected. Annoying bloatware, basically.) So, I cribbed this from the Hammerspoon "Getting started" page https://www.hammerspoon.org/go/...
function applicationWatcher(appName, eventType, appObject)
if (eventType == hs.application.watcher.launched) then
if (appName == "Music") then
hs.application:kill()
end
end
end
appWatcher = hs.application.watcher.new(applicationWatcher)
appWatcher:start()
This correctly responds to the Music app being launched, but it errors out like so... ERROR: LuaSkin: hs.application.watcher callback: /Users/seancamden/.hammerspoon/init.lua:142: method 'kill' is not callable (a nil value)
How I can make this method callable? Or, what is the right way to do this?
https://www.hammerspoon.org/docs/hs.application.watcher.html
https://www.hammerspoon.org/docs/hs.application.html#kill
your code is pretty much right, there is only one mistake. You used the global module hs.application and tried to call an object method :kill() from it. You would have to instantiate a new object first to be able to call it's kill method. For example: hs.application.get(appName):kill().
However, the watcher already provides you with the application object that called the function as appObject. So appObject:kill() is what you are looking for.
function applicationWatcher(appName, eventType, appObject)
if (eventType == hs.application.watcher.launched) then
if (appName == "Music") then
appObject:kill()
end
end
end
appWatcher = hs.application.watcher.new(applicationWatcher)
appWatcher:start()
Tested here on MacOS BigSur
I want to search the last message for a few strings and then echo the message back with those strings replaced with other strings.
I searched multiple documentations but didn't find a way to get the last message.
This is the first forum I ask as I already have an account so have no real starting point to give you.
Thanks in advance!
There is no way in the WoW API to get the last chat message of a specific channel. You will have to handle the CHAT_MSG_CHANNEL event (see Event Handling) to read all messages, and store the newest one. Specifically for the say or yell (shout) channels there are the CHAT_MSG_SAY and CHAT_MSG_YELL events respectively.
To do this your addon needs to own a Frame, these frames can register event handlers and you will have to store the last message you receive from that handler in a local variable in your script (let's call it last_message). Then when your other piece of code executes you can read the last_message variable:
local frame = CreateFrame("FRAME", "FooAddonFrame");
local last_message = nil;
frame:RegisterEvent("CHAT_MSG_CHANNEL");
local function eventHandler(self, event, ...)
-- Look up the arguments that are given to your specific event
-- and assign them to variables in order by retrieving them from
-- the `...` variable arguments
local msg, author, language, channel = ...
print("Hello World! Hello " .. event);
last_message = msg
end
frame:SetScript("OnEvent", eventHandler);
I'm using Sysdig to capture some events and have a small chisel (LUA script) to capture and format the events as necessary. On the on_init() I'm requesting fields like so :
f_field = chisel.request_field("<field>")
My question is how can I check if a field exists before requesting it? I'm going to use a new field only just released on 0.24.1 but ideally I'd like my chisel to continue to work on older versions of sysdig without this field. I've tried wrapping the call to chisel.request_field in a pcall() like so :
ok, f_field = pcall(chisel.request_field("<field>"))
and even implementing my own "get_field" function :
function get_field(field)
ok, f = pcall(chisel.request_field(field))
if ok then return f else return nil end
end
f_field = get_field("<field>")
if f_field ~= nil then
-- do something
end
but the error ("chisel requesting nonexistent field <field>") persists.
I can't see a way to check if a field exists but I can't seem to handle the error either. I really don't want multiple versions of my scripts if possible.
Thanks
Steve H
You're almost there. Your issue is in how you're using pcall. Pcall takes a function value and any arguments you wish to call that function with. In your example you're passing the result of the request_field function call to pcall. Try this instead..
ok, f = pcall(chisel.request_field, "field")
pcall will call the chisel method with your args in a protected mode and catch any subsequent errors.
Using the code:
function createNewBody(name,mass)
if not world.body[name]==nil then
print("This body has already been created. Maybe you meant to update it's values?\n")
else
world.body[name]={mass=m,x=0,y=0,xAccel=0,yAccel=0,xR=0,yR=0,properties={gaseous=false,texture=""}}
world.bodies=world.bodies+1
end
end
This code shows no errors, but when I bind createNewBody(moon,1.622) to a key and then use it, it lets me spam the key without showing the error message.
And, yes, I have defined world.bodies and world.body
not world.body[name]==nil is parsed as (not world.body[name])==nil. Since the result of not is a boolean, it is never nil.
Try not(world.body[name]==nil) or world.body[name]~=nil.
def checkdomains
#domains = Domain.all
##domains.where(:confirmed => "yes").each do |f|
#domains.each do |f|
r = Whois.whois(f.domain)
if r.available? == true
EmailNotify.notify_email(f).deliver
end
end
end
This method crashes when it comes upon an invalid url (the whois gem gives an error), and doesn't keep on checking the rest of the domains. Is there any way I can have it continue to check the rest of the domains even if it crashes on one? At least until I can sort out phising out each domain.
#domains.each do |f|
begin
r = Whois.whois(f.domain)
if r.available? == true
EmailNotify.notify_email(f).deliver
end
rescue Exception => e
puts "Error #{e}"
next # <= This is what you were looking for
end
end
When you say
crashing out
I assume you mean that you are getting an exception raised. If this is the case then just trap the exception, do what you want with it (Store the address in a bad_email table or whatever) then carry on doing what you are doing. Your log file will tell what exception is being raised so you know what your rescue statement should be
so
begin
r = Whois.whois(f.domain)
if r.available? == true
EmailNotify.notify_email(f).deliver
rescue WhateverException
#do something here like re raise the error or store the email address in a bad_emails table or do both just simply do nothing at all
end
If you are referring to something else like the whole app dying then I haven'ty got a clue and there is not enough info to advise further. Sorry
As jamesw suggests, you can wrap the statements in an exception handler, dealing with them as they occur. Let me suggest further that, wherever your program gets these (possibly invalid) domain names, you validate them as soon as you get them, and throw out the invalid ones. That way, by the time you reach this loop, you already know you're iterating over a list of good domains.
EDIT: For domain name validation, check here.