RE:NODE

Discord webhook-ების ახსნა: შექმნა, გაგზავნა, რედაქტირება, დაცვა

ავტორი RE:NODE-ის გუნდი
16 წუთის საკითხავი


Discord webhook არის URL, რომელიც შეტყობინებებს ერთ არხში აქვეყნებს. არხის პარამეტრებში ქმნი, მას მცირე JSON-ით HTTP POST მოთხოვნას უგზავნი და შეტყობინება ჩნდება იმ სახელითა და ავატარით, რომელიც შენ აირჩიე. აქ არ არის bot-ის ანგარიში, დასარეგისტრირებელი token, დასაყენებელი ბიბლიოთეკა და გასაშვებად დარჩენილი პროცესი. ამიტომ ის ზუსტად ის ინსტრუმენტია, რომელიც პროგრამიდან ცალმხრივი შეტყობინებებისთვის გჭირდება - deploy დასრულდა, ფორმა გაიგზავნა, backup ჩავარდა, ახალი ვიდეო აიტვირთა - და არასწორია ყველაფრისთვის, რაც უნდა უსმენდეს ან პასუხობდეს.

ყველაფერი, რაც ქვემოა, მუშაობს ნებისმიერი ენიდან და ნებისმიერი მანქანიდან, რომელსაც HTTPS მოთხოვნის გაგზავნა შეუძლია. ადამიანები უფრო გვიან ცდებიან: URL ერთადერთი credential-ია და არასდროს იწურება, რამდენიმე query პარამეტრი (wait, thread_id) ქცევას სრულიად ცვლის, ხოლო rate limit-ში მოხვედრილი webhook ზუსტად გეუბნება, რამდენი ხანი დაელოდო, თუ პასუხს წაიკითხავ. თუ game server-ის ცოცხალი სტატუსის შეტყობინება გჭირდება, Discord webhooks for game server alerts ამ თემას თავიდან ბოლომდე განიხილავს; ეს პოსტი კი ზოგადი ცნობარია, რომელსაც ის ეყრდნობა.

რა არის webhook და URL, რომელიც მთელი საქმეა#

webhook არხს ეკუთვნის. მას აქვს რიცხვითი id და გრძელი შემთხვევითი token, ხოლო URL უბრალოდ ორივეს შეერთებაა:

code
https://discord.com/api/webhooks/1290000000000000000/Xy7k...the-token...Qp2

ნებისმიერს, ვისაც ამ URL-ზე სწორი სხეულის მქონე მოთხოვნის გაგზავნა შეუძლია, არხში დაპოსტვა შეუძლია. არ არის მეორე ფაქტორი, ავტორიზაცია, ერთ არხზე მეტი უფლება და ვადა. URL არის პაროლი და ის მანამ მოქმედებს, სანამ ვინმე webhook-ს არ წაშლის. სწორედ ამ ერთი ფაქტით აიხსნება უსაფრთხოების უმეტესი რჩევა ამ პოსტის ბოლოს.

webhook-ით გამოქვეყნებულ შეტყობინებაზე ჩანს webhook-ის სახელი და ავატარი (ან ის, რასაც თითოეულ შეტყობინებაზე გადააფარებ), ასევე სახელის გვერდით პატარა ნიშანი, რომელიც მას ავტომატურად გაგზავნილად აღნიშნავს. ის სერვერის წევრი არ არის, წევრების სიაში არ ჩანს და როლები არ აქვს. მას ვერ ახსენებ, პირად შეტყობინებას ვერ მიიღებს და არხში ვერაფერს ხედავს - საკუთარ გამოქვეყნებულ შეტყობინებებსაც კი, გარდა იმ კონკრეტული endpoint-ებისა, რომლებიც მათ კითხულობენ, ცვლიან ან წაშლიან.

webhook-ები ორ ისეთ ადგილასაც ჩნდება, რომელსაც შესაძლოა არ ელოდე:

  • განცხადებების არხის გამოწერა. როცა სერვერი სხვა სერვერის announcement არხს ამოწერს, Discord დანიშნულების არხში webhook-ს ქმნის cross-post-ების მისაწოდებლად. ის integrations სიაში სხვა ყველას მსგავსად ჩანს.
  • ინტეგრაციები, რომლებიც შენს სახელით აქვეყნებენ. ბევრი სერვისი (CI სისტემები, მონიტორინგის ინსტრუმენტები, თვით GitHub) bot-ის დაყენების მაგივრად Discord webhook URL-ს გთხოვს, სწორედ იმიტომ, რომ webhook-ს ერთ არხზე მეტი უფლება არ სჭირდება.

webhook-ის შექმნა არხის პარამეტრებში#

გჭირდება Manage Webhooks უფლება ამ არხში, რომელიც სერვერის მფლობელებსა და ადმინისტრატორებს ნაგულისხმევად აქვთ.

  1. არხზე გადაიტანე კურსორი და დააჭირე გადაცემათა კოლოს (Edit Channel) ხატულას, ან არხზე მარჯვენა ღილაკით აირჩიე Edit Channel.
  2. გახსენი Integrations, შემდეგ Webhooks.
  3. დააჭირე New Webhook-ს. Discord მაშინვე ქმნის webhook-ს გენერირებული სახელით.
  4. დააჭირე მას გასაშლელად, დააყენე სახელი და სურვილისამებრ ატვირთე ავატარი, და შეამოწმე, რომ არხის სიაში სწორი არხია არჩეული.
  5. დააჭირე Copy Webhook URL-ს, შემდეგ Save Changes-ს, თუ რამე შეცვალე.

Server Settings, Integrations, Webhooks იგივეს მთელი სერვერისთვის აჩვენებს: ყველა არხის ყველა webhook-ს, ავტორის მითითებით. სწორედ ამ გვერდზე გადადიხარ აუდიტისთვის ან გასასუფთავებლად, ხოლო სერვერის audit log ინახავს webhook-ის შექმნას, ცვლილებებსა და წაშლას.

წერის მომენტისთვის რამდენიმე პრაქტიკული ლიმიტი მოქმედებს: ერთ არხში 15 webhook-მდე შეიძლება, webhook-ის სახელი 1-დან 80 სიმბოლომდე უნდა იყოს, ხოლო სახელები, რომლებშიც სიტყვები discord ან clyde გვხვდება, უარყოფილია. Discord ამას ხანდახან ცვლის, ამიტომ თუ შექმნა ლიმიტების შესახებ შეცდომით ჩავარდა, შეამოწმე დეველოპერის დოკუმენტაცია.

webhook-ს წყაროს სახელი დაარქვი - CI, Backups, Shop orders - და ნუ დატოვებ "Captain Hook"-ს ან რაც გენერირდა. სახელი ყველა შეტყობინების ნაგულისხმევი ავტორია და სწორედ ის ეტიკეტია, რომელსაც integrations სიაში ეძებ, როცა რამე არასწორად მუშაობს.

პირველი შეტყობინების გაგზავნა curl-ით#

ყველაზე მცირე ვალიდური მოთხოვნა არის POST JSON სხეულით, რომელსაც content აქვს:

bash
$ curl -X POST "$WEBHOOK_URL" \    -H "Content-Type: application/json" \    -d '{"content": "Deploy finished on main."}'

წარმატების შემთხვევაში Discord პასუხობს 204 No Content-ით და ცარიელი სხეულით. ეს არც შეცდომაა და არც შემთხვევით ცარიელი პასუხი: ნაგულისხმევად API არ ელოდება შეტყობინების შენახვას პასუხამდე. დაამატე ?wait=true და მიიღებ 200 OK-ს სრული შეტყობინების ობიექტით, მათ შორის მისი id-ით, რომელიც მოგვიანებით რედაქტირებისთვის ან წასაშლელად დაგჭირდება.

ველები, რომლებსაც თითქმის ყველა შეტყობინებაში გამოიყენებ:

ველირას აკეთებს
contentშეტყობინების ტექსტი, 2000 სიმბოლომდე, Discord markdown
usernamewebhook-ის სახელს ცვლის მხოლოდ ამ შეტყობინებისთვის
avatar_urlავატარს ცვლის, პირდაპირი ბმული სურათზე
embeds10-მდე embed ობიექტი (ბარათები სათაურითა და ველებით)
allowed_mentionsაკონტროლებს, რომელი ხსენება აგზავნის შეტყობინებას
flags4096 უხმოდ აგზავნის, შეტყობინებების გარეშე
ttsშეტყობინებას ხმამაღლა კითხულობს TTS-ის მქონე ადამიანებისთვის

მოთხოვნაში უნდა იყოს მინიმუმ ერთი: content, embeds, ფაილი ან poll, თორემ მოთხოვნა 400-ით ჩავარდება. სრული მაგალითი შეცვლილი იდენტობით და გამორთული ხსენებებით:

bash
$ curl -X POST "$WEBHOOK_URL?wait=true" \    -H "Content-Type: application/json" \    -d '{      "username": "Shop",      "avatar_url": "https://example.com/shop-icon.png",      "content": "New order #1042 - 2 items, paid by card",      "allowed_mentions": {"parse": []}    }'

avatar_url უნდა მიუთითებდეს პირდაპირ სურათის ფაილზე, რომლის გადმოწერაც Discord-ს შეუძლია - გვერდი, რომელშიც სურათია, არ გამოდგება, ხოლო ბმული, რომელსაც ავტორიზაცია სჭირდება, უხმოდ ნაგულისხმევ ავატარზე დაბრუნდება. username და avatar_url მოქმედებს მხოლოდ იმ ერთ შეტყობინებაზე; webhook-ის შენახული სახელი და ავატარი უცვლელი რჩება.

content-ში ჩვეულებრივი Discord markdown მუშაობს: **bold**, inline კოდი, კოდის ბლოკები, დამალული ბმულები, მაგალითად [changelog](https://example.com), მომხმარებლის ხსენებები <@USER_ID> სახით, როლის ხსენებები <@&ROLE_ID> სახით და დროის ნიშნულები, როგორიცაა <t:1760000000:R>, რომლებიც თითოეული მკითხველის დროის სარტყელში "3 საათის წინ"-ად გამოჩნდება. ხსენება რეალურად აგზავნის თუ არა შეტყობინებას, ამას allowed_mentions წყვეტს. ცარიელი parse მასივი, როგორც ზემოთ, ნიშნავს, რომ არაფერი არავის აცნობებს - ეს უსაფრთხო ნაგულისხმევია ყველაფრისთვის, რაც შენს მიერ დაუწერელ ტექსტს გადაგზავნის. ერთი კონკრეტული როლის გასაცნობად და არავისი სხვის, ის პირდაპირ ჩამოთვალე:

json
{  "content": "<@&123456789012345678> the nightly build failed",  "allowed_mentions": { "parse": [], "roles": ["123456789012345678"] }}

როცა რამე არასწორია, Discord პასუხობს 400-ით და JSON სხეულით, რომელშიც დასახელებულია უარყოფილი ველი. წაიკითხე ის, სანამ სხვა რამეს შეცვლი - ის თითქმის ყოველთვის უფრო კონკრეტულია, ვიდრე ელოდები.

გაგზავნა Python-იდან და JavaScript-იდან#

webhook-ში არაფერია, რაც Discord-ის ბიბლიოთეკას საჭიროებს. ნებისმიერი HTTP კლიენტი გამოდგება და კოდი იმდენად მოკლეა, რომ დამოკიდებულება არჩევითია.

Python requests-ით:

python
import osimport requestsurl = os.environ["WEBHOOK_URL"]payload = {    "username": "Backups",    "content": "Nightly backup finished: 412 MB in 38 s",    "allowed_mentions": {"parse": []},}r = requests.post(url, json=payload, params={"wait": "true"}, timeout=10)r.raise_for_status()print("message id:", r.json()["id"])

თუ პროექტი უკვე იყენებს discord.py 2.x-ს, მას აქვს სინქრონული webhook კლიენტი, რომელსაც არც bot სჭირდება და არც event loop:

python
from discord import SyncWebhookhook = SyncWebhook.from_url(os.environ["WEBHOOK_URL"])msg = hook.send("Deploy finished", username="CI", wait=True)print(msg.id)

JavaScript-ს Node 18-ზე ან უფრო ახალზე fetch ჩაშენებული აქვს, ამიტომ მარტივ ვერსიას პაკეტები არ სჭირდება:

javascript
const res = await fetch(`${process.env.WEBHOOK_URL}?wait=true`, {  method: "POST",  headers: { "Content-Type": "application/json" },  body: JSON.stringify({    username: "CI",    content: "Build 512 passed",    allowed_mentions: { parse: [] },  }),});if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);const message = await res.json();console.log(message.id);

discord.js-ში ექვივალენტი არის WebhookClient, რომელიც იქმნება new WebhookClient({ url })-ით და გამოიყენება send()-ით. ის rate limit-ებს შენს მაგივრად ამუშავებს, რაც ღირს, თუ სკრიპტი ბევრს აგზავნის.

ნებისმიერ ენაზე URL შეინახე გარემოს ცვლადში და არასდროს საწყის კოდში. დანარჩენი კოდი ყველგან ერთი და იგივე სამი ნაბიჯია: ააგე ლექსიკონი, გააგზავნე JSON-ად, შეამოწმე სტატუს კოდი. Environment variables and secrets განმარტავს, სად უნდა ინახებოდეს მნიშვნელობა სერვერზე.

Embed-ები, ფაილები და ლიმიტები, რომლებიც 400-ს აბრუნებს#

უბრალო content ერთსტრიქონიანი შეტყობინებებისთვის შესაფერისია. ყველაფრისთვის, რასაც სტრუქტურა აქვს - შეკვეთა რამდენიმე ველით, build commit-ითა და ავტორით, ანგარიში ფერით, რომელიც კარგს ან ცუდს ნიშნავს - embed გამოიყენე:

json
{  "username": "CI",  "embeds": [{    "title": "Build 512 passed",    "url": "https://example.com/builds/512",    "description": "main - fix login redirect",    "color": 3066993,    "fields": [      { "name": "Duration", "value": "2m 14s", "inline": true },      { "name": "Tests", "value": "418 passed", "inline": true }    ],    "footer": { "text": "runner-02" },    "timestamp": "2026-10-15T09:30:00.000Z"  }]}

ორი დეტალი თითქმის ყველას ერევა. color ათობითი მთელი რიცხვია, ამიტომ hex ფერი #2ECC71 იგზავნება როგორც 3066993; ტექსტი აქ 400-ს იძლევა. ხოლო timestamp უნდა იყოს ISO 8601, რომელსაც Discord თითოეული მკითხველის ადგილობრივ დროში აჩვენებს.

ლიმიტები სრულდება და არა შეკვეცით: content - 2000 სიმბოლო, 10 embed ერთ შეტყობინებაში, embed-ის სათაური 256 სიმბოლო, აღწერა 4096, 25 ველი 256-სიმბოლოიანი სახელებითა და 1024-სიმბოლოიანი მნიშვნელობებით, და 6000 სიმბოლო ერთი შეტყობინების ყველა embed-ში ერთად. server status პოსტს აქვს ლიმიტების სრული ცხრილი და აღწერა, რა ხდება, როცა stack trace მას აჭარბებს. გაგზავნამდე შეკვეცე შენს მხარეს.

ფაილები იტვირთება multipart/form-data-ად და არა JSON-ად. JSON სხეული გადადის ფორმის ველში სახელად payload_json, ხოლო თითოეული ფაილი არის ველი სახელად files[0], files[1] და ასე შემდეგ:

bash
$ curl -X POST "$WEBHOOK_URL" \    -F 'payload_json={"content": "Error log from the failed run"}' \    -F 'files[0]=@build.log'

ატვირთვის ზომის ლიმიტი სერვერის boost დონეზეა დამოკიდებული და Discord-მა ის ერთზე მეტჯერ შეცვალა; ბუსტის გარეშე სერვერზე ამჟამად 10 MB-ია ერთ შეტყობინებაზე. ამაზე დიდი log-ები object storage-ში ან log სისტემაში უნდა ინახებოდეს, შეტყობინებაში კი ბმული იყოს.

ორი თავსებადობის endpoint ადაპტერის წერას გიფრთხილებს. webhook URL-ზე /slack-ის დამატება Slack-ის ფორმატის payload-ს იღებს, ხოლო /github - GitHub-ის webhook ფორმატს, ასე რომ შეგიძლია ჩასვა https://discord.com/api/webhooks/ID/TOKEN/github repository-ის webhook პარამეტრებში (content type application/json) და commit-ებისა და pull request-ების შეტყობინებები კოდის გარეშე მიიღო.

wait=true, thread-ები და forum არხები#

execute URL-ის query string ქცევას ცვლის და მუშაობის უმეტეს ნაწილს ორი პარამეტრი ასრულებს.

პარამეტრიეფექტი
wait=trueპასუხობს 200-ით და შენახული შეტყობინებით, 204-ის ნაცვლად
thread_id=IDაქვეყნებს webhook-ის არხის არსებულ thread-ში

გამოიყენე wait=true ყოველთვის, როცა შეტყობინებას კიდევ შეეხები, ან როცა გინდა დარწმუნდე, რომ ის ნამდვილად შეინახა, სანამ სკრიპტი გააგრძელებს. მის გარეშე 204 მხოლოდ იმას გეუბნება, რომ მოთხოვნა მიიღეს და მეტს არაფერს.

thread_id ერთ webhook-ს ბევრი thread-ის კვების საშუალებას აძლევს. thread webhook-ის არხს უნდა ეკუთვნოდეს - webhook #builds-ში შეუძლია დაპოსტოს #builds-ის ქვეშ ნებისმიერ thread-ში და არა სხვაგან მდებარე thread-ში. გავრცელებული სქემაა თითო thread თითო release-ზე ან თითო ინციდენტზე, სადაც ყველა დაკავშირებული შეტყობინება იგზავნება, რათა მშობელი არხი იკითხებოდეს.

forum და media არხებს ჩვეულებრივი შეტყობინებების არე არ აქვთ, მხოლოდ პოსტები, ამიტომ იქ webhook-მა უნდა თქვას, რომელ პოსტს გულისხმობს. ან გადაეცი thread_id არსებულ პოსტზე საპასუხოდ, ან გააგზავნე thread_name სხეულში, რათა შეიქმნას ახალი პოსტი შენი შეტყობინებით, როგორც პირველით:

bash
$ curl -X POST "$WEBHOOK_URL?wait=true" \    -H "Content-Type: application/json" \    -d '{"thread_name": "Incident 2026-10-15", "content": "API returning 502 since 09:12"}'

ამ მოთხოვნის პასუხი შეიცავს შეტყობინებას და მისი channel_id ახალი thread-ის id-ია - შეინახე, თუ მოგვიანებით გააგრძელებ პოსტვას. forum-ის webhook-ზე მოთხოვნა thread_id-ისა და thread_name-ის გარეშე 400-ით ჩავარდება. თუ forum-ს tag-ები სჭირდება, applied_tags იღებს tag id-ების სიას.

შეტყობინებების რედაქტირება, წაშლა და მართვა#

webhook-ს მხოლოდ საკუთარ გაგზავნილ შეტყობინებებს შეცვლა შეუძლია და მათ id-ით მიმართავს საკუთარ URL-ზე:

bash
# Read a message the webhook sent$ curl "$WEBHOOK_URL/messages/$MESSAGE_ID"# Edit it - only the fields you send are changed$ curl -X PATCH "$WEBHOOK_URL/messages/$MESSAGE_ID" \    -H "Content-Type: application/json" \    -d '{"content": "Deploy finished on main (rolled back 09:40)"}'# Delete it$ curl -X DELETE "$WEBHOOK_URL/messages/$MESSAGE_ID"

თუ შეტყობინება thread-შია, ამ URL-ებს ასევე დაუმატე ?thread_id=THREAD_ID, თორემ Discord მას მშობელ არხში ეძებს და 404-ს აბრუნებს. რედაქტირება ორიგინალ ავტორის სახელსა და ავატარს უცვლელს ტოვებს; username და avatar_url რედაქტირებისას არ მიიღება. embed-ების გასასუფთავებლად გააგზავნე "embeds": []; ტექსტის გასასუფთავებლად - "content": "" (შეტყობინებაში მაინც უნდა დარჩეს რამე).

რედაქტირება არავის აცნობებს. ამიტომ რედაქტირება ადგილზე სწორი ფორმაა ყველაფრისთვის, რაც განმეორებით იცვლება - პროგრესის ხაზი, რიგის სიგრძე, ცოცხალი სტატუსის ბარათი - ხოლო ახალი პოსტი სწორი ფორმაა მოვლენებისთვის, რომლებიც ადამიანებმა უნდა შეამჩნიონ. server status პოსტი ზუსტად ამის გარშემო აგებს პატარა მდგომარეობის მანქანას.

თვით webhook-ის მართვა იმავე URL-ით ხდება:

  • GET $WEBHOOK_URL აბრუნებს webhook ობიექტს - მის სახელს, არხის id-ს, სერვერის id-სა და ავატარის hash-ს. მხოლოდ token-ით მოთხოვნისას ის შემქმნელ მომხმარებელს გამოტოვებს. ეს იაფი გზაა იმის შესამოწმებლად, რომ შენახული URL ჯერ კიდევ მუშაობს.
  • PATCH $WEBHOOK_URL name-ითა და/ან avatar-ით შენახულ იდენტობას ცვლის. avatar არის data URI (data:image/png;base64,...) და არა ბმული. webhook-ის სხვა არხში გადატანას bot-ის ან მომხმარებლის token სჭირდება და არა webhook-ის token.
  • DELETE $WEBHOOK_URL webhook-ს წაშლის. ამის შემდეგ URL-ზე ყველა მოთხოვნა სამუდამოდ 404-ს აბრუნებს.

ეს უკანასკნელი მნიშვნელოვანია: ნებისმიერს, ვისაც URL აქვს, შეუძლია webhook-ის წაშლა, რაც გამოსადეგია, როცა სხვის paste-ში გაჟონილს იპოვი, და გამაღიზიანებელია, როცა დაუდევარი სკრიპტი შემთხვევით ასრულებს მას.

Rate limit-ები და 429 პასუხი#

Discord ყველა route-ს rate limit-ს უწესებს, webhook-ებსაც. პრაქტიკული ჭერი ერთი webhook-ისთვის დაახლოებით ხუთი მოთხოვნაა ყოველ ორ წამში, ხოლო არხი დაახლოებით წუთში ოცდაათ შეტყობინებას იღებს, იმისდა მიუხედავად, რამდენი webhook აქვეყნებს მასში. ეს რიცხვები ფიქსირებულად გამოქვეყნებული არ არის და იცვლება, ამიტომ sleep-ს ხისტად ნუ ჩაწერ და ნუ ჩათვლი, რომ საქმე მოგვარდა. წაიკითხე პასუხი.

როცა გადააჭარბებ, პასუხია 429 Too Many Requests header-ებითა და სხეულით:

json
{ "message": "You are being rate limited.", "retry_after": 0.53, "global": false }

retry_after წამებშია და წილადი შეიძლება იყოს. დაელოდე იმდენ ხანს და იგივე მოთხოვნა ერთხელ გაიმეორე. header-ები X-RateLimit-Remaining და X-RateLimit-Reset-After ყურადღებიან კლიენტს საშუალებას აძლევს, შენელდეს, სანამ კედელს მიადგება. მინიმალური Python retry:

python
import time, requestsdef send(url, payload, attempts=5):    for _ in range(attempts):        r = requests.post(url, json=payload, timeout=10)        if r.status_code != 429:            r.raise_for_status()            return r        time.sleep(float(r.json().get("retry_after", 1)))    raise RuntimeError("still rate limited")

webhook-ებს პრობლემაში არა ხანდახან მიღებული 429 აგდებს, არამედ მასზე რეაქცია. სკრიპტი, რომელიც ციკლში მყისიერად იმეორებს, ნახევარ წამიან ლოდინს წყალდიდობად აქცევს, ხოლო განმეორებითმა არასწორმა მოთხოვნებმა (401, 403 და 429 პასუხები) გამგზავნი IP-ისთვის Discord API-ზე დროებითი ბლოკი შეიძლება გამოიწვიოს. სადაც შეგიძლია, დააჯგუფე - ათი log-ის ხაზი, ახალი ხაზებით გაერთიანებული, ერთი მოთხოვნაა - და 5xx შეცდომებზეც დაიხიე, რომლებსაც Discord დატვირთვისას აბრუნებს.

გაჟონილი webhook URL: რა ვქნა#

webhook URL-ები ჩვეულებრივი გზებით გაჟონავს: config ფაილში commit-ში, support ჩატში ჩასმული, ეკრანის ანაბეჭდზე ხილული, CI log-ში დაბეჭდილი, ვებსაიტის client-side JavaScript-ში ჩაშენებული. ეს უკანასკნელი ყველაზე გავრცელებულია და ყველაზე ადვილად თავიდან ასაცილებელი - ნებისმიერი URL, რომელიც ბრაუზერამდე აღწევს, საჯაროა, და არსებობს scraper-ები, რომლებიც სწორედ ამ ნიმუშს ეძებენ და მას სპამის ან phishing ბმულების შენი სერვერის სახელით გასავრცელებლად იყენებენ.

როცა ერთი გაჟონავს, გასუფთავება მოკლეა და ამ თანმიმდევრობით უნდა გაკეთდეს:

  1. წაშალე webhook. არხის პარამეტრები, Integrations, Webhooks, აირჩიე, Delete Webhook. ან curl -X DELETE "$WEBHOOK_URL" ნებისმიერი ადგილიდან. ძველი URL მაშინვე წყვეტს მუშაობას. "token-ის განულების" ვარიანტი არ არსებობს; წაშლა და თავიდან შექმნა არის ბრუნვა.
  2. შექმენი ახალი იმავე არხში და ახალი URL ჩასვი გარემოს ცვლადში ან secret საცავში, რომელსაც შენი გამგზავნი კითხულობს. გადატვირთე გამგზავნი, რომ აიღოს.
  3. გაასუფთავე არხი. წაშალე ყველაფერი, რაც თავდამსხმელმა დაპოსტა. უკვე გაგზავნილი შეტყობინებები webhook-ის გაქრობის შემდეგაც რჩება და webhook-ის გარეშე მათ მოდერატორად ხელით შლი.
  4. მოაცილე წყარო. გადაწერე ფაილი, გააუქმე paste, გადაატრიალე CI log. თუ ის Git repository-ში იყო, ახალ commit-ში წაშლა საკმარისი არ არის - ის ისტორიაში რჩება, თუმცა გაჟონილი URL მკვდარია, ამიტომ ყურადღება იქ გაამახვილე, რომ ახალი იმავე გზით არასდროს წავიდეს.
  5. შეამოწმე დანარჩენი. Server Settings, Integrations, Webhooks სერვერის ყველა webhook-ს ჩამოთვლის. წაშალე ყველა, რომელზეც არავინ პასუხობს.

URL ისე მოექეცი, როგორც მონაცემთა ბაზის პაროლს: გარემოს ცვლადი გამგზავნ სერვერზე, ეკრანის ანაბეჭდებსა და log-ებში დაფარული, და თითო გამგზავნზე ერთი, რომ ერთი გაჟონვა ერთი წაშლა იყოს.

Webhook თუ bot: სწორის არჩევა#

გადაწყვეტილება მიმართულებას ეხება. webhook არხში წერს. bot უკავშირდება Discord-ის gateway-ს, იღებს მოვლენებს და მათზე რეაგირება შეუძლია.

გინდაგამოიყენე
სკრიპტიდან, CI-დან ან ვებსაიტიდან შეტყობინებების გამოქვეყნებაWebhook
ამ შეტყობინებების მოგვიანებით რედაქტირება ან წაშლაWebhook
რამდენიმე სახელითა და ავატარით დაპოსტვაWebhook
slash command-ებზე ან ღილაკებზე პასუხიBot
ჩატის, რეაქციებისა და ახალი წევრების წაკითხვაBot
როლების მინიჭება, მოდერაცია, DM-ების გაგზავნაBot
ბევრ სერვერზე დაპოსტვა, რომლებიც შენი არ არისBot, თითოეულში მოწვეული

webhook-ს შეტყობინებებს შორის არაფერი სჭირდება გაშვებული, ამიტომ მისი შენახვა არაფერი ღირს. bot არის გრძელვადიანი პროცესი token-ით, intent-ებითა და gateway კავშირით, რომელიც უნდა იყოს ჩართული; თუ ჩერდება, offline-ად ჩანს და მისი ბრძანებები ვერ მუშაობს. ეს ცალკე ჰოსტინგის პრობლემაა, რომელიც განხილულია hosting a Discord bot 24/7 პოსტში discord.js-ისთვის და hosting a discord.py bot პოსტში Python-ისთვის.

ორი ჰიბრიდი ცოდნად ღირს. bot-ს შეუძლია თვითონ შექმნას webhook-ები და გამოიყენოს ისინი სხვა იდენტობებით დასაპოსტად - ასე ჩანან chat bridge-ებში თამაშის მოთამაშეები საკუთარი სახელებითა და ავატარებით. ხოლო webhook, რომელიც აპლიკაციამ შექმნა (და არა ადამიანმა არხის პარამეტრებში), შეუძლია გააგზავნოს ინტერაქტიული კომპონენტები, მაგალითად ღილაკები, რადგან ინტერაქციები ამ აპლიკაციას უბრუნდება. webhook, რომელსაც არხის პარამეტრებში ქმნი, ვერაფერს იღებს, ამიტომ მასზე ღილაკებს არსად ექნებოდათ ანგარიშის გაგზავნა.

არსებობს ასევე ცალკე ფუნქცია, რომელსაც Discord webhook events ეძახის: აპლიკაციას შეუძლია developer portal-ში HTTPS endpoint-ის რეგისტრაცია და გარკვეული მოვლენების, მაგალითად აპლიკაციის ავტორიზაციის, შემომავალი მოთხოვნების სახით მიღება. ეს საპირისპირო მიმართულებაა - Discord გირეკავს შენ - და განკუთვნილია აპლიკაციის დეველოპერებისთვის და არა არხის წასაკითხად.

საბოლოო გადაწყვეტილება ისაა, სად მუშაობს გამგზავნი. webhook-ს სჭირდება მხოლოდ ის, რაც მოვლენის დადგომისას მოთხოვნას გააგზავნის: CI job, cron ამოცანა, უკვე არსებული backend. თუ ის ჯერ არ არსებობს, პატარა მუდმივად ჩართული app სერვერი საკმარისია. RE:NODE app გეგმები Node.js-ისა და Python-ისთვის თვეში $4-დან იწყება, webhook URL კი გარემოს ცვლადად Startup ჩანართზე ინახება და deploy პირდაპირ GitHub-იდან ხდება.

FAQ#

საჭიროა თუ არა კოდის წერა Discord webhook-ის გამოსაყენებლად?

არა. ბევრი სერვისი webhook URL-ს იღებს და გაგზავნას თავად აკეთებს - ჩასვი და ისინი დაპოსტავენ. საკუთარი შეტყობინებების გასაგზავნად ერთი curl ბრძანება საკმარისია, არსებობს ვებ ინსტრუმენტებიც, რომლებიც JSON-ს შენს მაგივრად აგებენ. კოდი მხოლოდ მაშინ გჭირდება, როცა შენი პროგრამა წყვეტს, რას და როდის დაპოსტოს.

რატომ აბრუნებს ჩემი webhook 204-ს და არა შეტყობინების id-ს?

იმიტომ, რომ 204 No Content ნაგულისხმევი წარმატების პასუხია. დაამატე URL-ს ?wait=true და Discord დააბრუნებს 200-ს სრული შეტყობინებით, მათ შორის id-ით, რომელიც რედაქტირებისთვის ან წასაშლელად გჭირდება.

შეუძლია თუ არა webhook-ს რამდენიმე არხში დაპოსტვა?

არა. თითოეული webhook ერთ არხს ეკუთვნის და მხოლოდ ამ არხის thread-ებამდე აღწევს thread_id-ით. რამდენიმე არხისთვის თითოეულში შექმენი ცალკე webhook, რაც გაჟონვისა და ხმაურის თვალსაზრისითაც უკეთესია.

შემიძლია თუ არა webhook-ს როლის შეტყობინება ვაგზავნინო?

დიახ. ჩასვი <@&ROLE_ID> content-ში და id ჩართე allowed_mentions.roles-ში, parse კი ცარიელი დატოვე, რომ სხვას არავის შეატყობინოს. როლის id მიიღება როლზე მარჯვენა ღილაკით, როცა Discord-ის Advanced პარამეტრებში Developer Mode ჩართულია - ასევე კოპირდება მომხმარებლის, არხისა და შეტყობინების id-ები.

იწურება თუ არა webhook URL-ები?

არა. webhook მუშაობს, სანამ არ წაიშლება, მისი არხი არ წაიშლება ან სერვერი არ მოაშორებს. URL, რომელიც შარშან მუშაობდა და დღეს 404-ს აბრუნებს, ვიღაცამ წაშალა - შეამოწმე Server Settings, Integrations, Webhooks.

რატომ უარყოფს webhook ჩემს username-ს?

სახელი უნდა იყოს 1-დან 80 სიმბოლომდე და არ უნდა შეიცავდეს discord-ს ან clyde-ს. 400 პასუხის სხეული ამბობს, რომელ წესს დაეჯახა; შეამოკლე სახელი ან სიტყვა ამოიღე.