Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query chat #299

Closed
OverLordGoldDragon opened this issue Dec 15, 2020 · 10 comments
Closed

Query chat #299

OverLordGoldDragon opened this issue Dec 15, 2020 · 10 comments
Labels

Comments

@OverLordGoldDragon
Copy link

I see it's a work in progress; any working code that'd let me retrieve contents of a Friends chat window? Text and user names mainly.

@rossengeorgiev
Copy link
Contributor

rossengeorgiev commented Dec 15, 2020

I have not looked at exactly the flow of messages for the new chat system, but its all in the chat protobuf.

Retrieve message history:

message CChatRoom_GetMessageHistory_Request {
optional uint64 chat_group_id = 1;
optional uint64 chat_id = 2;
optional uint32 last_time = 3;
optional uint32 last_ordinal = 4;
optional uint32 start_time = 5;
optional uint32 start_ordinal = 6;
optional uint32 max_count = 7;
}
message ServerMessage {
optional .EChatRoomServerMessage message = 1 [default = k_EChatRoomServerMsg_Invalid];
optional string string_param = 2;
optional uint32 accountid_param = 3;
}
message CChatRoom_GetMessageHistory_Response {
message ChatMessage {
optional uint32 sender = 1;
optional uint32 server_timestamp = 2;
optional string message = 3;
optional uint32 ordinal = 4;
optional .ServerMessage server_message = 5;
optional bool deleted = 6;
}
repeated .CChatRoom_GetMessageHistory_Response.ChatMessage messages = 1;
optional bool more_available = 4;
}

Members and state:

message CChatRoom_GetChatRoomGroupState_Request {
optional uint64 chat_group_id = 1;
}
message CChatRoom_GetChatRoomGroupState_Response {
optional .CChatRoomGroupState state = 1;
}

These are unified messages, and you use https://steam.readthedocs.io/en/latest/api/steam.client.html#steam.client.SteamClient.send_um or send_um_and_wait().

The RPC definitions are at the end of the file. So for example,

rpc GetChatRoomGroupState (.CChatRoom_GetChatRoomGroupState_Request) returns (.CChatRoom_GetChatRoomGroupState_Response) {
option (method_description) = "Get information about a single chat room";
}

Your code might look like:

client = SteamClient() 

# CChatRoom_GetChatRoomGroupState_Request
msg = client.send_um_and_wait("ChatRoom.GetChatRoomGroupState#1", {"chat_group_id": 12345"}) 

# CChatRoom_GetChatRoomGroupState_Response
print(msg) 

@OverLordGoldDragon
Copy link
Author

Thanks; to refine my inquiry, I seek contents of a private chat window between myself and a Friend. This is more involved as I don't presume one can retrieve such information without authentication (... I hope?); is this something steam can handle? I looked around the API a bit; a closer pointer would help.

@rossengeorgiev
Copy link
Contributor

You can get the recent messages of friends. It's a different service:

message CFriendMessages_GetRecentMessages_Request {
optional fixed64 steamid1 = 1;
optional fixed64 steamid2 = 2;
optional uint32 count = 3 [(description) = "If non-zero, cap the number of recent messages to return."];
optional bool most_recent_conversation = 4 [(description) = "Grab the block of chat from the most recent conversation (a ~5 minute period)"];
optional fixed32 rtime32_start_time = 5 [(description) = "If non-zero, return only messages with timestamps greater or equal to this. If zero, we only return messages from a recent time cutoff."];
optional bool bbcode_format = 6 [(description) = "Return the results with bbcode formatting."];
optional uint32 start_ordinal = 7 [(description) = "Combined with start time, only messages after this ordinal are returned (dedupes messages in same second)"];
optional uint32 time_last = 8 [(description) = "if present/non-zero, return only messages before this."];
optional uint32 ordinal_last = 9;
}
message CFriendMessages_GetRecentMessages_Response {
message FriendMessage {
optional uint32 accountid = 1;
optional uint32 timestamp = 2;
optional string message = 3;
optional uint32 ordinal = 4;
}
repeated .CFriendMessages_GetRecentMessages_Response.FriendMessage messages = 1 [(description) = "Array of messages, returned newest to oldest."];
optional bool more_available = 4;
}

@OverLordGoldDragon
Copy link
Author

OverLordGoldDragon commented Dec 24, 2020

Made several attempts, can't get msg != None; any suggestions? Also no error raised if I omit steamid2; not exactly sure how to handle these parameters.

from steam.client import SteamClient
from steam.steamid import SteamID

client = SteamClient()
client.cli_login()

id1_64 = 76561198066775726  # me
id2_64 = # friend with recent chat
id1 = SteamID(id1_64).id#as_32
id2 = SteamID(id1_64).id#as_32

#%%########################################
msg = client.send_um_and_wait(
    "FriendMessages.GetRecentMessages#1",
    {"steamid1": id1,
     "steamid2": id2,
     "count": 100,
     "most_recent_conversation": True},
)
print(msg)

@Gobot1234
Copy link

Gobot1234 commented Dec 31, 2020

client.send_um_and_wait("FriendMessages.GetRecentMessages#1_Request", dict(steamid1=id1_64, steamid2=id2_64, count=100))

Should work. (Although I'm on mobile and can't test)

@OverLordGoldDragon
Copy link
Author

OverLordGoldDragon commented Jan 1, 2021

@Gobot1234 ValueError: Failed to find method named: FriendMessages.GetRecentMessages#1_Request unfortunately

@Gobot1234
Copy link

Oh sorry yes change that to just what you had for that so FriendMessages.GetRecentMessages#1

@rossengeorgiev
Copy link
Contributor

Closing as it looks resolved

@OverLordGoldDragon
Copy link
Author

My Dec 24 comment remains unresolved

@rossengeorgiev
Copy link
Contributor

rossengeorgiev commented Feb 10, 2021

What's unresolved? In your code, steamid1 and steamid2 are the same, and then you are coverting them to accountid and passing that. If look at the proto file, the type is fixed64 and variables are name steamid. It's pretty clear that it's not expecting accountid.

id1 = SteamID(id1_64).id#as_32
id2 = SteamID(id1_64).id#as_32

send_um_and_wait will only return None on a timeout. That means either your login did not succeed, or you disconnected before the response, or the message you send is invalid and causes Steam to disconnect you. I can't say which, since there is no debug log, or indication what EResult was returned by cli_login()

Basic example, and it works as one would expect:

>>> msg = client.send_um_and_wait("FriendMessages.GetRecentMessages#1", {
                'steamid1': client.steam_id, 'steamid2': 7xxxxxxxxxxxxxxxxxx, 'count': 2})
>>> print(msg)
<MsgProto(<EMsg.ServiceMethodResponse: 147> | CFriendMessages_GetRecentMessages_Response)>
-------------- header --
steamid: 7xxxxxxxxxxxxxxxxxx
client_sessionid: 111111111
jobid_target: 9
target_job_name: "FriendMessages.GetRecentMessages#1"
eresult: 1
---------------- body --
messages {
  accountid: 111111
  timestamp: 1234
  message: "asdasdasdasd"
}
messages {
  accountid: 222222
  timestamp: 1235
  message: "lol"
}
more_available: true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants