Turn project data into a usable channel brief
A new channel can launch structured analysis of the data its workflow returns.
Trigger
New Channel Created Trigger
Triggered when a new channel is created in Slack.
Action
Execute Code remotely in work bench
Process **REMOTE FILES** or script BULK TOOL EXECUTIONS using Python code IN A REMOTE SANDBOX. If you can see the data in chat, DON'T USE THIS TOOL. **ONLY** use this when processing **data stored in a remote file** or when scripting bulk tool executions. DO NOT USE - When the complete response is already inline/in-memory, or you only need quick parsing, summarization, or basic math. USE IF - To parse/analyze tool outputs saved by COMPOSIO_MULTI_EXECUTE_TOOL to a remote file in the sandbox or to script multi-tool chains there. - For bulk or repeated executions of known Composio tools (e.g., add a label to 100 emails). - To call APIs via proxy_execute when no Composio tool exists for that API. OUTPUTS - Returns a compact result or, if too long, artifacts under `/mnt/files/.composio/output` (cloud-backed FUSE mount, persisted across sandbox restarts). IMPORTANT CODING RULES: 1. Stepwise Execution: Split work into small steps. Save intermediate outputs to `/mnt/files/` (cloud-backed, persisted across failures/timeouts) or variables. Call COMPOSIO_REMOTE_WORKBENCH again for the next step. 2. Notebook Persistence: This is a persistent Jupyter notebook cell: variables, functions, imports, and in-memory state persist across executions. Helper functions are preloaded. 3. Top-level cells: Do not use `return`; Jupyter only allows it inside functions. For final values, end with `output` or `print(output)`, not `return output`. 4. Parallelism & Timeout (CRITICAL): There is a **hard 3-minute (180s) execution limit** per cell. Always prioritize PARALLEL execution using ThreadPoolExecutor for bulk operations - e.g., call run_composio_tool or invoke_llm across rows. If data is large, split it into smaller batches across cells. 5. Checkpoints: Save checkpoints to `/mnt/files/` so that long runs can be resumed from the last completed step, even after a timeout or sandbox restart. 6. Schema Safety: Never assume the response schema for run_composio_tool if not known already from previous tools. To inspect schema, either run a simple request **outside** the workbench or use invoke_llm helper. 7. LLM Helpers: Always use invoke_llm helper for summary, analysis, or field extraction on results; prefer it for much better results over ad hoc filtering. 8. Avoid Meta Loops: Do not use run_composio_tool to call COMPOSIO_* meta tools. Only use it for app tools. 9. Pagination: Use when data spans multiple pages. Continue fetching pages with the returned next_page_token or cursor until none remains. Parallelize page fetches when the tool supports page_number. 10. No Hardcoding: Never hardcode data. Load it from files or tool responses, iterating to construct intermediate or final inputs/outputs. 11. If the final output is in a workbench file, use upload_local_file to download it - never expose the raw workbench file path to the user. Prefer to download useful artifacts after task is complete. ENV & HELPERS: - Home directory: `/home/user`. - NOTE: Helper functions already initialized in the workbench - DO NOT import or redeclare them: - `run_composio_tool(tool_slug: str, arguments: dict) -> tuple[Dict[str, Any], str]`: Execute a known Composio **app** tool. Do not invent names; match the tool input schema. Use for loops/parallel/bulk calls. i) run_composio_tool returns JSON with top-level "data". Parse carefully—structure may be nested. - `invoke_llm(query: str) -> tuple[str, str]`: Invoke an LLM for semantic tasks. Pass MAX 200k characters. i) NOTE Prompting guidance: When building prompts for invoke_llm, prefer f-strings (or concatenation) so literal braces stay intact. If using str.format, escape braces by doubling them ({{ }}). ii) Define the exact JSON schema you want and batch items into smaller groups to stay within token limit. - `upload_local_file(*file_paths) -> tuple[Dict[str, Any], str]`: Upload sandbox files to Composio S3/R2 storage for user-downloadable artifacts. - `proxy_execute(method, endpoint, toolkit, query_params=None, body=None, headers=None) -> tuple[Any, str]`: Call a toolkit API directly when no Composio tool exists. Only one toolkit can be invoked with proxy_execute per workbench call - `web_search(query: str) -> tuple[str, str]`: Search the web for information. - `smart_file_extract(sandbox_file_path: str, show_preview: bool = True) -> tuple[str, str]`: Extracts text from files in the sandbox (e.g., PDF, image). All helper functions return a tuple (result, error). Always check error before using result. ## Python Helper Functions for LLM Scripting ### run_composio_tool Executes a known Composio tool via backend API. Do NOT call COMPOSIO_* meta tools to avoid cycles. def run_composio_tool(tool_slug: str, arguments: Dict[str, Any]) -> tuple[Dict[str, Any], str] # Returns: (tool_response_dict, error_message) # Success: ({"data": {actual_data}}, "") - Note the top-level data # Error: ({}, "error_message") or (response_data, "error_message") result, error = run_composio_tool("GMAIL_FETCH_EMAILS", {"max_results": 1, "user_id": "me"}) if error: print("GMAIL_FETCH_EMAILS error:", error) else: email_data = result.get("data", {}) print("Fetched:", email_data) ### invoke_llm Calls LLM for reasoning, analysis, and semantic tasks. Pass MAX 200k characters. # Returns: (llm_response, error_message) # Example: analyze tool response with LLM tool_resp, err = run_composio_tool("GMAIL_FETCH_EMAILS", {"max_results": 5, "user_id": "me"}) if not err: parsed = tool_resp.get("data", {}) resp, err2 = invoke_llm(f"Summarize these emails: {parsed}") if not err2: print(resp) # TIP: batch prompts to reduce LLM calls. ### upload_local_file Uploads sandbox files to Composio S3/R2 storage for upload/download requests involving generated sandbox artifacts. Single files upload directly; multiple files are auto-zipped. # Returns: (result_dict, error_string) # Success: ({"s3_url": str, "uploaded_file": str, "type": str, "id": str, "s3key": str, "message": str}, "") # Error: ({}, "error_message") # Single file result, error = upload_local_file("/path/to/report.pdf") # Multiple files are auto-zipped result, error = upload_local_file("/home/user/doc1.txt", "/home/user/doc2.txt") if not error: print("Uploaded:", result["s3_url"]) ### proxy_execute Direct API call to a connected toolkit service. def proxy_execute( method: Literal["GET","POST","PUT","DELETE","PATCH"], endpoint: str, toolkit: str, query_params: Optional[Dict[str, str]] = None, body: Optional[object] = None, headers: Optional[Dict[str, str]] = None, ) -> tuple[Any, str] # Returns: (response_data, error_message) # Example: GET request with query parameters query_params = {"q": "is:unread", "maxResults": "10"} data, error = proxy_execute("GET", "/gmail/v1/users/me/messages", "gmail", query_params=query_params) if not error: print("Success:", data) ### web_search Searches the web via Exa AI. # Returns: (search_results_text, error_message) results, error = web_search("latest developments in AI") if not error: print("Results:", results) ## Best Practices ### Error-first pattern and Defensive parsing (print keys while narrowing) res, err = run_composio_tool("GMAIL_FETCH_EMAILS", {"max_results": 5}) if err: print("error:", err) elif isinstance(res, dict): print("res keys:", list(res.keys())) data = res.get("data") or {} print("data keys:", list(data.keys())) msgs = data.get("messages") or [] print("messages count:", len(msgs)) for m in msgs: print("subject:", m.get("subject", "<missing>")) ### Parallelize within the 3-minute cell timeout Adjust concurrency so all tasks finish within 3 minutes. import concurrent.futures MAX_CONCURRENCY = 10 # Adjust as needed def process_one(item): result, error = run_composio_tool("GMAIL_SEND_EMAIL", item) if error: return {"status": "failed", "error": error} return {"status": "ok", "data": result} with concurrent.futures.ThreadPoolExecutor(max_workers=MAX_CONCURRENCY) as ex: results = list(ex.map(process_one, items))
Why this helps
Project kickoff data is scattered across large responses that nobody has time to inspect.
- Accelerate project kickoff
- Summarize large datasets
- Create a shared starting brief
Setup
Build it in a few focused steps.
- 1Connect Slackbot and Composio once in Notis.
- 2Create an automation that runs remote code to analyze returned project data.
- 3Pick New Channel Created Trigger as the trigger.
- 4Choose where the analysis brief should be reported.
- 5Test by creating one temporary channel with sample data.
Questions about this workflow
What does remote code process?
It processes remote files or bulk tool executions stored in the remote sandbox.
When this happens · Trigger
Do this · Action
Supported Triggers and Actions
Notis builds workflows that link Slackbot to Composio. A trigger fires from one place; an action lands in another.
Slackbot triggers
Composio actions
Recurring trigger
Notis starts this workflow on a schedule, such as daily, weekly, or during business hours.
Ask Oracle
Static helper that returns a comprehensive system prompt describing how to plan and execute tasks using the available composio tools and workflows. no inputs required; simply call to retrieve the prompt. always call this after the search tool is executed -- it will provide the best context on how to proceed, chain tools, and execute the task end-to-end. relevant tools referenced by the prompt: 1. composio search tools 2. composio multi execute tool 3. composio execute code 4. composio manage connections 5. composio bash tool
Webhook trigger
Notis starts this workflow when an external tool or custom backend sends an HTTP request.
Check active connection (deprecated)
Deprecated: use check active connections instead for bulk operations. check active connection status for a toolkit or specific connected account id. returns connection details if active, or required parameters for establishing connection if none exists. active connections enable agent actions on the toolkit.
New Channel Created Trigger
Triggered when a new channel is created in Slack.
Check multiple active connections
Check active connection status for multiple toolkits or specific connected account ids. returns connection details if active, or required parameters for establishing connection if none exists. active connections enable agent actions on toolkits.
Channel Message Received
Triggered when a message is posted in a Slack channel (public, private, or multi-party IM). Does NOT match direct messages.
Create Plan
This is a workflow builder that ensures the LLM produces a complete, step-by-step plan for any use case. WHEN TO CALL: - Call this tool based on COMPOSIO_SEARCH_TOOLS output. If search tools response indicates create_plan should be called and the usecase is not easy, call it. - Use this tool after COMPOSIO_SEARCH_TOOLS or COMPOSIO_MANAGE_CONNECTIONS to generate an execution plan for the user's use case. - USE for medium or hard tasks — skip it for easy ones. - If the user switches to a new use case in the same chat and COMPOSIO_SEARCH_TOOLS again instructs you to call the planner, you MUST call this tool again for that new use case. Memory Integration: - You can choose to add the memory received from the search tool into the known_fields parameter of the plan function to enhance planning with discovered relationships and information. Outputs a complete plan with sections such as "workflow_steps", "complexity_assessment", "decision_matrix", "failure_handling" "output_format", and more as needed. If you skip this step for non-easy tasks, workflows will likely be incomplete, or fail during execution for complex tasks. Calling it guarantees reliable, accurate, and end-to-end workflows aligned with the available tools and connections.
Direct Message Received
Triggered when a new direct message (DM) is sent to a user in Slack. Catches all DMs across all DM channels.
Enable trigger
Enable a specific trigger for the authenticated user.
Message Reaction Added
Triggered when a reaction is added to a message in Slack. Supports optional filtering by channel and emoji name.
Execute agent
Execute complex workflows using ai agent reasoning between multiple tool calls. use this for: complex multi-step workflows requiring reasoning, error handling and retry logic. use composio multi execute tool instead for: simple parallel operations, batch operations on similar data (e.g., fetch 5 emails, get 10 sent messages, retrieve multiple user profiles), independent tool calls that don't need each other's results, or bulk operations where all parameters are known upfront. performance: agent calls add ~2-3 seconds overhead. use for workflows >3 tools or requiring conditional logic. avoid for simple parameter passing.
Message Reaction Removed
Triggered when a reaction is removed from a message in Slack. Supports optional filtering by channel and emoji name.
Execute Composio Tool
Execute a tool using the composio api.
Reaction Added Trigger
DEPRECATED: use `SLACK_MESSAGE_REACTION_ADDED` instead. Triggered when a reaction is added to a message in Slack.
Get Tool Dependency Graph
Get the dependency graph for a given tool, showing related parent tools that might be useful. this action calls the composio labs dependency graph api to retrieve tools that are commonly used together with or before the specified tool. this helps discover related tools and understand common workflows.
Connect any two apps with Notis in the middle.
Slackbot and Composio, or any other combination from 1,000+ integrations.
When this happens · Trigger
Do this · Action
Save your first hour today.
7-day trial of any paid plan, with 20$ of usage included.
No card. Works with personal or business Composio.