{"id":16517164,"url":"https://github.com/kokseen1/chii","last_synced_at":"2025-08-20T20:26:17.766Z","repository":{"id":135184092,"uuid":"595639027","full_name":"kokseen1/Chii","owner":"kokseen1","description":"A minimal marketplace bot maker.","archived":false,"fork":false,"pushed_at":"2023-02-03T14:24:02.000Z","size":13,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-02T19:32:29.814Z","etag":null,"topics":["auction","automation","bidding","bot","carousell","crawler","ecommerce","marketplace","python","python-telegram-bot","scraper","telegram","telegram-bot","web-scraping","yahoo","yahoo-auction"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kokseen1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-31T14:04:14.000Z","updated_at":"2023-11-14T05:31:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"226ac43e-738f-480b-8732-011fa106dad4","html_url":"https://github.com/kokseen1/Chii","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kokseen1/Chii","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kokseen1%2FChii","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kokseen1%2FChii/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kokseen1%2FChii/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kokseen1%2FChii/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kokseen1","download_url":"https://codeload.github.com/kokseen1/Chii/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kokseen1%2FChii/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271378680,"owners_count":24749192,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-20T02:00:09.606Z","response_time":69,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auction","automation","bidding","bot","carousell","crawler","ecommerce","marketplace","python","python-telegram-bot","scraper","telegram","telegram-bot","web-scraping","yahoo","yahoo-auction"],"created_at":"2024-10-11T16:29:07.088Z","updated_at":"2025-08-20T20:26:17.734Z","avatar_url":"https://github.com/kokseen1.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Chii\n \nA minimal marketplace bot maker.\n\n## Installation\n\n```shell\npip install chii\n```\n\n## Usage\n\nImport and initialize the `Chii` object:\n\n```py\nfrom chii.main import Chii\n\nchii = Chii(\"\u003cbot_token\u003e\")\n```\n\n### Add decorators to the following callback functions:\n\nThis function takes in a query and must return an iterable of search results from the query (e.g. a `List` of result `Dict`s).\n\n```py\n@chii.query\ndef make_query(query: str):\n```\n\nThis function takes in a result (an element of the iterable returned by `make_query`) and returns a string containing the desired formatted message to be sent out to the user.\n\n```py\n@chii.message\ndef get_message(result) -\u003e str:\n```\n\nThis function takes in a result and must return a uniquely identifiable attribute of the result to use as the 'primary key'.\n\n```py\n@chii.key\ndef get_key(result):\n```\n\nThis function takes in a result and must return the image url of the result.\n\n```py\n@chii.image\ndef get_image(result) -\u003e str:\n```\n\nStart the bot:\n\n```py\nif __name__ == \"__main__\":\n    chii.start()\n```\n\n## Bot Usage\n\nAdd a query\n\n```\n/add \u003cquery\u003e\n```\n\nRemove a query\n\n```\n/rm \u003cquery\u003e\n```\n\nList queries\n\n```\n/ls\n```\n\nFetch queries\n\n```\n/fetch\n```\n\n## Example\n\nBelow is a complete example made for the Yahoo! Auctions marketplace.\n\n```py\nimport re\nimport requests\nimport urllib\nfrom bs4 import BeautifulSoup\nfrom datetime import datetime\n\nfrom chii.main import Chii\n\nYAHUOKU_SEARCH_TEMPLATE = r\"https://auctions.yahoo.co.jp/search/search?p={query}\u0026b={start}\u0026n={count}\u0026s1=new\u0026o1=d\"\n\nPOST_TIMESTAMP_REGEX = r\"^.*i-img\\d+x\\d+-(\\d{10}).*$\"\nAUCTION_TIMESTAMP_REGEX = r\"^.*etm=(\\d{10}),stm=(\\d{10}).*$\"\n\nKEY_TITLE = \"title\"\nKEY_URL = \"url\"\nKEY_IMAGE = \"img\"\nKEY_POST_TIMESTAMP = \"post_ts\"\nKEY_END_TIMESTAMP = \"end_ts\"\nKEY_START_TIMESTAMP = \"start_ts\"\nKEY_BUYNOW_PRICE = \"buynow_price\"\nKEY_CURRENT_PRICE = \"curr_price\"\nKEY_START_PRICE = \"start_price\"\nKEY_ITEM_ID = \"item_id\"\n\nchii = Chii(\"\u003cbot_token\u003e\")\n\n\n@chii.image\ndef get_image(result):\n    return result[KEY_IMAGE]\n\n\n@chii.key\ndef get_key(result):\n    return result[KEY_ITEM_ID]\n\n\n@chii.message\ndef get_message(result):\n    return f\"{result[KEY_URL]}\\n`{result[KEY_TITLE]}`\\n_{datetime.fromtimestamp(result[KEY_POST_TIMESTAMP]).strftime('%d/%m/%Y %I:%M:%S %p')}_\\n*{result[KEY_START_PRICE]}円*\"\n\n\n@chii.query\ndef make_query(query: str):\n    url = YAHUOKU_SEARCH_TEMPLATE.format(query=urllib.parse.quote_plus(query), start=1, count=100)\n    r = requests.get(url)\n\n    return parse_raw_results(r.text)\n\n\ndef parse_raw_results(raw: str):\n    results = []\n    soup = BeautifulSoup(raw, \"lxml\")\n\n    product_details = soup.find_all(\"div\", class_=\"Product__detail\")\n    for product_detail in product_details:\n        product_bonuses = product_detail.find_all(\"div\", class_=\"Product__bonus\")\n        product_titlelinks = product_detail.find_all(\"a\", class_=\"Product__titleLink\")\n\n        if not product_bonuses or not product_titlelinks:\n            continue\n\n        product_bonus = product_bonuses[0]\n        product_titlelink = product_titlelinks[0]\n\n        auction_title = product_titlelink[\"data-auction-title\"]\n        auction_img = product_titlelink[\"data-auction-img\"]\n        href = product_titlelink[\"href\"]\n        cl_params = product_titlelink[\"data-cl-params\"]\n\n        match = re.match(POST_TIMESTAMP_REGEX, auction_img)\n        if not match:\n            continue\n\n        post_timestamp = int(match.group(1))\n\n        match = re.match(AUCTION_TIMESTAMP_REGEX, cl_params)\n        if not match:\n            continue\n\n        end_timestamp = int(match.group(1))\n        start_timestamp = int(match.group(2))\n\n        auction_id = product_bonus[\"data-auction-id\"]\n        auction_buynowprice = product_bonus[\"data-auction-buynowprice\"]\n        auction_price = product_bonus[\"data-auction-price\"]\n        auction_startprice = product_bonus[\"data-auction-startprice\"]\n\n        result = {\n            KEY_TITLE: auction_title,\n            KEY_IMAGE: auction_img,\n            KEY_URL: href,\n            KEY_POST_TIMESTAMP: post_timestamp,\n            KEY_END_TIMESTAMP: end_timestamp,\n            KEY_START_TIMESTAMP: start_timestamp,\n            KEY_ITEM_ID: auction_id,\n            KEY_BUYNOW_PRICE: auction_buynowprice,\n            KEY_CURRENT_PRICE: auction_price,\n            KEY_START_PRICE: auction_startprice,\n        }\n\n        results.append(result)\n\n    return results\n\n\nif __name__ == \"__main__\":\n    chii.start()\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkokseen1%2Fchii","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkokseen1%2Fchii","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkokseen1%2Fchii/lists"}