Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions .github/workflows/auto-integrate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,23 @@ name: auto-integrate
# GitHub Actions injection-safety guidelines.

on:
schedule:
# 5-minute cadence (GitHub Actions minimum). `concurrency` block
# below ensures only one run executes at a time; overlapping
# cron triggers queue rather than parallelize. Combined with
# the self-dispatch step at the end of the workflow, this gives
# near-continuous processing when the producer queue has work,
# and 5-minute polling when it doesn't.
- cron: '*/5 * * * *'
# ─── DEACTIVATED 2026-05-30 ──────────────────────────────────────────────
# The auto-integrate cron is intentionally disabled. The workflow files are
# kept so the pipeline can be re-enabled later. To reactivate:
# 1. Uncomment the `schedule:` block below.
# 2. Restore the `if:` condition on the "Self-dispatch next run" step
# (its original value is preserved in a comment there).
# 3. Re-enable on GitHub: gh workflow enable auto-integrate.yml
# `workflow_dispatch` stays active so the pipeline can still be run manually
# on demand without restarting the automatic chain.
# schedule:
# # 5-minute cadence (GitHub Actions minimum). `concurrency` block
# # below ensures only one run executes at a time; overlapping
# # cron triggers queue rather than parallelize. Combined with
# # the self-dispatch step at the end of the workflow, this gives
# # near-continuous processing when the producer queue has work,
# # and 5-minute polling when it doesn't.
# - cron: '*/5 * * * *'
workflow_dispatch:
inputs:
provider:
Expand Down Expand Up @@ -406,7 +415,13 @@ jobs:
# Concurrency group (`auto-integrate`) ensures self-dispatched runs
# never overlap with cron-triggered runs — they queue serially.
- name: Self-dispatch next run (chain on success)
if: steps.run.outputs.skipped != 'true' && steps.run.outputs.failed != 'true' && steps.run.outputs.tool_name != '' && github.event.inputs.dry_run != 'true'
# DEACTIVATED 2026-05-30: the self-dispatch chain is disabled alongside
# the cron (see the `on:` block at the top of this file). This prevents
# a manual `workflow_dispatch` run from restarting the automatic chain.
# To reactivate, restore the original condition preserved on the next
# line and uncomment the `schedule:` block above.
# Original: steps.run.outputs.skipped != 'true' && steps.run.outputs.failed != 'true' && steps.run.outputs.tool_name != '' && github.event.inputs.dry_run != 'true'
if: false
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TOOL_NAME: ${{ steps.run.outputs.tool_name }}
Expand Down
83 changes: 83 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,89 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and

### Added

- `revolt` integration — 3 actions, auth: bearer_token. Revolt open-source
chat platform — group management and friend requests (create_group,
add_group_member, send_friend_request). Producer-staged by
integration-drafts; consumer-side audit applied 5 patches before merge.

- `woocommerce` integration — 17 actions, auth: custom. WooCommerce REST API
integration for managing orders, products, customers, and refunds on
self-hosted WooCommerce stores (create_order, get_order, list_orders,
delete_order, update_order_status, create_product, update_product,
get_product, list_products, search_customers, get_customer,
create_customer, add_order_note, get_order_note, list_order_notes,
create_refund, list_payment_method_options). Producer-staged by
integration-drafts; consumer-side audit applied 2 patches before merge.

- `coinmarketcap` integration — 4 actions, auth: api_key. Cryptocurrency
market data, quotes, and metadata from the CoinMarketCap API
(get_cryptocurrency_metadata, id_map, latest_listings, latest_quotes).
Producer-staged by integration-drafts; consumer-side audit applied
2 patches before merge.

- `cogmento` integration — 4 actions, auth: oauth2. CRM platform for
managing contacts, deals, and tasks via the Cogmento API
(create_contact, create_deal, create_task, list_user_ids_options).
Producer-staged by integration-drafts; consumer-side audit applied
3 patches before merge.

- `fellow` integration — 3 actions, auth: api_key. Meeting productivity
platform for notes, action items, and meeting management via the Fellow API
(archive_action_item, complete_action_item, get_note_by_id). Producer-staged
by integration-drafts; consumer-side audit applied 1 patch before merge.

- `canvas` integration — 5 actions, auth: custom. Canvas LMS integration
for course, assignment, and user management via the Canvas REST API
(list_accounts, list_courses, list_assignments, search_course_content,
update_assignment). Producer-staged by integration-drafts; consumer-side
audit applied 2 patches before merge.

- `motion` integration — 6 actions, auth: api_key. AI-powered task and
project management platform for automatic scheduling via the Motion API
(create_task, delete_task, get_schedules, get_task, move_workspace,
update_task). Producer-staged by integration-drafts; consumer-side audit
applied 1 patch before merge.

- `livestorm` integration — 7 actions, auth: oauth2. Video engagement
platform for webinars and virtual events via the Livestorm REST API
(create_event, get_event, list_attendees_from_event, list_events,
list_sessions, register_someone_for_session, update_event).
Producer-staged by integration-drafts; consumer-side audit applied
12 patches before merge.

- `heygen` integration — 5 actions, auth: api_key. AI video generation
platform for creating talking avatar videos via the HeyGen API
(create_talking_photo, create_video_from_template,
list_custom_events_options, list_voice_id_options, retrieve_video_link).
Producer-staged by integration-drafts; consumer-side audit applied
1 patch before merge.

- `yelp` integration — 4 actions, auth: api_key. Search businesses, read
reviews, and get business details via the Yelp Fusion API
(search_businesses, get_business_details, list_business_reviews,
search_businesses_by_phone_number). Producer-staged by
integration-drafts; consumer-side audit applied 1 patch before merge.

- `square` integration — 6 actions, auth: oauth2. Payment processing,
commerce, and business management platform via the Square Connect v2 API
(create_customer, create_invoice, create_order, list_event_types_options,
list_location_options, send_invoice). Producer-staged by
integration-drafts; consumer-side audit applied 4 patches before merge.

- `hunter` integration — 13 actions, auth: api_key. Professional email
finding and verification via the Hunter.io API (account_information,
combined_enrichment, create_lead, delete_lead, domain_search,
email_count, email_finder, email_verifier, get_lead, get_leads_list,
list_leads, list_leads_lists, update_lead). Producer-staged by
integration-drafts; consumer-side audit applied 1 patch before merge.

- `gong` integration — 5 actions, auth: oauth2. Revenue intelligence
platform for recording, transcribing, and analyzing sales conversations
via the Gong REST API (add_new_call, get_extensive_data, list_calls,
list_workspace_id_options, retrieve_transcripts_of_calls).
Producer-staged by integration-drafts; consumer-side audit applied
3 patches before merge.

- `figma` integration — 3 actions, auth: oauth2. Design collaboration
platform for creating, sharing, and commenting on design files via the
Figma REST API (list_comments, delete_comment, post_a_comment).
Expand Down
60 changes: 60 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ slack = "modulex_integrations.tools.slack"
etsy = "modulex_integrations.tools.etsy"
exa = "modulex_integrations.tools.exa"
fal_ai = "modulex_integrations.tools.fal_ai"
fellow = "modulex_integrations.tools.fellow"
figma = "modulex_integrations.tools.figma"
tavily = "modulex_integrations.tools.tavily"
insightly = "modulex_integrations.tools.insightly"
Expand All @@ -89,9 +90,11 @@ crunchbase = "modulex_integrations.tools.crunchbase"
dropbox = "modulex_integrations.tools.dropbox"
docusign = "modulex_integrations.tools.docusign"
hackernews = "modulex_integrations.tools.hackernews"
heygen = "modulex_integrations.tools.heygen"
help_scout = "modulex_integrations.tools.help_scout"
heroku = "modulex_integrations.tools.heroku"
hootsuite = "modulex_integrations.tools.hootsuite"
hunter = "modulex_integrations.tools.hunter"
lemon_squeezy = "modulex_integrations.tools.lemon_squeezy"
short_io = "modulex_integrations.tools.short_io"
nasdaq = "modulex_integrations.tools.nasdaq"
Expand All @@ -103,9 +106,11 @@ jira = "modulex_integrations.tools.jira"
cal_com = "modulex_integrations.tools.cal_com"
calendly = "modulex_integrations.tools.calendly"
canva = "modulex_integrations.tools.canva"
canvas = "modulex_integrations.tools.canvas"
instructure_canvas = "modulex_integrations.tools.instructure_canvas"
linear = "modulex_integrations.tools.linear"
linkedin = "modulex_integrations.tools.linkedin"
livestorm = "modulex_integrations.tools.livestorm"
luma = "modulex_integrations.tools.luma"
ahrefs = "modulex_integrations.tools.ahrefs"
airtable = "modulex_integrations.tools.airtable"
Expand All @@ -121,9 +126,11 @@ intercom = "modulex_integrations.tools.intercom"
scrape_do = "modulex_integrations.tools.scrape_do"
apollo_io = "modulex_integrations.tools.apollo_io"
cloudflare = "modulex_integrations.tools.cloudflare"
cogmento = "modulex_integrations.tools.cogmento"
segment = "modulex_integrations.tools.segment"
semrush = "modulex_integrations.tools.semrush"
gmail = "modulex_integrations.tools.gmail"
gong = "modulex_integrations.tools.gong"
godaddy = "modulex_integrations.tools.godaddy"
google_cloud = "modulex_integrations.tools.google_cloud"
google_contacts = "modulex_integrations.tools.google_contacts"
Expand All @@ -136,16 +143,19 @@ google_docs = "modulex_integrations.tools.google_docs"
sendgrid = "modulex_integrations.tools.sendgrid"
sentry = "modulex_integrations.tools.sentry"
coinbase = "modulex_integrations.tools.coinbase"
coinmarketcap = "modulex_integrations.tools.coinmarketcap"
databricks = "modulex_integrations.tools.databricks"
datadog = "modulex_integrations.tools.datadog"
postgresql = "modulex_integrations.tools.postgresql"
mysql = "modulex_integrations.tools.mysql"
snowflake = "modulex_integrations.tools.snowflake"
square = "modulex_integrations.tools.square"
supabase = "modulex_integrations.tools.supabase"
hubspot = "modulex_integrations.tools.hubspot"
notion = "modulex_integrations.tools.notion"
elevenlabs = "modulex_integrations.tools.elevenlabs"
reflect = "modulex_integrations.tools.reflect"
revolt = "modulex_integrations.tools.revolt"
salesforce = "modulex_integrations.tools.salesforce"
clickup = "modulex_integrations.tools.clickup"
google_drive = "modulex_integrations.tools.google_drive"
Expand Down Expand Up @@ -176,6 +186,7 @@ microsoft_teams = "modulex_integrations.tools.microsoft_teams"
mintlify = "modulex_integrations.tools.mintlify"
mixpanel = "modulex_integrations.tools.mixpanel"
monday = "modulex_integrations.tools.monday"
motion = "modulex_integrations.tools.motion"
postgrid = "modulex_integrations.tools.postgrid"
posthog = "modulex_integrations.tools.posthog"
postman = "modulex_integrations.tools.postman"
Expand All @@ -184,6 +195,8 @@ okta = "modulex_integrations.tools.okta"
pagerduty = "modulex_integrations.tools.pagerduty"
shopify = "modulex_integrations.tools.shopify"
shopify_partner = "modulex_integrations.tools.shopify_partner"
woocommerce = "modulex_integrations.tools.woocommerce"
yelp = "modulex_integrations.tools.yelp"
zoom = "modulex_integrations.tools.zoom"

[tool.hatch.version]
Expand Down Expand Up @@ -578,10 +591,57 @@ select = ["E", "F", "I", "N", "W", "B", "C4", "UP", "RUF"]
# ParameterDef / Field kwargs that cannot be wrapped.
"src/modulex_integrations/tools/instructure_canvas/manifest.py" = ["E501"]
"src/modulex_integrations/tools/instructure_canvas/tools.py" = ["E501"]
# gong manifest and tools have long description string literals in
# ParameterDef / Field kwargs and credential guard lines that cannot be wrapped.
"src/modulex_integrations/tools/gong/manifest.py" = ["E501"]
"src/modulex_integrations/tools/gong/tools.py" = ["E501"]
# postgrid manifest and tools have long description string literals in
# ParameterDef / Field kwargs that cannot be wrapped.
"src/modulex_integrations/tools/postgrid/manifest.py" = ["E501"]
"src/modulex_integrations/tools/postgrid/tools.py" = ["E501"]
# hunter manifest, tools, and tests have long description string literals in
# ParameterDef / Field kwargs that cannot be wrapped.
"src/modulex_integrations/tools/hunter/manifest.py" = ["E501"]
"src/modulex_integrations/tools/hunter/tools.py" = ["E501"]
"src/modulex_integrations/tools/hunter/tests/test_hunter.py" = ["E501"]
# square manifest, tools, and tests have long description string literals in
# ParameterDef / Field kwargs that cannot be wrapped.
"src/modulex_integrations/tools/square/manifest.py" = ["E501"]
"src/modulex_integrations/tools/square/tools.py" = ["E501"]
"src/modulex_integrations/tools/square/tests/test_square.py" = ["E501"]
# heygen manifest and tools have long description string literals in
# ParameterDef / Field kwargs that cannot be wrapped.
"src/modulex_integrations/tools/heygen/manifest.py" = ["E501"]
"src/modulex_integrations/tools/heygen/tools.py" = ["E501"]
# livestorm manifest and tools have long description string literals in
# ParameterDef / Field kwargs and credential guard lines that cannot be wrapped.
"src/modulex_integrations/tools/livestorm/manifest.py" = ["E501"]
"src/modulex_integrations/tools/livestorm/tools.py" = ["E501"]
# yelp manifest and tools have long description string literals in
# ParameterDef / Field kwargs that cannot be wrapped.
"src/modulex_integrations/tools/yelp/manifest.py" = ["E501"]
"src/modulex_integrations/tools/yelp/tools.py" = ["E501"]
# motion manifest, tools, and tests have long description string literals in
# ParameterDef / Field kwargs and credential guard lines that cannot be wrapped.
"src/modulex_integrations/tools/motion/manifest.py" = ["E501"]
"src/modulex_integrations/tools/motion/tools.py" = ["E501"]
"src/modulex_integrations/tools/motion/tests/test_motion.py" = ["E501"]
# canvas manifest and tools have long description string literals in
# ParameterDef / Field kwargs that cannot be wrapped.
"src/modulex_integrations/tools/canvas/manifest.py" = ["E501"]
"src/modulex_integrations/tools/canvas/tools.py" = ["E501"]
# cogmento tools have long description string literals in Field kwargs
# and credential guard lines that cannot be wrapped.
"src/modulex_integrations/tools/cogmento/tools.py" = ["E501"]
# coinmarketcap manifest and tools have long description string literals in
# ParameterDef / Field kwargs that cannot be wrapped.
"src/modulex_integrations/tools/coinmarketcap/manifest.py" = ["E501"]
"src/modulex_integrations/tools/coinmarketcap/tools.py" = ["E501"]
# woocommerce manifest, tools, and tests have long description string literals in
# ParameterDef / Field kwargs that cannot be wrapped.
"src/modulex_integrations/tools/woocommerce/manifest.py" = ["E501"]
"src/modulex_integrations/tools/woocommerce/tools.py" = ["E501"]
"src/modulex_integrations/tools/woocommerce/tests/test_woocommerce.py" = ["E501"]

[tool.mypy]
python_version = "3.12"
Expand Down
35 changes: 35 additions & 0 deletions src/modulex_integrations/tools/canvas/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Canvas LMS

Learning management system integration for course, assignment, and user management via the Canvas REST API (`https://{your-domain}/api/v1`).

## Authentication

### Canvas OAuth Token + Domain

Canvas LMS is self-hosted (each institution runs its own instance), so both your instance domain and an access token are required.

- **Canvas Domain**: Your Canvas instance hostname (e.g. `myschool.instructure.com`). Required env var: `CANVAS_DOMAIN`.
- **Access Token**: Generate from Account > Settings > Approved Integrations in your Canvas instance. Required env var: `CANVAS_ACCESS_TOKEN` (format: `7~xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`).
- Guide: [Managing API Access Tokens](https://community.canvaslms.com/t5/Admin-Guide/How-do-I-manage-API-access-tokens-as-an-admin/ta-p/89)

## Tools

| name | description | required params |
| --- | --- | --- |
| `list_accounts` | List Canvas accounts accessible to the authenticated user. | _(none)_ |
| `list_assignments` | Retrieve a list of assignments for a user in a specific course. | `user_id`, `course_id` |
| `list_courses` | List all courses associated with a given user. | `user_id` |
| `search_course_content` | Search for content in a course using Canvas smart search. | `course_id`, `query` |
| `update_assignment` | Update an existing assignment in a course. | `course_id`, `assignment_id` |

Every tool takes an additional `auth_type`/`auth_data` pair that the runtime fills in from the resolved credential (token-style injection).

## Limits & Quotas

- **Rate limits**: Canvas enforces per-user rate limits (typically 700 requests per 10 minutes for the default configuration, varies by institution).
- **Pagination**: List endpoints may return paginated results; current implementation fetches the first page.
- **Error model**: Non-2xx responses and timeouts are caught and returned as `success=False` + `error` rather than raising.

## Maintainer

ModuleX core team.
27 changes: 27 additions & 0 deletions src/modulex_integrations/tools/canvas/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Canvas LMS integration — discovered via the ``modulex.tools`` entry point."""
from modulex_integrations.tools.canvas.manifest import manifest
from modulex_integrations.tools.canvas.tools import (
list_accounts,
list_assignments,
list_courses,
search_course_content,
update_assignment,
)

TOOLS = (
list_accounts,
list_assignments,
list_courses,
search_course_content,
update_assignment,
)

__all__ = [
"TOOLS",
"list_accounts",
"list_assignments",
"list_courses",
"manifest",
"search_course_content",
"update_assignment",
]
3 changes: 3 additions & 0 deletions src/modulex_integrations/tools/canvas/dependencies.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Runtime dependencies for the canvas integration.
# CI assembles this into the root pyproject's [project.optional-dependencies].
dependencies = []
Loading
Loading