I would like to create a Slack bot to answer some simple question or perform some task on the server. Here is what I have tried
token = "i-put-my-bot-token-here" # found at https://api.slack.com/#auth)
sc = SlackClient(token)
sc.api_call("chat.postMessage", channel="magic", text="Hello World!")
It was posted as the Slackbot and not the bot account that I created?
Also if I were to listen the message, according to the python library it says
if sc.rtm_connect():
while True:
print sc.rtm_read()
time.sleep(1)
else:
print "Connection Failed, invalid token?"
Or should I use incoming webhook instead?
As you can see here this call accepts an argument 'as_user' which can be true. If you set it as true, messages will be posted as the bot you created.
I'm in the middle of creating a bot right now as well. I found that if you specified as_user='true', it would post as you, the authed user. If you want it to be your bot, pass in the name of our bot and other options like emoji's like so:
sc.api_call(
'chat.postMessage',
username='new_slack_bot',
icon_emoji=':ghost:',
as_user='false',
channel='magic',
text='Hello World!'
)
Check emoji cheat sheet for more.
Then, if you want to listen to events, like questions or commands, try intercepting the messages that are sent in. Example found on this post:
while True:
new_evts = sc.rtm_read()
for evt in new_evts:
print(evt)
if "type" in evt:
if evt["type"] == "message" and "text" in evt:
message=evt["text"]
# write operations below to receive commands and respond as you like
Related
I was trying to check if a new session has been created using the telethon library.
My first idea was to get the warning message from Telegram (New access: [...]), so when I get that kind of message, I know that another device has connected to my account.
I couldn't get that message, so I tried to get it another way:
chat = client.get_entity(777000) # Telegram chat id
print(chat)
for message in client.iter_messages(chat):
print(message.text)
(This is not the full code.)
The only message I was able to retrieve was the confirmation code, but only with that I can't do anything.
Another idea was to continuously receive the list of active sessions (using GetAuthorizationsRequest()) and, if that list changed, it means that a new device has connected to my account. But is it convenient to continuously send requests to Telegram servers?
I searched everywhere but couldn't find a good solution to my problem.
Any help is appreciated.
With the help of Lonami, I was able to solve my problem.
With client.iter_messages(chat), I could only view messages, while the "message" I was looking for was an UpdateServiceNotification, so I used events.Raw to get all types of updates.
Here is the code:
from telethon.sync import TelegramClient, events
from telethon.tl.types import UpdateServiceNotification
api_id = 123456
api_hash = "42132142c132145ej"
with TelegramClient('anon', api_id, api_hash) as client:
#client.on(events.Raw(func = lambda e: type(e) == UpdateServiceNotification))
async def handler(event):
print("New Login!")
client.run_until_disconnected()
I want to write a simple slack bot, which responds a given string to # mentions, however I am not able to make the official documentation code to work.
I gave all OAuth permission to the bot and have the following code:
from slack import RTMClient
#RTMClient.run_on(event="message")
def gravity_bot(**payload):
data = payload['data']
print(data.get('text'))
try:
rtm_client = RTMClient(
token="my_token_auth_code",
connect_method='rtm.start'
)
print("Bot is up and running!")
rtm_client.start()
except Exception as err:
print(err)
I think the connection is established, as the "Bot is up and running" message appears, however on the slack channel to bot seems to be offline, also I am not able to get any response in the terminal, not for direct messages, not for channel messages even after inviting the bot to given channels.
Sorry couldn't let this one go.. I figured it out and here are the steps:
Create a "Classic" app in Slack (this is the only way to get the appropriate scopes), just click this link: https://api.slack.com/apps?new_classic_app=1
From the "Add features and functionality" tab click on "bots":
Click the "Add Legacy Bot User" button (this will add the "rtm.stream" scope that you need, but that you cannot add manually)
From the basic information page, install your app in a workspace
From the OAuth & Permissions page, copy the "Bot User OAuth Access Token" (the bottom one)
Run the following code (slightly modified version of the code in the docs)
from slack_sdk.rtm import RTMClient
# This event runs when the connection is established and shows some connection info
#RTMClient.run_on(event="open")
def show_start(**payload):
print(payload)
#RTMClient.run_on(event="message")
def say_hello(**payload):
print(payload)
data = payload['data']
web_client = payload['web_client']
if 'Hello' in data['text']:
channel_id = data['channel']
thread_ts = data['ts']
user = data['user']
web_client.chat_postMessage(
channel=channel_id,
text=f"Hi <#{user}>!",
thread_ts=thread_ts
)
if __name__ == "__main__":
slack_token = "<YOUR TOKEN HERE>"
rtm_client = RTMClient(token=slack_token)
rtm_client.start()
Previous answer:
Hmm, this is tricky one... According to the docs this only works for "classic" Slack apps, so that might be the first pointer. It explicitly says that you should not upgrade your app. Furthermore, you'll need to set the right permissions (god knows which ones) by selecting the "bot" scope.
Honestly, I haven't been able to get this running. Looks like Slack is getting rid of this connection method, so you might have more luck looking into the "Events API". I know it's not the ideal solution because its not as real-time, but it looks better documented and it will stay around for a while. Another approach could be polling. Its not sexy but it works...
My guess is that your problem is that there is not a valid connection, but there is no proper error handling in the Slack library. The message is printed before you actually connect, so that doesn't indicate anything.
I want to develop a Telegram bot, that acts as a bookmarking system. It should process commands that reply to other messages. The instance:
I use python-telegram-bot for development and it seems that there is no way to see that message to which /important replies. I found the Update.message.reply_to_message object, which works only when a user replies to a message from the bot itself.
def important_handler(update: Update, context: CallbackContext):
reply_to_message = update.message.reply_to_message
if reply_to_message is None:
logger.error('reply_to_message is None. But it shouldn\'t.')
update.message.reply_text('There is no message attached. Try again.')
return
# ... business logic
Is there any way to get reply_to_message attribute (or an alternative) for all the replies? Thanks in advice;)
I had the same problem. It only worked when a user replied to the bot. My issue was that the bot had Privacy Mode enabled. Once I disabled it with Botfather via /setprivacy and then it worked.
I'm using python-telegram-bot (python-telegram-bot.org) to communicate with Telegram from Python3
I would like to update the last reply I sent.
Currently, the code below sends the message and then sends
another message 5 seconds later.
def echo(bot, update):
update.message.reply_text("Sorry, you're on your own, kiddo.")
time.sleep(5)
update.message.reply_text("Seriously, you're on your own, kiddo.")
I'd like to update the last message instead.
I tried
bot.editMessageText("Seriously, you're on your own, kiddo.",
chat_id=update.message.chat_id,
message_id=update.message.message_id)
which works in the examples to update replace an inline keyboard with a a message, but that crashes (and does not update the last message I sent as a bot).
I believe the order of your arguments in edit_message_text() is wrong. Check out the docs for that:
def echo(bot, update):
# Any send_* methods return the sent message object
msg = update.message.reply_text("Sorry, you're on your own, kiddo.")
time.sleep(5)
# you can explicitly enter the details
bot.edit_message_text(chat_id=update.message.chat_id,
message_id=msg.message_id,
text="Seriously, you're on your own, kiddo.")
# or use the shortcut (which pre-enters the chat_id and message_id behind)
msg.edit_text("Seriously, you're on your own, kiddo.")
The docs for the shortcut message.edit_text() is here.
This is a very specific question, but I cannot find any documentation on how I can do it. The Facebook Documentation is pretty vague with some horrible and useless PHP examples (really, it's code like the Facebook PHP Sample Code that make people think PHP sucks) but I cannot find anything around for Python.
I can't even work out how to apply the same principles from the PHP sample code into a Python world. The xmpppy and SleekXMPP docs are a bit bare (or broken) and Google only shows examples of people using passwords.
I have the access tokens coming from the database, I have no interest in spawning a browser to find stuff, or doing anything else to find a token. I have them, consider it a hardcoded string. I want to pass that string to XMPP and send a message, that is the whole scope of things.
Any suggestions?
The below code worked, but only after some modifications mentioned in this thread
I answered this with a link to a blog I wrote because it described the solution perfectly, but apparently that annoyed some moderators.
While that's clearly ridiculous, here is the answer reposted.
import sleekxmpp
import logging
logging.basicConfig(level=logging.DEBUG)
class SendMsgBot(sleekxmpp.ClientXMPP):
def init(self, jid, recipient, message):
sleekxmpp.ClientXMPP.__init__(self, jid, 'ignore')
# The message we wish to send, and the JID that
# will receive it.
self.recipient = recipient
self.msg = message
# The session_start event will be triggered when
# the bot establishes its connection with the server
# and the XML streams are ready for use. We want to
# listen for this event so that we we can initialize
# our roster.
self.add_event_handler("session_start", self.start, threaded=True)
def start(self, event):
self.send_presence()
self.get_roster()
self.send_message(mto=self.recipient, mbody=self.msg, mtype='chat')
# Using wait=True ensures that the send queue will be
#emptied before ending the session.
self.disconnect(wait=True)
I shoved that in a file called fbxmpp.py, then in another file (your worker, your command line app, your Flask controller, whatever) you'll need something like the following:
from fbxmpp import SendMsgBot
# The "From" Facebook ID
jid = '511501255#chat.facebook.com'
# The "Recipient" Facebook ID, with a hyphen for some reason
to = '-1000023894758#chat.facebook.com'
# Whatever you're sending
msg = 'Hey Other Phil, how is it going?'
xmpp = SendMsgBot(jid, to, unicode(msg))
xmpp.credentials['api_key'] = '123456'
xmpp.credentials['access_token'] = 'your-access-token'
if xmpp.connect(('chat.facebook.com', 5222)):
xmpp.process(block=True)
print("Done")
else:
print("Unable to connect.")