Stuck in Creating a Skype Bot via Python using skpy - python

I have been trying to make a Skype bot through Python but am stuck at processing events.
I have made a conversation and put the code to get events infinitely. In return, the code is supposed to respond to each message sent to the conversation only once until someone sends another message and so on. But the code runs mad and reproduces its own sent messages.
Here is the code so far:
from skpy import Skype
user = '***'
password = '***'
group_id = '***'
class MySkype(SkypeEventLoop):
def onEvent(self, event):
if (event.type == 'NewMessage'): # and (event.userId is None):
message_content = event.raw['resource']['content']
conversation_link = event.raw['resource']['conversationLink']
message_sender = event.raw['resource']['imdisplayname']
ch = sk.chats.chat(group_id)
ch.sendMsg('The code is responding to {}.\n You sent this message: {}'.format(message_sender, message_content))
sk = MySkype(user, password, autoAck = True)
sk.loop()
As you can see the code has responded to itself!

Related

slixmpp Add_event_hanlder ('Message') not working

I am creating a client with python and "slixmpp" library to connect using xmpp. I have achieved to send a message to a user, but I am not able to recive a message in the program. I am testing with another client (Gajim) to run some test but in that client the message are being recived.
My client has this plugins and this event listeners
class Client(slixmpp.ClientXMPP):
"""
A client class to manage conections an functionalities
Atributes:
jid: string with the JID of the client.
password: string
is_remove: boolean to indicate if need to delete the account
"""
def __init__(self, jid, password, status, status_message):
super().__init__(jid, password)
self.name = jid.split('#')[0]
self.status = status
self.status_message = status_message
self.actual_chat = None
# # plugins
self.register_plugin('xep_0030') # Service Discovery
self.register_plugin('xep_0199') # Ping
self.register_plugin('xep_0045') # MUC
self.register_plugin('xep_0085') # Notifications
self.register_plugin('xep_0004') # Data Forms
self.register_plugin('xep_0060') # PubSub
# events
self.add_event_handler('session_start', self.start)
self.add_event_handler('disco_items', self.print_rooms)
self.add_event_handler('groupchat_message', self.chatroom_message)
self.add_event_handler('message', self.chat_recived)
And this is the function chat_recived
async def chat_recived(self, message):
await aprint('aa')
await aprint('New message', message)
if message['type'] == 'chat':
user = str(message['from']).split('#')[0]
if user == self.actual_chat:
print(f'{message["from"]}: {message["body"]}')
else:
print(f'You have a new message from {message["from"]}')
Does anyone knows why the listener is not reciving the message? This are not even been display in the console when debuger mode is on.

Cloud function with pubsub trigger executed endlessly when calling gmail API messages.send()

We are using the Atlassian Status Page with email automation, which means that it displays an alert on screen whenever it receives an email with subject 'DOWN' and deletes the same alert when it receives an email with subject 'UP'.
I activated the Gmail Pub/Sub (https://developers.google.com/gmail/api/guides/push) push notifications, which watches the gmail inbox for changes and sends a push notification to a pub/sub topic when a change actually happens.
Then I created a cloud function which is triggered by pub/sub notifications. This cloud function should:
Read the latest unread email
If this email is an alert sent by our 3rd party provider, send a new email to the Status Page with subject 'DOWN' or 'UP' accordingly.
This is the code:
def access_oauth2_json():
### Code
return creds_dict
def create_message(subject):
### Code
return {'raw': b64_string}
def send_message(service, message, user_id = 'me'):
try:
response = service.users().messages().send(userId=user_id, body=message).execute()
return response
except HttpError as error:
logging.error('An error occurred:', error)
def update_status_page(arg1,arg2):
### Initialise creds
try:
service = build('gmail', 'v1', credentials=creds)
request = {
'labelIds': ['INBOX'],
'topicName': 'pubsub_topic_id'
}
service.users().watch(userId='me', body = request).execute()
last_message_info = service.users().messages().list(userId='me', labelIds=['UNREAD'], q = 'in:inbox is:unread', maxResults=1).execute().get('messages', [])
last_message = service.users().messages().get(userId='me', id=last_message_info[0]['id']).execute()
header = last_message['payload']['headers']
sub = ""
for x in header:
if x['name'] == 'Subject':
sub = x['value'] #subject
logging.info(sub)
if 'special_alert_string' in sub:
message = create_message(subject = 'DOWN')
response = send_message(service, message)
elif 'other_special_alert_string' in sub:
message = create_message(subject = 'UP')
response = send_message(service, message)
except HttpError as error:
logging.info(f'An error occurred: {error}')
return 200
What happens is that:
When the function is triggered by an email which is not a 3rd party alert, the if/elif blocks are not executed, and the cloud function is executed 2 or 3 times (instead of 1, but that's fine for me, so not really a problem)
2 - Problem - When the function is triggered by an email which is a 3rd part alert, the if/elif blocks are executed (one of the 2) and the function is executed endlessly! It only stops because it reaches the maximum API requests per interval of time.
What I have tried:
To remove the watch() line, without success
Commenting out the service.users().messages().send() line falls back into case 1, so my guess is that this instruction is triggering a push notification to the pub/sub topic and generates the infinite loop. The issue could maybe solved with another watch() labelId, but I haven't figured out which one.
I hope this is clear, thank you for your help!

How to work with slackbot in python?

I am trying to build a slackbot for my group , I tried sample codes and some other things but its not sending message to the group.
first i tried via terminal
export SLACK_API_TOKEN="my_token_id"
Then
from slackclient import SlackClient
import os
slack_token = os.environ["SLACK_API_TOKEN"]
sc = SlackClient(slack_token)
sc.api_call(
"chat.postMessage",
channel="#random",
text="Hello from Python! :tada:",
thread_ts="283.5127(dummy_id)",
reply_broadcast=False
)
print(sc)
#<slackclient.client.SlackClient object at 0x109b77ba8>
But there is no message in slack group.
I tried with this code:
from slackclient import SlackClient
import os
slack_token = os.environ['SLACK_API_TOKEN']
sc = SlackClient(slack_token)
print(sc.api_call("channels.list"))
its retuning :
{'error': 'invalid_auth', 'ok': False}
I am not getting what i am doing wrong , Access token is correct , i want to post some messages via a bot , so how i can create a bot on slack and using that bot i can send messages via python ?
I had similar issues when I implemented a slack bot with php & symfony.
It's not that simple to create and configure the slack app, bot and OAuth permissions properly.
I explained all these configurations in this blog post if you need it: https://blog.eleven-labs.com/en/en/replace-erp-by-slack-bot-with-dialogflow-and-symfony/
Also my code in PHP is very similar to what you need to parse Slack requests and post to its API.
Summary, TL;DR:
Go to https://api.slack.com/apps and click on 'Create New App'.
In this app configuration, go to the left menu 'Bot Users' or from 'Basic Information' > 'Add features and functionality' > 'Bots'.
Still in this app config, go to the menu 'OAuth & Permissions' and allow the scope 'chat:write:bot' and copy the value of 'OAuth Access Token'
From your code, call 'chat.postMessage' API method with an 'Authorization' header using previous token value.
built this from some examples found on the web: liza daly - brobot : github.com
and
How to Build Your First Slack Bot with Python : fullstackpython.com
certainly not the best implementation but it functions as an appropriate answer to (i think)
import random
import time
import re
from slackclient import SlackClient
bot_id = None
slack_token = 'xoxb-no.more.mister.nice.gui'
sc = SlackClient(slack_token)
# constants
RTM_READ_DELAY = 1 # 1 second delay between reading from RTM
DEFAULT_RESPONSE = "greetings: 'hello', 'hi', 'greetings', 'sup', 'what's up' / commands: 'do'"
DEFAULT_COMMAND = "do"
MENTION_REGEX = "^<#(|[WU].+?)>(.*)"
def parse_bot_commands(slack_events):
"""
parses a list of events coming from the slack rtm api to find bot commands
:param slack_events:
:return:
"""
for event in slack_events:
if event["type"] == "message" and not "subtype" in event:
user_id, message = parse_direct_mention(event["text"])
if user_id == bot_id:
return message, event["channel"]
return None, None
def parse_direct_mention(message_text):
"""
finds direct message and returns user id
:param message_text:
:return:
"""
matches = re.search(MENTION_REGEX, message_text)
# the first group contains the user name, the second group contains
# the remaining message
return (matches.group(1), matches.group(2).strip()) if matches else (None, None)
def handle_command(command, channel):
"""
executes bot command if the command is known
:param command:
:param channel:
:return:
"""
GREETING_KEYWORDS = ("hello", "hi", "greetings", "sup", "what's up",)
GREETING_RESPONSES = ["'sup brah", "hey", "*headnod*", "didjageddathingahsencha?"]
# default response is help text for the user
default_response = "Not sure what you mean. Try *{}*.".format(DEFAULT_RESPONSE)
# finds and executes the given command, filling the response
response = None
#implement more commands below this line
if command in GREETING_KEYWORDS:
response = random.choice(GREETING_RESPONSES)
else:
if command.startswith(DEFAULT_COMMAND):
response = "Sure...write some more code and I'll do that"
# Sends the response back to the channel
sc.api_call(
"chat.postMessage",
channel="#the_danger_room",
as_user="true:",
text=response or default_response)
if __name__ == "__main__":
if sc.rtm_connect(with_team_state=False):
print("Connected and running!")
#call web api method auth.test to get bot usre id
bot_id = sc.api_call("auth.test")["user_id"]
while True:
command, channel = parse_bot_commands(sc.rtm_read())
if command:
handle_command(command, channel)
time.sleep(RTM_READ_DELAY)
else:
print("Connection failed. Exception traceback printed above.")

XMPP on Python responds to Gtalk but not to Hangouts

I was trying out a Gtalk bot using python and XMPP.
When I ping the bot using iChat application, I could receive the response back.
But when I ping using Hangouts, I am not able to receive the response message. But still I could see my message at server side logs.
# -- coding: utf-8 -
import xmpp
user="BOTUSERNAME#gmail.com"
password="PASSWORD"
server=('talk.google.com', 5223)
def message_handler(connect_object, message_node):
us = str(message_node.getFrom()).split('/')[0]
if us == 'REALUSERNAME#gmail.com':
us = us[0:4]
print str(message_node)
message = "Welcome to my first Gtalk Bot :) " + us
s= str(message_node.getBody()).replace("\n", "\t")
if s <> 'None' :
print "MESSAGE: " + s
connect_object.send(xmpp.Message( message_node.getFrom() ,message))
jid = xmpp.JID(user)
connection = xmpp.Client(jid.getDomain())
connection.connect(server)
result = connection.auth(jid.getNode(), password )
connection.RegisterHandler('message', message_handler)
connection.sendInitPresence()
while connection.Process(1):
pass
Is this something to do with gtalk moving out of XMPP support?
My Bot is still able to receive message but my Hangouts Application is not receiving response
I was able to fix the issue.
You need to add typ = 'chat' attribute to xmpp.Message
connect_object.send(xmpp.Message( message_node.getFrom() ,message, typ='chat' ))
Now my gTalkBot reponds to my message from hangouts & ichat client.
Many thanks to this stack overflow answer
If you have extended sleekxmpp.ClientXMPP, then you can ensure messages are sent to hangouts by added mtype='chat' to send_message()
bot = MyBot([...])
bot.send_message(mto=JID,mbody=MSG,mtype='chat')

How can I send a message to a group conversation with Skype4Py in Python

I've been trying to get my script to send a message to a group conversation in Skype using the Skype4Py library, the only way I am currently able to send messages is to specific users.
import Skype4Py
Skype = Skype4Py.Skype()
Skype.Attach()
Skype.SendMessage('namehere','testmessage')
Does anyone know how I can change my code to send a message to a group conversation?
The following little script should work. (Assuming you already have a group chat open)
def sendGroupChatMessage():
"""
Send Group Chat Messages.
"""
import Skype4Py as skype
skypeClient = skype.Skype()
skypeClient.Attach()
for elem in skypeClient.ActiveChats:
if len(elem.Members) > 2:
elem.SendMessage("SomeMessageHere")
I'm basically importing all the current chats, checking the number of members and sending a message accordingly. It should be easy to check within various groups too.
To get the handles too, change your function to this.
def sendGroupChatMessage():
"""
Send Group Chat Messages.
"""
import Skype4Py as skype
skypeClient = skype.Skype()
skypeClient.Attach()
for elem in skypeClient.ActiveChats:
if len(elem.Members) > 2:
for friend in elem.Members:
print friend.Handle
elem.SendMessage("SomeMessageHere")
If you can bookmark your chat, you just have to do this, then.
>>> groupTopic = 'Insert a Topic Here'
>>> for chat in skypeClient.BookmarkedChats:
if chat.Topic == groupTopic:
chat.SendMessage("Send a Message Here")
This is the final code that should be standalone.
def sendGroupChatMessage(topic=""):
"""
Send Group Chat Messages.
"""
import Skype4Py as skype
skypeClient = skype.Skype()
skypeClient.Attach()
messageSent = False
for elem in skypeClient.ActiveChats:
if len(elem._GetMembers()) > 2 and elem.Topic == topic:
elem.SendMessage("SomeMessageHere")
messageSent = True
if not messageSent:
for chat in skypeClient.BookmarkedChats:
if chat.Topic == topic:
chat.SendMessage("SomeMessageHere")
messageSent = True
return messageSent

Categories