How to send/receive message from facebook messenger in python - python

I want to make a "Auto-Reply" on Facebook Messenger using python but I don't know how to do it
If it's possible, can you share the code?

If you use the fbchat library, you can do something like below (the example is from the docs, and just replies back with the same message)
from fbchat import log, Client
# Subclass fbchat.Client and override required methods
class EchoBot(Client):
def onMessage(self, author_id, message_object, thread_id, thread_type, **kwargs):
self.markAsDelivered(thread_id, message_object.uid)
self.markAsRead(thread_id)
log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name))
# If you're not the author, echo
if author_id != self.uid:
self.send(message_object, thread_id=thread_id, thread_type=thread_type)
client = EchoBot("<email>", "<password>")
client.listen()

Related

How can I publish custom broker messages in minos?

I want to send a message to notify about something in one of my microservices, but I don't want to do that through a domain event, which requires to create, update or delete one of the entities of the microservice.
Is there another way to send a message such that another microservices can handle them?
Yes! You can do that directly using the BrokerPublisher instance injected in the corresponding service.
If you want to send a message you can do as follows:
from minos.common import ModelType
from minos.cqrs import Service
from minos.networks import Request, enroute
MyContent = ModelType.build("MyContent", {"text": str, "number": int})
class MySenderService(Service):
#enroute.rest.command("/send/my-channel", "POST")
async def handle_send_my_channel(self, request: Request) -> Response:
# First, create the message.
message = BrokerMessageV1(
"MyChannel", BrokerMessageV1Payload(MyContent("foo", 56))
)
# Then, send it!
await self.broker_publisher.send(message)
In this case, "MyChannel" refers to the channel (or topic) on which the message will be sent.
Note that MyContent is a convenient ModelType created just to give the message's content some structure (but it could be another type, like int, str, dict and so on).
Finally, if you want to handle it in another microservice, you can do that as any other message:
from minos.cqrs import Service
from minos.networks import Request, enroute
class MyReceiverService(Service):
#enroute.broker.event("MyChannel")
async def handle_my_channel(self, request: Request):
# Print the received message's content!
print(await request.content())

odoo 14 message_new in custom module

I create a custom module that should receive mail incoming mail. After configuring the Incoming Mail Servers I tested it with the creating ticket in helpdesk but when I use my module nothing happens not receiving log am don't something wrong
Thank you for the help
from odoo import api, fields, models, tools, _
import logging
_logger = logging.getLogger(__name__)
class TestMailer(models.Model):
_name = 'test.mailer'
_inherit = ['mail.alias.mixin','mail.thread', 'mail.activity.mixin']
_description = 'Sort Email'
name = fields.Char(string='Name')
email_from = fields.Char(string='email from')
email_cc = fields.Char(string='email cc')
mail_body = fields.Text(string='mail body')
partner_id = fields.Many2one('res.partner', 'Partner',required=True,select=True)
#api.model
def message_new(msg_dict, custom_values=None):
# def message_new(self, msg, custom_values=None):
_logger.warning('hi i am message_new')
I get this when I fetch now in Incoming Mail Servers.
odoo.addons.mail.models.mail_thread: Routing mail from "name" <name#email.com> to test_sort#email.net,"test_sort#email.net" <test_sort#email.net> with Message-Id <DBBPR08MB49043139E291E368A928E963EA0F9#DBBPR08MB4904.eurprd08.prod.outlook.com>: fallback to model:test.mailer, thread_id:None, custom_values:None, uid:2
what is read
Create a new record on Incoming Mails odoo
customize the auto lead creation through incoming emails
solution
#api.model
def message_new(self, msg, custom_values=None):
_logger.warning('hi i am message_new')
return super(TestMailer, self).message_new(msg_dict, custom_values=defaults)
i think you forgot super call in this method...

How to restrict the acess to a few users in pyTelegramBotAPI?

I'm using telebot (https://github.com/eternnoir/pyTelegramBotAPI) to create a bot to send photos to its users. The point is I didn't see a way to restrict the access to this bot as I intend to share private images through this bot.
I read in this forum that through python-telegram-bot there is a way to limit the access from the sender's message (How To Limit Access To A Telegram Bot), but I didn't know if via pyTelegramBotAPI it is possible.
Do you know how can I solve it?
A bit late tot the party - perhaps for future post readers. You can wrap the function to disallow access.
An example below:
from functools import wraps
def is_known_username(username):
'''
Returns a boolean if the username is known in the user-list.
'''
known_usernames = ['username1', 'username2']
return username in known_usernames
def private_access():
"""
Restrict access to the command to users allowed by the is_known_username function.
"""
def deco_restrict(f):
#wraps(f)
def f_restrict(message, *args, **kwargs):
username = message.from_user.username
if is_known_username(username):
return f(message, *args, **kwargs)
else:
bot.reply_to(message, text='Who are you? Keep on walking...')
return f_restrict # true decorator
return deco_restrict
Then where you are handling commands you can restrict access to the command like this:
#bot.message_handler(commands=['start'])
#private_access()
def send_welcome(message):
bot.reply_to(message, "Hi and welcome")
Keep in mind, order matters. First the message-handler and then your custom decorator - or it will not work.
The easiest way is probably a hard coded check on the user id.
# The allowed user id
my_user_id = '12345678'
# Handle command
#bot.message_handler(commands=['picture'])
def send_picture(message):
# Get user id from message
to_check_id = message.message_id
if my_user_id = to_check_id:
response_message = 'Pretty picture'
else:
response_message = 'Sorry, this is a private bot!'
# Send response message
bot.reply_to(message, response_message)

Not receiving proper message from fbchat

from fbchat import log, Client
from ais import abc
# Subclass fbchat.Client and override required methods
class EchoBot(Client):
def onMessage(self, author_id, message_object, thread_id, thread_type, **kwargs):
self.markAsDelivered(author_id, thread_id)
self.markAsRead(author_id)
log.info("{} from {} in {}".format(message_object, thread_id, thread_type.name))
# If you're not the author, echo
if author_id != self.uid:
abc(message_object) <-- HERE IS THE PROBLEM
client = EchoBot("email", "password")
client.listen()
The problem is that message_object instead of being the sent message itself (123123) somehow becomes <Message (id): '123123', mentions=[] emoji_size=None attachments=[]> How can i fix this to get the desired result? (123123)
Try to replace
abc(message_object)
with
abc(message_object.text)

Python twisted irc: Wait for a whois reply inside privmsg method

I'm trying to make an IRC bot using the twisted.words.protocols.irc module.
The bot will parse messages from a channel and parse them for command strings.
Everything works fine except when I need the bot to identify a nick by sending a whois command. The whois reply will not be handled until the privmsg method (the method from which I'm doing the parsing) returns.
example:
from twisted.words.protocols import irc
class MyBot(irc.IRClient):
..........
def privmsg(self, user, channel, msg):
"""This method is called when the client recieves a message"""
if msg.startswith(':whois '):
nick = msg.split()[1]
self.whois(nick)
print(self.whoislist)
def irc_RPL_WHOISCHANNELS(self, prefix, params):
"""This method is called when the client recieves a reply for whois"""
self.whoislist[prefix] = params
Is there a way to somehow make the bot wait for a reply after self.whois(nick)?
Perhaps use a thread (I don't have any experience with those).
Deferred is a core concept in Twisted, you must be familiar with it to use Twisted.
Basically, your whois checking function should return a Deferred that will be fired when you receive whois-reply.
I managed to fix this by running all handler methods as threads, and then setting a field, following
kirelagin's suggestion, before running a whois query, and modifying the method that recieves the data
to change the field when it recieves a reply. Its not the most elegant solution but it works.
Modified code:
class MyBot(irc.IRClient):
..........
def privmsg(self, user, channel, msg):
"""This method is called when the client recieves a message"""
if msg.startswith(':whois '):
nick = msg.split()[1]
self.whois_status = 'REQUEST'
self.whois(nick)
while not self.whois_status == 'ACK':
sleep(1)
print(self.whoislist)
def irc_RPL_WHOISCHANNELS(self, prefix, params):
"""This method is called when the client recieves a reply for whois"""
self.whoislist[prefix] = params
def handleCommand(self, command, prefix, params):
"""Determine the function to call for the given command and call
it with the given arguments.
"""
method = getattr(self, "irc_%s" % command, None)
try:
# all handler methods are now threaded.
if method is not None:
thread.start_new_thread(method, (prefix, params))
else:
thread.start_new_thread(self.irc_unknown, (prefix, command, params))
except:
irc.log.deferr()
def irc_RPL_WHOISCHANNELS(self, prefix, params):
"""docstring for irc_RPL_WHOISCHANNELS"""
self.whoislist[prefix] = params
def irc_RPL_ENDOFWHOIS(self, prefix, params):
self.whois_status = 'ACK'

Categories