mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-05 04:07:07 +00:00
Merge branch 'master' into muc
This commit is contained in:
commit
cd71818577
8 changed files with 135 additions and 11 deletions
|
|
@ -68,7 +68,7 @@ func main() {
|
||||||
|
|
||||||
log.Infof("Starting telegabber version %v", version)
|
log.Infof("Starting telegabber version %v", version)
|
||||||
|
|
||||||
sm, component, err = xmpp.NewComponent(config.XMPP, config.Telegram, *idsPath)
|
sm, component, err = xmpp.NewComponent(config.XMPP, config.Telegram, *idsPath, version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ var transportCommands = map[string]command{
|
||||||
"help": command{0, []string{}, "help", false, nil},
|
"help": command{0, []string{}, "help", false, nil},
|
||||||
"login": command{1, []string{"phone"}, "sign in", false, nil},
|
"login": command{1, []string{"phone"}, "sign in", false, nil},
|
||||||
"logout": command{0, []string{}, "sign out", true, nil},
|
"logout": command{0, []string{}, "sign out", true, nil},
|
||||||
|
"cleanup": command{0, []string{}, "unsubscribe from all known chats", false, nil},
|
||||||
"cancelauth": command{0, []string{}, "quit the signin wizard", false, nil},
|
"cancelauth": command{0, []string{}, "quit the signin wizard", false, nil},
|
||||||
"code": command{1, []string{"xxxxx"}, "check one-time code", false, nil},
|
"code": command{1, []string{"xxxxx"}, "check one-time code", false, nil},
|
||||||
"password": command{1, []string{"********"}, "check 2fa password", false, nil},
|
"password": command{1, []string{"********"}, "check 2fa password", false, nil},
|
||||||
|
|
@ -358,13 +359,14 @@ func (c *Client) ProcessTransportCommand(cmdline string, resource string) (strin
|
||||||
return errors.Wrap(err, "Logout error").Error(), false
|
return errors.Wrap(err, "Logout error").Error(), false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, id := range c.cache.OwnChatsKeys() {
|
c.unsubscribeFromAll()
|
||||||
c.leaveChat(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Session.Login = ""
|
c.Session.Login = ""
|
||||||
c.wizardStageOrPrompt(LoginStageCancel, "")
|
c.wizardStageOrPrompt(LoginStageCancel, "")
|
||||||
c.online = false
|
c.online = false
|
||||||
|
// cleanup
|
||||||
|
case "cleanup":
|
||||||
|
c.unsubscribeFromAll()
|
||||||
// cancel auth
|
// cancel auth
|
||||||
case "cancelauth":
|
case "cancelauth":
|
||||||
if c.Online() {
|
if c.Online() {
|
||||||
|
|
@ -687,11 +689,7 @@ func (c *Client) ProcessChatCommand(chatID int64, cmdline string) (string, bool,
|
||||||
state = &client.MessageSchedulingStateSendWhenOnline{}
|
state = &client.MessageSchedulingStateSendWhenOnline{}
|
||||||
result = due
|
result = due
|
||||||
} else {
|
} else {
|
||||||
if c.Session.Timezone == "" {
|
due += c.GetTZD()
|
||||||
due += "Z"
|
|
||||||
} else {
|
|
||||||
due += c.Session.Timezone
|
|
||||||
}
|
|
||||||
|
|
||||||
switch 0 {
|
switch 0 {
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -155,11 +155,13 @@ func (c *Client) Connect(resource string) error {
|
||||||
c.addResource(resource)
|
c.addResource(resource)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
_, err = c.client.GetChats(&client.GetChatsRequest{
|
chats, err := c.client.GetChats(&client.GetChatsRequest{
|
||||||
Limit: chatsLimit,
|
Limit: chatsLimit,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Could not retrieve chats: %v", err)
|
log.Errorf("Could not retrieve chats: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Infof("Obtained ≈%v chats for initialization", chats.TotalCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
gateway.SubscribeToTransport(c.xmpp, c.jid)
|
gateway.SubscribeToTransport(c.xmpp, c.jid)
|
||||||
|
|
|
||||||
|
|
@ -2948,6 +2948,13 @@ func (c *Client) sendMessagesReverse(chatID int64, messages []*client.Message, p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetTZD() string {
|
||||||
|
if c.Session.Timezone == "" {
|
||||||
|
return "Z"
|
||||||
|
}
|
||||||
|
return c.Session.Timezone
|
||||||
|
}
|
||||||
|
|
||||||
// GetChatMembers retrieves a list of chat members. "Limited" mode works only if there are no more than 20 members at all
|
// GetChatMembers retrieves a list of chat members. "Limited" mode works only if there are no more than 20 members at all
|
||||||
func (c *Client) GetChatMembers(chatID int64, limited bool, query string, membersList MembersList) ([]*client.ChatMember, error) {
|
func (c *Client) GetChatMembers(chatID int64, limited bool, query string, membersList MembersList) ([]*client.ChatMember, error) {
|
||||||
if membersList == MembersListCreators {
|
if membersList == MembersListCreators {
|
||||||
|
|
@ -3084,6 +3091,12 @@ func (c *Client) unsubscribe(chatID int64) error {
|
||||||
return c.sendPresence(args...)
|
return c.sendPresence(args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) unsubscribeFromAll() {
|
||||||
|
for _, id := range c.cache.ChatsKeys() {
|
||||||
|
c.leaveChat(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) leaveChat(chatID int64) error {
|
func (c *Client) leaveChat(chatID int64) error {
|
||||||
chat, err := c.GetChatByID(chatID, nil, true)
|
chat, err := c.GetChatByID(chatID, nil, true)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,11 @@ var sizeRegex = regexp.MustCompile("\\A([0-9]+) ?([KMGTPE]?B?)\\z")
|
||||||
|
|
||||||
// NewComponent starts a new component and wraps it in
|
// NewComponent starts a new component and wraps it in
|
||||||
// a stream manager that you should start yourself
|
// a stream manager that you should start yourself
|
||||||
func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig, idsPath string) (*xmpp.StreamManager, *xmpp.Component, error) {
|
func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig, idsPath string, version string) (*xmpp.StreamManager, *xmpp.Component, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
gateway.Jid, err = stanza.NewJid(conf.Jid)
|
gateway.Jid, err = stanza.NewJid(conf.Jid)
|
||||||
|
gateway.Version = version
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -482,6 +482,14 @@ type MAM2MetadataEnd struct {
|
||||||
Timestamp string `xml:"timestamp,attr,omitempty"`
|
Timestamp string `xml:"timestamp,attr,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EntityTime is from XEP-0202
|
||||||
|
type EntityTime struct {
|
||||||
|
XMLName xml.Name `xml:"urn:xmpp:time time"`
|
||||||
|
Tzo string `xml:"tzo"`
|
||||||
|
Utc string `xml:"utc"`
|
||||||
|
ResultSet *stanza.ResultSet `xml:"set,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// Namespace is a namespace!
|
// Namespace is a namespace!
|
||||||
func (c PresenceNickExtension) Namespace() string {
|
func (c PresenceNickExtension) Namespace() string {
|
||||||
return c.XMLName.Space
|
return c.XMLName.Space
|
||||||
|
|
@ -562,6 +570,16 @@ func (c MessageDelayLegacy) Namespace() string {
|
||||||
return c.XMLName.Space
|
return c.XMLName.Space
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Namespace is a namespace!
|
||||||
|
func (c EntityTime) Namespace() string {
|
||||||
|
return c.XMLName.Space
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSet getsets!
|
||||||
|
func (c EntityTime) GetSet() *stanza.ResultSet {
|
||||||
|
return c.ResultSet
|
||||||
|
}
|
||||||
|
|
||||||
// Name is a packet name
|
// Name is a packet name
|
||||||
func (ClientMessage) Name() string {
|
func (ClientMessage) Name() string {
|
||||||
return "message"
|
return "message"
|
||||||
|
|
@ -895,4 +913,10 @@ func init() {
|
||||||
"urn:xmpp:mam:2",
|
"urn:xmpp:mam:2",
|
||||||
"metadata",
|
"metadata",
|
||||||
}, MAM2Metadata{})
|
}, MAM2Metadata{})
|
||||||
|
|
||||||
|
// entity time
|
||||||
|
stanza.TypeRegistry.MapExtension(stanza.PKTIQ, xml.Name{
|
||||||
|
"urn:xmpp:time",
|
||||||
|
"time",
|
||||||
|
}, EntityTime{})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,9 @@ var QueueLock = sync.Mutex{}
|
||||||
// Jid stores the component's JID object
|
// Jid stores the component's JID object
|
||||||
var Jid *stanza.Jid
|
var Jid *stanza.Jid
|
||||||
|
|
||||||
|
// Version stores this software's version
|
||||||
|
var Version string
|
||||||
|
|
||||||
// IdsDB provides a disk-backed bidirectional dictionary of Telegram and XMPP ids
|
// IdsDB provides a disk-backed bidirectional dictionary of Telegram and XMPP ids
|
||||||
var IdsDB badger.IdsDB
|
var IdsDB badger.IdsDB
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,16 @@ func HandleIq(s xmpp.Sender, p stanza.Packet) {
|
||||||
go handleGetMetadataMAM2(s, iq)
|
go handleGetMetadataMAM2(s, iq)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
_, ok = iq.Payload.(*stanza.Version)
|
||||||
|
if ok {
|
||||||
|
go handleGetVersion(s, iq)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, ok = iq.Payload.(*extensions.EntityTime)
|
||||||
|
if ok {
|
||||||
|
go handleGetEntityTime(s, iq)
|
||||||
|
return
|
||||||
|
}
|
||||||
} else if iq.Type == stanza.IQTypeSet {
|
} else if iq.Type == stanza.IQTypeSet {
|
||||||
queryRegister, ok := iq.Payload.(*extensions.QueryRegister)
|
queryRegister, ok := iq.Payload.(*extensions.QueryRegister)
|
||||||
if ok {
|
if ok {
|
||||||
|
|
@ -1072,6 +1082,8 @@ func handleGetDiscoInfo(s xmpp.Sender, iq *stanza.IQ, di *stanza.DiscoInfo) {
|
||||||
disco.AddFeatures("jabber:iq:register")
|
disco.AddFeatures("jabber:iq:register")
|
||||||
}
|
}
|
||||||
disco.AddFeatures(gateway.NSCommand)
|
disco.AddFeatures(gateway.NSCommand)
|
||||||
|
disco.AddFeatures("jabber:iq:version")
|
||||||
|
disco.AddFeatures("urn:xmpp:time")
|
||||||
} else if di.Node == "x-roomuser-item" {
|
} else if di.Node == "x-roomuser-item" {
|
||||||
bare, _, fromOk := gateway.SplitJID(iq.From)
|
bare, _, fromOk := gateway.SplitJID(iq.From)
|
||||||
if fromOk {
|
if fromOk {
|
||||||
|
|
@ -1254,6 +1266,77 @@ func handleGetQueryRegister(s xmpp.Sender, iq *stanza.IQ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleGetVersion(s xmpp.Sender, iq *stanza.IQ) {
|
||||||
|
component, ok := s.(*xmpp.Component)
|
||||||
|
if !ok {
|
||||||
|
log.Error("Not a component")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
answer, err := stanza.NewIQ(stanza.Attrs{
|
||||||
|
Type: stanza.IQTypeResult,
|
||||||
|
From: iq.To,
|
||||||
|
To: iq.From,
|
||||||
|
Id: iq.Id,
|
||||||
|
Lang: "en",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to create answer IQ: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
answer.Version().SetInfo(gateway.Jid.Resource, gateway.Version, "")
|
||||||
|
|
||||||
|
log.Debugf("%#v", answer.Payload)
|
||||||
|
|
||||||
|
_ = gateway.ResumableSend(component, answer)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleGetEntityTime(s xmpp.Sender, iq *stanza.IQ) {
|
||||||
|
component, ok := s.(*xmpp.Component)
|
||||||
|
if !ok {
|
||||||
|
log.Error("Not a component")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// separate declaration is crucial for passing as pointer to defer
|
||||||
|
var answer *stanza.IQ
|
||||||
|
var err error
|
||||||
|
answer, err = stanza.NewIQ(stanza.Attrs{
|
||||||
|
Type: stanza.IQTypeResult,
|
||||||
|
From: iq.To,
|
||||||
|
To: iq.From,
|
||||||
|
Id: iq.Id,
|
||||||
|
Lang: "en",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to create answer IQ: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
defer gateway.ResumableSend(component, answer)
|
||||||
|
|
||||||
|
fromJid, err := stanza.NewJid(iq.From)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Invalid from JID!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
session, ok := sessions[fromJid.Bare()]
|
||||||
|
if !ok {
|
||||||
|
log.Error("IQ from stranger")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
entityTime := extensions.EntityTime{
|
||||||
|
Tzo: session.GetTZD(),
|
||||||
|
Utc: time.Now().UTC().Format(time.RFC3339),
|
||||||
|
}
|
||||||
|
answer.Payload = &entityTime
|
||||||
|
|
||||||
|
log.Debugf("%#v", entityTime)
|
||||||
|
}
|
||||||
|
|
||||||
func handleGetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.QueryMucAdmin) {
|
func handleGetQueryMucAdmin(s xmpp.Sender, iq *stanza.IQ, query *extensions.QueryMucAdmin) {
|
||||||
component, answer, ok := iqResultStub(s, iq)
|
component, answer, ok := iqResultStub(s, iq)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue