Can anybody help me to fix this code, I really need it, but have no idea what to do next. I need to create a groupchat and send messega to invited persons, now it is example2#gmail.com, but it does not...
Is there mistake?
#!/usr/bin/python
import sys,os,xmpp,time
jid = 'example1#gmail.com'
psw = 'psw'
jid=xmpp.protocol.JID(jid)
cl=xmpp.Client(jid.getDomain(),debug=[])
cl.connect()
cl.auth(jid.getNode(),psw)
node = jid.getNode()
domain = 'talk.google.com'
room = node + '#' + domain
nroom = room + '/' + 'Maria'
mes = xmpp.Presence(to=nroom)
cl.sendInitPresence()
cl.send(mes)
NS_MUCUSER = 'http://jabber.org/protocol/muc#user'
invite = xmpp.simplexml.Node('invite')
invite.setAttr('to', 'example2#gmail.com')
invite.setTagData('reason', 'I really need it!')
mess = xmpp.Message(to=room)
mess.setTag('x', namespace=NS_MUCUSER).addChild(node=invite)
cl.send(mess)
msg = xmpp.protocol.Message(body="Hello there!")
msg.setTo(room)
msg.setType('groupchat')
cl.send(msg)
time.sleep(1) # some older servers will not send the message if you disconnect immediately after sending
cl.disconnect()
print "Done"
According to the specs - http://xmpp.org/extensions/xep-0045.html#createroom - sending a request to join a room that doesn't exist should create that room (or MUC)
The workflow for creating and configuring such rooms is as follows:
The user sends presence to <room#service/nick> and signal his or her support
for the Multi-User Chat protocol by including extended presence information
in an empty <x/> child element qualified by the 'http://jabber.org/protocol/muc'
namespace (note the lack of an '#owner' or '#user' fragment).
If this user is allowed to create a room and the room does not yet exist, the
service MUST create the room according to some default configuration, assign the
requesting user as the initial room owner, and add the owner to the room but not
allow anyone else to enter the room (effectively "locking" the room). The initial
presence stanza received by the owner from the room MUST include extended
presence information indicating the user's status as an owner and acknowledging
that the room has been created (via status code 201) and is awaiting
configuration.
So something like this is supposed to work according to the documentation.
jid=xmpp.protocol.JID('example#gmail.com')
cl=xmpp.Client(jid.getDomain(),debug=[])
jid = xmpp.protocol.JID('example#gmail.com')
client = xmpp.Client(jid.getDomain(), debug=[])
client.connect()
client.auth(jid.getNode(), 'my secret password')
client.send(xmpp.Presence(to='room#talk.google.com/ANick')
I find my mistake. Problem is that I didn't wait enough to get answer from the server and I invited people before server was able to create a chat room. Now I wait until I get answer from server and then send invite message.
Related
I want to create something like feedback form in my telegram bot.
User fills in some information & at the end - sends his phone number (as contact). The Bot ought to copy the contact, append some information & forwad/send formed message to an admin.
I'm using this markup:
contact_btn = types.ReplyKeyboardMarkup(resize_keyboard=True)
send_contact = types.KeyboardButton("Confirm", request_contact=True)
cancel = types.KeyboardButton("Cancel")
send_contact_btn.add(send_contact, cancel)
bot.send_message(message.chat.id, "Confirm the operation:", reply_markup=contact_btn)
I would like to check if this contact belongs to the sender or not & forward/send received contact by using:
bot.forward_message(???)
bot.send_message(???)
How can i do it?
someone on the internet suggests to check if user_id in from object is equal to user_id in Contact. Origin
Error:
NOTICE Auth :*** Looking up your hostname...
433 * testbot:Nickname is already in use.
NOTICE Auth :*** Could not resolve your hostname: Request timed out; using your IP address () instead.
451 837AAAABB JOIN :You have not registered
The script works fine, the only issue I'm having is when another user has the same name and so the bot won't join, how can I fix this?
#IRC Info, Where the bot connects too
server="Server"
botnick="testbot"
channel="#test"
What I have tried:
Google, YouTube, Looking at other github IRC bot's and stackoverflow.
One idea I had was to use an random string generator, so if the name "testbot" was taken the script would generator something random and try again. I'm unsure how I would add this.
It is difficult to help you without seeing some code that you tried. Or any code at all.
The overall idea would be to detect when an incoming message is a 433 (aka ERR_NICKNAMEINUSE), and then send a new NICK command with a new nickname; and try again until you find a free nickname.
Pseudocode:
MAINNICK = 'testbot'
nick_suffix = 1
send_msg('NICK {}'.format(MAINNICK))
while True:
msg = recv_msg()
if msg.split(' ')[1] == '433':
send_msg('NICK {}{}'.format(MAINNICK, nick_suffix))
nick_suffix += 1
This answer assumes that the nick is registered by you.
When receiving ERR_NICKNAMEINUSE (433), send REGAIN to nickserv. Personally I also take care to not send REGAIN more than 3 times in 30 seconds, otherwise I disconnect and reconnect because something else is wrong.
REGAIN YourRegisteredNick YourPassword
Once in a while, NOTICE with a second argument containing can not regain your nickname is then received. This indicates a REGAIN failure. The only way I am aware of to handle this error is to disconnect, reconnect, and rejoin channels.
irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def ircwrite(message):
global irc
irc.send(str(message).encode('utf-8'))
botnick = "ME_Number-1" # Nickname of the bot
InUse_alt = "Me2" # if Nickname: "('botnick')" is already in use, A.K.A. 433, uses this alternative option instead
while 1:
text = irc.recv(2048).decode('utf-8')
print(text)
if "433" in text:
print("Bot's nick IN USE or has been regged by another; switching to: "+ (InUse_alt))
if text.find("433") != -1:
ircwrite("NICK "+ InUse_alt +" \r\n")
---
Something like that would work in most situations, but it can be set off by: someone saying: "433"; trying to work on that.
Send one nick but not both nick1 and nick2. To send new nick2
send_msg(f'NICK {}'.format(nick2_suffix))
In my case:
socket.socket.send(f'NICK {NICK2}')
Another way. In entry box.
/NICK NICK2
I've little question about Django Channels, WebSockets, and chat applications. Serving with google gets me to chatrooms, where people can connect and start a chat. But I don't know how one user can send another user instant message.
For example:
1) I add John to friends, and want to start chat.
2) On server side I can generate object Room, with me and John as members.
3) When I send message via WebSocket to this room, I know for who this message is, but I don't know how to get John's channel
#channel_session_user_from_http
def ws_connect(message):
rooms_with_user = Room.objects.filter(members=message.user)
for r in rooms_with_user:
Group('%s' % r.name).add(message.reply_channel)
#channel_session_user
def ws_receive(message):
prefix, label = message['path'].strip('/').split('/')
try:
room = Room.objects.get(name=label)
except Exception, e:
room = Room.objects.create(name=get_random_string(30))
for u in message.chmembers:
room.members.add(u)
# here can be somethis like this
# try
reply_channel = Channels.objects.get(online=True, user=u)
Group('%s' % r.name).add(reply_channel)
Group('%s' % room.name).send({
"text": "%s : %s" % (message.user.username, message['text']),
})
#channel_session_user
def ws_disconnect(message):
prefix, label = message['path'].strip('/').split('/')
Group(label).discard(message.reply_channel)
Simply make "automatic unique rooms" for user pairs. The rest stays the same. For example like this
def get_group_name(user1, user2):
return 'chat-{}-{}'.format(*sorted([user1.id, user2.id]))
Give it two user objects, and it returns a unique room for that pair of users, ordered the User.id, something like "chat-1-2" for the users with User.id "1" and "2".
That way, a user can connect with more than one logged-in device and still get the messages sent between the two users.
You can get the authenticated user's object from message.user.
For the receiving User object, I'd just sent the username along with the message. Then you can unpack it from the message['text'] the same way you unpack the actual message.
payload = json.loads(message.content['text'])
msg = payload['msg']
sender = message.user
receiver = get_object_or_404(User, username=payload['receiver'])
# ... here you could check if they have required permission ...
group_name = get_group_name(sender, receiver)
response = {'msg': msg}
Group(group_name).send({'text': json.dumps(response)})
# ... here you could persist the message in a database ...
So with that, you can drop all the "room" things from your example, including the room table etc. Because group names are always created on-the-fly when a message is send between two users.
Another important thing: One user will connect later than the other user, and may miss initial messages. So when you connect, you probably want to check some "chat_messages" database table, fetch the last 10 or 20 messages between the user pair, and send those back. So users can catch up on their past conversation.
is there a way to check if a chat is a group chat? Or at least to find out how many users there are in a group.
Like by checking for the user number, if it is 2, then it is obviously 1-1 (Single), but if it as anything else, it would be a group chat.
The Type property of the chat object will be either chatTypeDialog or chatTypeMultiChat with the latter being a group chat. You can safely ignore the other legacy enumeration values.
This is a slight modification of a code that I wrote for another question here. The following code checks if there are any Group chats in either the open chats or the bookmarked chats. You should pass in a topic to find a chat of that topic.
def checkGroupChat(topic=""):
"""
Checks if a group exists.
"""
import Skype4Py as skype
skypeClient = skype.Skype()
skypeClient.Attach()
for elem in skypeClient.ActiveChats: # Looks in active chats and returns True if chat is found.
if len(elem.Members) > 2 and elem.Topic == topic:
return True
for chat in skypeClient.BookmarkedChats: # Looks in Bookmarked Chats.
if chat.Topic == topic:
return True
return False
This worked for me:
def on_message(message, status):
len(message.Chat.Members) > 2:
# this is a private chat
s = Skype4Py.Skype()
s.OnMessageStatus = on_message
s.Attach()
message.Chat.Type always hanged for me and then after some seconds the connection to Skype is lost. Seems to be a bug
I'm trying to access my google talk contacts' custom status messages with xmpppy. I'm made it this far:
import xmpp
import sys
userID = 'myname#gmail.com'
password = 'mypassword'
ressource = 'Script'
jid = xmpp.protocol.JID(userID)
jabber = xmpp.Client(jid.getDomain(), debug=[])
connection = jabber.connect(('talk.google.com',5222))
auth = jabber.auth(jid.getNode(), password, ressource)
jabber.sendInitPresence(requestRoster=1)
myroster = jabber.getRoster()
the roster object myroster now contains my contacts, but the custom status message is not included.
myroster.getStatus('oneofmyfriends#gmail.com')
returns None
looking at the 'raw roster', I can see that the resources dictionary is empty
u'oneofmyfriends#googlemail.com': {'ask': None, 'resources': {}, 'name': u'Some Name', 'groups': [], 'subscription': u'both'}
The weird thing is that I have gotten this to work today, but I the code might have been slightly different, but I can't figure out what exactly I did differently...
Any help would be greatly appreciated!
Cheers,
Martin
Here's one thing I've found, which was not clear to me when I first started working with xmpp. Friending is two-way.
Using presence stanzas
(a) You can "subscribe" to your friend, and your friend can return "subscribed".
(b) Your friend can "subscribe" to you, and you can return "subscribed".
Your friend will be in your roster if either (a) or (b) has happened.
You will be in your friends roster if either (a) or (b) has happened.
However...
You will not see their status unless you "subscribe" to your friend - (a) must happen
They will not see your status unless they "subscribe" to you - (b) must happen.
Most XMPP clients (pidgin, trillian, etc) will automatically make you send "subscribe" back to your friend when you send them "subscribed" (after they've sent you "subscribe"). XMPPPY does not do this out of the box. You must code it to do this.
This could explain why you weren't seeing status. Or if this doesn't cover your situation, it might be informative to someone else.
It's a timing issue. Add a handler with:
jabber.RegisterHandler('presence', myPresenceHandler)
def myPresenceHandler(self, con, event):
fromjid = event.getFrom().getStripped()
status = myroster.getStatus(fromjid)
BEFORE connecting. Then make sure to call jabber.Process() in a loop. The issue is that with your code, you'll sometimes receive presence stanzas before you look at the roster object, and sometimes after.