I am able to send text to Mattermost channel through incoming webhooks
import requests, json
URL = 'http://chat.something.com/hooks/1pgrmsj88qf5jfjb4eotmgfh5e'
payload = {"channel": "general", "text": "some text"}
r = requests.post(URL, data=json.dumps(payload))
this code simplly post text. I could not find a way to post file to channel. Suppose I want to post file located at /home/alok/Downloads/Screenshot_20170217_221447.png. If anyone know please share.
You can't currently attach files using the Incoming Webhooks API. You would need to use the Mattermost Client API to make a post with files attached to it.
Here's an example of how you could achieve that (using Mattermost API v3 for Mattermost >= 3.5)
SERVER_URL = "http://chat.example.com/"
TEAM_ID = "team_id_goes_here"
CHANNEL_ID = "channel_id_goes_here"
USER_EMAIL = "you#example.com"
USER_PASS = "password123"
FILE_PATH = '/home/user/thing_to_upload.png'
import requests, json, os
# Login
s = requests.Session() # So that the auth cookie gets saved.
s.headers.update({"X-Requested-With": "XMLHttpRequest"}) # To stop Mattermost rejecting our requests as CSRF.
l = s.post(SERVER_URL + 'api/v3/users/login', data = json.dumps({'login_id': USER_EMAIL, 'password': USER_PASS}))
USER_ID = l.json()["id"]
# Upload the File.
form_data = {
"channel_id": ('', CHANNEL_ID),
"client_ids": ('', "id_for_the_file"),
"files": (os.path.basename(FILE_PATH), open(FILE_PATH, 'rb')),
}
r = s.post(SERVER_URL + 'api/v3/teams/' + TEAM_ID + '/files/upload', files=form_data)
FILE_ID = r.json()["file_infos"][0]["id"]
# Create a post and attach the uploaded file to it.
p = s.post(SERVER_URL + 'api/v3/teams/' + TEAM_ID + '/channels/' + CHANNEL_ID + '/posts/create', data = json.dumps({
'user_id': USER_ID,
'channel_id': CHANNEL_ID,
'message': 'Post message goes here',
'file_ids': [FILE_ID,],
'create_at': 0,
'pending_post_id': 'randomstuffogeshere',
}))
I have done a version for API v4, with the use of a personal access token. https://docs.mattermost.com/developer/personal-access-tokens.html
import os
import json
import requests
SERVER_URL = "YOUR_SERVER_URL"
CHANNEL_ID = "YOUR_CHANNEL_ID"
FILE_PATH = './test.jpg'
s = requests.Session()
s.headers.update({"Authorization": "Bearer YOUR_PERSONAL_ACCESS_TOKEN"})
form_data = {
"channel_id": ('', CHANNEL_ID),
"client_ids": ('', "id_for_the_file"),
"files": (os.path.basename(FILE_PATH), open(FILE_PATH, 'rb')),
}
r = s.post(SERVER_URL + '/api/v4/files', files=form_data)
FILE_ID = r.json()["file_infos"][0]["id"]
p = s.post(SERVER_URL + '/api/v4/posts', data=json.dumps({
"channel_id": CHANNEL_ID,
"message": "YOUR_MESSAGE",
"file_ids": [ FILE_ID ]
}))
EDIT:
I have created a simple CLI.
https://github.com/Tim-Schwalbe/python_mattermost
as per #George , you cann't sent the file to the incoming webhook directly.
below is code to send the file to the channel
from mattermostdriver import Driver
team_name = "<name of your team in mattermost>"
channel_name = "<channel name>" # name of channel which you want to upload document
file_path = "<file to uploaded >" # name of the file to upload
message = "<message to sent on channel>"
options = {
"url": "", # url of your mattermost acocunt https://<url>
"port": 8065, # port of the website
"password": "<account password>",
"login_id": "<login id>",
"token": None
}
x = Driver(options=options)
# loggin into the mattermost server
x.login()
# getting team id
team_id = x.teams.get_team_by_name(team_name)['id']
# getting channel id
channel_id = x.channels.get_channel_by_name(team_id, channel_name)['id'] # give channel id
#setting up the options
form_data = {
"channel_id": ('', channel_id),
"client_ids": ('', "id_for_the_file"),
"files": (file_path, open(file_path, 'rb'))
}
pp = x.files.upload_file(channel_id, form_data)
file_id = pp['file_infos'][0]['id']
# uploading the file
x.posts.create_post({'channel_id': channel_id, "message": message, "file_ids": [file_id]})
# logout from the server
x.logout()
Related
I am trying to upload reel with Graph Api using Python.
I'm getting an error every time I try to upload video.
Error :
{"debug_info":{"retriable":false,"type":"NotAuthorizedError","message":"User not authorized to perform this request"}}
Note: I have given every possible permission to my app and page.
code:
import requests
import os
import json
Title ="Title of the video"
title = Title
description = title
source = f"F:\proj_ytTofb\downloads\{Title}.mp4"
files = {'source': open(source, 'rb')}
file_size = os.path.getsize(source)
print("File Size is :", file_size, "bytes")
def Initialize():
url = f"https://graph.facebook.com/v13.0/{page_id}/video_reels?upload_phase=start"
payload = {
'access_token': token,
}
r = requests.post(url, data = payload)
return r.json()["video_id"]
video_id=Initialize()
print(video_id)
def Upload():
url = f"https://rupload.facebook.com/video-upload/v15.0/{video_id}"
payload ={
'access_token': token,
'offset': 0,
'file_size': file_size,
}
r = requests.post(url, files=files, data=payload)
return r.text
print(Upload())
output: {"debug_info":{"retriable":false,"type":"NotAuthorizedError","message":"User not authorized to perform this request"}}
Your Upload code seem bit wrong if you refer on documentation
def Upload(vidid, size, filedata):
url = f"https://rupload.facebook.com/video-upload/v13.0/{vidid}"
payloadUp = {
'Authorization': 'OAuth ' + page_access_token,
'offset': "0",
'file_size': str(size),
}
print(payloadUp)
r = requests.post(url, data=filedata, headers=payloadUp)
return r.text
with parameter like this
files = {'source': open(mp4_path, 'rb')}
file_size = os.path.getsize(mp4_path)
and then you called it like this
Upload(video_id, file_size, files)
Note: I successfully upload it on fb reels and published it, but I dont what happen the video failed to convert without error notice.
I create a bot to monitor the comment if there is any new comment and if so it will automatically private_replies them But instead i got a Request [400] Error instead.
def monitor_comment():
print("Bot is monitoring comments")
time.sleep(5)
comment_data = graph.get_connections(COMBINED_POST_ID_TO_MONITOR,"comments",order='reverse_chronological')
commends = []
for comment in comment_data['data'][:10]:
commends.append (comment)
data = commends[0]['id']
data_converted = str(data)
#time.sleep(5)
print(data)
return data_converted
def private_reply(comment_ids):
url = "https://graph.facebook.com/v12.0/me/messages?"
access = {"access_token":Page_Token}
params = {
"recipient": {
"comment_id": comment_ids
},
"message": {
"text":"Testing Private_Replies"
}
request = requests.post(url=url, files=access, json=params)
print(request)
This is the logs
{"error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500,"fbtrace_id":"AMCiqy1Aw8CyODPlUBE1b98"}}
I am trying to get a python script to say whether a twitch channel is live but haven't been able to do it, any and all help would be appreciated.
here are the docs I've been able to find
https://dev.twitch.tv/docs/api/guide
This is what I have atm but I keep on getting "'set' object has no attribute 'items'". This is modified code from "Is There Any Way To Check if a Twitch Stream Is Live Using Python?" however it is now outdated because of the new API.
import requests
def checkUser():
API_HEADERS = {
'Client-ID : [client id here from dev portal]',
'Accept : application/vnd.twitchtv.v5+json',
}
url = "https://api.twitch.tv/helix/streams/[streamer here]"
req = requests.Session().get(url, headers=API_HEADERS)
jsondata = req.json()
print(jsondata)
checkUser()
The answer to your problem of "'set' object has no attribute 'items'" is just a simple typo. It should be
API_HEADERS = {
'Client-ID' : '[client id here from dev portal]',
'Accept' : 'application/vnd.twitchtv.v5+json'
}
Notice how the Colon's aren't part of the text now
And to answer your overarching question of how to tell if a channel is online you can look at this sample code I made.
import requests
URL = 'https://api.twitch.tv/helix/streams?user_login=[Channel_Name_Here]'
authURL = 'https://id.twitch.tv/oauth2/token'
Client_ID = [Your_client_ID]
Secret = [Your Client_Secret]
AutParams = {'client_id': Client_ID,
'client_secret': Secret,
'grant_type': 'client_credentials'
}
def Check():
AutCall = requests.post(url=authURL, params=AutParams)
access_token = AutCall.json()['access_token']
head = {
'Client-ID' : Client_ID,
'Authorization' : "Bearer " + access_token
}
r = requests.get(URL, headers = head).json()['data']
if r:
r = r[0]
if r['type'] == 'live':
return True
else:
return False
else:
return False
print(Check())
I've been having some trouble sending files via python's rest module. I can send emails without attachments just fine but as soon as I try and add a files parameter, the call fails and I get a 415 error.
I've looked through the site and found out it was maybe because I wasn't sending the content type of the files when building that array of data so altered it to query the content type with mimetypes; still 415.
This thread: python requests file upload made a couple of more edits but still 415.
The error message says:
"A supported MIME type could not be found that matches the content type of the response. None of the supported type(s)"
Then lists a bunch of json types e.g: "'application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false"
then says:
"matches the content type 'multipart/form-data; boundary=0e5485079df745cf0d07777a88aeb8fd'"
Which of course makes me think I'm still not handling the content type correctly somewhere.
Can anyone see where I'm going wrong in my code?
Thanks!
Here's the function:
def send_email(access_token):
import requests
import json
import pandas as pd
import mimetypes
url = "https://outlook.office.com/api/v2.0/me/sendmail"
headers = {
'Authorization': 'Bearer '+access_token,
}
data = {}
data['Message'] = {
'Subject': "Test",
'Body': {
'ContentType': 'Text',
'Content': 'This is a test'
},
'ToRecipients': [
{
'EmailAddress':{
'Address': 'MY TEST EMAIL ADDRESS'
}
}
]
}
data['SaveToSentItems'] = "true"
json_data = json.dumps(data)
#need to convert the above json_data to dict, otherwise it won't work
json_data = json.loads(json_data)
###ATTACHMENT WORK
file_list = ['test_files/test.xlsx', 'test_files/test.docx']
files = {}
pos = 1
for file in file_list:
x = file.split('/') #seperate file name from file path
files['file'+str(pos)] = ( #give the file a unique name
x[1], #actual filename
open(file,'rb'), #open the file
mimetypes.MimeTypes().guess_type(file)[0] #add in the contents type
)
pos += 1 #increase the naming iteration
#print(files)
r = requests.post(url, headers=headers, json=json_data, files=files)
print("")
print(r)
print("")
print(r.text)
I've figured it out! Took a look at the outlook API documentation and realised I should be adding attachments as encoded lists within the message Json, not within the request.post function. Here's my working example:
import requests
import json
import pandas as pd
import mimetypes
import base64
url = "https://outlook.office.com/api/v2.0/me/sendmail"
headers = {
'Authorization': 'Bearer '+access_token,
}
Attachments = []
file_list = ['test_files/image.png', 'test_files/test.xlsx']
for file in file_list:
x = file.split('/') #file the file path so we can get it's na,e
filename = x[1] #get the filename
content = open(file,'rb') #load the content
#encode the file into bytes then turn those bytes into a string
encoded_string = ''
with open(file, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
encoded_string = encoded_string.decode("utf-8")
#append the file to the attachments list
Attachments.append({
"#odata.type": "#Microsoft.OutlookServices.FileAttachment",
"Name": filename,
"ContentBytes": encoded_string
})
data = {}
data['Message'] = {
'Subject': "Test",
'Body': {
'ContentType': 'Text',
'Content': 'This is a test'
},
'ToRecipients': [
{
'EmailAddress':{
'Address': 'EMAIL_ADDRESS'
}
}
],
"Attachments": Attachments
}
data['SaveToSentItems'] = "true"
json_data = json.dumps(data)
json_data = json.loads(json_data)
r = requests.post(url, headers=headers, json=json_data)
print(r)
I'm using python to access elasticsearch cluster. Now I want to backup my index by using snapshot.
The most difficult thing is that: the python-elasticsearch's doc just give me a API description. there is no example to show me how to create snapshot. I tried some parameters, but failed. Can anyone give a snapshot example of elastic-search by using python? The following is my code:
from elasticsearch import Elasticsearch
es = Elasticsearch()
snapshot_body = {
"type": "url",
"settings": {
"url": "http://download.elasticsearch.org/definitiveguide/sigterms_demo/"
}
}
body = {"snapshot": snapshot_body}
es.snapshot.create_repository(repository='test', body=body)
Your repository creation is almost correct, you don't need the line body = {"snapshot": snapshot_body}, simply create your repository like this:
es.snapshot.create_repository(repository='test', body=snapshot_body)
Now in order to create a snapshot, all you have to do is this:
es.snapshot.create(repository='test', snapshot='my_snapshot')
If you want to store only a few indices and not all you can also provide a body like this:
index_body = {
"indices": "index_1,index_2"
}
es.snapshot.create(repository='test', snapshot='my_snapshot', body=index_body)
Save the following sample Python code as a Python file, such as register-repo.py. The client requires the AWS SDK for Python (Boto3), requests and requests-aws4auth packages. The client contains commented-out examples for other snapshot operations.
import boto3
import requests
from requests_aws4auth import AWS4Auth
host = '' # include https:// and trailing /
region = '' # e.g. us-west-1
service = 'es'
credentials = boto3.Session().get_credentials()
awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)
# Register repository
path = '_snapshot/my-snapshot-repo-name' # the Elasticsearch API endpoint
url = host + path
payload = {
"type": "s3",
"settings": {
"bucket": "s3-bucket-name",
# "endpoint": "s3.amazonaws.com", # for us-east-1
"region": "us-west-1", # for all other regions
"role_arn": "arn:aws:iam::123456789012:role/TheSnapshotRole"
}
}
headers = {"Content-Type": "application/json"}
r = requests.put(url, auth=awsauth, json=payload, headers=headers)
print(r.status_code)
print(r.text)
# # Take snapshot
#
# path = '_snapshot/my-snapshot-repo/my-snapshot'
# url = host + path
#
# r = requests.put(url, auth=awsauth)
#
# print(r.text)
#
# # Delete index
#
# path = 'my-index'
# url = host + path
#
# r = requests.delete(url, auth=awsauth)
#
# print(r.text)
#
# # Restore snapshot (all indices except Kibana and fine-grained access control)
#
# path = '_snapshot/my-snapshot-repo/my-snapshot/_restore'
# url = host + path
#
# payload = {
# "indices": "-.kibana*,-.opendistro_security",
# "include_global_state": false
# }
#
# headers = {"Content-Type": "application/json"}
#
# r = requests.post(url, auth=awsauth, json=payload, headers=headers)
#
# # Restore snapshot (one index)
#
# path = '_snapshot/my-snapshot-repo/my-snapshot/_restore'
# url = host + path
#
# payload = {"indices": "my-index"}
#
# headers = {"Content-Type": "application/json"}
#
# r = requests.post(url, auth=awsauth, json=payload, headers=headers)
#
# print(r.text)
DONT USE THIS IN US EAST 1 then you have to use this
Important
If the S3 bucket is in the us-east-1 region, you must use "endpoint": "s3.amazonaws.com" instead of "region": "us-east-1".
To enable server-side encryption with S3-managed keys for the snapshot repository, add "server_side_encryption": true to the "settings" JSON.
https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-managedomains-snapshots.html#es-managedomains-snapshot-registerdirectory