Can I use metadata in a create action to track which request triggered it?

I’m working on a feature where a chatbot guides the user to a certain page, and once an action is performed on that page, the chatbot should be able to detect it and proceed with the next step.

To make that possible, I want to associate a request_id with the action, so I can track which request led to the creation of a particular resource. My idea was to inject this request_id into the action’s metadata and then use pub_sub to broadcast the result. That way, the chatbot can listen for events tied to its own requests.

However, based on how metadata works in a create action, it seems there’s no straightforward way to input metadata — only to set it after the resource is created. It would be really helpful if incoming metadata could be preserved.

Is there a supported way to achieve this? Or is there a better pattern to track which external context (like a chatbot session) triggered a given action?

Any thoughts or suggestions would be appreciated!

You should be able to set metadata in an after action hook, have you tried that? Or does that not make it into the notification?

Thanks! I think we might be talking about slightly different things.

Ideally, I want to be able to pass metadata in when calling the action (like arguments), and have that metadata be preserved and available later for notifications or other uses. Is that possible? For example:

defmodule MyApp.Music.Artist do
  ...
  actions do
    create :create do
      accept [:name]
      metadata :request_id, :string, allow_nil?: true
    end
  end
end

artist = MyApp.Music.create_artist!(%{name: "250", request_id: "req-1"})
"req-1" = artist.__metadata__[:request_id]

This way, the request_id is carried all the way through, and when I broadcast a notification about the created artist, I can include that request_id to correlate it with the chatbot flow.

BTW, declaring metadata like :request_id in the action doesn’t seem to affect how put_metadata/2 behaves — options like type or allow_nil? also appear to be ignored. I’m curious about the purpose of declaring metadata this way. Is it mainly for documentation, or does it serve another function?

That information is informative and is used by API extensions when you configure them to display it.

What I meant about an after action hook is that you can use an argument or context to provide the information you want retained to the action. Then you use an after action hook and Ash.Resource.set_metadata/2 etc to set it on the record. There is no direct way to set metadata when calling an action, but you can do it indirectly that way.

1 Like