-
-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
302 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package connector | ||
|
||
import ( | ||
"context" | ||
|
||
"go.mau.fi/mautrix-googlechat/pkg/gchatmeow" | ||
|
||
"maunium.net/go/mautrix/bridgev2" | ||
"maunium.net/go/mautrix/bridgev2/networkid" | ||
"maunium.net/go/mautrix/bridgev2/simplevent" | ||
) | ||
|
||
type GChatClient struct { | ||
UserLogin *bridgev2.UserLogin | ||
Client *gchatmeow.Client | ||
} | ||
|
||
var ( | ||
_ bridgev2.NetworkAPI = (*GChatClient)(nil) | ||
) | ||
|
||
func (c *GChatClient) Connect(ctx context.Context) error { | ||
_, err := c.Client.LoadMessagesPage() | ||
if err != nil { | ||
return err | ||
} | ||
err = c.Client.Connect() | ||
if err != nil { | ||
return err | ||
} | ||
return c.onConnect(ctx) | ||
} | ||
|
||
func (c *GChatClient) Disconnect() { | ||
} | ||
|
||
func (c *GChatClient) GetCapabilities(ctx context.Context, portal *bridgev2.Portal) *bridgev2.NetworkRoomCapabilities { | ||
return nil | ||
} | ||
|
||
func (c *GChatClient) GetChatInfo(ctx context.Context, portal *bridgev2.Portal) (*bridgev2.ChatInfo, error) { | ||
return nil, nil | ||
} | ||
|
||
func (c *GChatClient) GetUserInfo(ctx context.Context, ghost *bridgev2.Ghost) (*bridgev2.UserInfo, error) { | ||
return nil, nil | ||
} | ||
|
||
func (c *GChatClient) IsLoggedIn() bool { | ||
return false | ||
} | ||
|
||
func (c *GChatClient) IsThisUser(ctx context.Context, userID networkid.UserID) bool { | ||
return networkid.UserID(c.UserLogin.ID) == userID | ||
} | ||
|
||
func (c *GChatClient) LogoutRemote(ctx context.Context) { | ||
} | ||
|
||
func (c *GChatClient) onConnect(ctx context.Context) error { | ||
res, err := c.Client.GetPaginatedWorlds(nil) | ||
if err != nil { | ||
return err | ||
} | ||
for _, item := range res.WorldItems { | ||
// TODO room name for DM, and full members list | ||
name := item.GetRoomName() | ||
memberMap := map[networkid.UserID]bridgev2.ChatMember{} | ||
memberMap[networkid.UserID(c.UserLogin.ID)] = bridgev2.ChatMember{ | ||
EventSender: bridgev2.EventSender{ | ||
IsFromMe: true, | ||
Sender: networkid.UserID(c.UserLogin.ID), | ||
}, | ||
} | ||
c.UserLogin.Bridge.QueueRemoteEvent(c.UserLogin, &simplevent.ChatResync{ | ||
EventMeta: simplevent.EventMeta{ | ||
Type: bridgev2.RemoteEventChatResync, | ||
PortalKey: networkid.PortalKey{ | ||
ID: networkid.PortalID(item.GroupId.String()), | ||
Receiver: c.UserLogin.ID, | ||
}, | ||
CreatePortal: true, | ||
}, | ||
ChatInfo: &bridgev2.ChatInfo{ | ||
Name: &name, | ||
Members: &bridgev2.ChatMemberList{ | ||
MemberMap: memberMap, | ||
}, | ||
}, | ||
}) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,56 @@ | ||
package connector | ||
|
||
import ( | ||
"context" | ||
|
||
"go.mau.fi/util/configupgrade" | ||
"maunium.net/go/mautrix/bridgev2" | ||
"maunium.net/go/mautrix/bridgev2/database" | ||
) | ||
|
||
type GChatConnector struct { | ||
Bridge *bridgev2.Bridge | ||
} | ||
|
||
var ( | ||
_ bridgev2.NetworkConnector = (*GChatConnector)(nil) | ||
) | ||
|
||
func (gc *GChatConnector) Init(bridge *bridgev2.Bridge) { | ||
gc.Bridge = bridge | ||
} | ||
|
||
func (gc *GChatConnector) Start(ctx context.Context) error { | ||
return nil | ||
} | ||
|
||
func (gc *GChatConnector) GetName() bridgev2.BridgeName { | ||
return bridgev2.BridgeName{ | ||
DisplayName: "Google Chat", | ||
NetworkURL: "https://chat.google.com", | ||
NetworkIcon: "mxc://maunium.net/BDIWAQcbpPGASPUUBuEGWXnQ", | ||
NetworkID: "googlechat", | ||
BeeperBridgeType: "googlechat", | ||
DefaultPort: 29320, | ||
} | ||
} | ||
|
||
func (gc *GChatConnector) GetCapabilities() *bridgev2.NetworkGeneralCapabilities { | ||
return &bridgev2.NetworkGeneralCapabilities{} | ||
} | ||
|
||
func (gc *GChatConnector) GetConfig() (example string, data any, upgrader configupgrade.Upgrader) { | ||
return "", nil, nil | ||
} | ||
|
||
func (gc *GChatConnector) GetDBMetaTypes() database.MetaTypes { | ||
return database.MetaTypes{ | ||
Portal: nil, | ||
Ghost: nil, | ||
Message: nil, | ||
Reaction: nil, | ||
UserLogin: func() any { | ||
return &UserLoginMetadata{} | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package connector | ||
|
||
import ( | ||
"context" | ||
|
||
"maunium.net/go/mautrix/bridgev2" | ||
) | ||
|
||
func (c *GChatClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage) (message *bridgev2.MatrixMessageResponse, err error) { | ||
return nil, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package connector | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"go.mau.fi/mautrix-googlechat/pkg/gchatmeow" | ||
"go.mau.fi/mautrix-googlechat/pkg/gchatmeow/cookies" | ||
"go.mau.fi/mautrix-googlechat/pkg/gchatmeow/debug" | ||
|
||
"maunium.net/go/mautrix/bridge/status" | ||
"maunium.net/go/mautrix/bridgev2" | ||
"maunium.net/go/mautrix/bridgev2/database" | ||
"maunium.net/go/mautrix/bridgev2/networkid" | ||
"maunium.net/go/mautrix/id" | ||
) | ||
|
||
const ( | ||
LoginStepIDCookies = "com.beeper.googlechat.login.cookies" | ||
LoginStepIDComplete = "com.beeper.googlechat.login.complete" | ||
) | ||
|
||
func (gc *GChatConnector) CreateLogin(ctx context.Context, user *bridgev2.User, flowID string) (bridgev2.LoginProcess, error) { | ||
return &GChatCookieLogin{User: user}, nil | ||
} | ||
|
||
func (gc *GChatConnector) GetLoginFlows() []bridgev2.LoginFlow { | ||
return []bridgev2.LoginFlow{{ | ||
Name: "Cookies", | ||
Description: "Log in with your cookies", | ||
ID: "cookies", | ||
}} | ||
} | ||
|
||
func (gc *GChatConnector) LoadUserLogin(ctx context.Context, login *bridgev2.UserLogin) error { | ||
loginMetadata := login.Metadata.(*UserLoginMetadata) | ||
var client *gchatmeow.Client | ||
clientOptions := gchatmeow.ClientOpts{ | ||
Cookies: cookies.NewCookiesFromString(loginMetadata.Cookies), | ||
} | ||
client = gchatmeow.NewClient(&clientOptions, debug.NewLogger()) | ||
c := &GChatClient{ | ||
UserLogin: login, | ||
Client: client, | ||
} | ||
login.Client = c | ||
return nil | ||
} | ||
|
||
type GChatCookieLogin struct { | ||
User *bridgev2.User | ||
} | ||
|
||
type UserLoginMetadata struct { | ||
Cookies string | ||
} | ||
|
||
var _ bridgev2.LoginProcessCookies = (*GChatCookieLogin)(nil) | ||
|
||
func (gl *GChatCookieLogin) Start(ctx context.Context) (*bridgev2.LoginStep, error) { | ||
step := &bridgev2.LoginStep{ | ||
Type: bridgev2.LoginStepTypeCookies, | ||
StepID: LoginStepIDCookies, | ||
Instructions: "Enter a JSON object with your cookies, or a cURL command copied from browser devtools.", | ||
CookiesParams: &bridgev2.LoginCookiesParams{ | ||
URL: "https://chat.google.com/", | ||
}, | ||
} | ||
return step, nil | ||
} | ||
|
||
func (gl *GChatCookieLogin) Cancel() {} | ||
|
||
func (gl *GChatCookieLogin) SubmitCookies(ctx context.Context, strCookies map[string]string) (*bridgev2.LoginStep, error) { | ||
cookies := &cookies.Cookies{} | ||
cookies.UpdateValues(strCookies) | ||
|
||
clientOptions := gchatmeow.ClientOpts{ | ||
Cookies: cookies, | ||
} | ||
client := gchatmeow.NewClient(&clientOptions, debug.NewLogger()) | ||
|
||
initialData, err := client.LoadMessagesPage() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
user := initialData.CurrentUser.Data | ||
|
||
userId := user.Id.Id | ||
ul, err := gl.User.NewLogin(ctx, &database.UserLogin{ | ||
ID: networkid.UserLoginID(userId), | ||
RemoteName: user.Fullname, | ||
RemoteProfile: status.RemoteProfile{ | ||
Name: user.Fullname, | ||
Email: user.Email, | ||
Avatar: id.ContentURIString(user.GetAvatarUrl()), | ||
}, | ||
Metadata: &UserLoginMetadata{ | ||
Cookies: cookies.String(), | ||
}, | ||
}, nil) | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("failed to save new login: %w", err) | ||
} | ||
|
||
ul.Client.Connect(ctx) | ||
c := ul.Client.(*GChatClient) | ||
c.UserLogin = ul | ||
c.Client = client | ||
|
||
return &bridgev2.LoginStep{ | ||
Type: bridgev2.LoginStepTypeComplete, | ||
StepID: LoginStepIDComplete, | ||
Instructions: fmt.Sprintf("Logged in as %s (%s)", user.Fullname, userId), | ||
CompleteParams: &bridgev2.LoginCompleteParams{ | ||
UserLoginID: ul.ID, | ||
UserLogin: ul, | ||
}, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
//lint:file-ignore U1000 ignore | ||
|
||
package gchatmeow_test | ||
|
||
import ( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.