I have a function that runs every hour with apscheduler, this verifies few conditions and according to this sends an email to an arrangement of emails
from mailsnake import MailSnake
mapi = MailSnake('XXXXXXXX', api='mandrill')
def functionEverHour():
users=Users.objects.all()
for users in users:
if users.notificated==False:
mapi.messages.send(message={'html':'sending emails', 'subject':'test', 'from_email':'tes#test.com', 'from_name':'example', 'to':[{'email':str(users.email)}]})
maybe putting this line (mapi = MailSnake('Xajnas12sjnjas', api='mandrill')) in the cycle avoid that kind of mistake?
what does exactly mapi = MailSnake ('Xajnas12sjnjas' api = 'mandrill') that opens a connection to mandrill and never closes and that's the reason I sent emails repetitive (is accumulative?)?
Thanks
This may or not be an error, but why are you doing users in users? It's probably not going to cause an error, but the naming isn't the best in my opinion. My suggestion would be to use naming: all_users = User.objects.all() and users_to_notify in all_users:
Not sure why you're using MailSnake, but this is something mandrill's API handles pretty well.
this is my suggestion about how to change your code. One thing is your method is doing too much. It's handling both the logic of finding the users to notify as well as send the emails. It's best practice to have a function and objects, etc handling only one responsibility.
def get_users_to_notify():
all_users=Users.objects.all()
users_to_notify = []
for user in all_users:
if user.notified==False:
users_to_notify.append(user)
return users_to_notify
def functionEverHour():
users = get_users_to_notify()
for user in user:
mapi.messages.send(message={'html':'sending emails', 'subject':'test', 'from_email':'tes#test.com', 'from_name':'example', 'to':[{'email':str(users.email)}]})
Related
I'm trying to use telethon and telebot to send notification from my code in python.
I have configureted everythings, but the code ask me the following:
receiver = InputPeerUser('user_id', 'user_hash')
I fund user_id, but I don't understand where I could catch my user_hash.
You must have an open dialogue with that user. Or you received a message from him. When all the dialogs are loaded, the information of that user comes with it.
If you don't have a 'user_hash', just enter 0.
I.e.:
userid=555555555
userhash=0
receiver=InputPeerUser(userid, userhash)
For those requests having a “limit” parameter, you can often set it to
zero to signify “return default amount”. This won’t work for all of
them though, for instance, in “messages.search” it will actually
return 0 items.
Reference:
https://telethonn.readthedocs.io/en/latest/extra/advanced-usage/accessing-the-full-api.html
I want to create the bot with telepot that ask the users frequent questions.
For example first ask 'whats your name.?' then the user reply 'user-name',then ask how old are you? and the user reply his age and ...
I had written a code for this chat between user and bot,but sometimes I am getting error. Please guide me how can I make this bot with telepot.?
I want to make conversation between bot and users with telepot
I am no longer maintaining this library. Thanks for considering
telepot.
- the maintainer, nickoala
What you're looking for is DelegatorBot.
Consider this tutorial.
Consider this scenario. A bot wants to have an intelligent
conversation with a lot of users, and if we could only use a single
line of execution to handle messages (like what we have done so far),
we would have to maintain some state variables about each conversation
outside the message-handling function(s). On receiving each message,
we first have to check whether the user already has a conversation
started, and if so, what we have been talking about. To avoid such
mundaneness, we need a structured way to maintain “threads” of
conversation.
DelegatorBot provides you with one instance of your bot for every user, so you don't have to think about what happens when multiple users talk to it. (If it helps you, feel free to have a look at how I am using it.)
The tutorial's example is a simple counter of how many messages the user has sent:
import sys
import time
import telepot
from telepot.loop import MessageLoop
from telepot.delegate import pave_event_space, per_chat_id, create_open
class MessageCounter(telepot.helper.ChatHandler):
def __init__(self, *args, **kwargs):
super(MessageCounter, self).__init__(*args, **kwargs)
self._count = 0
def on_chat_message(self, msg):
self._count += 1
self.sender.sendMessage(self._count)
TOKEN = sys.argv[1] # get token from command-line
bot = telepot.DelegatorBot(TOKEN, [
pave_event_space()(
per_chat_id(), create_open, MessageCounter, timeout=10),
])
MessageLoop(bot).run_as_thread()
while 1:
time.sleep(10)
This code creates an instance of MessageCounter for every individual user.
I had written a code for this chat between user and bot,but sometimes I am getting error.
If your question was rather about the errors you're getting than about how to keep a conversation with state, you need to provide more information about what errors you're getting, and when those appear.
I've been having issues with Wit.ai where my Python bot will retain the context after ending a conversation. This behaviour is the same in the Facebook client and the pywit interactive client.
The conversation starts with a simple 'Hi' and can end at different points within different branches if a user taps a 'Thanks, bye' quick reply after a successful query.
If the conversation is then started with 'Hi' once again, the session state is saved from before which leads to wrong responses. What is the best way to delete the context after the user has said goodbye?
I tried creating a goodbye function that triggers after the bot has sent its final message but it didn't work e.g.
def goodbye(request):
del request['context'] # or request.clear()
return request
The documentation (https://wit.ai/docs/http/20160526#post--converse-link) suggests you clear the session_id and generate a new one but gives no hints as to how.
You can generate new Session Ids using uuid. Session ID has to be any text that is unique, it can even be system date. I suggest you use uuid
Check here as to how to generate it.
I was confronted with the same issue and I solved it in the following way.
I first created a simple end_session action, to be called at the end of each conversation path:
def end_session(request):
return {'end_session': True}
Then I inserted the following code just after returning from run_actions:
if 'end_session' in context:
context = {}
session_hash = uuid.uuid1().hex
As you see, in addition to clearing the context, as you do, I also recreate a new session id (as per Swapnesh Khare's suggestion).
I'm not sure this is the best solution, but it works for me.
I need to set up a jabber bot, using python, that will send messages based on the online/offline availability of several contacts.
I've been looking into pyxmpp and xmpppy, but couldn't find any way (at least nothing straightforward) to check the status of a given contact.
Any pointers on how to achieve this?
Ideally I would like something like e.g. bot.status_of("contact1#gmail.com") returning "online"
I don't think it is possible in the way you want it because the presence of contacts (which contains the information about their availability) is received asynchronously by the bot.
You will have to write a presence handler function and registered it with the connection. This function will get called whenever a presence is received from a contact. The parameter of the call will tell you if the contact is online or not. Depending upon it you can send the message to the contact.
Using xmpppy you do it something like this:
def connect(jid, password, res, server, proxy, use_srv):
conn = xmpp.Client(jid.getDomain())
if not conn.connect(server=server, proxy=proxy, use_srv=use_srv):
log( 'unable to connect to server.')
return None
if not conn.auth(jid.getNode(), password, res):
log( 'unable to authorize with server.')
return None
conn.RegisterHandler( 'presence', callback_presence)
return conn
conn = connect(...)
def callback_presence(sess, pres):
if pres.getStatus() == "online":
msg = xmpp.Message(pres.getFrom(), "Hi!")
conn.send(msg)
PS: I have not tested the code but it should be something very similar to this.
What you want is done via a <presence type="probe"/>. This is done on behalf of the client, and SHOULD not be done by them (as per the RFC for XMPP IM). Since this is a bot, you could implement the presence probe, and receive the current presence of a given entity. Remember to send the probe to the bare JID (sans resource), because the server responds on behalf of clients for presence probes. This means your workflow will look like:
<presence/> // I'm online! BOT
<presence from="juliet#capulet.org/balcony"/> RESPONSE
<presence from="romeo#montague.net/hallway"/> // and so on... RESPONSE
<presence type="probe" to="benvolio#montague.net"/> BOT
<presence from="benvoio#montague.net/hallway"> RESPONSE
<status>Huzzah!</status>
<priority>3</priority>
</presence>
Take a look at that portion of the RFC for more in depth information on how your call flow should behave.
What you need to do is:
Connect.
Declare a presence handler. That handler maintains a cache of every contact's presence (see details below)
Send initial presence to the server, which will provoke the reception of presence statuses from all of your online contacts, which will in turn trigger the handler.
The status_of() method reads the cache and deduces the contact's presence status immediately.
Now, it depends on what presence information you need. For the sake of simplicity, let's pretend you just need an "online"/"offline" value. The cache would be a dictionary whose keys are the bare (no resource) JIDs, and the values are a set of connected resources for this JID. For example:
{'foo#bar.com': set(['work', 'notebook']), 'bob#example.net': set(['gtalk'])}
Now, when you receive an "available" presence from a certain JID/resource:
if jid not in cache:
cache[jid] = set()
cache[jid].add(resource)
Reciprocally, when you receive an "unavailable" presence:
if jid in cache: # bad people send "unavailable" just to make your app crash
cache[jid].discard(resource)
if 0 == len(cache[jid]):
del cache[jid]
And now:
def is_online(jid):
return jid in cache
Of course, if you want more detailed information, you could maintain not only the list of available resources for a contact but also the status, status message, priority, etc. of each resource.
I'm attempting to write a quick load-test script for our ejabberd cluster that simply logs into a chat room, posts a couple of random messages, then exits.
We had attempted this particular test with tsung, but according to the authors, the muc functionality did not make it into this release.
pyxmpp seems to have this functionality, but darned if I can figure out how to make it work. Here's hoping someone has a quick explanation of how to build the client and join/post to the muc.
Thanks!
Hey I stumbled over your question a few times, while trying the same thing.
Here is my answer:
Using http://pyxmpp.jajcus.net/svn/pyxmpp/trunk/examples/echobot.py as a quickstart, all you have to do is import the MUC-Stuff
from pyxmpp.jabber.muc import MucRoomState, MucRoomManager
And once your Client is connected, you can connect to your room:
def session_started(self):
"""Handle session started event. May be overriden in derived classes.
This one requests the user's roster and sends the initial presence."""
print u'SESSION STARTED'
self.request_roster()
p=Presence()
self.stream.send(p)
print u'ConnectToParty'
self.connectToMUC()
def connectToMUC(self):
self.roomManager = MucRoomManager(self.stream);
self.roomHandler = MucRoomHandler()
self.roomState = self.roomManager.join(
room=JID('room#conference.server.domain'),
nick='PartyBot',
handler=self.roomHandler,
history_maxchars=0,
password = None)
self.roomManager.set_handlers()
To send a message, all you have to do is call self.roomState.send_message("Sending this Message")
To do stuff, inherit from MucRoomHandler and react on events. Notice the "set_handlers()" to roomManager though, it's is important, otherwise callbacks will not be called..