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.
Related
So I'm getting an issue here where I'm trying to make a status check command to check if a user is online, offline, idle, or dnd, if they are on mobile or desktop, and maybe even their custom status. However, my main problem is seeing if a user is online/offline or whatever. It seems to always return 'offline' even though I know I'm not offline. Here's my code (currently its just printing to console to see)
#client.command(name="status")
async def status(ctx, user: discord.Member=None):
if not user:
user = ctx.message.author
print(user)
print(user.raw_status)
However when I initiate this command it always returns 'offline', and I haven't been able to figure out why. I've tried: user.status, user.raw_status, user.desktop_status, and just in case it was being weird or I didn't understand it, mobile_status (I'm on desktop.) If anyone has a fix to this please let me know, thanks!
If you haven't added intents to your bot, then you cannot deal with user statuses in a server. Head to "https://discord.com/developers/applications//bot" and under "Privileged Gateway Intents" tick "PRESENCE INTENT" and "SERVER MEMBERS INTENT". This will allow the bot to request presence data from users in the server.
In your bot's code, add
from discord import Intents
client = commands.Bot(command_prefix=YOUR_PREFIX, intents = Intents.all())
I am new to Microsoft Bot Framework, I am learning it through a youtube video https://youtu.be/ynG6Muox81o and making my bot on python3 on Ubuntu.
The Microsoft Bot Emulator says "sending failed. Retry".
Visual Studio Code shows KeyError: 'HTTP_CONTEXT_TYPE'.
I did everything right, my bot is connected to http://localhost:3978/, and bot emulator is connected to http://localhost:3978/api/messages/.
Many people on stackoverflow who had the same issue faced it due to windows firewall, but mine is ubuntu and i did check if it was enabled but its not.
app.py
from flask import Flask, request, Response
from botbuilder.schema import Activity
from botbuilder.core import BotFrameworkAdapter,BotFrameworkAdapterSettings
import asyncio
from echobot import EchoBot
app = Flask(__name__)
loop = asyncio.get_event_loop()
botadaptersettings=BotFrameworkAdapterSettings("","")
botadapter = BotFrameworkAdapter(botadaptersettings)
ebot = EchoBot()
#POST is the message
#app.route("/api/messages",methods=["POST"])
def messages():
#checking if HTTP file format is JSON or not
if "application/json" in request.headers["context-type"]:
#reading the JSON message
jsonmessage = request.json
else:
#unsupported media type 415
return Response(status=415)
activity = Activity().deserialize(jsonmessage)
async def turn_call(turn_context):
await ebot.on_turn(turn_context)
task = loop.create_task(botadapter.process_activity(activity,"",turn_call))
loop.run_until_complete(task)
if __name__ == '__main__':
app.run('localhost',3978)
echobot.py
from botbuilder.core import TurnContext
class EchoBot:
async def on_turn(self,turn_context:TurnContext):
await turn_context.send_activity(turn_context.activity.text)
I cant seem to understand the issue and how to fix it. it would be really helpfull if someone could help me fix this as i am really interested in building bots.
I have uploaded my Bot Project on gitlab https://gitlab.com/pdmnbhrawal/myechobot01.
This is a simple typo. You've written "context-type" instead of "content-type." The YouTube tutorial you linked to tells you to write a line like this:
if "application/json" in request.headers["content-type"]:
In order to avoid this kind of typo, you can download the source code that the video links to directly instead of trying to rewrite it yourself.
You can troubleshoot this kind of error yourself by noticing in the stack trace that it tells you what line of code is throwing the error. When it says KeyError: 'HTTP_CONTEXT_TYPE' that should indicate to you that you've entered the wrong key and you should check for a typo. You can also try using a debugger and stepping through your code.
There are a few other problems with the bot that you may notice. It doesn't handle conversation update activities correctly because it doesn't account for the incoming activity having no text. It also doesn't return an HTTP response from the api/messages endpoint. You might want to fix those problems later, but your bot will run despite them.
Hi I have an issue integrating slack custom bot-user into my slack app, based on python-slackclient documentation python-slackclient
to use the RTM
import time
from slackclient import SlackClient
token = "xoxp-xxxxxxxxx"# found at https://api.slack.com/web#authentication
sc = SlackClient(token)
if sc.rtm_connect():
while True:
print sc.rtm_read()
time.sleep(1)
else:
print "Connection Failed, invalid token?"
that code is working for bot-user token, but since I use oauth, I need to connect RTM using the bot_access_token everytime user install my app to act on behalf my app to the added team
any solution or example how to do it?
Cheers,
Your question is had to understand. You wrote:
since I use oauth, I need to connect RTM using the bot_access_token everytime user install my app to act on behalf my app to the added team
The access token you're using here...
token = "xoxp-xxxxxxxxx"# found at https://api.slack.com/web#authentication
...should be the same as the access token that is associated with your bot. (You should not make your bot use your own personal access token!) You can get an access token for your bot at https://my.slack.com/services/new/bot (assuming you're logged into Slack in the browser with which you follow that link).
If you participate in multiple Slack "teams" (a Slack "team" being basically a company), you'll need to set up a separate bot for each "team". Each bot will have a different access token. To pass the correct access token in to your bot, you could add a command-line parameter, or read the token from an environment variable, or read it from disk, among other options.
You can loop over tokens for connecting if you are planning to setup bot
for multiple teams, then your code can be converted to :-
clients = [SlackClient(token) for t in tokens]
for client in clients:
client.rtm_connect()
while True:
for client in clients:
print client.rtm_read()
time.sleep(1)
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
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.")