Comments (14)
I'm not sure I understand what you're trying to do. Wouldn't that cause a loop?
from hedwig.
it wouldn't.
I really only want the bot to re-interpret the last thing I messaged him.
So if I message him "!!", he should execute any responder that matches the last message I sent him.
There is an implementation of that in hubot, I just can't find the sources yet.
from hedwig.
Shouldn't that just be a case of saving history in a separate process? Then '!!' could just query the latest history entry, and '!43' could re-apply entry #43, etc. It's probably better to feed it back to the bot internally, than take the indirect route over the chat room.
If the bot were to trigger on its own messages, it would indeed be very easy to cause a loop..
from hedwig.
@jwarlander Agreed, and that's how I tried to implement it.
I have implemented a brain, (that is a simple KV store, named process).
I have a responder that hears any command (and store the last thing he hears in the brain).
I have another responder that listens to "!!" and answers with the last heard thing.
Strangely, it does not react to the last message (sent by himself)
from hedwig.
I still didn't get it to work, but I'll post my attempts here.
Instead of making a round-trip and let the bot hear what he just said, I tried to directly ask him to interpret what was stored:
defmodule Edgar.Responder.NotNot do
use Hedwig.Responder
respond ~r/(.*)/i, msg do
case msg.matches[1] do
"!!" -> ""
_ -> Edgar.Brain.memorize(:lastmsg, msg.matches[1])
end
end
respond ~r/!!/i, msg do
remembered_msg = %{ msg | text: Edgar.Brain.remember(:lastmsg) }
pid = Hedwig.whereis("edgar")
send msg, Edgar.Robot.send(pid, remembered_msg)
end
end
getting an error:
16:58:20.481 [error] Task #PID<0.306.0> started from #PID<0.264.0> terminating
** (ArgumentError) argument error
:erlang.send(:undefined, {:"$gen_cast", {:send, %Hedwig.Message{adapter: {Hedwig.Adapters.Console, #PID<0.265.0>}, matches: %{0 => "@edgar !!"}, private: %{}, ref: #Reference<0.0.3.3237>, robot: %Hedwig.Robot{adapter: #PID<0.265.0>, aka: "@edgar", name: "Edgar Bot", opts: [robot: Edgar.Robot, otp_app: :edgar, responders: [{Hedwig.Responders.Help, []}, {Hedwig.Responders.Panzy, []}, {Hedwig.Responders.GreatSuccess, []}, {Hedwig.Responders.ShipIt, []}, {Edgar.Responder.Giphy, []}, {Edgar.Responder.NotNot, []}, {Edgar.Responder.Weather, []}, {Edgar.Responder.ItIsSomething, []}, {Edgar.Responder.OhYou, []}, {Edgar.Responder.TIL, []}, {Edgar.Responder.Bookmark, []}], adapter: Hedwig.Adapters.Console], responders: []}, room: nil, text: "it's something", type: "chat", user: "florian"}}})
(elixir) lib/gen_server.ex:639: GenServer.do_send/2
(edgar) lib/edgar/responder/NotNot.ex:26: Edgar.Responder.NotNot."__!!__"/2
(elixir) lib/task/supervised.ex:89: Task.Supervised.do_apply/2
(elixir) lib/task/supervised.ex:40: Task.Supervised.reply/5
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Function: #Function<2.28577963/0 in Hedwig.Responder.run_aysnc/2>
Args: []
Any idea how I should implement that?
from hedwig.
@docteurklein what about calling Hedwig.Robot.handle_message/2
?
https://github.com/hedwig-im/hedwig/blob/master/lib/hedwig/robot.ex#L183-L185
from hedwig.
And it looks like in your case that Hedwig.whereis("edgar")
is returning :undefined
. So it's not registered.
You should probably store the whole message in your brain process, instead of just the matches. Then you can run the whole message through Hedwig.Robot.handle_message(robot, msg)
from hedwig.
Looks like the Console
adapter doesn't register the bot...so that's why you're getting :undefined
from hedwig.
Thanks! I will try your propositions.
from hedwig.
Hedwig.Robot.handle_message(robot, msg)
is casting, so I just get :ok
as a return value.
How could I get what is sent back by the responder that matches msg
?
from hedwig.
mmh, now I get a working test with this code, but not with the console adapter:
code
respond ~r/!!/i, msg do
pid = Hedwig.whereis("Edgar Bot")
remembered = Edgar.Brain.remember(:lastmsg)
send msg, Hedwig.Robot.handle_message(pid, %{
remembered | robot: %{
remembered.robot | adapter: msg.robot.adapter
}
})
end
test (green)
@tag start_robot: true, name: "edgar", responders: [{Edgar.Responder.NotNot, []}, {Hedwig.Responders.Help, []}]
test "!! repeats last command", %{adapter: adapter, msg: msg} do
send adapter, {:message, %{msg | text: "edgar help"}}
send adapter, {:message, %{msg | text: "edgar !!"}}
assert_receive {:message, %{text: text}}
assert String.contains?(text, "help")
end
console adapter error:
00:53:02.115 [error] Task #PID<0.266.0> started from #PID<0.265.0> terminating
** (ArgumentError) invalid ANSI sequence specification: :ok
(elixir) lib/io/ansi.ex:167: IO.ANSI.format_sequence/1
(elixir) lib/io/ansi.ex:218: IO.ANSI.do_format/5
(hedwig) lib/hedwig/adapters/console.ex:109: Hedwig.Adapters.Console.Connection.print/1
(hedwig) lib/hedwig/adapters/console.ex:87: Hedwig.Adapters.Console.Connection.loop/3
(elixir) lib/task/supervised.ex:89: Task.Supervised.do_apply/2
(stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
Function: &Hedwig.Adapters.Console.Connection.loop/3
Args: [#PID<0.265.0>, "florian", "Edgar Bot"]
Not sure I'm on the good path.
Also, if you think this issue is getting nowhere, or should be discussed elsewhere, don't hesitate to tell me :)
PS: I've locally modified the console adapter to do like the test one, i.e registering itself :after_init
, so that i don't get an :undefined
pid.
from hedwig.
The bot is now registered in the console adapter under the :name
field in the config.
from hedwig.
Ok...so I"ve been able to get this all working...
Hedwig Console - press Ctrl+C to exit.
The console adapter is useful for quickly verifying how your
bot will respond based on the current installed responders
scrogson> alfred hey
alfred> sup?
scrogson> alfred !!
alfred> sup?
scrogson>
Here's the NotNot
responder:
defmodule Alfred.Responders.NotNot do
use Hedwig.Responder
respond ~r/(.*)/i, msg do
case msg.matches[1] do
"!!" -> ""
_ -> Alfred.Brain.put(:lastmsg, msg)
end
end
respond ~r/!!/i, _msg do
msg = Alfred.Brain.get(:lastmsg)
pid = Hedwig.whereis("alfred")
Hedwig.Robot.handle_message(pid, msg)
end
end
from hedwig.
Awesome! many thanks. Closing now.
from hedwig.
Related Issues (20)
- Support multiple configurations of the same adapter HOT 1
- Hedwig.whereis/1 not working HOT 2
- Can't compile responder when there are chinese characters in regular expression HOT 4
- Document return values from `handle_in/2`
- What is the recommended alternative to `ignore_from_self?` HOT 2
- how to test responders? HOT 2
- Process registration: `handle_connect` not being called? HOT 3
- Double supervision HOT 1
- Make Robot a real OTP behaviour HOT 4
- Making a tutorial / howto regarding adapters HOT 6
- A single message can trigger multiple responses HOT 6
- Crash when trying to create a secure connection HOT 3
- enter responder macro HOT 4
- hot code reload responders when in dev mode
- Use up and down arrows for history in console adapter HOT 1
- Reconnect does not work HOT 7
- `hedwig` package published on hex is out of date HOT 3
- Defining adapter-dependent actions HOT 2
- Support multiple AKA fields
- Ability to listen but not respond HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hedwig.