diff --git a/__init__.py b/__init__.py
index 68ce38fd..50e724a0 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1196,12 +1196,25 @@ async def channel_url_list(request):
return web.Response(status=200)
+@server.PromptServer.instance.routes.get("/manager/check_matrix")
+async def check_matrix(request):
+ # Check if the user has provided Matrix credentials in a file called 'matrix_accesstoken'
+ # in the same directory as the ComfyUI base folder
+ print("Checking for Matrix credentials...")
+ if not os.path.exists(os.path.join(folder_paths.base_path, "matrix_accesstoken")):
+ return web.Response(status=404)
+ with open(os.path.join(folder_paths.base_path, "matrix_accesstoken"), "r") as f:
+ access_token = f.read()
+ if not access_token.strip():
+ return web.Response(status=404)
+ return web.Response(status=200)
@server.PromptServer.instance.routes.post("/manager/share")
async def share_art(request):
# get json data
json_data = await request.json()
+ share_destinations = json_data['share_destinations']
credits = json_data['credits']
title = json_data['title']
description = json_data['description']
@@ -1228,49 +1241,87 @@ async def share_art(request):
# get the mime type of the asset
assetFileType = mimetypes.guess_type(asset_filepath)[0]
- share_website_host = "https://comfyworkflows.com"
- share_endpoint = f"{share_website_host}/api"
+ if "comfyworkflows" in share_destinations:
+ share_website_host = "https://comfyworkflows.com"
+ share_endpoint = f"{share_website_host}/api"
+
+ # get presigned urls
+ async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
+ async with session.post(
+ f"{share_endpoint}/get_presigned_urls",
+ json={
+ "assetFileName": asset_filename,
+ "assetFileType": assetFileType,
+ },
+ ) as resp:
+ assert resp.status == 200
+ presigned_urls_json = await resp.json()
+ assetFilePresignedUrl = presigned_urls_json["assetFilePresignedUrl"]
+ assetFileKey = presigned_urls_json["assetFileKey"]
+
+ # upload asset
+ async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
+ async with session.put(assetFilePresignedUrl, data=open(asset_filepath, "rb")) as resp:
+ assert resp.status == 200
- # get presigned urls
- async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
- async with session.post(
- f"{share_endpoint}/get_presigned_urls",
- json={
- "assetFileName": asset_filename,
- "assetFileType": assetFileType,
- },
- ) as resp:
- assert resp.status == 200
- presigned_urls_json = await resp.json()
- assetFilePresignedUrl = presigned_urls_json["assetFilePresignedUrl"]
- assetFileKey = presigned_urls_json["assetFileKey"]
+ # make a POST request to /api/upload_workflow with form data key values
+ async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
+ form = aiohttp.FormData()
+ form.add_field("assetFileKey", assetFileKey)
+ form.add_field("assetFileType", assetFileType)
+ form.add_field("sharedWorkflowWorkflowJsonString", json.dumps(prompt['workflow']))
+ form.add_field("sharedWorkflowPromptJsonString", json.dumps(prompt['output']))
+ form.add_field("shareWorkflowCredits", credits)
+ form.add_field("shareWorkflowTitle", title)
+ form.add_field("shareWorkflowDescription", description)
+ form.add_field("shareWorkflowIsNSFW", str(is_nsfw).lower())
+
+ async with session.post(
+ f"{share_endpoint}/upload_workflow",
+ data=form,
+ ) as resp:
+ assert resp.status == 200
+ upload_workflow_json = await resp.json()
+ workflowId = upload_workflow_json["workflowId"]
+
+ # check if the user has provided Matrix credentials
+ if "matrix" in share_destinations:
+ with open(os.path.join(folder_paths.base_path, "matrix_accesstoken"), "r") as f:
+ access_token = f.read().strip()
+
+ comfyui_share_room_id = '!LGYSoacpJPhIfBqVfb:matrix.org'
+ filename = os.path.basename(asset_filepath)
+ content_type = assetFileType
+
+ try:
+ from matrix_client.api import MatrixHttpApi
+ matrix = MatrixHttpApi("https://matrix.org", token=access_token)
+ with open(asset_filepath, 'rb') as f:
+ mxc_url = matrix.media_upload(f.read(), content_type, filename=filename)['content_uri']
+ text_content = ""
+ if title:
+ text_content += f"{title}\n"
+ if description:
+ text_content += f"{description}\n"
+ if credits:
+ text_content += f"\ncredits: {credits}\n"
+ response = matrix.send_message(comfyui_share_room_id, text_content)
+ print(response)
+ response = matrix.send_content(comfyui_share_room_id, mxc_url, filename, 'm.image')
+ print(response)
+ except:
+ import traceback
+ traceback.print_exc()
+ return web.json_response({"error" : "An error occurred when sharing your art to Matrix."}, content_type='application/json', status=500)
- # upload asset
- async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
- async with session.put(assetFilePresignedUrl, data=open(asset_filepath, "rb")) as resp:
- assert resp.status == 200
-
- # make a POST request to /api/upload_workflow with form data key values
- async with aiohttp.ClientSession(trust_env=True, connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
- form = aiohttp.FormData()
- form.add_field("assetFileKey", assetFileKey)
- form.add_field("assetFileType", assetFileType)
- form.add_field("sharedWorkflowWorkflowJsonString", json.dumps(prompt['workflow']))
- form.add_field("sharedWorkflowPromptJsonString", json.dumps(prompt['output']))
- form.add_field("shareWorkflowCredits", credits)
- form.add_field("shareWorkflowTitle", title)
- form.add_field("shareWorkflowDescription", description)
- form.add_field("shareWorkflowIsNSFW", str(is_nsfw).lower())
-
- async with session.post(
- f"{share_endpoint}/upload_workflow",
- data=form,
- ) as resp:
- assert resp.status == 200
- upload_workflow_json = await resp.json()
- workflowId = upload_workflow_json["workflowId"]
-
- return web.json_response({"url" : f"{share_website_host}/workflows/{workflowId}"}, content_type='application/json', status=200)
+ return web.json_response({
+ "comfyworkflows" : {
+ "url" : None if "comfyworkflows" not in share_destinations else f"{share_website_host}/workflows/{workflowId}",
+ },
+ "matrix" : {
+ "success" : None if "matrix" not in share_destinations else True
+ }
+ }, content_type='application/json', status=200)
WEB_DIRECTORY = "js"
NODE_CLASS_MAPPINGS = {}
diff --git a/js/comfyui-manager.js b/js/comfyui-manager.js
index 13ec6184..b98bf809 100644
--- a/js/comfyui-manager.js
+++ b/js/comfyui-manager.js
@@ -1995,6 +1995,16 @@ class ShareDialog extends ComfyDialog {
this.is_nsfw_checkbox.style.color = "var(--fg-color)";
this.is_nsfw_checkbox.checked = false;
+ this.matrix_destination_checkbox = $el("input", { type: 'checkbox', id: "matrix_destination" }, [])
+ const matrix_destination_checkbox_text = $el("label", {}, [" ComfyUI Matrix server"])
+ this.matrix_destination_checkbox.style.color = "var(--fg-color)";
+ this.matrix_destination_checkbox.checked = true;
+
+ this.comfyworkflows_destination_checkbox = $el("input", { type: 'checkbox', id: "comfyworkflows_destination" }, [])
+ const comfyworkflows_destination_checkbox_text = $el("label", {}, [" ComfyWorkflows.com"])
+ this.comfyworkflows_destination_checkbox.style.color = "var(--fg-color)";
+ this.comfyworkflows_destination_checkbox.checked = true;
+
this.credits_input = $el("input", {
type: "text",
placeholder: "This will be used to give you credits",
@@ -2026,6 +2036,35 @@ class ShareDialog extends ComfyDialog {
const nodes = app.graph._nodes;
+ const destinations = [];
+ if (this.matrix_destination_checkbox.checked) {
+ destinations.push("matrix");
+ }
+ if (this.comfyworkflows_destination_checkbox.checked) {
+ destinations.push("comfyworkflows");
+ }
+
+ // if destinations includes matrix, make an api call to /manager/check_matrix to ensure that the user has configured their matrix settings
+ if (destinations.includes("matrix")) {
+ const response = await api.fetchApi(`/manager/check_matrix`);
+ if (response.status != 200) {
+ alert("Please add your Matrix access token in a file called 'matrix_accesstoken' in the ComfyUI folder. To get your Matrix access token, go to https://app.element.io/, click on your profile, click on 'All settings', click on 'Help & About', and copy 'Access Token', and then click on 'Regenerate'.");
+ // Reset state
+ this.matrix_destination_checkbox.checked = true;
+ this.comfyworkflows_destination_checkbox.checked = true;
+ this.share_button.textContent = "Share";
+ this.share_button.style.display = "inline-block";
+ this.final_message.innerHTML = "";
+ this.final_message.style.color = "white";
+ this.credits_input.value = "";
+ this.title_input.value = "";
+ this.description_input.value = "";
+ this.is_nsfw_checkbox.checked = false;
+ this.close();
+ return;
+ }
+ }
+
const potential_outputs = [];
const potential_output_nodes = [];
@@ -2068,6 +2107,7 @@ class ShareDialog extends ComfyDialog {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
+ share_destinations: destinations,
credits: this.credits_input.value,
title: this.title_input.value,
description: this.description_input.value,
@@ -2086,7 +2126,17 @@ class ShareDialog extends ComfyDialog {
const response_json = await response.json();
- this.final_message.innerHTML = "Your art has been shared: " + response_json.url + "";
+ if (response_json.comfyworkflows.url) {
+ this.final_message.innerHTML = "Your art has been shared: " + response_json.comfyworkflows.url + "";
+ if (response_json.matrix.success) {
+ this.final_message.innerHTML += "
Your art has been shared in the ComfyUI Matrix server's #share channel!";
+ }
+ } else {
+ if (response_json.matrix.success) {
+ this.final_message.innerHTML = "Your art has been shared in the ComfyUI Matrix server's #share channel!";
+ }
+ }
+
this.final_message.style.color = "green";
// hide the share button
@@ -2101,18 +2151,27 @@ class ShareDialog extends ComfyDialog {
[
$el("tr.td", { width: "100%" }, [
$el("font", { size: 6, color: "white" }, [`Share your art`]),
- $el("div", { size: 3, color: "white" }, [
- $el("a", {
- href: `https://comfyworkflows.com/?ref=cms`,
- target: `_blank`,
- color: "white",
- // style: `color:white;`
- }, `comfyworkflows.com`)
- ])
+ // $el("div", { size: 3, color: "white" }, [
+ // $el("a", {
+ // href: `https://comfyworkflows.com/?ref=cms`,
+ // target: `_blank`,
+ // color: "white",
+ // // style: `color:white;`
+ // }, `comfyworkflows.com`)
+ // ])
]),
$el("p", { size: 4, color: "white" }, [`Get a public link for this art & workflow.`]),
// $el("br", {}, []),
+ $el("div", {}, [
+ $el("p", { size: 3, color: "white" }, [`Select where to share your art:`]),
+ this.matrix_destination_checkbox,
+ matrix_destination_checkbox_text,
+ $el("br", {}, []),
+ this.comfyworkflows_destination_checkbox,
+ comfyworkflows_destination_checkbox_text,
+ ]),
+
$el("h2", {
textContent: "Your name/username (optional)",
size: 3,
@@ -2148,6 +2207,8 @@ class ShareDialog extends ComfyDialog {
textContent: "Close",
onclick: () => {
// Reset state
+ this.matrix_destination_checkbox.checked = true;
+ this.comfyworkflows_destination_checkbox.checked = true;
this.share_button.textContent = "Share";
this.share_button.style.display = "inline-block";
this.final_message.innerHTML = "";
diff --git a/requirements.txt b/requirements.txt
index 5779f396..3467b3e5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1,2 @@
-GitPython
\ No newline at end of file
+GitPython
+matrix-client==0.4.0
\ No newline at end of file