I am trying to print the channel a message was posted to in slack with the python SlackClient. After running this code I only get an ID and not the channel name.
import time
import os
from slackclient import SlackClient
BOT_TOKEN = os.environ.get('SLACK_BOT_TOKEN')
def main():
# Creates a slackclient instance with bots token
sc = SlackClient(BOT_TOKEN)
#Connect to slack
if sc.rtm_connect():
print "connected"
while True:
# Read latest messages
for slack_message in sc.rtm_read():
message = slack_message.get("text")
print message
channel = slack_message.get("channel")
print channels
time.sleep(1)
if __name__ == '__main__':
main()
This is the output:
test
U1K78788H
This will always produce a channel id and not channel name. You must call channels.info to get the channel name.
import time
import os
from slackclient import SlackClient
BOT_TOKEN = os.environ.get('SLACK_BOT_TOKEN')
def main():
# Creates a slackclient instance with bots token
sc = SlackClient(BOT_TOKEN)
#Connect to slack
if sc.rtm_connect():
print "connected"
while True:
# Read latest messages
for slack_message in sc.rtm_read():
message = slack_message.get("text")
print message
channel = slack_message.get("channel")
print channel
channel_info=sc.api_call("channels.info",channel=channel)
print channel_info["channel"]["name"]
time.sleep(1)
if __name__ == '__main__':
main()
This will also print channel Name.
Another way is that you can store names of all the channels with their channel_id in a dictionary beforehand. And then get the channel name with id as key.
I'm not sure what you are outputting. Shouldn't "channels" be "channel" ? Also, I think this output is the "user" field. The "Channel" field should yield an id starting with C or G (doc).
{
"type": "message",
"channel": "C2147483705",
"user": "U2147483697",
"text": "Hello world",
"ts": "1355517523.000005"
}
Then, use either the python client to retrieve the channel name, if it stores it (I don't know the Python client), or use the web API method channels.info to retrieve the channel name.
Related
hi and thanks for your answer. i want to create a bot for forward message to my channel and delete the last message every 1 minute
i made that but i have some problem for removing the last message. i cant get the last message id from my channel to the bot.
my source is:
from telegram.bot import Bot
from telegram.update import Update
from telegram.ext.updater import Updater
from telegram.ext.callbackcontext import CallbackContext
from telegram.ext.messagehandler import MessageHandler
from telegram.ext.filters import Filters
from telegram.chataction import ChatAction
from time import sleep
import telegram_send
import socket
import telegram
import json
api_key="My API Key"
user_id = "My User Id"
updater = Updater(api_key, use_context=True)
bot = telegram.Bot(token=api_key)
def echo(update: Update, context: CallbackContext):
context.bot.send_chat_action(chat_id=update.effective_chat.id, action=ChatAction.TYPING)
sleep(60)
if update.message['photo'] == []:
bot.send_message(chat_id=user_id, text=update.message.text)
else:
fileID = update.message['photo'][-1]['file_id']
context.bot.sendPhoto(chat_id = user_id,caption=update.message['caption'],photo = fileID)
msg_id = update.message._id_attrs[]
#------------- And Also i user that too -------------
#msg_id=update.message.message_id
#------------- -------------
context.bot.delete_message(chat_id=user_id, message_id=msg_id)
update.effective_chat
update.effective_user
update.effective_message
print(json.dumps(update.to_dict(), indent=2))
dp = updater.dispatcher
dp.add_handler(MessageHandler(Filters.document | Filters.photo, echo))
dp.add_handler(MessageHandler(Filters.text, echo))
updater.start_polling()
and when i use that code this error will show:
The message_id that you want to remove is not exist....
actually i type a message id in manually for delete message and it was work
but i want to delete that message auto
please help me to do that. thanks
I fixed That With Python-Telegram-Bot Version 20
Read This Docs:
https://docs.python-telegram-bot.org/en/v20.0a2/
I have 10 groups in telegram with different name. I am able to print message with the below example code from telethon library. I also need the group name to be printed.
EG:
G10001 Bhuvan Testing (GroupName UserName/Phoneno Message)
#!/usr/bin/env python3
# A simple script to print some messages.
import os
import sys
import time
from telethon import TelegramClient, events, utils
def get_env(name, message, cast=str):
if name in os.environ:
return os.environ[name]
while True:
value = input(message)
try:
return cast(value)
except ValueError as e:
print(e, file=sys.stderr)
time.sleep(1)
session = os.environ.get('TG_SESSION', 'printer')
api_id = get_env('TG_API_ID', 'Enter your API ID: ', int)
api_hash = get_env('TG_API_HASH', 'Enter your API hash: ')
proxy = None # https://github.com/Anorov/PySocks
# Create and start the client so we can make requests (we don't here)
client = TelegramClient(session, api_id, api_hash, proxy=proxy).start()
# `pattern` is a regex, see https://docs.python.org/3/library/re.html
# Use https://regexone.com/ if you want a more interactive way of learning.
#
# "(?i)" makes it case-insensitive, and | separates "options".
#client.on(events.NewMessage(pattern=r''))#pattern=r'(?i).*\b(hello|hi)\b'))
async def handler(event):
sender = await event.get_sender()
#client.get_input_entity(PeerChannel(fwd.from_id))
#channel = await event.get_channel()
#group = event.group()
#group = event.get_group()
#print(group)
#print(utils.get_peer_id(sender))
#print(utils.get_input_location(sender))
#print(utils.get_input_dialog(sender))
#print(utils.get_inner_text(sender))
#print(utils.get_extension(sender))
#print(utils.get_attributes(sender))
#print(utils.get_input_user(sender))
name = utils.get_display_name(sender)
print(name, 'said', event.text, '!')
#print(utils.get_input_entity(PeerChannel(sender)))
#print(utils.get_input_channel(get_input_peer(channel)))
try:
print('(Press Ctrl+C to stop this)')
client.run_until_disconnected()
finally:
client.disconnect()
# Note: We used try/finally to show it can be done this way, but using:
#
# with client:
# client.run_until_disconnected()
#
# is almost always a better idea.
I also need help to send message to groups. I have gone through some answer given below, which doesn't working for me.
(Sending Telegram messages with Telethon: some entity parameters work, others don't?)
First get the chat from incoming event:
chat = await event.get_chat()
Print group name:
try:
if chat.title:
print(chat.title)
except AttributeError:
print('no such attribute present')
Send message to group:
await client.send_message(entity=chat.id,message='hi')
I am trying to use my bot to delete certain messages in a slack channel with this api call
import os
import time
import re
from slackclient import SlackClient
slack_client = SlackClient(
'xsssssseeeeeeee')
slack_mute_bot_id = None
def delete_message(slack_event):
for event in slack_event:
if event["type"] == "message":
message_text = event['text']
time_stamp = event['ts']
channel_id = event['channel']
slack_client.api_call(
'chat.delete',
channel=channel_id,
ts=time_stamp,
as_user=True
)
print(message_text + " delted")
if __name__ == "__main__":
if slack_client.rtm_connect(with_team_state=False):
slack_mute_bot_id = slack_client.api_call("auth.test")["user_id"]
while True:
# print(slack_client.rtm_read())
delete_message(slack_client.rtm_read())
time.sleep(1)
else:
print("Connection failed. Exception traceback printed above.")
I do not get any error message after doing this and the bot does not delete the message. I am using the bot user token. I have benn able to send message succesfully but the delete method does not work and still gives np responses
Refer - https://api.slack.com/methods/chat.delete
When used with a user token, this method may only delete messages
that user themselves can delete in Slack.
When used with a bot token, this method may delete only messages
posted by that bot.
I got stumbled into the same thing.
My name is Ken. I am trying to create a Slack Bot first one message every Monday at 9:00 am and asks for a input (goal number of sales for the week). Then responds with user input in new message saying (great your weekly sales goal is (#). Then it takes this number and adds it to Google sheets. Then asks user to enter daily goal for the day. And responds with (daily goal set as). Then at 9:00 pm asks user to input the number of deals written and keeps track of all data in Google sheets and provides graphs. I have been thinking maybe MySQL would work for that too.
Here is some of the code I have so far:
starterbot.py
import os
import time
from slackclient import slackclient
# starterbot's ID as an environment variable
BOT_ID = os.environ.get("BOT_ID")
# contasts
AT_BOT = "<#" + BOT_ID + ">"
EXAMPLE_COMMAND = "do"
#instantiate Slack & Twilio clients
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
def handle_command (command, channel)
"""
Receives commnds directed at the bot and determines if they
are valid commands. if so, then acts on the commands. if not,
returns back what it needs for clarification.
"""
response = "Not sure what you mean. Use the *" + EXAMPLE_COMMAND + \
"* command with numbers, delimited by spaces."
if command.startswitch(EXAMPLE_COMMAND):
response = "Sure ... wire some more c ie then I can do
that!"
slack_client.api_call("chat.postMessage", channel=channel,
text=response, as_user=True)
def parse_slack_output(slack_messages):
"""
The Slack Real Time Messaging API is an event firehose.
this parsing function returns None unless a message is
directed at the Bot, based on its ID.
"""
if slack_messages and len(slack_messages) > 0;
for message in slack_messages:
if message and 'text' in message and AT_BOT in message['text']:
command = message['text'].split(AT_BOT)[1].strip().lower()
channel = message['channel']
# return text after the # mention, white space removed
return command, channel
return None, None
if __name__ == "__main__":
READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose
if slack_client.rtm_connect():
print("starterbot connected and running!")
while True:
command, channel = parse_slack_output(slack_client.rtm_read())
if command and channel:
handle_command(command, channel)
time.sleep(READ_WEBSOCKET_DELAY)
else:
print("Connection failed. Invalid Slack token or bot ID?")
bot_id_py
import os
from slackclient import SlackClient
import pdb
BOT_NAME = 'pilot4u'
slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))
if __name__ == "__main__":
api_call = slack_client.api_call("users.list")
if api_call.get('members'):
pdb.set_trace()
# Retrieve all users so we can find our bot
users = api_call.get('members')
for user in users:
if 'name' in user and user.get('name') == BOT_NAME:
print("Bot ID for '" + user ['name'] + "'is " +
user.get('id'))
else:
print("could not find bot user with the name " + BOT_NAME)
I have an isolated python script that simply captures data from Twitter's streaming API and then on the receipt of each message, using redis pubsub it publishes to the channel "tweets". Here is that script:
def main():
username = "username"
password = "password"
track_list = ["apple", "microsoft", "google"]
with tweetstream.FilterStream(username, password, track=track_list) as stream:
for tweet in stream:
text = tweet["text"]
user = tweet["user"]["screen_name"]
message = {"text": text, "user": user}
db.publish("tweets", message)
if __name__ == '__main__':
try:
print "Started..."
main()
except KeyboardInterrupt:
print '\nGoodbye!'
My server side socket.io implementation is done using django-socketio (based off of gevent-socketio) https://github.com/stephenmcd/django-socketio which simply provides a few helper decorators as well as a broadcast_channel method. Because it's done in django, I've simply put this code in views.py simply so that they're imported. My views.py code:
def index(request):
return render_to_response("twitter_app/index.html", {
}, context_instance=RequestContext(request))
def _listen(socket):
db = redis.Redis(host="localhost", port=6379, db=0)
client = db.pubsub()
client.subscribe("tweets")
tweets = client.listen()
while True:
tweet = tweets.next()
tweet_data = ast.literal_eval(tweet["data"])
message = {"text": tweet_data["text"], "user": tweet_data["user"], "type": "tweet"}
socket.broadcast_channel(message)
#on_subscribe(channel="livestream")
def subscribe(request, socket, context, channel):
g = Greenlet.spawn(_listen, socket)
The client side socket.io JavaScript simply connects and subscribes to the channel "livestream" and captures any received messages to that channel:
var socket = new io.Socket();
socket.connect();
socket.on('connect', function() {
socket.subscribe("livestream");
});
socket.on('message', function(data) {
console.log(data);
});
The obvious problem with this code is that each time a new user or browser window is opened to the page, a new _listen method is spawned and the tweets get subscribed to and broadcast for each user resulting in duplicate messages being received on the client. My question is, where would the proper place be to put the _listen method so that it's only created once regardless of the # of clients? Also, keeping in mind that the broadcast_channel method is a method of a socket instance.
The problem was that I was using socket.broadcast_channel when I should have been using socket.send.