MetalAPI
XAU3,997.89−1.54‎%‎XAG53.936−1.51‎%‎XPT1,554.47−0.83‎%‎XPD1,047.03−0.44‎%‎XCU6.5080+2.29‎%‎WTI103.27+3.82‎%‎BRENT111.70−1.30‎%‎EUR1.120400−0.01‎%‎GBP1.337500−0.01‎%‎JPY0.0063761+0.14‎%‎CHF1.213445−0.25‎%‎TRY0.020125−0.12‎%‎BTC80,644.51−0.16‎%‎ETH2,354.43−0.06‎%‎
جميع المقالات
الذهبجداول البياناتدرس تطبيقي

سعر الذهب في Google Sheets وExcel: أسعار مباشرة عبر API

احصل على سعر الذهب المباشر في Google Sheets عبر دالة مخصصة في Apps Script، وفي Excel عبر Power Query، مع تحديث مجدول وإبقاء مفتاح API في مأمن.

بقلم MetalAPI Team··وقت القراءة: 12 دقيقة

أسعار الذهب المباشرة في جدول بيانات

لا يزال جزء كبير من تسعير الذهب يجري في جداول البيانات: قائمة أسعار لدى صائغ، أو مخزون من السبائك، أو ورقة لعروض أسعار ذهب الكسر، أو أداة لتتبع المحفظة. ومع سعر ذهب مباشر في Google Sheets أو Excel، تتحدّث هذه الأرقام تلقائيًا بدلًا من نسخها من موقع ويب. يبني هذا الدليل الحلّين معًا: دالة مخصصة =GOLDPRICE("EUR", "gram") في Google Sheets باستخدام Apps Script، وجدول Power Query في Excel، وكلاهما يتحدّث تلقائيًا ويُبقي مفتاح API خارج الخلايا.

يحتاج كلاهما إلى قليل من الشيفرة. فـ MetalAPI تُرجع JSON، ولا يملك أيٌّ من البرنامجين صيغة في ورقة العمل تحلّل JSON من عنوان URL وترسل مفتاح API في ترويسة. أما Apps Script وPower Query فيؤديان الأمرين معًا.

تحتاج إلى مفتاح MetalAPI: أنشئ حسابًا مجانيًا، دون بطاقة ائتمان، مع 100 طلب شهريًا وتحديث يومي للأسعار. وتحتاج في Excel أيضًا إلى إصدار يتضمن Power Query (الحصول على البيانات وتحويلها، Get & Transform)، مثل Excel لـ Microsoft 365 أو Excel 2016 وما بعده على Windows. وتكون الأسعار بالحداثة التي تتيحها خطتك: يوميًا في Free، وكل 30 دقيقة في Lite، وكل 10 دقائق في Standard، وحتى كل 5 ثوانٍ في Enterprise.

تسرد كل استجابة كل رمز مرتين: USDXAU (أو EURXAU مع base=EUR) هو سعر أونصة تروي واحدة من الذهب، والمفتاح المجرد XAU هو مقلوبه. والشيفرة هنا تقرأ دائمًا المفتاح ذا البادئة.

كيف تحصل على أسعار الذهب المباشرة في Google Sheets

الإعداد مشروع Apps Script صغير مرتبط بجدول البيانات: يقرأ المفتاح من خاصية في النص البرمجي، ويجلب الأسعار باستخدام UrlFetchApp، ويخزّنها مؤقتًا باستخدام CacheService، ويتيح دوال مخصصة لخلاياك. ويُبقيها مشغّل يعمل حسب الوقت محدَّثة.

  1. افتح جدول البيانات واختر الإضافات (Extensions) ثم Apps Script. ينشئ ذلك مشروعًا للنص البرمجي مرتبطًا بذلك الملف.
  2. في محرر Apps Script، افتح إعدادات المشروع (Project Settings)، وهي رمز الترس، ومرّر إلى خصائص النص البرمجي (Script Properties)، وانقر إضافة خاصية نص برمجي (Add script property). أدخل METALAPI_KEY اسمًا للخاصية، والصق مفتاحك قيمةً لها، وانقر حفظ خصائص النص البرمجي (Save script properties).
  3. بعد العودة إلى المحرِّر (Editor)، استبدل محتوى Code.gs بكتلتي الشيفرة أدناه واحفظ.
  4. اختر refreshPrices في قائمة الدوال وانقر تشغيل (Run). تطلب منك Google مرة واحدة تفويض النص البرمجي بالاتصال بخدمة خارجية وتعديل جدول البيانات.

أبقِ مفتاح API خارج الخلايا

لا تلصق المفتاح في خلية ولا تبنِ عنوان URL بصيغة. فالمفتاح الموجود في خلية مرئي لكل من يستطيع فتح جدول البيانات، وينتقل مع كل نسخة وكل تصدير، ويبقى في سجل النسخ بعد حذفه. وكل من يحصل عليه يستطيع استهلاك حصتك.

خصائص النص البرمجي مكان أفضل: فهي ليست جزءًا من الشبكة، لذا لا تظهر في الخلايا أو التصديرات أو سجل النسخ. لكنها ليست خزنة آمنة. فكل من يملك صلاحية التعديل على جدول البيانات يستطيع فتح الإضافات (Extensions) ثم Apps Script وقراءتها. لذلك:

  • استخدم مفتاحًا منفصلًا لكل جدول بيانات، حتى تستطيع إلغاءه دون تعطيل عمليات التكامل الأخرى. ويتناول دليل المصادقة إنشاء المفاتيح وتدويرها.
  • امنح صلاحية التعديل فقط لمن قد تعطيه المفتاح. لا يستطيع المشاهدون والمعلّقون فتح محرر النص البرمجي، لكن نسخة جدول البيانات تتضمن نسخة من النص البرمجي المرتبط به. وللملفات المشتركة على نطاق واسع، عطّل النسخ للمشاهدين والمعلّقين في إعدادات المشاركة.
  • أرسل المفتاح في ترويسة. يستخدم النص البرمجي X-API-Key بدلًا من المعامل api_key، حتى لا ينتهي المفتاح في عناوين URL المسجَّلة.
  • دوِّر المفتاح عند الشك: أنشئ مفتاحًا جديدًا، وحدّث خاصية النص البرمجي، ثم ألغِ المفتاح القديم في لوحة التحكم.

دالة مخصصة GOLDPRICE في Google Sheets

الصق هذا في Code.gs. تغطي METALPRICE المعادن الثمينة الأربعة، وGOLDPRICE اختصار للذهب. ويُرجع طلب واحد المعادن الأربعة، لذا يتشارك الذهب والفضة بالعملة والوحدة نفسيهما استجابة واحدة مخزَّنة مؤقتًا.

Code.gs (الجزء 1)
// MetalAPI prices for Google Sheets. The API key is read from the
// script property METALAPI_KEY (Project Settings), never from a cell.
const API = "https://metalapi.com/api/v1";
const SYMBOLS = ["XAU", "XAG", "XPT", "XPD"];
const CACHE_SECONDS = 3600; // 1 hour; Apps Script allows up to 21600

function fetchLatest_(base, unit) {
  const key = PropertiesService.getScriptProperties().getProperty("METALAPI_KEY");
  if (!key) throw new Error("Add the script property METALAPI_KEY first.");
  const url = API + "/latest?base=" + encodeURIComponent(base) +
    "&currencies=" + SYMBOLS.join(",") + "&unit=" + encodeURIComponent(unit);
  const res = UrlFetchApp.fetch(url, {
    headers: { "X-API-Key": key },
    muteHttpExceptions: true, // return error responses instead of throwing
  });
  let data;
  try {
    data = JSON.parse(res.getContentText());
  } catch (e) {
    throw new Error("MetalAPI: unexpected HTTP " + res.getResponseCode() + " response");
  }
  if (!data.success) {
    throw new Error("MetalAPI " + data.error.code + " (" + data.error.type + "): " + data.error.info);
  }
  return data;
}

function cachedLatest_(base, unit, refresh) {
  const cache = CacheService.getScriptCache();
  const cacheKey = ["latest", base, unit, refresh].join("|");
  const hit = cache.get(cacheKey);
  if (hit) return JSON.parse(hit);
  const data = fetchLatest_(base, unit);
  cache.put(cacheKey, JSON.stringify(data), CACHE_SECONDS);
  return data;
}

/**
 * Latest price of a precious metal from MetalAPI.
 *
 * @param {string} symbol XAU (gold), XAG (silver), XPT (platinum) or XPD (palladium).
 * @param {string} currency Currency code such as USD, EUR or GBP. Default USD.
 * @param {string} unit troy_oz (default), gram or kilogram.
 * @param {any} refresh Optional cell such as Prices!B1. When it changes, prices are fetched again.
 * @return The price of one unit of the metal in the currency.
 * @customfunction
 */
function METALPRICE(symbol, currency, unit, refresh) {
  const s = String(symbol || "XAU").trim().toUpperCase();
  const base = String(currency || "USD").trim().toUpperCase();
  const u = String(unit || "troy_oz").trim().toLowerCase();
  const data = cachedLatest_(base, u, String(refresh || ""));
  const price = data.rates[data.base + s];
  if (price === undefined) throw new Error("No " + s + " price in " + base + ".");
  return price;
}

/**
 * Latest gold price from MetalAPI, for example =GOLDPRICE("EUR", "gram").
 *
 * @param {string} currency Currency code such as USD, EUR or GBP. Default USD.
 * @param {string} unit troy_oz (default), gram or kilogram.
 * @param {any} refresh Optional cell such as Prices!B1. When it changes, prices are fetched again.
 * @return The price of gold in the currency per unit.
 * @customfunction
 */
function GOLDPRICE(currency, unit, refresh) {
  return METALPRICE("XAU", currency, unit, refresh);
}

الآن اكتب صيغة في أي خلية:

الصيغةالنتيجة
=GOLDPRICE()الذهب بالدولار الأمريكي لكل أونصة تروي
=GOLDPRICE("EUR", "gram")الذهب باليورو لكل غرام
=GOLDPRICE("GBP", "kilogram")الذهب بالجنيه الإسترليني لكل كيلوغرام
=METALPRICE("XAG", "USD", "troy_oz")الفضة بالدولار الأمريكي لكل أونصة تروي

ما يجري خلف الكواليس:

  • @customfunction يضيف الدوال إلى الإكمال التلقائي للصيغ، مع التعليق نصًا للمساعدة.
  • muteHttpExceptions: true يُرجع استجابات الخطأ بدلًا من إطلاق استثناء، فتعرض الخلية #ERROR! مع رمز MetalAPI ورسالته عند تمرير المؤشر فوقها، مثل 201 (invalid_base) لعملة غير معروفة.
  • CacheService يحتفظ بكل استجابة لمدة CACHE_SECONDS، بحد أقصى ست ساعات. وتتشاركها الخلايا التي لها العملة والوحدة وقيمة التحديث نفسها.
  • كل عملة ووحدة غير مخزَّنة مؤقتًا تكلّف طلبًا واحدًا، وكل خلية صيغة استدعاء منفصل لخوادم Google. وللأوراق التي تحتوي على مئات من خلايا الأسعار، أشِر إلى ورقة Prices أدناه بدلًا من ذلك.

تُحتسب أخطاء التحقق، مثل العملة غير المعروفة، لذا أصلح الصيغ المعطوبة سريعًا. ويسرد دليل حدود المعدل ما يُحتسب.

حدّث سعر الذهب في Google Sheets بمشغّل يعمل حسب الوقت

يعيد Google Sheets تشغيل الدالة المخصصة حين تتغير وسيطاتها، لا وفق ساعة؛ فإعداد إعادة الحساب ضمن ملف (File) ثم الإعدادات (Settings) ثم العمليات الحسابية (Calculation) لا يؤثر إلا في دوال مثل NOW وRAND. وللتحديثات المجدولة، دع مشغّلًا يعمل حسب الوقت يكتب الأسعار في ورقة. أضف هذا أسفل الجزء 1:

Code.gs (الجزء 2)
/** Writes the latest prices to a sheet named "Prices". Run it from a time-driven trigger. */
function refreshPrices() {
  const data = fetchLatest_("USD", "troy_oz");
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName("Prices") || ss.insertSheet("Prices");
  const rows = [
    ["Updated", new Date(data.timestamp * 1000)],
    ["Symbol", data.base + " per troy oz"],
  ];
  SYMBOLS.forEach(function (s) {
    rows.push([s, data.rates[data.base + s]]);
  });
  sheet.getRange(1, 1, rows.length, 2).setValues(rows);
}

/** Run once from the editor. Replaces any existing schedule for refreshPrices. */
function installTrigger() {
  ScriptApp.getProjectTriggers().forEach(function (t) {
    if (t.getHandlerFunction() === "refreshPrices") ScriptApp.deleteTrigger(t);
  });
  ScriptApp.newTrigger("refreshPrices").timeBased().everyHours(1).create();
}

شغّل installTrigger مرة واحدة من المحرر، أو أضف المشغّل يدويًا من المشغّلات (Triggers)، وهي رمز الساعة، ثم إضافة مشغّل (Add Trigger) مع refreshPrices وحسب الوقت (Time-driven) وفترة زمنية.

يكلّف كل تشغيل طلبًا واحدًا، ويكتب وقت البيانات في Prices!B1 وصفًّا لكل معدن أسفله؛ وPrices!B3 هو الذهب بالدولار الأمريكي لكل أونصة تروي. أشِر إلى هذه الخلايا مباشرةً، أو مرّر Prices!B1 وسيطًا للتحديث: فالصيغة =GOLDPRICE("EUR", "gram", Prices!B1) تجلب الأسعار مجددًا كلما كتب المشغّل وقت بيانات جديدًا، مرة لكل عملة ووحدة، ولا تجلبها إطلاقًا في عطلة نهاية الأسبوع، حين لا يتغير الوقت. ولجعل ورقة Prices بعملة أو وحدة أخرى، غيّر وسيطات fetchLatest_ في refreshPrices.

طابِق الفترة مع خطتك؛ فالتحديث بوتيرة أسرع من تحديث الأسعار لا يفعل سوى تكرارها:

الخطةتحديثات الأسعارالمشغّلطلبات المشغّل / شهر
Free (100 طلب)يوميًا.everyDays(1).atHour(6)نحو 31
Lite (1,000 طلب)كل 30 دقيقة.everyHours(1)نحو 744
Standard (10,000 طلب)كل 10 دقائق.everyMinutes(10)نحو 4,500

تضيف الدوال المخصصة مع وسيط التحديث طلبًا واحدًا لكل تحديث لكل عملة ووحدة. ففي Lite، يمكن لمشغّل يعمل كل ساعة مع GOLDPRICE("EUR", "gram", Prices!B1) أن يصل إلى نحو 1,500 طلب شهريًا، متجاوزًا حد الخطة البالغ 1,000؛ فاستخدم .everyHours(2) أو ورقة Prices وحدها. وتعمل المشغّلات قرب الوقت المجدول لا عنده بالضبط، ويستخدم atHour المنطقة الزمنية للنص البرمجي.

سعر الذهب في Excel باستخدام Power Query

في Excel، يستدعي Power Query الواجهة ويحلّل JSON ويحمّل جدولًا يتحدّث وفق جدول زمني:

  1. في علامة التبويب بيانات (Data)، اختر الحصول على البيانات (Get Data) ثم من مصادر أخرى (From Other Sources) ثم استعلام فارغ (Blank Query).
  2. في محرر Power Query، اختر الصفحة الرئيسية (Home) ثم المحرر المتقدم (Advanced Editor)، والصق الاستعلام أدناه وانقر تم (Done).
  3. عندما يُطلب منك تحديد طريقة الاتصال بـ https://metalapi.com/، انقر تحرير بيانات الاعتماد (Edit Credentials)، واختر واجهة برمجة تطبيقات ويب (Web API)، والصق مفتاحك في المفتاح (Key)، وانقر اتصال (Connect).
  4. أعد تسمية الاستعلام إلى GoldPrices واختر الصفحة الرئيسية (Home) ثم إغلاق وتحميل (Close & Load). يحمّله Excel في ورقة جديدة على هيئة جدول يحمل اسم الاستعلام.
GoldPrices (لغة M في Power Query)
let
    BaseCurrency = "EUR",
    MassUnit = "gram",
    Symbols = {"XAU", "XAG", "XPT", "XPD"},
    Response = Json.Document(
        Web.Contents(
            "https://metalapi.com/api/v1/latest",
            [
                Query = [base = BaseCurrency, currencies = Text.Combine(Symbols, ","), unit = MassUnit],
                ApiKeyName = "api_key"
            ]
        )
    ),
    Updated = #datetime(1970, 1, 1, 0, 0, 0) + #duration(0, 0, 0, Response[timestamp]),
    Prices = Table.FromRecords(
        List.Transform(
            Symbols,
            (symbol) => [
                Symbol = symbol,
                Price = Record.Field(Response[rates], Response[base] & symbol),
                Currency = Response[base],
                Unit = MassUnit,
                #"Updated (UTC)" = Updated
            ]
        )
    ),
    Typed = Table.TransformColumnTypes(
        Prices,
        {{"Symbol", type text}, {"Price", type number}, {"Currency", type text},
         {"Unit", type text}, {"Updated (UTC)", type datetime}}
    )
in
    Typed

يقرأ الاستعلام المفتاح ذا البادئة المأخوذة من base في الاستجابة (EURXAU مع EUR) ويحوّل timestamp بتنسيق Unix إلى UTC. غيّر BaseCurrency وMassUnit بما يناسبك.

يُبقي ApiKeyName = "api_key" المفتاح خارج الملف: إذ يأخذه Power Query من بيانات اعتماد Web API ويُلحقه بالطلب معاملَ استعلام api_key، وهي إحدى الطرق الثلاث التي تقبل بها MetalAPI المفتاح. وتُحفظ بيانات الاعتماد في إعدادات مصدر البيانات في Excel على جهازك، لا في المصنف، لذا يُطلب من الزميل الذي يفتح الملف إدخال مفتاحه الخاص. ويمكنك تغييرها أو إزالتها من بيانات (Data) ثم الحصول على البيانات (Get Data) ثم إعدادات مصدر البيانات (Data Source Settings).

يقبل Web.Contents أيضًا Headers = [#"X-API-Key" = "..."]، لكن ذلك يحفظ المفتاح داخل المصنف. لا تستخدمه إلا للملفات التي لا تغادر جهازك أبدًا.

في الصيغ، ابحث عن الأسعار في الجدول: يُرجع =XLOOKUP("XAU", GoldPrices[Symbol], GoldPrices[Price]) سعر الذهب باليورو لكل غرام، ويؤدي INDEX مع MATCH الأمر نفسه في الإصدارات الأقدم.

حدّث أسعار الذهب في Excel تلقائيًا

لا يتحدّث جدول Power Query من تلقاء نفسه. افتح بيانات (Data) ثم الاستعلامات والاتصالات (Queries & Connections)، وانقر بزر الماوس الأيمن على الاستعلام GoldPrices واختر خصائص (Properties). ثم ضمن التحكم في التحديث (Refresh control):

  • تحديث كل N دقيقة (Refresh every N minutes) يعيد تشغيل الاستعلام وفق مؤقت.
  • تحديث البيانات عند فتح الملف (Refresh data when opening the file) يجلب أسعارًا جديدة في كل مرة يُفتح فيها المصنف.
  • تمكين التحديث في الخلفية (Enable background refresh) يُبقي Excel قابلًا للاستخدام أثناء تشغيل الاستعلام.

يحدّث الأمر تحديث الكل (Refresh All) في علامة التبويب بيانات (Data)، أو الاختصار Ctrl+Alt+F5، عند الطلب. ولا يعمل المؤقت إلا والمصنف مفتوح.

كل تحديث طلب واحد. فالتحديث كل ساعة خلال يوم عمل من ثماني ساعات يبلغ نحو 180 طلبًا شهريًا، والتحديث كل 10 دقائق نحو 1,050. وفي Free، حيث تتحدّث الأسعار يوميًا، يكفي التحديث عند فتح الملف.

أسعار الذهب التاريخية في Sheets وExcel

تأتي أسعار الإغلاق السابقة من /timeframe: مدخل واحد لكل يوم تداول بين start_date وend_date، بحد أقصى 30 يومًا لكل طلب في Free و365 في الخطط المدفوعة. وفي Excel، يعطيك استعلام ثانٍ عمودًا للتاريخ وعمودًا لكل معدن:

GoldHistory (لغة M في Power Query)
let
    Response = Json.Document(
        Web.Contents(
            "https://metalapi.com/api/v1/timeframe",
            [
                Query = [start_date = "2026-09-24", end_date = "2026-10-23", currencies = "XAU,XAG"],
                ApiKeyName = "api_key"
            ]
        )
    ),
    Days = Record.ToTable(Response[rates]),
    History = Table.FromRecords(
        List.Transform(
            Table.ToRecords(Days),
            (row) => [
                Date = Date.FromText(row[Name]),
                Gold = Record.FieldOrDefault(row[Value], Response[base] & "XAU", null),
                Silver = Record.FieldOrDefault(row[Value], Response[base] & "XAG", null)
            ]
        )
    ),
    Typed = Table.TransformColumnTypes(History, {{"Date", type date}, {"Gold", type number}, {"Silver", type number}})
in
    Typed

عطلات نهاية الأسبوع وعطلات السوق مفقودة، لذا توقّع صفوفًا أقل من أيام التقويم. وفي Apps Script، استدعِ /timeframe باستخدام UrlFetchApp بالطريقة التي تستدعي بها fetchLatest_ نقطة النهاية /latest، واكتب كل الصفوف باستدعاء setValues واحد.

أسعار الإغلاق السابقة لا تتغير أبدًا، لذا حمّل النطاق مرة واحدة واحتفظ به. ويتناول مقال أسعار الذهب والفضة التاريخية عبر API ملء البيانات السابقة لفترات طويلة وتخزينها ورسمها بيانيًا.

الخطوات التالية

أنشئ حسابًا مجانيًا، وأضف المفتاح بوصفه خاصية في النص البرمجي أو بيانات اعتماد Web API، وسيكون لديك سعر الذهب في جدول بياناتك في نحو عشر دقائق. تناسب الأسعار اليومية في خطة Free قائمة أسعار يومية أو ورقة لمحفظة؛ وللحصول على أسعار أحدث أو تحديثات أكثر، قارن الخطط في صفحة الأسعار. ويسرد توثيق API كل نقطة نهاية يمكنك استدعاؤها بالطريقة نفسها، بما فيها /convert، و/carat لأسعار الذهب حسب العيار في الخطط المدفوعة.

الأسئلة الشائعة

هل يمكنني استيراد أسعار الذهب باستخدام IMPORTDATA أو IMPORTXML بدلًا من ذلك؟

ليس من MetalAPI. فهذه الدوال تقرأ CSV أو TSV أو XML أو HTML، بينما تُرجع الواجهة JSON، ولا تستطيع إرسال ترويسة، لذا سيبقى المفتاح في الصيغة مكشوفًا لكل مشاهد.

كم مرة يتحدّث سعر الذهب في جدول بياناتي؟

بقدر ما تحدّثه أنت وبقدر ما تسمح خطتك: يوميًا في Free، وكل 30 دقيقة في Lite، وكل 10 دقائق في Standard، وأسرع في الخطط الأعلى. ومن الجمعة 17:00 حتى الأحد 17:00 بتوقيت نيويورك تكون السوق الفورية مغلقة ويبقى السعر عند إغلاق الجمعة.

كم طلب API سيستهلك جدول بياناتي؟

طلبًا واحدًا لكل تحديث لورقة Prices أو لجدول Power Query، إضافةً إلى طلب لكل عملة ووحدة حين تجلب الدوال المخصصة أسعارًا جديدة. فالمشغّل الذي يعمل كل ساعة يستهلك نحو 744 طلبًا شهريًا، واليومي نحو 31. وتُبلغ /usage عن استهلاكك دون أن تُحتسب من الحصة.

هل مشاركة جدول بيانات يجلب أسعار الذهب آمنة؟

نعم، إذا بقي المفتاح خارج الخلايا: في خاصية للنص البرمجي في Google Sheets، مع منح صلاحية التعديل فقط لمن تأتمنهم على المفتاح، وفي بيانات اعتماد Web API في Excel. واستخدم مفتاحًا منفصلًا لكل ملف مشترك حتى تستطيع إلغاءه وحده.

هل يمكنني الحصول على سعر غرام الذهب أو السعر بعملتي المحلية؟

نعم. مرّر رمز عملة وgram أو kilogram، كما في =GOLDPRICE("INR", "gram")، أو غيّر BaseCurrency وMassUnit في Power Query. وتحوّل الواجهة الأمرين من اللقطة نفسها.

جرّبه مع بياناتك الخاصة

أنشئ حسابًا مجانيًا وأرسل طلبك الأول في أقل من دقيقتين. 100 طلب شهريًا، دون بطاقة ائتمان.

تابع القراءة