Skip to main content

SessionConfig

Struct SessionConfig 

Source
pub struct SessionConfig { /* private fields */ }
Expand description

One Grok Bot web session, ready to register. Built from the host environment (SessionConfig::from_env) or from the same fields the host would have injected. The nick is nick_from_display_name of bot_name. Local grok CLI sessions do not use this type.

Implementations§

Source§

impl SessionConfig

Source

pub fn new( homeserver_url: impl Into<String>, bot_name: &str, session_id: impl Into<String>, store_root: impl Into<PathBuf>, device_token: Option<String>, ) -> Result<Self, ShellError>

bot_name is the display name (Alice, Привет мир), not a nick.

Examples found in repository?
examples/wake_test_sender.rs (lines 40-46)
29fn main() {
30    let homeserver = std::env::var("M4A_HOMESERVER_URL")
31        .unwrap_or_else(|_| fail("env", "M4A_HOMESERVER_URL is not set"));
32    let target = std::env::var("M4A_TEST_TARGET").unwrap_or_else(|_| "alice".to_string());
33    let wait_secs: u64 = std::env::var("M4A_TEST_WAIT_SECS")
34        .ok()
35        .and_then(|value| value.parse().ok())
36        .unwrap_or(90);
37    let stamp = now_ms() / 1000;
38    let session_id = format!("wake-test-sender-{stamp}");
39    let store_root = std::env::temp_dir().join(format!("m4a-wake-test-{stamp}"));
40    let config = SessionConfig::new(
41        &homeserver,
42        "WakeTestSender",
43        &session_id,
44        &store_root,
45        None,
46    )
47    .unwrap_or_else(|err| fail("config", err));
48    let mut store = OpenedStore::connect(&config).unwrap_or_else(|err| fail("register", err));
49    println!("registered nick={} session={session_id}", config.nick());
50    let room_id = store
51        .ensure_dm(&target, now_ms())
52        .unwrap_or_else(|err| fail("ensure_dm", err));
53    println!("dm room={room_id}");
54    let started = Instant::now();
55    let peer = store
56        .find_nick(&target, now_ms())
57        .unwrap_or_else(|err| fail("find_nick", err))
58        .user_id;
59    loop {
60        if store.member_joined(&room_id, &peer) {
61            break;
62        }
63        if started.elapsed().as_secs() >= wait_secs {
64            fail(
65                "join wait",
66                format!("{target} did not join in {wait_secs}s"),
67            );
68        }
69        store
70            .drive(now_ms(), false)
71            .unwrap_or_else(|err| fail("drive", err));
72        std::thread::sleep(Duration::from_millis(500));
73    }
74    println!("peer joined user={peer}");
75    let encrypted = store
76        .rooms()
77        .into_iter()
78        .any(|room| room.room_id == room_id && room.encrypted);
79    println!("room encrypted={encrypted}");
80    let text = format!("wake test {stamp}");
81    store
82        .write_to_nick(&target, &text, now_ms())
83        .unwrap_or_else(|err| fail("write_to_nick", err));
84    let event_id = store
85        .texts()
86        .into_iter()
87        .find(|row| row.room_id == room_id && row.body == text)
88        .and_then(|row| row.event_id)
89        .unwrap_or_default();
90    println!("sent event={event_id}");
91}
Source

pub fn new_product( product_url: impl Into<String>, nick: &str, secret: ProductSecret, session_id: impl Into<String>, store_root: impl Into<PathBuf>, ) -> Result<Self, ShellError>

Product-session mode: log in at the product server product_url as nick and talk to the messenger only through its proxy. The nick is the product nick; the session id still names the local store.

Source

pub fn from_env() -> Result<Self, ShellError>

Host environment for a Grok Bot web session.

Required: HOMESERVER_URL_ENV or homeserver_url in toml, BOT_NAME_ENV (display name), SESSION_ID_ENV, STORE_ROOT_ENV. Optional: DEVICE_TOKEN_ENV. M4A_NICK, ROUTINE_URL_ENV, and LEADER_SOCK_ENV are not read. Wake is chosen by the open path.

Source

pub fn is_product(&self) -> bool

True in product-session mode.

Source

pub fn nick(&self) -> &str

Derived nick. Not the display name.

Examples found in repository?
examples/wake_test_sender.rs (line 49)
29fn main() {
30    let homeserver = std::env::var("M4A_HOMESERVER_URL")
31        .unwrap_or_else(|_| fail("env", "M4A_HOMESERVER_URL is not set"));
32    let target = std::env::var("M4A_TEST_TARGET").unwrap_or_else(|_| "alice".to_string());
33    let wait_secs: u64 = std::env::var("M4A_TEST_WAIT_SECS")
34        .ok()
35        .and_then(|value| value.parse().ok())
36        .unwrap_or(90);
37    let stamp = now_ms() / 1000;
38    let session_id = format!("wake-test-sender-{stamp}");
39    let store_root = std::env::temp_dir().join(format!("m4a-wake-test-{stamp}"));
40    let config = SessionConfig::new(
41        &homeserver,
42        "WakeTestSender",
43        &session_id,
44        &store_root,
45        None,
46    )
47    .unwrap_or_else(|err| fail("config", err));
48    let mut store = OpenedStore::connect(&config).unwrap_or_else(|err| fail("register", err));
49    println!("registered nick={} session={session_id}", config.nick());
50    let room_id = store
51        .ensure_dm(&target, now_ms())
52        .unwrap_or_else(|err| fail("ensure_dm", err));
53    println!("dm room={room_id}");
54    let started = Instant::now();
55    let peer = store
56        .find_nick(&target, now_ms())
57        .unwrap_or_else(|err| fail("find_nick", err))
58        .user_id;
59    loop {
60        if store.member_joined(&room_id, &peer) {
61            break;
62        }
63        if started.elapsed().as_secs() >= wait_secs {
64            fail(
65                "join wait",
66                format!("{target} did not join in {wait_secs}s"),
67            );
68        }
69        store
70            .drive(now_ms(), false)
71            .unwrap_or_else(|err| fail("drive", err));
72        std::thread::sleep(Duration::from_millis(500));
73    }
74    println!("peer joined user={peer}");
75    let encrypted = store
76        .rooms()
77        .into_iter()
78        .any(|room| room.room_id == room_id && room.encrypted);
79    println!("room encrypted={encrypted}");
80    let text = format!("wake test {stamp}");
81    store
82        .write_to_nick(&target, &text, now_ms())
83        .unwrap_or_else(|err| fail("write_to_nick", err));
84    let event_id = store
85        .texts()
86        .into_iter()
87        .find(|row| row.room_id == room_id && row.body == text)
88        .and_then(|row| row.event_id)
89        .unwrap_or_default();
90    println!("sent event={event_id}");
91}
Source

pub fn homeserver_url(&self) -> &str

Homeserver origin this session will register against.

Source

pub fn store_dir(&self) -> PathBuf

session_store_dir for this session under the configured root.

Source

pub fn session_id(&self) -> &str

Session id the host assigned. Not a secret.

Trait Implementations§

Source§

impl Debug for SessionConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more