Add provisioning API for using group invite links

This commit is contained in:
Tulir Asokan 2023-05-06 16:36:31 +03:00
parent eb5f28355f
commit a97f9765bc

View file

@ -68,6 +68,9 @@ func (prov *ProvisioningAPI) Init() {
r.HandleFunc("/v1/bulk_resolve_identifier", prov.BulkResolveIdentifier).Methods(http.MethodPost) r.HandleFunc("/v1/bulk_resolve_identifier", prov.BulkResolveIdentifier).Methods(http.MethodPost)
r.HandleFunc("/v1/pm/{number}", prov.StartPM).Methods(http.MethodPost) r.HandleFunc("/v1/pm/{number}", prov.StartPM).Methods(http.MethodPost)
r.HandleFunc("/v1/open/{groupID}", prov.OpenGroup).Methods(http.MethodPost) r.HandleFunc("/v1/open/{groupID}", prov.OpenGroup).Methods(http.MethodPost)
r.HandleFunc("/v1/group/open/{groupID}", prov.OpenGroup).Methods(http.MethodPost)
r.HandleFunc("/v1/group/resolve/{inviteCode}", prov.ResolveGroupInvite).Methods(http.MethodPost)
r.HandleFunc("/v1/group/join/{inviteCode}", prov.JoinGroup).Methods(http.MethodPost)
prov.bridge.AS.Router.HandleFunc("/_matrix/app/com.beeper.asmux/ping", prov.BridgeStatePing).Methods(http.MethodPost) prov.bridge.AS.Router.HandleFunc("/_matrix/app/com.beeper.asmux/ping", prov.BridgeStatePing).Methods(http.MethodPost)
prov.bridge.AS.Router.HandleFunc("/_matrix/app/com.beeper.bridge_state", prov.BridgeStatePing).Methods(http.MethodPost) prov.bridge.AS.Router.HandleFunc("/_matrix/app/com.beeper.bridge_state", prov.BridgeStatePing).Methods(http.MethodPost)
@ -503,6 +506,81 @@ func (prov *ProvisioningAPI) OpenGroup(w http.ResponseWriter, r *http.Request) {
} }
} }
func (prov *ProvisioningAPI) resolveGroupInvite(w http.ResponseWriter, r *http.Request) (*types.GroupInfo, *User) {
inviteCode, _ := mux.Vars(r)["inviteCode"]
if user := r.Context().Value("user").(*User); !user.IsLoggedIn() {
jsonResponse(w, http.StatusBadRequest, Error{
Error: "User is not logged into WhatsApp",
ErrCode: "no session",
})
} else if info, err := user.Client.GetGroupInfoFromLink(inviteCode); err != nil {
if errors.Is(err, whatsmeow.ErrInviteLinkRevoked) {
jsonResponse(w, http.StatusBadRequest, Error{
Error: whatsmeow.ErrInviteLinkRevoked.Error(),
ErrCode: "invite link revoked",
})
} else if errors.Is(err, whatsmeow.ErrInviteLinkInvalid) {
jsonResponse(w, http.StatusBadRequest, Error{
Error: whatsmeow.ErrInviteLinkInvalid.Error(),
ErrCode: "invalid invite link",
})
} else {
jsonResponse(w, http.StatusInternalServerError, Error{
Error: fmt.Sprintf("Failed to fetch group info with link: %v", err),
ErrCode: "error getting group info",
})
}
} else {
return info, user
}
return nil, nil
}
func (prov *ProvisioningAPI) ResolveGroupInvite(w http.ResponseWriter, r *http.Request) {
info, user := prov.resolveGroupInvite(w, r)
if info == nil {
return
}
jsonResponse(w, http.StatusOK, PortalInfo{
RoomID: user.GetPortalByJID(info.JID).MXID,
GroupInfo: info,
})
}
func (prov *ProvisioningAPI) JoinGroup(w http.ResponseWriter, r *http.Request) {
info, user := prov.resolveGroupInvite(w, r)
if info == nil {
return
}
inviteCode, _ := mux.Vars(r)["inviteCode"]
if jid, err := user.Client.JoinGroupWithLink(inviteCode); err != nil {
jsonResponse(w, http.StatusInternalServerError, Error{
Error: fmt.Sprintf("Failed to join group: %v", err),
ErrCode: "error joining group",
})
} else {
prov.log.Debugln(user.MXID, "successfully joined group", jid)
portal := user.GetPortalByJID(jid)
status := http.StatusOK
if len(portal.MXID) == 0 {
time.Sleep(500 * time.Millisecond) // Wait for incoming group info to create the portal automatically
err = portal.CreateMatrixRoom(user, info, true, true)
if err != nil {
jsonResponse(w, http.StatusInternalServerError, Error{
Error: fmt.Sprintf("Failed to create portal: %v", err),
})
return
}
status = http.StatusCreated
}
jsonResponse(w, status, PortalInfo{
RoomID: portal.MXID,
GroupInfo: info,
JustCreated: status == http.StatusCreated,
})
}
}
func (prov *ProvisioningAPI) Ping(w http.ResponseWriter, r *http.Request) { func (prov *ProvisioningAPI) Ping(w http.ResponseWriter, r *http.Request) {
user := r.Context().Value("user").(*User) user := r.Context().Value("user").(*User)
wa := map[string]interface{}{ wa := map[string]interface{}{