Code Monkey home page Code Monkey logo

Comments (14)

scrogson avatar scrogson commented on September 24, 2024

I'm not sure I understand what you're trying to do. Wouldn't that cause a loop?

from hedwig.

docteurklein avatar docteurklein commented on September 24, 2024

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.

jwarlander avatar jwarlander commented on September 24, 2024

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.

docteurklein avatar docteurklein commented on September 24, 2024

@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.

docteurklein avatar docteurklein commented on September 24, 2024

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.

scrogson avatar scrogson commented on September 24, 2024

@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.

scrogson avatar scrogson commented on September 24, 2024

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.

scrogson avatar scrogson commented on September 24, 2024

Looks like the Console adapter doesn't register the bot...so that's why you're getting :undefined

from hedwig.

docteurklein avatar docteurklein commented on September 24, 2024

Thanks! I will try your propositions.

from hedwig.

docteurklein avatar docteurklein commented on September 24, 2024

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.

docteurklein avatar docteurklein commented on September 24, 2024

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.

scrogson avatar scrogson commented on September 24, 2024

The bot is now registered in the console adapter under the :name field in the config.

5f91e1d

from hedwig.

scrogson avatar scrogson commented on September 24, 2024

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.

docteurklein avatar docteurklein commented on September 24, 2024

Awesome! many thanks. Closing now.

from hedwig.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.