pub trait SlackHost: Send + Sync {
Show 26 methods
// Required methods
fn client(
&self,
workspace: &str,
timeout: Duration,
) -> Result<Arc<dyn SlackApi>, String>;
fn user_id(&self, workspace: &str) -> Option<String>;
fn user_name(&self, workspace: &str, user: &str) -> Option<String>;
fn set_user_name(&self, workspace: &str, user: &str, name: &str);
fn subscriptions(&self, workspace: &str) -> Vec<SlackSubscription>;
fn watermark(
&self,
workspace: &str,
conversation: &str,
) -> Result<Option<String>, String>;
fn set_watermark(&self, workspace: &str, conversation: &str, ts: &str);
fn followed_threads(
&self,
workspace: &str,
conversation: &str,
) -> Vec<SlackFollowedThread>;
fn thread_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> Result<Option<String>, String>;
fn set_thread_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
ts: &str,
);
fn mark_thread_participating(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
);
fn thread_full_read_at(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> Option<Instant>;
fn mark_thread_full_read(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
at: Instant,
);
fn thread_first_walk(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> bool;
fn clear_thread_first_walk(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
);
fn thread_edit_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> Option<String>;
fn set_thread_edit_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
ts: &str,
);
fn first_author_failure(&self, workspace: &str, user: &str) -> bool;
fn first_draft_user_failure(&self, workspace: &str, user: &str) -> bool;
fn follow_thread(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
owner: SlackThreadOwner,
since: &str,
);
fn set_connected(&self, workspace: &str, connected: bool);
fn name_conversation(&self, workspace: &str, conversation: &str, name: &str);
fn deliver(
&self,
subscription: &SlackSubscription,
messages: &[SlackMessage],
) -> bool;
fn auto_subscribe(&self, workspace: &str, message: &SlackMessage) -> bool;
fn own_post(&self, workspace: &str, conversation: &str, ts: &str) -> bool;
fn post_in_flight(
&self,
workspace: &str,
conversation: &str,
) -> Option<Duration>;
}Expand description
What the pump needs from the workspace. The connector holds no state of its own, so the subscription set, the watermarks and the liveness flag all live behind this.
Required Methods§
Sourcefn client(
&self,
workspace: &str,
timeout: Duration,
) -> Result<Arc<dyn SlackApi>, String>
fn client( &self, workspace: &str, timeout: Duration, ) -> Result<Arc<dyn SlackApi>, String>
A ready API for this workspace, or an error when the workspace is not configured. The host builds it, so the token stays with the workspace and the connector never asks for the credential itself. The trait object is what the pump drives, so a test host can hand back a double instead of a live client.
Sourcefn user_id(&self, workspace: &str) -> Option<String>
fn user_id(&self, workspace: &str) -> Option<String>
The authenticated user’s id for a workspace, resolved at boot.
Needed to recognise <@U...> mentions.
Sourcefn user_name(&self, workspace: &str, user: &str) -> Option<String>
fn user_name(&self, workspace: &str, user: &str) -> Option<String>
The display name this workspace has already resolved for a user id,
or None when it has not. A users.info lookup is a call, so the
host keeps what it has learned rather than the sweep re-asking for
every message from a known author.
Sourcefn set_user_name(&self, workspace: &str, user: &str, name: &str)
fn set_user_name(&self, workspace: &str, user: &str, name: &str)
Record a user’s display name, so the next message from them is free.
Sourcefn subscriptions(&self, workspace: &str) -> Vec<SlackSubscription>
fn subscriptions(&self, workspace: &str) -> Vec<SlackSubscription>
The subscriptions scoped to one workspace.
Sourcefn watermark(
&self,
workspace: &str,
conversation: &str,
) -> Result<Option<String>, String>
fn watermark( &self, workspace: &str, conversation: &str, ) -> Result<Option<String>, String>
The last timestamp delivered for a conversation, or None when it
has never been swept. An error means the cursor could not be read:
the caller skips the conversation rather than sweeping it from the
beginning, which would deliver its whole history as new.
Sourcefn set_watermark(&self, workspace: &str, conversation: &str, ts: &str)
fn set_watermark(&self, workspace: &str, conversation: &str, ts: &str)
Record the last timestamp delivered. A ts is a string with a
microsecond fraction; never round-trip it through a number.
Sourcefn followed_threads(
&self,
workspace: &str,
conversation: &str,
) -> Vec<SlackFollowedThread>
fn followed_threads( &self, workspace: &str, conversation: &str, ) -> Vec<SlackFollowedThread>
The threads tracked for a conversation, each with the owners still subscribed to it. The host prunes while listing: an owner whose subscription is gone is dropped from the record, a row’s last owner deletion removes the row, and a row idle past the host’s drop age never comes back.
Sourcefn thread_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> Result<Option<String>, String>
fn thread_watermark( &self, workspace: &str, conversation: &str, parent_ts: &str, ) -> Result<Option<String>, String>
How far a thread’s replies have been read: normally the newest reply seen, and nothing at all before the first walk. An error means the cursor could not be read: the caller skips the thread this tick rather than walking it from the parent.
Sourcefn set_thread_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
ts: &str,
)
fn set_thread_watermark( &self, workspace: &str, conversation: &str, parent_ts: &str, ts: &str, )
Advance a thread’s reply cursor. It is compared as a string, and the
per-tick read sends one microsecond below it as the walk’s oldest -
see just_below - so a reply at the cursor is re-read for an edit.
Sourcefn mark_thread_participating(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
)
fn mark_thread_participating( &self, workspace: &str, conversation: &str, parent_ts: &str, )
Record that the user is in a thread, so later walks read past the cursor instead of reading the thread whole to find out again.
Sourcefn thread_full_read_at(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> Option<Instant>
fn thread_full_read_at( &self, workspace: &str, conversation: &str, parent_ts: &str, ) -> Option<Instant>
When this thread was last read whole, if it ever was. The attempt is stamped whether or not the read lands, so a thread that errors or is past the page cap backs off instead of retrying every tick.
Sourcefn mark_thread_full_read(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
at: Instant,
)
fn mark_thread_full_read( &self, workspace: &str, conversation: &str, parent_ts: &str, at: Instant, )
Record a whole-thread read attempt at at.
Sourcefn thread_first_walk(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> bool
fn thread_first_walk( &self, workspace: &str, conversation: &str, parent_ts: &str, ) -> bool
Whether this thread’s next walk is its first since the row was
created. Peek, not take: a throttled or failed first walk must
keep the mark, or the replay guard is lost for the row’s life. A first
walk filters by ts alone: its seed is latest_reply, which an edit
does not move, so an edit-aware filter would hand over corrections the
previous row already had.
Sourcefn clear_thread_first_walk(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
)
fn clear_thread_first_walk( &self, workspace: &str, conversation: &str, parent_ts: &str, )
Clear the first-walk mark, once that walk has actually read the thread.
Sourcefn thread_edit_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
) -> Option<String>
fn thread_edit_watermark( &self, workspace: &str, conversation: &str, parent_ts: &str, ) -> Option<String>
The newest edit stamp a whole read has already judged. A whole read
tests edited against this, never against the reply cursor: the cheap
tick moves the cursor to the newest reply, and an edit below it would
otherwise be behind the cursor forever. Durable with the thread
row, not process state: a restart that lost it would judge every
edited reply against nothing and re-offer corrections already
delivered.
Sourcefn set_thread_edit_watermark(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
ts: &str,
)
fn set_thread_edit_watermark( &self, workspace: &str, conversation: &str, parent_ts: &str, ts: &str, )
Advance a thread’s edit watermark to ts.
Whether this is the first time an author lookup has failed for this
user. The lookup is retried either way; this only decides whether the
failure is worth a line a reader sees, since a persistent one - a
token missing users:read, a network that is down - would otherwise
report itself for every author on every tick.
Sourcefn first_draft_user_failure(&self, workspace: &str, user: &str) -> bool
fn first_draft_user_failure(&self, workspace: &str, user: &str) -> bool
The same once-per-user line for a held draft’s tag lookup. Kept apart
from Self::first_author_failure so a draft’s miss does not spend
the line the sweep relies on, and the sweep’s does not hide the draft’s.
Sourcefn follow_thread(
&self,
workspace: &str,
conversation: &str,
parent_ts: &str,
owner: SlackThreadOwner,
since: &str,
)
fn follow_thread( &self, workspace: &str, conversation: &str, parent_ts: &str, owner: SlackThreadOwner, since: &str, )
Track a thread, owned by the matching subscription. A new row’s cursor
starts at since, which the caller picks to be recent enough to
survive the idle window and below everything still worth delivering.
Tracking again by another owner adds that owner and keeps the cursor.
Sourcefn set_connected(&self, workspace: &str, connected: bool)
fn set_connected(&self, workspace: &str, connected: bool)
Liveness for the Inspector’s status line.
Sourcefn name_conversation(&self, workspace: &str, conversation: &str, name: &str)
fn name_conversation(&self, workspace: &str, conversation: &str, name: &str)
Fill in a conversation’s display name on any subscription that has none, so the Inspector can render the name rather than the raw id. Only unnamed records are touched: a conversation renamed since it was subscribed keeps the stored name.
Sourcefn deliver(
&self,
subscription: &SlackSubscription,
messages: &[SlackMessage],
) -> bool
fn deliver( &self, subscription: &SlackSubscription, messages: &[SlackMessage], ) -> bool
Hand one conversation’s matched messages to its subscriber’s
session, as the one block they will be read as. Returns whether
delivery succeeded: a false means the caller did not advance the
conversation cursor past this batch, so the next sweep re-delivers
it instead of losing it.
Sourcefn auto_subscribe(&self, workspace: &str, message: &SlackMessage) -> bool
fn auto_subscribe(&self, workspace: &str, message: &SlackMessage) -> bool
Called after a mention is delivered, so the conversation it came from is watched too and the agent can reply into it rather than only seeing the ping. Returns whether a record was added: the host does nothing when that owner already covers the conversation.
Sourcefn own_post(&self, workspace: &str, conversation: &str, ts: &str) -> bool
fn own_post(&self, workspace: &str, conversation: &str, ts: &str) -> bool
Whether forge posted this message itself, read from the outbound ledger by its ts. This is what the sweep refuses: forge posts as the user, so the author says nothing about who wrote the words.
Sourcefn post_in_flight(
&self,
workspace: &str,
conversation: &str,
) -> Option<Duration>
fn post_in_flight( &self, workspace: &str, conversation: &str, ) -> Option<Duration>
How long the oldest live post call in conversation has been in
flight, or None when none is. A message can reach history before
the post call returns and its ts is ledgered, so the sweep skips
the conversation for the tick instead of delivering its own post.
A mark older than REQUEST_TIMEOUT is the host’s to expire,
never something to obey.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".