hangups icon indicating copy to clipboard operation
hangups copied to clipboard

How to use the send_message.py code within another code?

Open masterchop opened this issue 6 years ago • 44 comments

Hello i have been using this software alot for my home security system but i have struggle with the send_message.py script i cant figure out how to use it in another code. i tried using its code on the interactive shell:

` import hangups

from common import run_example

async def send_message(client): request = hangups.hangouts_pb2.SendChatMessageRequest( request_header=client.get_request_header(), event_request_header=hangups.hangouts_pb2.EventRequestHeader( conversation_id=hangups.hangouts_pb2.ConversationId( id="Ugz1TPwdoBnYwNq9RXN4AaABAagB-YGbAQ" ), client_generated_id=client.get_client_generated_id(), ), message_content=hangups.hangouts_pb2.MessageContent( segment=[ hangups.ChatMessageSegment("Test").serialize() ], ), ) await client.send_chat_message(request)`

But i am not able to call it to send a message i have tried all this sequenses:

` run_example(send_message, '--conversation-id Ugz1TPwdoBn9RXN4AaABAagB-YGbAQ', '--message-text hola')

run_example(send_message, '--conversation-id', 'Ugz1TPwdoBnq9RXN4AaABAagB-YGbAQ', '--message-text', 'hola')

run_example(send_message, '--conversation-id:Ugz1TPwdoBNq9RXN4AaABAagB-YGbAQ', '--message-text:hola')

run_example(send_message, 'Ugz1TPwdoBnq9R4AaABAagB-YGbAQ', 'hola')`

Any help is welcome

masterchop avatar Jun 18 '18 06:06 masterchop

whats the error when you try to run it this way?

IamSierraCharlie avatar Jul 04 '18 11:07 IamSierraCharlie

I got the following error :+1:

error: the following arguments are required: --conversation-id Ugz1TPwdoBn9RXN4AaABAagB-YGbAQ, --message-text hola

it always complain about the arguments so i am not sure how to pass them inside a script.

masterchop avatar Jul 04 '18 20:07 masterchop

The example code defines script command arguments; it doesn't send the actual conversation ID because that's read from the argument list (i.e. as given from your shell) as per common.run_example.

If you're interacting with hangups from another script then don't go via the examples -- they're exactly that: simple examples under an independent wrapper. You should work with the client directly, which means creating a client, adding a handler for on_connect that starts whatever tasks you need to do, and running your client in an asyncio event loop:

async def callback():
    # Do your tasks here.

client = hangups.Client(...)
client.on_connect.add_observer(callback)
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(client.connect(), loop=loop)
try:
    loop.run_until_complete(task)
except KeyboardInterrupt:
    task.cancel()
    loop.run_until_complete(task)
finally:
    loop.close()

Terrance avatar Jul 04 '18 21:07 Terrance

OllieTerrance, thanks for the response but i am too new to python so i am not sure were to go from there but thanks that will help others with better knowledge.

masterchop avatar Jul 04 '18 21:07 masterchop

is there any chance you could create a quick sample to send msg? i am using 'import os' to run the send_message.py and this is taking alot of resources, i am running PI3B with Opencv with MobileNet SSD neural network and sending screenshot results through hangups works great but pi is to resource limited.

masterchop avatar Jul 06 '18 08:07 masterchop

masterchop, can you please share the code of sending sms (of your work)..

ubaid4j avatar Jul 24 '18 11:07 ubaid4j

I am not doing anything special, i am just importing the os module and do a system command:

os.system("send_message.py --conversation-id Ugz1TPwdoBn9RXN4AaABAagB-YGbAQ, --message-text hello ")

But this code probably creates a session everytime and i would like to have the session open like the chat client.

masterchop avatar Jul 24 '18 14:07 masterchop

ok

ubaid4j avatar Jul 25 '18 06:07 ubaid4j

I have the same question. I am really new to python and would like an example of a basic .py that would simply repeat the received text to the sender.

I would then be able to work from there.

Synoptic2 avatar Sep 05 '18 17:09 Synoptic2

tritto

umop3plsdn avatar Sep 11 '18 22:09 umop3plsdn

@Synoptic2 Same here

ghost avatar Dec 10 '18 03:12 ghost

I am really new to python

Then this probably isn't a good place for you to start off. Working with hangups directly requires knowledge of using the asyncio module correctly, which itself requires a strong understanding of Python. You should make yourself familiar with the language (and programming in general, if applicable) -- this guide lists plenty of places to make a start.

From there, you should learn how to make a simple asyncio program before continuing. The docs cover all the details, but it's not the easiest thing to pick up from there -- a tutorial like this one may be easier to digest.

At that point you should be able to take the sample code above and adjust the callback to your needs, or wrap it up into something a bit more usable. Note that the client here isn't really suited for one-shot style invocation, as there's a lot of startup overhead -- ideally you would have a long-running client along with a way to pass messages into a running instance.

Terrance avatar Dec 11 '18 19:12 Terrance

ERROR:asyncio:SSL error in data received protocol: <asyncio.sslproto.SSLProtocol object at 0x7fe15c5c30f0> transport: <_SelectorSocketTransport fd=24 read=polling write=<idle, bufsize=0>> Traceback (most recent call last): File "/home/mark/miniconda3/envs/HSenv/lib/python3.7/asyncio/sslproto.py", line 526, in data_received ssldata, appdata = self._sslpipe.feed_ssldata(data) File "/home/mark/miniconda3/envs/HSenv/lib/python3.7/asyncio/sslproto.py", line 207, in feed_ssldata self._sslobj.unwrap() File "/home/mark/miniconda3/envs/HSenv/lib/python3.7/ssl.py", line 767, in unwrap return self._sslobj.shutdown() ssl.SSLError: [SSL: KRB5_S_INIT] application data after close notify (_ssl.c:2605) Terminated This is the error that I get when I run send_message.py with common.py

This my code; this function is called when a certain button is selected using urwid item_chosen() and is passed these params (conversation.id_ , 'lorem ipusm')

def send_message_func(conv_id, text='hello world'): run_example(send_message, conv_id, text) can anyone help me... Thanks in advance

Kop3sh avatar Feb 09 '19 20:02 Kop3sh

@masterchop is this still an issue for you? Did you get this to work for your home security system?

IamSierraCharlie avatar Feb 09 '19 23:02 IamSierraCharlie

It seems a few people want to use hangups as part of a bigger project - perhaps as part of a notification system for home security for example. I had many issues initially trying to get hangups to work, but I did have some success in the end. I agree with the statement above comment about asyncio. You really need to understand how it works to get a better overall understanding of the workings of hangups itself. I'm not quote there myself, but have managed to fumble my way through. I have extracted the code that I use from my home security program that sends messages to my phone every time a person is detected on the camera at the front door. I hope that it will be useful for a few of you. The code provides a basic function to send a hangouts message and then 2 scenarios. 1 with an image and 1 without.

import datetime
import asyncio
import hangups

CLIENT_SECRET_FILE = '/home/scarter/.google/sb_client_secrets.json'
APPLICATION_NAME = 'Gmail API Python Send Email'
MY_CONVERSATION_ID = '???????????????' # todo use your own conversation_id
IMG_NAME = 'bee-closeup.jpeg' # todo use your own image here
REFRESH_TOKEN = '/home/scarter/.cache/hangups/refresh_token.txt' # todo this path must exist - if the file is empty, you will be asked to log in


class HangupsExample(object):
	def __init__(self):
		self.conversation_id = MY_CONVERSATION_ID
		self.refresh_token_path = REFRESH_TOKEN
		self.client = None
		self.notifier = {'start date': None, 'detection': False, 'counter': 0}
		self.test_hangups()

	def test_hangups(self):
		now_time = datetime.datetime.now()
		self.notifier['start date'] = now_time.strftime('%Y%m%d%H%M')
		incident_time = now_time.strftime('%Y%m%d @ %H:%M')
		cookies = hangups.auth.get_auth_stdin(self.refresh_token_path)
		self.client = hangups.Client(cookies)
		self.client.on_connect.add_observer(lambda: asyncio.async(self.hangout_notifier(hclient=self.client,
		                                                                                image=None,
		                                                                                time_of_incident=incident_time)))
		loop = asyncio.get_event_loop()
		loop.run_until_complete(self.client.connect())
		self.client = hangups.Client(cookies)
		self.client.on_connect.add_observer(lambda: asyncio.async(self.hangout_notifier(hclient=self.client,
		                                                                                image=open(IMG_NAME,'rb'),
		                                                                                time_of_incident=incident_time)))
		loop = asyncio.get_event_loop()
		loop.run_until_complete(self.client.connect())



	async def hangout_notifier(self, hclient, image, time_of_incident):
		notification_message = 'SOMEONE IS AT THE FRONT DOOR -> ' + time_of_incident
		user_list, conversation_list = await hangups.build_user_conversation_list(hclient)
		this_conversation = conversation_list.get(self.conversation_id)
		if image is None:
			await this_conversation.send_message([hangups.ChatMessageSegment(notification_message)], image_file=None)  # a message only
		else:
			await this_conversation.send_message([], image_file=image)  #  a pic only
		await hclient.disconnect()

if __name__ == '__main__':
	HangupsExample()

I hope this is useful to someone.

IamSierraCharlie avatar Feb 10 '19 00:02 IamSierraCharlie

dude, i have been waiting for this for while, how do i use it. i am kinda new to python, i used the smtp solution as this one disconnected to much for me but i am interested into test yours.

Please tell me how to use it!

masterchop avatar Feb 10 '19 08:02 masterchop

Hi,
Here are some tips You need your own MY_CONVERSATION_ID Research how to find the conversation ID using hangups. No one can provide this for you, you need your own from a conversation between your hangouts ID and another party. Secondly, you just need to set a path to your REFRESH_TOKEN. When you log in for the first time, the refresh token should be written. It takes away the need for you to log onto google hangouts every time you run the program . Finally, set the path to a jpeg you want to test with (IMG_NAME).

Everything I have learned in Python is through research & review of other peoples code, but I honestly believe I have learned more through my own mistakes (and fixing them) than anyone simply giving me the code and telling me how to use it. I'd suggest you run it first and look at any errors to understand what you might be missing. Its only my opinion, but you really need to understand it yourself to make sense of it. I've found looking at other peoples code to be helpful in making a start, but you will need to do some research here first yourself to truly understand what you are looking at here.

IamSierraCharlie avatar Feb 10 '19 09:02 IamSierraCharlie

Yes, i understand what you are saying for the variables but wont this one disconnects from the session too? Can i send multiple messages in a row? Also have you been able to read a message and respond ?

masterchop avatar Feb 10 '19 10:02 masterchop

Yes, it could send multiple messages - given it is incorporated into your own code properly. I can read the message on my phone. I guess I could respond. This code is out of a program for finding people in a security camera. There is a counter - once the counter hits a certain number, it sends a message and a picture - in both hangouts and to my gmail account. The counter resets and then will alarm again if the counter hits that number. It works, but is not without its bugs that I need to fix. The code I have provided simply shows how to send a message in hangouts using hangups. You can use it as an example and incorporate it into your own code to send as many messages as you want to as many people as you want or to a group chat. All you need to do is take the functions and call them as necessary. Its fair to say its not simple to do, but again, once you understand the code, you can send messages at will. If you want to set up some sort of security system as your first post advises, then this is but a very small snippet of code in a much larger more complex program. The code I provided is from my project probably doing something similar to what I presume you are trying to achieve...

  1. Connect to some sort of camera stream
  2. Use a neural network to detect a person inside the image
  3. Report via hangouts that someone is at the door
  4. Save the images as evidence (perhaps)
  5. Repeat as necessary again

This is what I see in hangouts sent from the program. The code I provided is responsible for getting that information into hangouts.

image

IamSierraCharlie avatar Feb 10 '19 11:02 IamSierraCharlie

yes. something like that. My main goal is to have the hangups as a chatbot that i can write back and forward. I can request updates and stuff without port forwarding. I tell him to do stuff inside my network like patterns of activity when noone is home. i had it ready with my crappy workaround but unfortunately it disconnected to much been inconsistent and i had to switch to SMTP emails. Ill give it a go to your code and see if this works as expected. Thanks for sharing :)

masterchop avatar Feb 10 '19 16:02 masterchop

I am not able to send images, i get the following error:

Failed to send message: Request failed with status 3: 'Unexpected error'
Task exception was never retrieved
future: <Task finished coro=<HangupsExample.hangout_notifier() done, defined at hangups_example.py:40> exception=NetworkError("Request failed with status 3: 'Unexpected error'",)>
Traceback (most recent call last):
  File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
    result = coro.send(None)
  File "hangups_example.py", line 47, in hangout_notifier
    await this_conversation.send_message([], image_file=image)  #  a pic only
  File "/home/chop/.local/lib/python3.5/site-packages/hangups/conversation.py", line 445, in send_message
    yield from self._client.send_chat_message(request)
  File "/home/chop/.local/lib/python3.5/site-packages/hangups/client.py", line 611, in send_chat_message
    send_chat_message_request, response)
  File "/home/chop/.local/lib/python3.5/site-packages/hangups/client.py", line 442, in _pb_request
    .format(status, description)
hangups.exceptions.NetworkError: Request failed with status 3: 'Unexpected error'

The message does arrived and i make sure the image existed, i also replace the image with None to see if i could just send a txt msg but that hang too.

masterchop avatar Feb 10 '19 16:02 masterchop

Hmm, Are you just using the code provided above?
If you send no image and end up with the same error, then there is something else at play there - not just an image problem. Looks like a timeout of some sort. Are you saying you get some messages but not others or you have not received ANY messages?

IamSierraCharlie avatar Feb 10 '19 21:02 IamSierraCharlie

I got the text msg, then the error and terminal hang. Same behavior without image. I didnt supply this CLIENT_SECRET_FILE = '/home/scarter/.google/sb_client_secrets.json' As it wasnt called anywhere in the script and i never had to setup that before. The image never arrives.

masterchop avatar Feb 10 '19 22:02 masterchop

yeah you don't need that. Whats is the image that you are trying to send? And what is its name, and what type of image is it? Can you give me some info about it?

IamSierraCharlie avatar Feb 10 '19 22:02 IamSierraCharlie

I tried wit ha PNG and a JPEG file both with the same result.

PATH: /home/chop/Scripts/images/2.jpeg

The path is the home folder of the user executing the script.

masterchop avatar Feb 10 '19 22:02 masterchop

Hmm, I can't replicate that issue here.
What is the conversation ID you are using?

IamSierraCharlie avatar Feb 10 '19 22:02 IamSierraCharlie

That conversation id works on the send_message.py sample

masterchop avatar Feb 10 '19 22:02 masterchop

Not sure there is anything else I can do to help you here. The code I provided works for me - I can send message after message without any issue with or without an image. You might want to do some research on hangups.exceptions.NetworkError: Request failed with status 3: 'Unexpected error' or parts of that error to understand your issue a little better, but I don't believe its the actual code that is causing your problem.

IamSierraCharlie avatar Feb 10 '19 23:02 IamSierraCharlie

I really appreciate your help @IamSierraCharlie , thank you I was running your code to analyze it and understand it more but the lines containing lambda expressions give me an invalid syntax error and the program wouldn't run in vs code although I properly changed the REFRESH_TOKEN_PATH and the conversation_id

I've read multiple threads in asyncio and I know roughly how it works but it's still a new concept for me but from my understanding I can't use a lambda expression with async functions

Kop3sh avatar Feb 10 '19 23:02 Kop3sh

what version of python are you running? I have that code running on 3.6.3

IamSierraCharlie avatar Feb 10 '19 23:02 IamSierraCharlie

3.7.2 I'll try to make a new env a run it again

Kop3sh avatar Feb 10 '19 23:02 Kop3sh

Do you us an IDE - like pycharm?

IamSierraCharlie avatar Feb 11 '19 00:02 IamSierraCharlie

vs code

Kop3sh avatar Feb 11 '19 00:02 Kop3sh

so is it the IDE complaining about invalid syntax? or do you see an error when you attempt to run the code?

IamSierraCharlie avatar Feb 11 '19 00:02 IamSierraCharlie

yes when I type: python example.py from the terminal i get the same error File "example.py", line 27 self.client.on_connect.add_observer(lambda: asyncio.async(self.hangout_notifier(hclient=self.client,hclient=self.client, image=None, time_of_incident=incident_time)))

Kop3sh avatar Feb 11 '19 00:02 Kop3sh

@IamSierraCharlie I made a new python env with 3.6.3 and hangups using the git method (cloning then 'python setup.py install) using conda... Now the first error disappeared and this is the error now (in the same line though) Module 'asyncio' has no 'async' member; maybe 'async_'?pylint(no-member)

Kop3sh avatar Feb 11 '19 00:02 Kop3sh

okay - great to see you are moving along a little. I think its fair to say that hangups is particular about modules that are installed. Do you know what version of hangups you are running? Did you install it using pip or did you build it from source? Could you tell me your process? I'll try and replicate your setup here. To be honest, I set this up a while back and I probably need to go through it again myself so why not follow your setup process and see if I end up with the same issue.

What I can tell you is that my IDE complains about async reference missing from asyncio, but it still works

IamSierraCharlie avatar Feb 11 '19 00:02 IamSierraCharlie

I used the github source cloning then cd hangups then python setup.py install I used this approach because manual-login didn't work for me with the pip installation...

Kop3sh avatar Feb 11 '19 00:02 Kop3sh

hmm okay. I used pip and run hangups 0.4.6 (0.4.4) also works. Was there an open issue for manual login not working? What is the motive for using this?

I'll try build this from source and see if I get the same result - standby

IamSierraCharlie avatar Feb 11 '19 00:02 IamSierraCharlie

my installed hangups version is 0.4.6

Kop3sh avatar Feb 11 '19 01:02 Kop3sh

Okay, I created a new environment (using anaconda) in Ubuntu 16.04 using python 3.6.3 and I've just built from source and it works fine. What can you tell me about your asynchio module? What version is it? Just to be certain, you are running this in Linux or MAC OS?

IamSierraCharlie avatar Feb 11 '19 01:02 IamSierraCharlie

So I made a new conda env on Ubuntu 18.04.1 LTS and using python=3.6.3 and installing hangups using pip this time in that env and it ran and it magically worked although vs code is still highlighting the first error of invald syntax mentioned above... I'm really greatefull for your help Thanks You @IamSierraCharlie

Kop3sh avatar Feb 11 '19 01:02 Kop3sh

Glad that it is working for you.
👍

IamSierraCharlie avatar Feb 11 '19 02:02 IamSierraCharlie

It was easier to move to telegram. Simple api if Hangouts is not mandatory

masterchop avatar May 03 '20 02:05 masterchop