Adding Skills
Adding skills for new apps is the most valuable contribution. Every new app skill makes the framework more useful for everyone. This page covers the process specifically for contributors.
Contribution Types
Section titled “Contribution Types”| Type | Difficulty | Impact |
|---|---|---|
| Add UI elements for a new app | Easy-Medium | High |
| Write an Action for an existing app | Medium | High |
| Write a Workflow (multi-step) | Medium | High |
| Build a complete app Skill | Medium-Hard | Very High |
Step-by-Step
Section titled “Step-by-Step”1. Scaffold the Directory
Section titled “1. Scaffold the Directory”mkdir -p marketing_system/skills/whatsapp/actionsmkdir -p marketing_system/skills/whatsapp/workflowstouch marketing_system/skills/whatsapp/__init__.pytouch marketing_system/skills/whatsapp/actions/__init__.pytouch marketing_system/skills/whatsapp/workflows/__init__.py2. Define UI Elements
Section titled “2. Define UI Elements”Use the Skill Creator tab (live device stream with element overlay) to identify elements on the target app:
package: com.whatsappapp_version: "2.24.x"
elements: search_icon: resource_id: "com.whatsapp:id/menuitem_search" content_desc: "Search" description: "Search icon in toolbar"
chat_input: resource_id: "com.whatsapp:id/entry" description: "Message text input field"
send_button: resource_id: "com.whatsapp:id/send" content_desc: "Send" description: "Send message button"Always provide at least 2 locator fields per element (e.g., resource_id + content_desc).
3. Write Actions
Section titled “3. Write Actions”from marketing_system.skills.base import Action, ActionResult
class SendMessage(Action): name = "send_message" description = "Type a message and tap send"
def precondition(self, dev, xml): return dev.find_bounds(xml, resource_id="com.whatsapp:id/entry") is not None
def execute(self, dev, text="Hello", **kwargs): xml = dev.dump_xml() bounds = dev.find_bounds(xml, resource_id="com.whatsapp:id/entry") dev.tap(*dev.bounds_center(bounds)) dev.type_text(text)
xml = dev.dump_xml() bounds = dev.find_bounds(xml, resource_id="com.whatsapp:id/send") if bounds: dev.tap(*dev.bounds_center(bounds)) return ActionResult(success=True) return ActionResult(success=False, error="Send button not found")4. Write Workflows (Optional)
Section titled “4. Write Workflows (Optional)”from marketing_system.skills.base import Workflow
class SendDM(Workflow): name = "send_dm" description = "Send a DM to a contact"
def steps(self): return [ ("open_app", {}), ("search_contact", {"query": self.params["contact"]}), ("send_message", {"text": self.params["message"]}), ]5. Register
Section titled “5. Register”from marketing_system.skills.base import Skill
def load(): skill = Skill.from_yaml("marketing_system/skills/whatsapp") from .actions.send_message import SendMessage skill.register_action(SendMessage) from .workflows.send_dm import SendDM skill.register_workflow(SendDM) return skill6. Test
Section titled “6. Test”# Verify it loadspython3 -c "from marketing_system.skills.whatsapp import loads = load()print(f'{s.name}: {len(s.elements)} elements, {s.list_actions()}, {s.list_workflows()}')"
# Run on devicepython3 -c "from marketing_system.skills.whatsapp import loadfrom marketing_system.bots.common.adb import Devices = load()dev = Device()action = s.get_action('send_message', dev)result = action.run(text='Hello from the bot')print(f'Success: {result.success}')"7. Submit PR
Section titled “7. Submit PR”git checkout -b skill/whatsappgit add marketing_system/skills/whatsapp/git commit -m "Add WhatsApp skill: send_message action, send_dm workflow"Include in the PR:
- App name and version tested on
- Device model and Android version
- What actions and workflows are included
- Screenshot of the skill working (appreciated but optional)
Quality Checklist
Section titled “Quality Checklist”Before submitting:
-
skill.yamlhasname,version,app_package,description -
elements.yamluses multiple locator fields per element - All actions have
nameanddescription - At least one action has a
postcondition() - Skill loads without errors
- Tested on a real device
- No hardcoded serials or credentials
Even Partial Skills Help
Section titled “Even Partial Skills Help”Even a skeleton with just skill.yaml and elements.yaml (no actions) is a valid contribution. It saves the next person from starting from scratch and provides the UI element mappings for the app.
Related
Section titled “Related”- Creating Skills Guide — detailed walkthrough
- Elements Reference — how locator chains work
- Code Contributions — general PR guidelines