본문으로 건너뛰기
cccskills
무료GitHub에 공개

thunderbird-extension

Use when developing Thunderbird MailExtensions - Manifest V2/V3 configuration, messenger.* APIs for accounts, messages, folders and compose, UI actions, message display scripts, Experiment APIs, ATN submission, or migration from legacy extensions

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(5)

  • SKILL.md11.7 KB
  • references/atn-submission.md2.3 KB
  • references/experiment-apis.md3.5 KB
  • references/messenger-apis.md6.8 KB
  • references/testing-migration.md3.7 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Thunderbird MailExtension Development

Complete reference for building, testing, and publishing email extensions for Mozilla Thunderbird.

Overview

Thunderbird extensions use the MailExtension API (based on WebExtensions) with the messenger.* namespace. Thunderbird supports both Manifest V2 and V3 since version 128.

Key Characteristics:

  • Global namespace: messenger (Thunderbird-specific) + browser (standard WebExtensions)
  • Both MV2 and MV3 supported (Thunderbird 128+)
  • Thunderbird-specific APIs: accounts, addressBooks, compose, folders, mailTabs, messages, messageDisplay
  • Submission via ATN (addons.thunderbird.net)

Version Requirements

VersionStatusNotes
128.x (ESR)CurrentFull MV2 + MV3 support
115.xLegacyEnd of support
< 115DeprecatedNot recommended

Best Practice: Set strict_min_version to "128.0"

Manifest Structure

Manifest V3 (Recommended, Thunderbird 128+)

{
  "manifest_version": 3,
  "name": "My Thunderbird Extension",
  "version": "1.0.0",
  "description": "Extension description",
  "author": "Your Name",

  "browser_specific_settings": {
    "gecko": {
      "id": "extension@example.com",
      "strict_min_version": "128.0"
    }
  },

  "icons": {
    "16": "icons/icon-16.png",
    "32": "icons/icon-32.png",
    "64": "icons/icon-64.png"
  },

  "background": {
    "service_worker": "background.js",
    "type": "module"
  },

  "action": {
    "default_popup": "popup.html",
    "default_title": "My Extension",
    "default_icon": "icons/icon-32.png"
  },

  "permissions": [
    "storage",
    "messagesRead",
    "addressBooks"
  ]
}

Manifest V2 (Still Supported)

{
  "manifest_version": 2,
  "name": "My Thunderbird Extension",
  "version": "1.0.0",
  "author": "Your Name",

  "browser_specific_settings": {
    "gecko": {
      "id": "extension@example.com",
      "strict_min_version": "128.0"
    }
  },

  "background": {
    "scripts": ["background.js"],
    "type": "module"
  },

  "browser_action": {
    "default_popup": "popup.html",
    "default_title": "My Extension"
  },

  "permissions": [
    "storage",
    "messagesRead",
    "addressBooks"
  ]
}

MV2 vs MV3 Key Differences

FeatureMV2MV3
Toolbar buttonbrowser_actionaction
Backgroundbackground.scriptsbackground.service_worker
Execute scripttabs.executeScriptmessenger.scripting.messageDisplay.executeScript
Compose scriptscomposeScriptsscripting.compose
Contacts APImessenger.contacts.*messenger.addressBooks.contacts.* (vCard only)

All Manifest Keys Reference

Metadata:

  • name (required) - Extension name
  • version (required) - Version string
  • description - Short description
  • author - Author name
  • icons - Extension icons

Thunderbird-Specific:

  • browser_specific_settings.gecko.id - Required for ATN
  • browser_specific_settings.gecko.strict_min_version - Minimum version

Background & Scripts:

  • background - Service worker (MV3) or scripts (MV2)
  • message_display_scripts (MV2) - Scripts for displayed messages

UI Components:

  • action (MV3) / browser_action (MV2) - Main toolbar button
  • compose_action - Compose window toolbar button
  • message_display_action - Message view toolbar button

Permissions:

  • permissions - API permissions
  • experiment_apis - Custom Experiment APIs

Other:

  • commands - Keyboard shortcuts
  • options_ui - Options page

UI Actions (Toolbar Buttons)

Main Toolbar (action / browser_action)

{
  "action": {
    "default_popup": "popup.html",
    "default_title": "My Extension",
    "default_icon": {
      "16": "icons/icon-16.png",
      "32": "icons/icon-32.png"
    }
  }
}
// Listen for clicks (if no popup)
messenger.action.onClicked.addListener((tab) => {
  console.log("Action clicked");
});

// Update badge
await messenger.action.setBadgeText({ text: "5" });
await messenger.action.setBadgeBackgroundColor({ color: "#ff0000" });

// Update icon
await messenger.action.setIcon({ path: "icons/icon-active.png" });

Compose Window (compose_action)

{
  "compose_action": {
    "default_popup": "compose_popup.html",
    "default_title": "Compose Tool",
    "default_icon": "icons/compose-icon.png"
  }
}
// Listen for clicks in compose window
messenger.composeAction.onClicked.addListener((tab) => {
  const details = await messenger.compose.getComposeDetails(tab.id);
  console.log("Compose action clicked:", details.subject);
});

Message Display (message_display_action)

{
  "message_display_action": {
    "default_popup": "message_popup.html",
    "default_title": "Message Tool",
    "default_icon": "icons/message-icon.png"
  }
}
// Listen for clicks on message
messenger.messageDisplayAction.onClicked.addListener(async (tab) => {
  const message = await messenger.messageDisplay.getDisplayedMessage(tab.id);
  console.log("Message action clicked:", message.subject);
});

Message Display Scripts

MV2 Configuration

{
  "message_display_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["message_content.js"],
      "css": ["message_styles.css"]
    }
  ]
}

MV3 Configuration

// In background.js
await messenger.scripting.messageDisplay.executeScript({
  tabId: tabId,
  files: ["message_content.js"]
});

Available APIs in Display Scripts

Limited APIs available:

  • messenger.runtime.connect(), messenger.runtime.sendMessage()
  • messenger.runtime.onConnect, messenger.runtime.onMessage
  • messenger.i18n.getMessage(), messenger.i18n.getAcceptLanguages()
  • messenger.storage.*
// message_content.js
// Send message to background
const response = await messenger.runtime.sendMessage({
  action: "processMessage",
  content: document.body.innerText
});

// Listen for messages from background
messenger.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === "highlight") {
    // Highlight text in message
    document.body.innerHTML = document.body.innerHTML.replace(
      message.text,
      `<mark>${message.text}</mark>`
    );
  }
});

Deep Dives

For detailed reference on specific topics, load these reference files on demand:

  • Messenger APIs - Complete messenger.* API reference (accounts, messages, folders, addressBooks, compose, mailTabs): ./references/messenger-apis.md
  • Experiment APIs - Custom Experiment API development guide: ./references/experiment-apis.md
  • ATN Submission - Publishing workflow and review criteria: ./references/atn-submission.md
  • Testing & Migration - Debugging, testing workflow, and legacy migration: ./references/testing-migration.md

Best Practices

Code Organization

my-extension/
├── manifest.json
├── background.js
├── popup.html
├── popup.js
├── compose_popup.html
├── compose_popup.js
├── api/
│   └── myapi/
│       ├── schema.json
│       └── implementation.js
├── icons/
│   ├── icon-16.png
│   ├── icon-32.png
│   └── icon-64.png
├── _locales/
│   ├── en/
│   │   └── messages.json
│   └── it/
│       └── messages.json
└── README.md

Error Handling

async function safeAsync(fn) {
  try {
    return await fn();
  } catch (error) {
    console.error("Error:", error);
    return { error: error.message };
  }
}

// Usage
const result = await safeAsync(() => messenger.messages.get(messageId));
if (result.error) {
  console.error("Failed to get message:", result.error);
}

Performance

  • Use pagination for large message lists
  • Cache frequently accessed data
  • Debounce rapid events
  • Use messages.query() with filters instead of list() + filter manually

Security

  • Validate all user input
  • Sanitize HTML before display
  • Use minimal permissions
  • Don't store sensitive data in storage.local unencrypted
  • Validate message content before processing

Differences from Firefox WebExtensions

FeatureFirefoxThunderbird
Namespacebrowser.*messenger.* (mail) + browser.* (common)
ContextWeb browserEmail client
Content scriptsWork on web pagesOnly in web tabs, not email content
Main actionbrowser_action / actionSame + compose_action, message_display_action
Mail APIsNoneaccounts, compose, messages, etc.
ExperimentsLimitedCommon for email-specific features
StoreAMOATN

File Structure Template

my-thunderbird-extension/
├── manifest.json
├── background.js
├── popup.html
├── popup.js
├── compose_popup.html
├── compose_popup.js
├── message_popup.html
├── message_popup.js
├── message_content.js
├── styles/
│   └── popup.css
├── icons/
│   ├── icon-16.png
│   ├── icon-32.png
│   └── icon-64.png
├── api/
│   └── myapi/
│       ├── schema.json
│       └── implementation.js
├── _locales/
│   ├── en/
│   │   └── messages.json
│   └── it/
│       └── messages.json
└── README.md

Quick Reference

Essential Permissions

{
  "permissions": [
    "storage",           // Data storage
    "messagesRead",      // Read messages
    "messagesMove",      // Move/copy/delete messages
    "addressBooks",      // Access contacts
    "compose",           // Compose windows
    "accountsRead",      // Read accounts
    "accountsFolders"    // Access folders
  ]
}

Essential APIs

// Messages
messenger.messages.list(folderId)
messenger.messages.get(messageId)
messenger.messages.query({ from, unread })
messenger.messages.update(messageId, { read: true })

// Folders
messenger.folders.get(folderId)
messenger.folders.getSubFolders(account)

// Compose
messenger.compose.beginNew({ to, subject, body })
messenger.compose.getComposeDetails(tabId)

// Address Books
messenger.addressBooks.list()
messenger.addressBooks.contacts.create(addressBookId, { vCard })

// Display
messenger.messageDisplay.getDisplayedMessage(tabId)
messenger.messageDisplayAction.onClicked

Workflow Summary

  1. Develop: Write code, load temporarily
  2. Debug: Use Debug Add-ons → Inspect
  3. Test: Test all functionality
  4. Build: Create .zip with manifest and scripts
  5. Submit: Upload to ATN
  6. Review: Respond to reviewer feedback
  7. Publish: Extension goes live

References

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

aiohttp

무료

Use when building Python async HTTP services or clients with aiohttp - web server routing, middleware, WebSocket, SSE, streaming, client sessions, pytest-aiohttp testing, or troubleshooting SSL and timeout issues

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

CodeAtCode/oss-ai-skills242026년 10월 9일 업데이트

ast-grep

무료

Use when doing structural code search and rewriting - ast-grep linting, refactoring, multi-language patterns

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

CodeAtCode/oss-ai-skills242026년 10월 9일 업데이트

Use when building GBA games with the BPCore Lua engine - entity, sprite and tilemap functions, SRAM save and load, link cable multiplayer protocol, camera and scrolling, or optimization patterns

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

CodeAtCode/oss-ai-skills242026년 10월 9일 업데이트

celery

무료

Use when running background tasks with Celery - worker and broker configuration (Redis, RabbitMQ), task routing by name vs queue, chains/groups/chords, retry patterns (autoretry_for, retry_backoff), acks_late semantics, failure detection, and monitoring with Flower

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

CodeAtCode/oss-ai-skills242026년 10월 9일 업데이트

django

무료

Use when building Django applications - security hardening, authentication and permissions, ORM optimization, PostgreSQL features, Django 6.0, migrations, testing, and ecosystem libraries

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

CodeAtCode/oss-ai-skills242026년 10월 9일 업데이트

Use when customizing Django Admin - save_formset, get_search_results, formsets, queryset optimization, db_index, custom URLs

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

CodeAtCode/oss-ai-skills242026년 10월 9일 업데이트

CodeAtCode의 스킬 모두 보기

이 스킬의 문제 신고