OCC talk:bot:install which URL? Can't auth to send Msg via Bot

Hey Nextclouders

I’ve managed to install a Bot for commands and now I want to send messages.
I’m working on a developmet nextcloud 28:

sudo docker exec -it -u 33 master-nextcloud-1 /var/www/html/occ talk:bot:install bot3 bda701f4ad9dacddd79db288e5faff9c3b9dd7e40cb7932f55d919a3ed95a0b0761c68b32f2a983f9deafffd4383 http://nextcloud.local/ocs/v2.php/apps/spreed/api/v1/bot/goryfy4a

I can activate the bot in the conversation but got 401 when trying to authenticate via PHP or Python.
I’m not sure which URL i should register the BOT?

This is my “sending script”


import requests
import json
import hashlib
import random
import string


api_url = 'http://nextcloud.local/ocs/v2.php/apps/spreed/api/v1/bot/goryfy4a/message'  
secret = 'bda701f4ad9dacddd79db288e5faff9c3b9dd7e40cb7932f55d919a3ed95a0b0761c68b32f2a983f9deafffd4382' 

message_data = {
    'message': 'Hello, this is your bot message!',  # Replace with the actual message content
    'replyTo': 123,  
    'referenceId': hashlib.sha256(''.join(random.choice(string.ascii_letters + string.digits) for _ in range(32)).encode('utf-8')).hexdigest(),
    'silent': False,  
}

print(message_data)

# Calculate the HMAC digest using SHA256
random_value = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(32))  # Generate a random value
request_body = json.dumps(message_data)
digest = hashlib.sha256((random_value + request_body).encode('utf-8')).hexdigest()

# Set the headers for the request
headers = {
    'Content-Type': 'application/json',
    'X-Nextcloud-Talk-Bot-Random': random_value,
    'X-Nextcloud-Talk-Bot-Signature': digest,
    'OCS-APIRequest': 'true',
}

# Send the HTTP POST request
response = requests.post(api_url, data=request_body, headers=headers)

# Check the response status and print the result
if response.status_code == 200:
    print('Message sent successfully.')
    print('API Response:', response.text)
else:
    print('Failed to send message. Status Code:', response.status_code)

Thanks for your help

Hey,

Your secrets do not match.
Regarding the URL, if you want to send messages, I suggest to set the feature of the bot to „response“ and use an invalid url to register.

my bad… the secrets are correct now :slight_smile:

Sorry, just to be sure here :wink: The last digit is different in what you posted. But the ones you used are really correct?

1 Like

Ah, just looking at your code again, you are building a SHA256, but you need to build an HMAC256. The secret you specified is never used in your code.

1 Like

Hey,

I’ve tried also on a “online test” Environment but cant send any messages… I’m mixing here something up

I am able to install a bot. But i am not sure if i have the right URL ?!

sudo docker exec --user www-data -it nextcloud-aio-nextcloud php occ talk:bot:install bot4 bda701f4ad9dacddd79db288e5faff9c3b9dd7e40cb7932f55d919a3ed95a0b0761c68b32f2a983f9deafffd4383 https://myurl.com/ocs/v2.php/apps/spreed/api/v1/bot/q4yaajxj/message

API Endpoint
/ocs/v2.php/apps/spreed/api/v1

Send Message endpoint
/bot/{token}/message

token is the talk chatroom token. so far so good but I’m running in 404.

Have someone an example Post how I can send a simple message according to my bot? Python/postman/php/javascript would really appriciate it

thanks again

Just ignoring what I pointed out will not help you in getting closer to the solution :wink:

1 Like

Sorry, not ignoring you at all - just tried several new approaches and I think I’m making here something completly wrong!

Then you might update us on what you’re doing now. What I can understand from the things you posted:

  • The secret in your code differs in the last digit (might be resolved already)
  • You need to use an HMAC256 instead of a SHA256
  • The URL of the bot to register is only used for webhooks, if you only want to send messages (and not receive them at some endpoint), disable the webhook feature (use response) and just use an arbitrary invalid url at registration

Hello again,

after few days I’m trying again!

So 'ive created a new bot with the feature “response”

sudo docker exec --user www-data -it nextcloud-aio-nextcloud php occ talk:bot:install --feature response bot4 bda701f4ad9dacddd79db288e5faff9c3b9dd7e40cb7932f55d919a3ed95a0b0761c68b32f2a983f9deafffd4383 https://someurl

In the list I can see the bot

  ~ sudo docker exec --user www-data -it nextcloud-aio-nextcloud php occ talk:bot:list
+----+------+-------------+-------------+-------+----------+
| id | name | description | error_count | state | features |
+----+------+-------------+-------------+-------+----------+
| 5  | bot4 |             | 0           | 1     | response |
+----+------+-------------+-------------+-------+----------+

No I’ve tried to remake the python app to just send a message

import requests
import json
import hashlib
import random
import string
import hmac
import hashlib

def sign_message(shared_secret, message, random_header):
    shared_secret_bytes = shared_secret.encode('utf-8')
    random_header_bytes = random_header.encode('utf-8')
    signature = hmac.new(shared_secret_bytes, digestmod=hashlib.sha256)
    signature.update(message.encode('utf-8'))
    signature.update(random_header_bytes)
    
    return signature.hexdigest()

random_value = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(32))  # Generate a random value

api_url = 'https://mynextcloudurl/ocs/v2.php/apps/spreed/api/v1/bot/x2q73rfp/message'  
secret = 'bda701f4ad9dacddd79db288e5faff9c3b9dd7e40cb7932f55d919a3ed95a0b0761c68b32f2a983f9deafffd4383' 

message_data = {
    'message': 'Hello, I am here',  
    'replyTo':1,
    'referenceId':'heyho',
    'silent': False,  
}


request_body = json.dumps(message_data)
message = message_data.get("message", "")
digest = sign_message(secret, request_body, random_value)

headers = {
    'Content-Type': 'application/json',
    'X-Nextcloud-Talk-Bot-Random': random_value,
    'X-Nextcloud-Talk-Bot-Signature': digest,
    'OCS-APIRequest': 'true',
}


response = requests.post(api_url, data=request_body, headers=headers)

if response.status_code == 200:
    print('Message sent successfully.')
    print('API Response:', response.text)
else:
    print('Failed to send message. Status Code:', response.status_code)
    

Edit: Bot is activate in Talk conversation

Unfortunately, only Status Code 401 :frowning:

Any Ideas?

I haven’t tested this, but according to the docs the random needs to be in front of the message, this looks like you’re doing it the other way round?

1 Like

Hey,

thanks again for your help but same result in 401 by changing the two lines


def sign_message(shared_secret, message, random_header):
    random_header_bytes = random_header.encode('utf-8')
    shared_secret_bytes = shared_secret.encode('utf-8')
    signature = hmac.new(shared_secret_bytes, digestmod=hashlib.sha256)
    signature.update(random_header_bytes)
    signature.update(message.encode('utf-8'))
    
    return signature.hexdigest()

The issue is here. You’re generating the hmac on the whole request_body, while you should do it soley on the message:

digest = sign_message(secret, message, random_value)

Also I am not sure if you really have a messageId 1 you can reply to, so you might want to remove that parameters fro your message data:

1 Like

Absolutely amazing - that did the trick!

SysKeeper, thank you very much for your excellent help and patience in guiding me through this process. :blush:

Cool, glad you got it working!
Would it be okay if we add the python script to our documentation as an example? We can link to the thread here or show any other name if you like.

1 Like